[PULL 11/11] ui/cocoa: Comment about modifier key input quirks

2021-03-15 Thread Gerd Hoffmann
From: Akihiko Odaki 

Based-on: <20210310042348.21931-1-akihiko.od...@gmail.com>
Signed-off-by: Akihiko Odaki 
Message-Id: <20210312133212.3131-1-akihiko.od...@gmail.com>
Signed-off-by: Gerd Hoffmann 
---
 ui/cocoa.m | 38 +-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 9da0e884b712..37e1fb52eb4d 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -690,7 +690,43 @@ QemuCocoaView *cocoaView;
 NSPoint p = [self screenLocationOfEvent:event];
 NSUInteger modifiers = [event modifierFlags];
 
-// emulate caps lock keydown and keyup
+/*
+ * Check -[NSEvent modifierFlags] here.
+ *
+ * There is a NSEventType for an event notifying the change of
+ * -[NSEvent modifierFlags], NSEventTypeFlagsChanged but these operations
+ * are performed for any events because a modifier state may change while
+ * the application is inactive (i.e. no events fire) and we don't want to
+ * wait for another modifier state change to detect such a change.
+ *
+ * NSEventModifierFlagCapsLock requires a special treatment. The other 
flags
+ * are handled in similar manners.
+ *
+ * NSEventModifierFlagCapsLock
+ * ---
+ *
+ * If CapsLock state is changed, "up" and "down" events will be fired in
+ * sequence, effectively updates CapsLock state on the guest.
+ *
+ * The other flags
+ * ---
+ *
+ * If a flag is not set, fire "up" events for all keys which correspond to
+ * the flag. Note that "down" events are not fired here because the flags
+ * checked here do not tell what exact keys are down.
+ *
+ * If one of the keys corresponding to a flag is down, we rely on
+ * -[NSEvent keyCode] of an event whose -[NSEvent type] is
+ * NSEventTypeFlagsChanged to know the exact key which is down, which has
+ * the following two downsides:
+ * - It does not work when the application is inactive as described above.
+ * - It malfactions *after* the modifier state is changed while the
+ *   application is inactive. It is because -[NSEvent keyCode] does not 
tell
+ *   if the key is up or down, and requires to infer the current state from
+ *   the previous state. It is still possible to fix such a malfanction by
+ *   completely leaving your hands from the keyboard, which hopefully makes
+ *   this implementation usable enough.
+ */
 if (!!(modifiers & NSEventModifierFlagCapsLock) !=
 qkbd_state_modifier_get(kbd, QKBD_MOD_CAPSLOCK)) {
 qkbd_state_key_event(kbd, Q_KEY_CODE_CAPS_LOCK, true);
-- 
2.29.2




[PULL 10/11] ui: fold qemu_alloc_display in only caller

2021-03-15 Thread Gerd Hoffmann
From: Marc-André Lureau 

A minor code simplification.

Signed-off-by: Marc-André Lureau 
Message-Id: <20210312100108.2706195-2-marcandre.lur...@redhat.com>
Signed-off-by: Gerd Hoffmann 
---
 ui/console.c | 14 +++---
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/ui/console.c b/ui/console.c
index c2fdf975b6b3..2de5f4105b59 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1386,26 +1386,18 @@ static QemuConsole *new_console(DisplayState *ds, 
console_type_t console_type,
 return s;
 }
 
-static void qemu_alloc_display(DisplaySurface *surface, int width, int height)
+DisplaySurface *qemu_create_displaysurface(int width, int height)
 {
-qemu_pixman_image_unref(surface->image);
-surface->image = NULL;
+DisplaySurface *surface = g_new0(DisplaySurface, 1);
 
+trace_displaysurface_create(surface, width, height);
 surface->format = PIXMAN_x8r8g8b8;
 surface->image = pixman_image_create_bits(surface->format,
   width, height,
   NULL, width * 4);
 assert(surface->image != NULL);
-
 surface->flags = QEMU_ALLOCATED_FLAG;
-}
 
-DisplaySurface *qemu_create_displaysurface(int width, int height)
-{
-DisplaySurface *surface = g_new0(DisplaySurface, 1);
-
-trace_displaysurface_create(surface, width, height);
-qemu_alloc_display(surface, width, height);
 return surface;
 }
 
-- 
2.29.2




[PULL 08/11] ui: use client width/height in WMVi message

2021-03-15 Thread Gerd Hoffmann
From: Daniel P. Berrangé 

The WMVi message is supposed to provide the same width/height
information as the regular desktop resize and extended desktop
resize messages. There can be times where the client width and
height are different from the pixman surface dimensions.

Signed-off-by: Daniel P. Berrangé 
Reviewed-by: Marc-André Lureau 
Message-Id: <20210311182957.486939-4-berra...@redhat.com>
Signed-off-by: Gerd Hoffmann 
---
 ui/vnc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index 7291429c04cf..8c9890b3cdc4 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2319,8 +2319,8 @@ static void vnc_colordepth(VncState *vs)
 vnc_write_u8(vs, 0);
 vnc_write_u16(vs, 1); /* number of rects */
 vnc_framebuffer_update(vs, 0, 0,
-   pixman_image_get_width(vs->vd->server),
-   pixman_image_get_height(vs->vd->server),
+   vs->client_width,
+   vs->client_height,
VNC_ENCODING_WMVi);
 pixel_format_message(vs);
 vnc_unlock_output(vs);
-- 
2.29.2




[PULL 06/11] ui: add more trace points for VNC client/server messages

2021-03-15 Thread Gerd Hoffmann
From: Daniel P. Berrangé 

This adds trace points for desktop size and audio related messages.

Signed-off-by: Daniel P. Berrangé 
Reviewed-by: Marc-André Lureau 
Message-Id: <20210311182957.486939-2-berra...@redhat.com>
Signed-off-by: Gerd Hoffmann 
---
 ui/vnc.c| 21 +++--
 ui/trace-events |  9 +
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index e8e3426a65c4..7291429c04cf 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -659,6 +659,9 @@ void vnc_framebuffer_update(VncState *vs, int x, int y, int 
w, int h,
 
 static void vnc_desktop_resize_ext(VncState *vs, int reject_reason)
 {
+trace_vnc_msg_server_ext_desktop_resize(
+vs, vs->ioc, vs->client_width, vs->client_height, reject_reason);
+
 vnc_lock_output(vs);
 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
 vnc_write_u8(vs, 0);
@@ -705,6 +708,9 @@ static void vnc_desktop_resize(VncState *vs)
 return;
 }
 
+trace_vnc_msg_server_desktop_resize(
+vs, vs->ioc, vs->client_width, vs->client_height);
+
 vnc_lock_output(vs);
 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
 vnc_write_u8(vs, 0);
@@ -1182,6 +1188,7 @@ static void audio_capture_notify(void *opaque, 
audcnotification_e cmd)
 assert(vs->magic == VNC_MAGIC);
 switch (cmd) {
 case AUD_CNOTIFY_DISABLE:
+trace_vnc_msg_server_audio_end(vs, vs->ioc);
 vnc_lock_output(vs);
 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
@@ -1191,6 +1198,7 @@ static void audio_capture_notify(void *opaque, 
audcnotification_e cmd)
 break;
 
 case AUD_CNOTIFY_ENABLE:
+trace_vnc_msg_server_audio_begin(vs, vs->ioc);
 vnc_lock_output(vs);
 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
@@ -1210,6 +1218,7 @@ static void audio_capture(void *opaque, const void *buf, 
int size)
 VncState *vs = opaque;
 
 assert(vs->magic == VNC_MAGIC);
+trace_vnc_msg_server_audio_data(vs, vs->ioc, buf, size);
 vnc_lock_output(vs);
 if (vs->output.offset < vs->throttle_output_offset) {
 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
@@ -2454,9 +2463,11 @@ static int protocol_client_msg(VncState *vs, uint8_t 
*data, size_t len)
 
 switch (read_u16 (data, 2)) {
 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
+trace_vnc_msg_client_audio_enable(vs, vs->ioc);
 audio_add(vs);
 break;
 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
+trace_vnc_msg_client_audio_disable(vs, vs->ioc);
 audio_del(vs);
 break;
 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
@@ -2492,6 +2503,8 @@ static int protocol_client_msg(VncState *vs, uint8_t 
*data, size_t len)
 break;
 }
 vs->as.freq = freq;
+trace_vnc_msg_client_audio_format(
+vs, vs->ioc, vs->as.fmt, vs->as.nchannels, vs->as.freq);
 break;
 default:
 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
@@ -2510,6 +2523,7 @@ static int protocol_client_msg(VncState *vs, uint8_t 
*data, size_t len)
 {
 size_t size;
 uint8_t screens;
+int w, h;
 
 if (len < 8) {
 return 8;
@@ -2520,12 +2534,15 @@ static int protocol_client_msg(VncState *vs, uint8_t 
*data, size_t len)
 if (len < size) {
 return size;
 }
+w = read_u16(data, 2);
+h = read_u16(data, 4);
 
+trace_vnc_msg_client_set_desktop_size(vs, vs->ioc, w, h, screens);
 if (dpy_ui_info_supported(vs->vd->dcl.con)) {
 QemuUIInfo info;
 memset(, 0, sizeof(info));
-info.width = read_u16(data, 2);
-info.height = read_u16(data, 4);
+info.width = w;
+info.height = h;
 dpy_set_ui_info(vs->vd->dcl.con, );
 vnc_desktop_resize_ext(vs, 4 /* Request forwarded */);
 } else {
diff --git a/ui/trace-events b/ui/trace-events
index 0ffcdb4408a6..bd8f8a9d186a 100644
--- a/ui/trace-events
+++ b/ui/trace-events
@@ -37,6 +37,15 @@ vnc_key_event_ext(bool down, int sym, int keycode, const 
char *name) "down %d, s
 vnc_key_event_map(bool down, int sym, int keycode, const char *name) "down %d, 
sym 0x%x -> keycode 0x%x [%s]"
 vnc_key_sync_numlock(bool on) "%d"
 vnc_key_sync_capslock(bool on) "%d"
+vnc_msg_server_audio_begin(void *state, void *ioc) "VNC server msg audio begin 
state=%p ioc=%p"
+vnc_msg_server_audio_end(void *state, void *ioc) "VNC server msg audio end 
state=%p ioc=%p"
+vnc_msg_server_audio_data(void *state, void *ioc, const void *buf, size_t len) 
"VNC server msg audio data state=%p ioc=%p buf=%p len=%zd"
+vnc_msg_server_desktop_resize(void *state, void *ioc, int width, int height) 
"VNC server msg ext 

[PULL 05/11] ui/cocoa: Do not exit immediately after shutdown

2021-03-15 Thread Gerd Hoffmann
From: Akihiko Odaki 

ui/cocoa used to call exit immediately after calling
qemu_system_shutdown_request, which prevents QEMU from actually
perfoming system shutdown. Just sleep forever, and wait QEMU to call
exit and kill the Cocoa thread.

Signed-off-by: Akihiko Odaki 
Message-Id: <20210219111652.20623-1-akihiko.od...@gmail.com>
Signed-off-by: Gerd Hoffmann 
---
 ui/cocoa.m | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index a7848ae0a30e..9da0e884b712 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -1115,7 +1115,13 @@ QemuCocoaView *cocoaView;
 COCOA_DEBUG("QemuCocoaAppController: applicationWillTerminate\n");
 
 qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_UI);
-exit(0);
+
+/*
+ * Sleep here, because returning will cause OSX to kill us
+ * immediately; the QEMU main loop will handle the shutdown
+ * request and terminate the process.
+ */
+[NSThread sleepForTimeInterval:INFINITY];
 }
 
 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication 
*)theApplication
-- 
2.29.2




[PULL 00/11] Ui 20210316 patches

2021-03-15 Thread Gerd Hoffmann
The following changes since commit 6157b0e19721aadb4c7fdcfe57b2924af6144b14:

  Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-6.0-pull-=
request' into staging (2021-03-14 17:47:49 +)

are available in the Git repository at:

  git://git.kraxel.org/qemu tags/ui-20210316-pull-request

for you to fetch changes up to ad7f2f8ee9fbded410fbf77158b0065f8e2f08e3:

  ui/cocoa: Comment about modifier key input quirks (2021-03-16 06:36:45 +010=
0)


vnc+spice: password-secret option.
bugfixes for cocoa, vnc, opengl.



Akihiko Odaki (3):
  opengl: Do not convert format with glTexImage2D on OpenGL ES
  ui/cocoa: Do not exit immediately after shutdown
  ui/cocoa: Comment about modifier key input quirks

Daniel P. Berrang=C3=A9 (7):
  ui: introduce "password-secret" option for VNC servers
  ui: introduce "password-secret" option for SPICE server
  ui: deprecate "password" option for SPICE server
  ui: add more trace points for VNC client/server messages
  ui: avoid sending framebuffer updates outside client desktop bounds
  ui: use client width/height in WMVi message
  ui: honour the actual guest display dimensions without rounding

Marc-Andr=C3=A9 Lureau (1):
  ui: fold qemu_alloc_display in only caller

 ui/vnc.h   |  1 +
 ui/console-gl.c| 19 +++---
 ui/console.c   | 14 ++--
 ui/spice-core.c| 32 +++--
 ui/vnc-jobs.c  | 44 ---
 ui/vnc.c   | 71 +-
 docs/system/deprecated.rst |  8 +
 qemu-options.hx| 18 --
 ui/cocoa.m | 46 ++--
 ui/trace-events| 16 +
 10 files changed, 234 insertions(+), 35 deletions(-)

--=20
2.29.2





[PULL 01/11] ui: introduce "password-secret" option for VNC servers

2021-03-15 Thread Gerd Hoffmann
From: Daniel P. Berrangé 

Currently when using VNC the "password" flag turns on password based
authentication. The actual password has to be provided separately via
the monitor.

This introduces a "password-secret" option which lets the password be
provided up front.

  $QEMU --object secret,id=vncsec0,file=passwd.txt \
--vnc localhost:0,password-secret=vncsec0

Signed-off-by: Daniel P. Berrangé 
Message-Id: <2021034343.439820-2-berra...@redhat.com>
Signed-off-by: Gerd Hoffmann 
---
 ui/vnc.c| 23 ++-
 qemu-options.hx |  5 +
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index 310abc937812..e8e3426a65c4 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -48,6 +48,7 @@
 #include "crypto/tlscredsanon.h"
 #include "crypto/tlscredsx509.h"
 #include "crypto/random.h"
+#include "crypto/secret_common.h"
 #include "qom/object_interfaces.h"
 #include "qemu/cutils.h"
 #include "qemu/help_option.h"
@@ -3459,6 +3460,9 @@ static QemuOptsList qemu_vnc_opts = {
 },{
 .name = "password",
 .type = QEMU_OPT_BOOL,
+},{
+.name = "password-secret",
+.type = QEMU_OPT_STRING,
 },{
 .name = "reverse",
 .type = QEMU_OPT_BOOL,
@@ -3931,6 +3935,7 @@ void vnc_display_open(const char *id, Error **errp)
 int lock_key_sync = 1;
 int key_delay_ms;
 const char *audiodev;
+const char *passwordSecret;
 
 if (!vd) {
 error_setg(errp, "VNC display not active");
@@ -3948,7 +3953,23 @@ void vnc_display_open(const char *id, Error **errp)
 goto fail;
 }
 
-password = qemu_opt_get_bool(opts, "password", false);
+
+passwordSecret = qemu_opt_get(opts, "password-secret");
+if (passwordSecret) {
+if (qemu_opt_get(opts, "password")) {
+error_setg(errp,
+   "'password' flag is redundant with 'password-secret'");
+goto fail;
+}
+vd->password = qcrypto_secret_lookup_as_utf8(passwordSecret,
+ errp);
+if (!vd->password) {
+goto fail;
+}
+password = true;
+} else {
+password = qemu_opt_get_bool(opts, "password", false);
+}
 if (password) {
 if (fips_get_state()) {
 error_setg(errp,
diff --git a/qemu-options.hx b/qemu-options.hx
index 622d3bfa5a7d..357fc4596ecc 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2165,6 +2165,11 @@ SRST
 time to allow  password to expire immediately or never
 expire.
 
+``password-secret=``
+Require that password based authentication is used for client
+connections, using the password provided by the ``secret``
+object identified by ``secret-id``.
+
 ``tls-creds=ID``
 Provides the ID of a set of TLS credentials to use to secure the
 VNC server. They will apply to both the normal VNC server socket
-- 
2.29.2




[PULL 09/11] ui: honour the actual guest display dimensions without rounding

2021-03-15 Thread Gerd Hoffmann
From: Daniel P. Berrangé 

A long time ago the VNC server code had some memory corruption
fixes done in:

  commit bea60dd7679364493a0d7f5b54316c767cf894ef
  Author: Peter Lieven 
  Date:   Mon Jun 30 10:57:51 2014 +0200

ui/vnc: fix potential memory corruption issues

One of the implications of the fix was that the VNC server would have a
thin black bad down the right hand side if the guest desktop width was
not a multiple of 16. In practice this was a non-issue since the VNC
server was always honouring a guest specified resolution and guests
essentially always pick from a small set of sane resolutions likely in
real world hardware.

We recently introduced support for the extended desktop resize extension
and as a result the VNC client has ability to specify an arbitrary
desktop size and the guest OS may well honour it exactly. As a result we
no longer have any guarantee that the width will be a multiple of 16,
and so when resizing the desktop we have a 93% chance of getting the
black bar on the right hand size.

The VNC server maintains three different desktop dimensions

 1. The guest surface
 2. The server surface
 3. The client desktop

The requirement for the width to be a multiple of 16 only applies to
item 2, the server surface, for the purpose of doing dirty bitmap
tracking.

Normally we will set the client desktop size to always match the server
surface size, but that's not a strict requirement. In order to cope with
clients that don't support the desktop size encoding, we already allow
for the client desktop to be a different size that the server surface.

Thus we can trivially eliminate the black bar, but setting the client
desktop size to be the un-rounded server surface size - the so called
"true width".

Signed-off-by: Daniel P. Berrangé 
Reviewed-by: Marc-André Lureau 
Message-Id: <20210311182957.486939-5-berra...@redhat.com>
Signed-off-by: Gerd Hoffmann 
---
 ui/vnc.h|  1 +
 ui/vnc.c| 23 +++
 ui/trace-events |  2 ++
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/ui/vnc.h b/ui/vnc.h
index 116463d5f099..d4f3e1555809 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -164,6 +164,7 @@ struct VncDisplay
 
 struct VncSurface guest;   /* guest visible surface (aka ds->surface) */
 pixman_image_t *server;/* vnc server surface */
+int true_width; /* server surface width before rounding up */
 
 const char *id;
 QTAILQ_ENTRY(VncDisplay) next;
diff --git a/ui/vnc.c b/ui/vnc.c
index 8c9890b3cdc4..9c004a11f495 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -608,6 +608,11 @@ static int vnc_width(VncDisplay *vd)
VNC_DIRTY_PIXELS_PER_BIT));
 }
 
+static int vnc_true_width(VncDisplay *vd)
+{
+return MIN(VNC_MAX_WIDTH, surface_width(vd->ds));
+}
+
 static int vnc_height(VncDisplay *vd)
 {
 return MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
@@ -691,16 +696,16 @@ static void vnc_desktop_resize(VncState *vs)
 !vnc_has_feature(vs, VNC_FEATURE_RESIZE_EXT))) {
 return;
 }
-if (vs->client_width == pixman_image_get_width(vs->vd->server) &&
+if (vs->client_width == vs->vd->true_width &&
 vs->client_height == pixman_image_get_height(vs->vd->server)) {
 return;
 }
 
-assert(pixman_image_get_width(vs->vd->server) < 65536 &&
-   pixman_image_get_width(vs->vd->server) >= 0);
+assert(vs->vd->true_width < 65536 &&
+   vs->vd->true_width >= 0);
 assert(pixman_image_get_height(vs->vd->server) < 65536 &&
pixman_image_get_height(vs->vd->server) >= 0);
-vs->client_width = pixman_image_get_width(vs->vd->server);
+vs->client_width = vs->vd->true_width;
 vs->client_height = pixman_image_get_height(vs->vd->server);
 
 if (vnc_has_feature(vs, VNC_FEATURE_RESIZE_EXT)) {
@@ -774,6 +779,7 @@ static void vnc_update_server_surface(VncDisplay *vd)
 
 width = vnc_width(vd);
 height = vnc_height(vd);
+vd->true_width = vnc_true_width(vd);
 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
   width, height,
   NULL, 0);
@@ -809,13 +815,22 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl,
 vd->guest.fb = pixman_image_ref(surface->image);
 vd->guest.format = surface->format;
 
+
 if (pageflip) {
+trace_vnc_server_dpy_pageflip(vd,
+  surface_width(surface),
+  surface_height(surface),
+  surface_format(surface));
 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
surface_width(surface),
surface_height(surface));
 return;
 }
 
+trace_vnc_server_dpy_recreate(vd,
+  surface_width(surface),
+  surface_height(surface),
+   

[PULL 03/11] ui: deprecate "password" option for SPICE server

2021-03-15 Thread Gerd Hoffmann
From: Daniel P. Berrangé 

With the new "password-secret" option, there is no reason to use the old
inecure "password" option with -spice, so it can be deprecated.

Signed-off-by: Daniel P. Berrangé 
Message-Id: <2021034343.439820-4-berra...@redhat.com>
Signed-off-by: Gerd Hoffmann 
---
 ui/spice-core.c| 2 ++
 docs/system/deprecated.rst | 8 
 qemu-options.hx| 4 
 3 files changed, 14 insertions(+)

diff --git a/ui/spice-core.c b/ui/spice-core.c
index b9d8aced91df..272d19b0c152 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -686,6 +686,8 @@ static void qemu_spice_init(void)
 } else {
 str = qemu_opt_get(opts, "password");
 if (str) {
+warn_report("'password' option is deprecated and insecure, "
+"use 'password-secret' instead");
 password = g_strdup(str);
 }
 }
diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst
index 5e3a31c12361..8cba672a7b4a 100644
--- a/docs/system/deprecated.rst
+++ b/docs/system/deprecated.rst
@@ -174,6 +174,14 @@ Input parameters that take a size value should only use a 
size suffix
 the value is hexadecimal.  That is, '0x20M' is deprecated, and should
 be written either as '32M' or as '0x200'.
 
+``-spice password=string`` (since 6.0)
+''
+
+This option is insecure because the SPICE password remains visible in
+the process listing. This is replaced by the new ``password-secret``
+option which lets the password be securely provided on the command
+line using a ``secret`` object instance.
+
 QEMU Machine Protocol (QMP) commands
 
 
diff --git a/qemu-options.hx b/qemu-options.hx
index a98f8e84a29d..4da3f4f48c03 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1928,6 +1928,10 @@ SRST
 ``password=``
 Set the password you need to authenticate.
 
+This option is deprecated and insecure because it leaves the
+password visible in the process listing. Use ``password-secret``
+instead.
+
 ``password-secret=``
 Set the ID of the ``secret`` object containing the password
 you need to authenticate.
-- 
2.29.2




[PULL 04/11] opengl: Do not convert format with glTexImage2D on OpenGL ES

2021-03-15 Thread Gerd Hoffmann
From: Akihiko Odaki 

OpenGL ES does not support conversion from the given data format
to the internal format with glTexImage2D.

Use the given data format as the internal format, and ignore
the given alpha channels with GL_TEXTURE_SWIZZLE_A in case the
format contains alpha channels.

Signed-off-by: Akihiko Odaki 
Message-Id: <20210219094803.90860-1-akihiko.od...@gmail.com>
Signed-off-by: Gerd Hoffmann 
---
 ui/console-gl.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/ui/console-gl.c b/ui/console-gl.c
index 0a6478161fed..7c9894a51d99 100644
--- a/ui/console-gl.c
+++ b/ui/console-gl.c
@@ -73,11 +73,20 @@ void surface_gl_create_texture(QemuGLShader *gls,
 glBindTexture(GL_TEXTURE_2D, surface->texture);
 glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT,
   surface_stride(surface) / surface_bytes_per_pixel(surface));
-glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
- surface_width(surface),
- surface_height(surface),
- 0, surface->glformat, surface->gltype,
- surface_data(surface));
+if (epoxy_is_desktop_gl()) {
+glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
+ surface_width(surface),
+ surface_height(surface),
+ 0, surface->glformat, surface->gltype,
+ surface_data(surface));
+} else {
+glTexImage2D(GL_TEXTURE_2D, 0, surface->glformat,
+ surface_width(surface),
+ surface_height(surface),
+ 0, surface->glformat, surface->gltype,
+ surface_data(surface));
+glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE);
+}
 
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-- 
2.29.2




[PULL 02/11] ui: introduce "password-secret" option for SPICE server

2021-03-15 Thread Gerd Hoffmann
From: Daniel P. Berrangé 

Currently when using SPICE the "password" option provides the password
in plain text on the command line. This is insecure as it is visible
to all processes on the host. As an alternative, the password can be
provided separately via the monitor.

This introduces a "password-secret" option which lets the password be
provided up front.

  $QEMU --object secret,id=vncsec0,file=passwd.txt \
--spice port=5901,password-secret=vncsec0

Signed-off-by: Daniel P. Berrangé 
Message-Id: <2021034343.439820-3-berra...@redhat.com>
Signed-off-by: Gerd Hoffmann 
---
 ui/spice-core.c | 30 --
 qemu-options.hx |  9 +++--
 2 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/ui/spice-core.c b/ui/spice-core.c
index cadec766fe3a..b9d8aced91df 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -34,6 +34,7 @@
 #include "qapi/qapi-events-ui.h"
 #include "qemu/notify.h"
 #include "qemu/option.h"
+#include "crypto/secret_common.h"
 #include "migration/misc.h"
 #include "hw/pci/pci_bus.h"
 #include "ui/spice-display.h"
@@ -415,6 +416,9 @@ static QemuOptsList qemu_spice_opts = {
 },{
 .name = "password",
 .type = QEMU_OPT_STRING,
+},{
+.name = "password-secret",
+.type = QEMU_OPT_STRING,
 },{
 .name = "disable-ticketing",
 .type = QEMU_OPT_BOOL,
@@ -636,7 +640,9 @@ void qemu_spice_display_init_done(void)
 static void qemu_spice_init(void)
 {
 QemuOpts *opts = QTAILQ_FIRST(_spice_opts.head);
-const char *password, *str, *x509_dir, *addr,
+char *password = NULL;
+const char *passwordSecret;
+const char *str, *x509_dir, *addr,
 *x509_key_password = NULL,
 *x509_dh_file = NULL,
 *tls_ciphers = NULL;
@@ -663,7 +669,26 @@ static void qemu_spice_init(void)
 error_report("spice tls-port is out of range");
 exit(1);
 }
-password = qemu_opt_get(opts, "password");
+passwordSecret = qemu_opt_get(opts, "password-secret");
+if (passwordSecret) {
+Error *local_err = NULL;
+if (qemu_opt_get(opts, "password")) {
+error_report("'password' option is mutually exclusive with "
+ "'password-secret'");
+exit(1);
+}
+password = qcrypto_secret_lookup_as_utf8(passwordSecret,
+ _err);
+if (!password) {
+error_report_err(local_err);
+exit(1);
+}
+} else {
+str = qemu_opt_get(opts, "password");
+if (str) {
+password = g_strdup(str);
+}
+}
 
 if (tls_port) {
 x509_dir = qemu_opt_get(opts, "x509-dir");
@@ -809,6 +834,7 @@ static void qemu_spice_init(void)
 g_free(x509_key_file);
 g_free(x509_cert_file);
 g_free(x509_cacert_file);
+g_free(password);
 
 #ifdef HAVE_SPICE_GL
 if (qemu_opt_get_bool(opts, "gl", 0)) {
diff --git a/qemu-options.hx b/qemu-options.hx
index 357fc4596ecc..a98f8e84a29d 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1899,7 +1899,8 @@ DEF("spice", HAS_ARG, QEMU_OPTION_spice,
 "   [,tls-ciphers=]\n"
 "   [,tls-channel=[main|display|cursor|inputs|record|playback]]\n"
 "   
[,plaintext-channel=[main|display|cursor|inputs|record|playback]]\n"
-"   [,sasl=on|off][,password=][,disable-ticketing=on|off]\n"
+"   [,sasl=on|off][,disable-ticketing=on|off]\n"
+"   [,password=][,password-secret=]\n"
 "   [,image-compression=[auto_glz|auto_lz|quic|glz|lz|off]]\n"
 "   [,jpeg-wan-compression=[auto|never|always]]\n"
 "   [,zlib-glz-wan-compression=[auto|never|always]]\n"
@@ -1924,9 +1925,13 @@ SRST
 ``ipv4=on|off``; \ ``ipv6=on|off``; \ ``unix=on|off``
 Force using the specified IP version.
 
-``password=``
+``password=``
 Set the password you need to authenticate.
 
+``password-secret=``
+Set the ID of the ``secret`` object containing the password
+you need to authenticate.
+
 ``sasl=on|off``
 Require that the client use SASL to authenticate with the spice.
 The exact choice of authentication method used is controlled
-- 
2.29.2




[PULL 07/11] ui: avoid sending framebuffer updates outside client desktop bounds

2021-03-15 Thread Gerd Hoffmann
From: Daniel P. Berrangé 

We plan framebuffer update rects based on the VNC server surface. If the
client doesn't support desktop resize, then the client bounds may differ
from the server surface bounds. VNC clients may become upset if we then
send an update message outside the bounds of the client desktop.

This takes the approach of clamping the rectangles from the worker
thread immediately before sending them. This may sometimes results in
sending a framebuffer update message with zero rectangles.

Signed-off-by: Daniel P. Berrangé 
Reviewed-by: Marc-André Lureau 
Message-Id: <20210311182957.486939-3-berra...@redhat.com>
Signed-off-by: Gerd Hoffmann 
---
 ui/vnc-jobs.c   | 44 
 ui/trace-events |  5 +
 2 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c
index dbbfbefe5619..4562bf89288e 100644
--- a/ui/vnc-jobs.c
+++ b/ui/vnc-jobs.c
@@ -32,6 +32,7 @@
 #include "qemu/sockets.h"
 #include "qemu/main-loop.h"
 #include "block/aio.h"
+#include "trace.h"
 
 /*
  * Locking:
@@ -94,6 +95,8 @@ int vnc_job_add_rect(VncJob *job, int x, int y, int w, int h)
 {
 VncRectEntry *entry = g_new0(VncRectEntry, 1);
 
+trace_vnc_job_add_rect(job->vs, job, x, y, w, h);
+
 entry->rect.x = x;
 entry->rect.y = y;
 entry->rect.w = w;
@@ -190,6 +193,8 @@ static void vnc_async_encoding_start(VncState *orig, 
VncState *local)
 local->zlib = orig->zlib;
 local->hextile = orig->hextile;
 local->zrle = orig->zrle;
+local->client_width = orig->client_width;
+local->client_height = orig->client_height;
 }
 
 static void vnc_async_encoding_end(VncState *orig, VncState *local)
@@ -202,6 +207,34 @@ static void vnc_async_encoding_end(VncState *orig, 
VncState *local)
 orig->lossy_rect = local->lossy_rect;
 }
 
+static bool vnc_worker_clamp_rect(VncState *vs, VncJob *job, VncRect *rect)
+{
+trace_vnc_job_clamp_rect(vs, job, rect->x, rect->y, rect->w, rect->h);
+
+if (rect->x >= vs->client_width) {
+goto discard;
+}
+rect->w = MIN(vs->client_width - rect->x, rect->w);
+if (rect->w == 0) {
+goto discard;
+}
+
+if (rect->y >= vs->client_height) {
+goto discard;
+}
+rect->h = MIN(vs->client_height - rect->y, rect->h);
+if (rect->h == 0) {
+goto discard;
+}
+
+trace_vnc_job_clamped_rect(vs, job, rect->x, rect->y, rect->w, rect->h);
+return true;
+
+ discard:
+trace_vnc_job_discard_rect(vs, job, rect->x, rect->y, rect->w, rect->h);
+return false;
+}
+
 static int vnc_worker_thread_loop(VncJobQueue *queue)
 {
 VncJob *job;
@@ -260,14 +293,17 @@ static int vnc_worker_thread_loop(VncJobQueue *queue)
 goto disconnected;
 }
 
-n = vnc_send_framebuffer_update(, entry->rect.x, entry->rect.y,
-entry->rect.w, entry->rect.h);
+if (vnc_worker_clamp_rect(, job, >rect)) {
+n = vnc_send_framebuffer_update(, entry->rect.x, entry->rect.y,
+entry->rect.w, entry->rect.h);
 
-if (n >= 0) {
-n_rectangles += n;
+if (n >= 0) {
+n_rectangles += n;
+}
 }
 g_free(entry);
 }
+trace_vnc_job_nrects(, job, n_rectangles);
 vnc_unlock_display(job->vs->vd);
 
 /* Put n_rectangles at the beginning of the message */
diff --git a/ui/trace-events b/ui/trace-events
index bd8f8a9d186a..3838ae2d849a 100644
--- a/ui/trace-events
+++ b/ui/trace-events
@@ -59,6 +59,11 @@ vnc_client_throttle_audio(void *state, void *ioc, size_t 
offset) "VNC client thr
 vnc_client_unthrottle_forced(void *state, void *ioc) "VNC client unthrottle 
forced offset state=%p ioc=%p"
 vnc_client_unthrottle_incremental(void *state, void *ioc, size_t offset) "VNC 
client unthrottle incremental state=%p ioc=%p offset=%zu"
 vnc_client_output_limit(void *state, void *ioc, size_t offset, size_t 
threshold) "VNC client output limit state=%p ioc=%p offset=%zu threshold=%zu"
+vnc_job_add_rect(void *state, void *job, int x, int y, int w, int h) "VNC add 
rect state=%p job=%p offset=%d,%d size=%dx%d"
+vnc_job_discard_rect(void *state, void *job, int x, int y, int w, int h) "VNC 
job discard rect state=%p job=%p offset=%d,%d size=%dx%d"
+vnc_job_clamp_rect(void *state, void *job, int x, int y, int w, int h) "VNC 
job clamp rect state=%p job=%p offset=%d,%d size=%dx%d"
+vnc_job_clamped_rect(void *state, void *job, int x, int y, int w, int h) "VNC 
job clamp rect state=%p job=%p offset=%d,%d size=%dx%d"
+vnc_job_nrects(void *state, void *job, int nrects) "VNC job state=%p job=%p 
nrects=%d"
 vnc_auth_init(void *display, int websock, int auth, int subauth) "VNC auth 
init state=%p websock=%d auth=%d subauth=%d"
 vnc_auth_start(void *state, int method) "VNC client auth start state=%p 
method=%d"
 vnc_auth_pass(void *state, int method) "VNC client auth passed state=%p 
method=%d"
-- 

Bug in tlbi_aa64_vae2is_write: tlbbits_for_regime called with swapped ARMMMUIdx_ values?

2021-03-15 Thread Rebecca Cran
I noticed the following in tlbi_aa64_vae2is_write: it appears that when 
calling tlbbits_for_regime the ARMMMUIdx values are swapped?


static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
   uint64_t value)
{
CPUState *cs = env_cpu(env);
uint64_t pageaddr = sextract64(value << 12, 0, 56);
bool secure = arm_is_secure_below_el3(env);
int mask = secure ? ARMMMUIdxBit_SE2 : ARMMMUIdxBit_E2;
int bits = tlbbits_for_regime(env, secure ? ARMMMUIdx_E2 : 
ARMMMUIdx_SE2,

  pageaddr);

tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, 
bits);

}

--
Rebecca Cran



Re: [RFC PATCH] configure: Poison (almost) all target-specific #defines

2021-03-15 Thread Thomas Huth

On 15/03/2021 19.24, Eric Blake wrote:

On 3/15/21 8:54 AM, Thomas Huth wrote:

We are generating a lot of target-specific defines in the *-config-devices.h
and *-config-target.h files. Using them in common code is wrong and leads
to very subtle bugs since a "#ifdef CONFIG_SOMETHING" is not working there
as expected. To avoid these issues, we are already poisoning some of the
macros in include/exec/poison.h - but maintaining this list manually is
cumbersome. Thus let's generate the list of poisoned macros automatically
instead.
Note that CONFIG_TCG (which is also defined in config-host.h) and
CONFIG_USER_ONLY are special, so we have to filter these out.

Signed-off-by: Thomas Huth 
---
  RFC since the shell stuff in "configure" is quite ugly ... maybe there's
  a better way to do this via meson, but my meson-foo is still lacking...




+++ b/configure
@@ -6441,6 +6441,11 @@ if test -n "${deprecated_features}"; then
  echo "  features: ${deprecated_features}"
  fi
  
+cat *-config-devices.h *-config-target.h | grep '^#define '  \

+| grep -v CONFIG_TCG | grep -v CONFIG_USER_ONLY \
+| sed -e 's/#define //' -e 's/ .*//' | sort -u \
+| sed -e 's/^/#pragma GCC poison /' > config-poison.h


Most times, a 'grep | sed' pipeline can be rewritten in pure sed.  In
this case:

cat *-config-devices.h *-config-target.h | \
   sed -n -e '/^#define / { s///; /CONFIG_TCG/d; /CONFIG_USER_ONLY/d;' \
  -e 's/ .*//; s/^/#pragma GCC poison /p; }' | \
   sort -u > config-poison.h


Thanks! I'll update my patch and use your suggestion (unless someone comes 
up with some Meson magic to do it there instead)


 Thomas





Re: [PATCH] migration: Move populate_vfio_info() into a separate file

2021-03-15 Thread Thomas Huth

On 15/03/2021 22.05, Philippe Mathieu-Daudé wrote:

Hi Thomas,

+Alex

On 3/15/21 8:07 PM, Thomas Huth wrote:

The CONFIG_VFIO switch only works in target specific code. Since
migration/migration.c is common code, the #ifdef does not have
the intended behavior here. Move the related code to a separate
file now which gets compiled via specific_ss instead.

Fixes: 3710586caa ("qapi: Add VFIO devices migration stats in Migration stats")
Signed-off-by: Thomas Huth 
---
  migration/meson.build |  3 ++-
  migration/migration.c | 15 ---
  migration/migration.h |  2 ++
  migration/special.c   | 25 +
  4 files changed, 29 insertions(+), 16 deletions(-)
  create mode 100644 migration/special.c

diff --git a/migration/meson.build b/migration/meson.build
index 9645f44005..e1f72f6ba0 100644
--- a/migration/meson.build
+++ b/migration/meson.build
@@ -30,4 +30,5 @@ softmmu_ss.add(when: ['CONFIG_RDMA', rdma], if_true: 
files('rdma.c'))
  softmmu_ss.add(when: 'CONFIG_LIVE_BLOCK_MIGRATION', if_true: files('block.c'))
  softmmu_ss.add(when: zstd, if_true: files('multifd-zstd.c'))
  
-specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: files('dirtyrate.c', 'ram.c'))

+specific_ss.add(when: 'CONFIG_SOFTMMU',
+if_true: files('dirtyrate.c', 'ram.c', 'special.c'))


Why not simply name this migration/vfio.c? That way we do not start
mixed bag of everything target specific.


I don't mind ... well, if we have other small functions there in the future 
that depend on CONFIG switches, a mixed bag file might not be such a bad 
idea instead of having lots and lots of small other files ... OTOH, if there 
is more vfio migration code in the works that might fit here, a name like 
vfio.c would be better, of course. What do the maintainers think?


 Thomas




Re: [PATCH] hw/i8254: fix vmstate load

2021-03-15 Thread Pavel Dovgalyuk

On 15.03.2021 23:13, Dr. David Alan Gilbert wrote:

* Pavel Dovgalyuk (pavel.dovgal...@ispras.ru) wrote:

QEMU timer of channel 0 in i8254 is used to raise irq
at the specified moment of time. This irq can be disabled
with irq_disabled flag. But when vmstate of the pit is
loaded, timer may be rearmed despite the disabled interrupts.
This patch adds irq_disabled flag check to fix that.

Signed-off-by: Pavel Dovgalyuk 


Hi Pavel,
   I'm curious, did you see this cause a problem on a particular guest
OS?


That was Windows 7 on i386.
I found this when tested reverse debugging.



Dave


---
  hw/timer/i8254.c |2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/timer/i8254.c b/hw/timer/i8254.c
index c01ee2c72a..c8388ea432 100644
--- a/hw/timer/i8254.c
+++ b/hw/timer/i8254.c
@@ -324,7 +324,7 @@ static void pit_post_load(PITCommonState *s)
  {
  PITChannelState *sc = >channels[0];
  
-if (sc->next_transition_time != -1) {

+if (sc->next_transition_time != -1 && !sc->irq_disabled) {
  timer_mod(sc->irq_timer, sc->next_transition_time);
  } else {
  timer_del(sc->irq_timer);







Re: [PATCH 06/38] target/riscv: SIMD 16-bit Shift Instructions

2021-03-15 Thread LIU Zhiwei




On 2021/3/16 5:25, Alistair Francis wrote:

On Fri, Feb 12, 2021 at 10:16 AM LIU Zhiwei  wrote:

Signed-off-by: LIU Zhiwei 
---
  target/riscv/helper.h   |   9 ++
  target/riscv/insn32.decode  |  17 
  target/riscv/insn_trans/trans_rvp.c.inc | 115 
  target/riscv/packed_helper.c| 104 +
  4 files changed, 245 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index a69a6b4e84..20bf400ac2 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1184,3 +1184,12 @@ DEF_HELPER_3(rsub8, tl, env, tl, tl)
  DEF_HELPER_3(ursub8, tl, env, tl, tl)
  DEF_HELPER_3(ksub8, tl, env, tl, tl)
  DEF_HELPER_3(uksub8, tl, env, tl, tl)
+
+DEF_HELPER_3(sra16, tl, env, tl, tl)
+DEF_HELPER_3(sra16_u, tl, env, tl, tl)
+DEF_HELPER_3(srl16, tl, env, tl, tl)
+DEF_HELPER_3(srl16_u, tl, env, tl, tl)
+DEF_HELPER_3(sll16, tl, env, tl, tl)
+DEF_HELPER_3(ksll16, tl, env, tl, tl)
+DEF_HELPER_3(kslra16, tl, env, tl, tl)
+DEF_HELPER_3(kslra16_u, tl, env, tl, tl)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 358dd1fa10..6f053bfeb7 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -23,6 +23,7 @@
  %rd7:5

  %sh1020:10
+%sh420:4
  %csr20:12
  %rm 12:3
  %nf 29:3 !function=ex_plus_1
@@ -59,6 +60,7 @@
  @j     . ...   imm=%imm_j  
%rd

  @sh  ..  .. .  ... . ...   shamt=%sh10  
%rs1 %rd
+@sh4 ..  .. .  ... . ...   shamt=%sh4  %rs1 
%rd
  @csr    .  ... . ...   %csr %rs1 
%rd

  @atom_ld . aq:1 rl:1 .  . ...  rs2=0 %rs1 
%rd
@@ -635,3 +637,18 @@ rsub8  101  . . 000 . 111 @r
  ursub8 0010101  . . 000 . 111 @r
  ksub8  0001101  . . 000 . 111 @r
  uksub8 0011101  . . 000 . 111 @r
+
+sra16  0101000  . . 000 . 111 @r
+sra16_u011  . . 000 . 111 @r
+srai16 0111000  0 . 000 . 111 @sh4
+srai16_u   0111000  1 . 000 . 111 @sh4
+srl16  0101001  . . 000 . 111 @r
+srl16_u0110001  . . 000 . 111 @r
+srli16 0111001  0 . 000 . 111 @sh4
+srli16_u   0111001  1 . 000 . 111 @sh4
+sll16  0101010  . . 000 . 111 @r
+slli16 0111010  0 . 000 . 111 @sh4
+ksll16 0110010  . . 000 . 111 @r
+kslli160111010  1 . 000 . 111 @sh4
+kslra160101011  . . 000 . 111 @r
+kslra16_u  0110011  . . 000 . 111 @r
diff --git a/target/riscv/insn_trans/trans_rvp.c.inc 
b/target/riscv/insn_trans/trans_rvp.c.inc
index 109f560ec9..848edab7e5 100644
--- a/target/riscv/insn_trans/trans_rvp.c.inc
+++ b/target/riscv/insn_trans/trans_rvp.c.inc
@@ -238,3 +238,118 @@ GEN_RVP_R_OOL(rsub8);
  GEN_RVP_R_OOL(ursub8);
  GEN_RVP_R_OOL(ksub8);
  GEN_RVP_R_OOL(uksub8);
+
+/* 16-bit Shift Instructions */
+static bool rvp_shift_ool(DisasContext *ctx, arg_r *a,
+  gen_helper_rvp_r *fn, target_ulong mask)
+{
+TCGv src1, src2, dst;
+
+src1 = tcg_temp_new();
+src2 = tcg_temp_new();
+dst = tcg_temp_new();
+
+gen_get_gpr(src1, a->rs1);
+gen_get_gpr(src2, a->rs2);
+tcg_gen_andi_tl(src2, src2, mask);
+
+fn(dst, cpu_env, src1, src2);
+gen_set_gpr(a->rd, dst);
+
+tcg_temp_free(src1);
+tcg_temp_free(src2);
+tcg_temp_free(dst);
+return true;
+}
+
+typedef void GenGvecShift(unsigned, uint32_t, uint32_t, TCGv_i32,
+  uint32_t, uint32_t);
+static inline bool
+rvp_shift(DisasContext *ctx, arg_r *a, uint8_t vece,
+  GenGvecShift *f64, gen_helper_rvp_r *fn,
+  uint8_t mask)
+{
+if (!has_ext(ctx, RVP)) {
+return false;
+}
+
+#ifdef TARGET_RISCV64

Hmm

I don't want to add any more #defines on the RISC-V xlen. We are
trying to make the QEMU RISC-V implementation xlen independent.

I noticed the change, but was not quite clear about the benefit of it.

Could you give a brief explanation?

Can you use `riscv_cpu_is_32bit(env)` instead, here are everywhere
else you add a #define TARGET... ?

Sure, I think there are two ways.

1) Get env from the current_cpu, then call riscv_cpu_is_32bit(env).

It's some strange,  because I can't find current_cpu reference from many 
archs.


I don't know whether it has side effects.

2)  Add a similar function cpu_is_32bit(DisasContext *ctx).

In this way, the type of  misa field  in struct DisasContext should be 
target_ulong.

Currently, the type of misa filed is uint32_t.

Do you think which one is better? Thanks very much.

Zhiwei


Alistair


+if (a->rd && a->rs1 && a->rs2) {
+TCGv_i32 shift = tcg_temp_new_i32();

Re: [PATCH v2 03/13] net: slirp: Pad short frames to minimum size before send

2021-03-15 Thread Jason Wang



在 2021/3/15 下午3:57, Bin Meng 写道:

The minimum Ethernet frame length is 60 bytes. For short frames with
smaller length like ARP packets (only 42 bytes), on a real world NIC
it can choose either padding its length to the minimum required 60
bytes, or sending it out directly to the wire. Such behavior can be
hardcoded or controled by a register bit. Similarly on the receive
path, NICs can choose either dropping such short frames directly or
handing them over to software to handle.

On the other hand, for the network backends like SLiRP/TAP, they
don't expose a way to control the short frame behavior. As of today
they just send/receive data from/to the other end connected to them,
which means any sized packet is acceptable. So they can send and
receive short frames without any problem. It is observed that ARP
packets sent from SLiRP/TAP are 42 bytes, and SLiRP/TAP just send
these ARP packets to the other end which might be a NIC model that
does not allow short frames to pass through.

To provide better compatibility, for packets sent from QEMU network
backends, we change to pad short frames before sending it out to the
other end. This ensures a backend as an Ethernet sender does not
violate the spec. But with this change, the behavior of dropping
short frames in the NIC model cannot be emulated because it always
receives a packet that is spec complaint. The capability of sending
short frames from NIC models cannot be supported as well.

This commit should be able to fix the issue as reported with some
NIC models before, that ARP requests get dropped, preventing the
guest from becoming visible on the network. It was workarounded in
these NIC models on the receive path, that when a short frame is
received, it is padded up to 60 bytes.

The following 2 commits seem to be the one to workaround this issue
in e1000 and vmxenet3 before, and should probably be reverted.

   commit 78aeb23eded2 ("e1000: Pad short frames to minimum size (60 bytes)")
   commit 40a87c6c9b11 ("vmxnet3: Pad short frames to minimum size (60 bytes)")

Signed-off-by: Bin Meng 
---

  net/slirp.c | 12 
  1 file changed, 12 insertions(+)

diff --git a/net/slirp.c b/net/slirp.c
index be914c0be0..ad2db03182 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -31,6 +31,7 @@
  #include 
  #include 
  #endif
+#include "net/eth.h"
  #include "net/net.h"
  #include "clients.h"
  #include "hub.h"
@@ -115,6 +116,17 @@ static ssize_t net_slirp_send_packet(const void *pkt, 
size_t pkt_len,
   void *opaque)
  {
  SlirpState *s = opaque;
+uint8_t min_buf[ETH_ZLEN];
+
+if (!s->nc.peer->do_not_pad) {
+/* Pad to minimum Ethernet frame length */
+if (pkt_len < ETH_ZLEN) {
+memcpy(min_buf, pkt, pkt_len);
+memset(_buf[pkt_len], 0, ETH_ZLEN - pkt_len);
+pkt = min_buf;
+pkt_len = ETH_ZLEN;
+}
+}



Let's introduce a helper for this padding then it could be reused by at 
least TAP?


Thanks


  
  return qemu_send_packet(>nc, pkt, pkt_len);

  }





Re: Windows 10 won't run on default x86_64 machine anymore

2021-03-15 Thread Isaku Yamahata
On Mon, Mar 15, 2021 at 11:27:29PM +0100,
Reinoud Zandijk  wrote:

> On Mon, Mar 15, 2021 at 06:53:02PM +0100, Igor Mammedov wrote:
> > Windows 10 1607x64 boots fine when I test it with default machine.
> > 
> > So
> >   1) can you provide full QEMU command line used
> >   2) What Windows build do you use
> >   3) is it existing guest image (i.e. installed in older QEMU version)
> 
> I've used:
> 
> qemu-system-x86_64 -m 4G -smp cores=2 -accel nvmm \
>   -snapshot \
>   -drive file=/home/reinoud/Downloads/Win10-demo.raw,format=raw \
>   -rtc base=localtime,clock=host \
>   -spice port=5924,disable-ticketing=on \
>   -vga qxl \
>   -usb -device usb-tablet \
>   -net nic -net tap,ifname=tap0,script=no &
> 
> If I add in '-M pc-i440fx-5.2' it works again with the accelerator. If I add
> in '-M q35' it does work fine with or without the accelerator.

Anyhow, can you please try "-global PIIX4_PM.smm-compat=on"
(or "-global ICH9-LPC.smm-compat=on" if q35 is used) so that the old behavior
is presented.


> Surprisingly without accelerator ie with tcg the default machine does seem to
> get to the login prompt. Is the ACPI data tailored to indicate an
> accelerator/VM or is it static? Could it be that the CPU reported by my
> machine is causing the issue? With the NVMM accelerator it passes on the hosts

I think tcg case can be explained by x86_machine_is_smm_enabled()

  bool x86_machine_is_smm_enabled(const X86MachineState *x86ms)
  ...
  if (tcg_enabled() || qtest_enabled()) {
  smm_available = true;
  } else if (kvm_enabled()) {
  smm_available = kvm_has_smm();
  }
  ...

Although I don't know about nvmm case, this function also needs to be updated
if smi isn't supported.

Thanks,


> CPU:
> 
> cpu0: "Intel(R) Celeron(R) 2957U @ 1.40GHz"
> cpu0: Intel 4th gen Core, Xeon E3-12xx v3 (Haswell) (686-class), 1396.77 MHz
> cpu0: family 0x6 model 0x45 stepping 0x1 (id 0x40651)
> 
> Running with NVMM gives the following warnings that might be relevant though
> doesn't seem to bother the BSDs nor Linux last time I tried and Google tells
> me they are power saving related MSRs:
> 
> qemu-system-x86_64: NVMM: Unexpected RDMSR 0x611, ignored
> qemu-system-x86_64: NVMM: Unexpected RDMSR 0x641, ignored
> qemu-system-x86_64: NVMM: Unexpected RDMSR 0x606, ignored
> qemu-system-x86_64: NVMM: Unexpected RDMSR 0x606, ignored
> qemu-system-x86_64: NVMM: Unexpected RDMSR 0x641, ignored
> qemu-system-x86_64: NVMM: Unexpected RDMSR 0x611, ignored
> 
> I am not sure if that makes ACPI take a different route or not.
> 
> The Windows used is
>   Windows 10 Enterprise Evaluation
>   Build 17763.rs5_release.180914-1434
>   version 1809
> 
> The image file was downloaded pre-installed from Microsoft for Edge browser
> evaluation. I used it first on Qemu 5.1 IIRC and it kept working in Qemu 5.2.
> 
> The NVMM accelerator was presented here before but is not yet committed. Its
> API/construction is similar to WHPX.
> 
> As for the cause, I don't know; q35-6.0 works so why isn't pc-i440fx-6.0 ?
> 
> With regards,
> Reinoud
> 
> 

-- 
Isaku Yamahata 



Re: [PATCH v2] hw/block: m25p80: Support fast read for SST flashes

2021-03-15 Thread Bin Meng
On Thu, Mar 11, 2021 at 4:18 PM Bin Meng  wrote:
>
> On Sat, Mar 6, 2021 at 2:01 PM Bin Meng  wrote:
> >
> > From: Bin Meng 
> >
> > Per SST25VF016B datasheet [1], SST flash requires a dummy byte after
> > the address bytes. Note only SPI mode is supported by SST flashes.
> >
> > [1] http://ww1.microchip.com/downloads/en/devicedoc/s71271_04.pdf
> >
> > Signed-off-by: Bin Meng 
> > Acked-by: Alistair Francis 
> >
> > ---
> >
> > Changes in v2:
> > - rebase on qemu/master
> >
> >  hw/block/m25p80.c | 3 +++
> >  1 file changed, 3 insertions(+)
> >
>
> Ping?

Ping?



[PULL 11/11] hw/block/pflash_cfi: Replace DPRINTF with trace events

2021-03-15 Thread Philippe Mathieu-Daudé
From: David Edmondson 

Rather than having a device specific debug implementation in
pflash_cfi01.c and pflash_cfi02.c, use the standard tracing facility.

Signed-off-by: David Edmondson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20210216142721.1985543-2-david.edmond...@oracle.com>
[PMD: Rebased]
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Bin Meng 
---
 hw/block/pflash_cfi01.c | 80 +
 hw/block/pflash_cfi02.c | 78 
 hw/block/trace-events   | 41 +++--
 3 files changed, 95 insertions(+), 104 deletions(-)

diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 07910356756..81f9f971d88 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -56,16 +56,6 @@
 #include "sysemu/runstate.h"
 #include "trace.h"
 
-/* #define PFLASH_DEBUG */
-#ifdef PFLASH_DEBUG
-#define DPRINTF(fmt, ...)   \
-do {\
-fprintf(stderr, "PFLASH: " fmt , ## __VA_ARGS__);   \
-} while (0)
-#else
-#define DPRINTF(fmt, ...) do { } while (0)
-#endif
-
 #define PFLASH_BE  0
 #define PFLASH_SECURE  1
 
@@ -155,10 +145,8 @@ static uint32_t pflash_cfi_query(PFlashCFI01 *pfl, hwaddr 
offset)
  * wider part.
  */
 if (pfl->device_width != 1 || pfl->bank_width > 4) {
-DPRINTF("%s: Unsupported device configuration: "
-"device_width=%d, max_device_width=%d\n",
-__func__, pfl->device_width,
-pfl->max_device_width);
+trace_pflash_unsupported_device_configuration(pfl->name,
+pfl->device_width, pfl->max_device_width);
 return 0;
 }
 /* CFI query data is repeated, rather than zero padded for
@@ -210,14 +198,14 @@ static uint32_t pflash_devid_query(PFlashCFI01 *pfl, 
hwaddr offset)
 switch (boff & 0xFF) {
 case 0:
 resp = pfl->ident0;
-trace_pflash_manufacturer_id(resp);
+trace_pflash_manufacturer_id(pfl->name, resp);
 break;
 case 1:
 resp = pfl->ident1;
-trace_pflash_device_id(resp);
+trace_pflash_device_id(pfl->name, resp);
 break;
 default:
-trace_pflash_device_info(offset);
+trace_pflash_device_info(pfl->name, offset);
 return 0;
 }
 /* Replicate responses for each device in bank. */
@@ -265,10 +253,9 @@ static uint32_t pflash_data_read(PFlashCFI01 *pfl, hwaddr 
offset,
 }
 break;
 default:
-DPRINTF("BUG in %s\n", __func__);
 abort();
 }
-trace_pflash_data_read(offset, width, ret);
+trace_pflash_data_read(pfl->name, offset, width, ret);
 return ret;
 }
 
@@ -282,7 +269,7 @@ static uint32_t pflash_read(PFlashCFI01 *pfl, hwaddr offset,
 switch (pfl->cmd) {
 default:
 /* This should never happen : reset state & treat it as a read */
-DPRINTF("%s: unknown command state: %x\n", __func__, pfl->cmd);
+trace_pflash_read_unknown_state(pfl->name, pfl->cmd);
 pfl->wcycle = 0;
 /*
  * The command 0x00 is not assigned by the CFI open standard,
@@ -320,7 +307,7 @@ static uint32_t pflash_read(PFlashCFI01 *pfl, hwaddr offset,
  */
 ret |= pfl->status << 16;
 }
-DPRINTF("%s: status %x\n", __func__, ret);
+trace_pflash_read_status(pfl->name, ret);
 break;
 case 0x90:
 if (!pfl->device_width) {
@@ -335,14 +322,14 @@ static uint32_t pflash_read(PFlashCFI01 *pfl, hwaddr 
offset,
 switch (boff) {
 case 0:
 ret = pfl->ident0 << 8 | pfl->ident1;
-trace_pflash_manufacturer_id(ret);
+trace_pflash_manufacturer_id(pfl->name, ret);
 break;
 case 1:
 ret = pfl->ident2 << 8 | pfl->ident3;
-trace_pflash_device_id(ret);
+trace_pflash_device_id(pfl->name, ret);
 break;
 default:
-trace_pflash_device_info(boff);
+trace_pflash_device_info(pfl->name, boff);
 ret = 0;
 break;
 }
@@ -389,7 +376,7 @@ static uint32_t pflash_read(PFlashCFI01 *pfl, hwaddr offset,
 
 break;
 }
-trace_pflash_io_read(offset, width, ret, pfl->cmd, pfl->wcycle);
+trace_pflash_io_read(pfl->name, offset, width, ret, pfl->cmd, pfl->wcycle);
 
 return ret;
 }
@@ -419,7 +406,7 @@ static inline void pflash_data_write(PFlashCFI01 *pfl, 
hwaddr offset,
 {
 uint8_t *p = pfl->storage;
 
-trace_pflash_data_write(offset, width, value, pfl->counter);
+trace_pflash_data_write(pfl->name, offset, width, value, pfl->counter);
 switch (width) {
 case 1:
 p[offset] = value;
@@ -458,7 +445,7 @@ static void pflash_write(PFlashCFI01 *pfl, 

[PULL 09/11] hw/block/pflash_cfi01: Clarify trace events

2021-03-15 Thread Philippe Mathieu-Daudé
Use the 'mode_read_array' event when we set the device in such
mode, and use the 'reset' event in DeviceReset handler.

Reviewed-by: Bin Meng 
Reviewed-by: David Edmondson 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20210310170528.1184868-10-phi...@redhat.com>
---
 hw/block/pflash_cfi01.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 779a62f3b06..c8cecb3ac8b 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -663,7 +663,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
   "\n", __func__, offset, pfl->wcycle, pfl->cmd, value);
 
  mode_read_array:
-trace_pflash_reset();
+trace_pflash_mode_read_array();
 memory_region_rom_device_set_romd(>mem, true);
 pfl->wcycle = 0;
 pfl->cmd = 0x00; /* This model reset value for READ_ARRAY (not CFI) */
@@ -886,6 +886,7 @@ static void pflash_cfi01_system_reset(DeviceState *dev)
 {
 PFlashCFI01 *pfl = PFLASH_CFI01(dev);
 
+trace_pflash_reset();
 /*
  * The command 0x00 is not assigned by the CFI open standard,
  * but QEMU historically uses it for the READ_ARRAY command (0xff).
-- 
2.26.2




[PULL 07/11] hw/block/pflash_cfi02: Factor out pflash_reset_state_machine()

2021-03-15 Thread Philippe Mathieu-Daudé
There is multiple places resetting the internal state machine.
Factor the code out in a new pflash_reset_state_machine() method.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: David Edmondson 
Reviewed-by: Bin Meng 
Message-Id: <20210310170528.1184868-8-phi...@redhat.com>
---
 hw/block/pflash_cfi02.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 2ba77a0171b..aea47a99c61 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -184,11 +184,17 @@ static void pflash_setup_mappings(PFlashCFI02 *pfl)
 pfl->rom_mode = true;
 }
 
+static void pflash_reset_state_machine(PFlashCFI02 *pfl)
+{
+trace_pflash_reset();
+pfl->cmd = 0x00;
+pfl->wcycle = 0;
+}
+
 static void pflash_mode_read_array(PFlashCFI02 *pfl)
 {
 trace_pflash_mode_read_array();
-pfl->cmd = 0x00;
-pfl->wcycle = 0;
+pflash_reset_state_machine(pfl);
 pfl->rom_mode = true;
 memory_region_rom_device_set_romd(>orig_mem, true);
 }
@@ -330,8 +336,7 @@ static uint64_t pflash_read(void *opaque, hwaddr offset, 
unsigned int width)
 default:
 /* This should never happen : reset state & treat it as a read*/
 DPRINTF("%s: unknown command state: %x\n", __func__, pfl->cmd);
-pfl->wcycle = 0;
-pfl->cmd = 0;
+pflash_reset_state_machine(pfl);
 /* fall through to the read code */
 case 0x80: /* Erase (unlock) */
 /* We accept reads during second unlock sequence... */
@@ -669,8 +674,7 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 }
 reset_dq3(pfl);
 timer_del(>timer);
-pfl->wcycle = 0;
-pfl->cmd = 0;
+pflash_reset_state_machine(pfl);
 return;
 }
 /*
@@ -710,10 +714,8 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 
 /* Reset flash */
  reset_flash:
-trace_pflash_reset();
 pfl->bypass = 0;
-pfl->wcycle = 0;
-pfl->cmd = 0;
+pflash_reset_state_machine(pfl);
 return;
 
  do_bypass:
-- 
2.26.2




[PULL 10/11] hw/block/pflash_cfi01: Correct the type of PFlashCFI01.ro

2021-03-15 Thread Philippe Mathieu-Daudé
From: David Edmondson 

PFlashCFI01.ro is a bool, declare it as such.

Signed-off-by: David Edmondson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20210216142721.1985543-3-david.edmond...@oracle.com>
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Bin Meng 
---
 hw/block/pflash_cfi01.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index c8cecb3ac8b..07910356756 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -82,7 +82,7 @@ struct PFlashCFI01 {
 uint8_t max_device_width;  /* max device width in bytes */
 uint32_t features;
 uint8_t wcycle; /* if 0, the flash is read normally */
-int ro;
+bool ro;
 uint8_t cmd;
 uint8_t status;
 uint16_t ident0;
@@ -853,7 +853,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 } else {
-pfl->ro = 0;
+pfl->ro = false;
 }
 
 if (pfl->blk) {
-- 
2.26.2




[PULL 06/11] hw/block/pflash_cfi02: Rename register_memory(true) as mode_read_array

2021-03-15 Thread Philippe Mathieu-Daudé
The same pattern is used when setting the flash in READ_ARRAY mode:
- Set the state machine command to READ_ARRAY
- Reset the write_cycle counter
- Reset the memory region in ROMD

Refactor the current code by extracting this pattern.
It is used three times:

- When the timer expires and not in bypass mode

- On a read access (on invalid command).

- When the device is initialized. Here the ROMD mode is hidden
  by the memory_region_init_rom_device() call.

pflash_register_memory(rom_mode=true) already sets the ROM device
in "read array" mode (from I/O device to ROM one). Explicit that
by renaming the function as pflash_mode_read_array(), adding
a trace event and resetting wcycle.

Reviewed-by: Bin Meng 
Reviewed-by: David Edmondson 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20210310170528.1184868-7-phi...@redhat.com>
---
 hw/block/pflash_cfi02.c | 18 +-
 hw/block/trace-events   |  1 +
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 897b7333222..2ba77a0171b 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -184,10 +184,13 @@ static void pflash_setup_mappings(PFlashCFI02 *pfl)
 pfl->rom_mode = true;
 }
 
-static void pflash_register_memory(PFlashCFI02 *pfl, int rom_mode)
+static void pflash_mode_read_array(PFlashCFI02 *pfl)
 {
-memory_region_rom_device_set_romd(>orig_mem, rom_mode);
-pfl->rom_mode = !!rom_mode;
+trace_pflash_mode_read_array();
+pfl->cmd = 0x00;
+pfl->wcycle = 0;
+pfl->rom_mode = true;
+memory_region_rom_device_set_romd(>orig_mem, true);
 }
 
 static size_t pflash_regions_count(PFlashCFI02 *pfl)
@@ -249,11 +252,10 @@ static void pflash_timer(void *opaque)
 toggle_dq7(pfl);
 if (pfl->bypass) {
 pfl->wcycle = 2;
+pfl->cmd = 0;
 } else {
-pflash_register_memory(pfl, 1);
-pfl->wcycle = 0;
+pflash_mode_read_array(pfl);
 }
-pfl->cmd = 0;
 }
 
 /*
@@ -315,7 +317,7 @@ static uint64_t pflash_read(void *opaque, hwaddr offset, 
unsigned int width)
 /* Lazy reset to ROMD mode after a certain amount of read accesses */
 if (!pfl->rom_mode && pfl->wcycle == 0 &&
 ++pfl->read_counter > PFLASH_LAZY_ROMD_THRESHOLD) {
-pflash_register_memory(pfl, 1);
+pflash_mode_read_array(pfl);
 }
 offset &= pfl->chip_len - 1;
 boff = offset & 0xFF;
@@ -933,8 +935,6 @@ static void pflash_cfi02_realize(DeviceState *dev, Error 
**errp)
 sysbus_init_mmio(SYS_BUS_DEVICE(dev), >mem);
 
 timer_init_ns(>timer, QEMU_CLOCK_VIRTUAL, pflash_timer, pfl);
-pfl->wcycle = 0;
-pfl->cmd = 0;
 pfl->status = 0;
 
 pflash_cfi02_fill_cfi_table(pfl, nb_regions);
diff --git a/hw/block/trace-events b/hw/block/trace-events
index ef06d2ea747..6d0c43f9977 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -7,6 +7,7 @@ fdc_ioport_write(uint8_t reg, uint8_t value) "write reg 0x%02x 
val 0x%02x"
 # pflash_cfi01.c
 # pflash_cfi02.c
 pflash_reset(void) "reset"
+pflash_mode_read_array(void) "mode: read array"
 pflash_timer_expired(uint8_t cmd) "command 0x%02x done"
 pflash_io_read(uint64_t offset, unsigned size, uint32_t value, uint8_t cmd, 
uint8_t wcycle) "offset:0x%04"PRIx64" size:%u value:0x%04x cmd:0x%02x wcycle:%u"
 pflash_io_write(uint64_t offset, unsigned size, uint32_t value, uint8_t 
wcycle) "offset:0x%04"PRIx64" size:%u value:0x%04x wcycle:%u"
-- 
2.26.2




[PULL 08/11] hw/block/pflash_cfi02: Add DeviceReset method

2021-03-15 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: David Edmondson 
Reviewed-by: Bin Meng 
Message-Id: <20210310170528.1184868-9-phi...@redhat.com>
---
 hw/block/pflash_cfi02.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index aea47a99c61..c40febd2a41 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -942,6 +942,13 @@ static void pflash_cfi02_realize(DeviceState *dev, Error 
**errp)
 pflash_cfi02_fill_cfi_table(pfl, nb_regions);
 }
 
+static void pflash_cfi02_reset(DeviceState *dev)
+{
+PFlashCFI02 *pfl = PFLASH_CFI02(dev);
+
+pflash_reset_state_machine(pfl);
+}
+
 static Property pflash_cfi02_properties[] = {
 DEFINE_PROP_DRIVE("drive", PFlashCFI02, blk),
 DEFINE_PROP_UINT32("num-blocks", PFlashCFI02, uniform_nb_blocs, 0),
@@ -979,6 +986,7 @@ static void pflash_cfi02_class_init(ObjectClass *klass, 
void *data)
 DeviceClass *dc = DEVICE_CLASS(klass);
 
 dc->realize = pflash_cfi02_realize;
+dc->reset = pflash_cfi02_reset;
 dc->unrealize = pflash_cfi02_unrealize;
 device_class_set_props(dc, pflash_cfi02_properties);
 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
-- 
2.26.2




Re: [PATCH v2 03/29] tcg: Re-order tcg_region_init vs tcg_prologue_init

2021-03-15 Thread Roman Bolshakov
On Sun, Mar 14, 2021 at 03:26:58PM -0600, Richard Henderson wrote:
> Instead of delaying tcg_region_init until after tcg_prologue_init
> is complete, do tcg_region_init first and let tcg_prologue_init
> shrink the first region by the size of the generated prologue.
> 
> Signed-off-by: Richard Henderson 
> ---
>  accel/tcg/tcg-all.c   | 11 -
>  accel/tcg/translate-all.c |  3 +++
>  bsd-user/main.c   |  1 -
>  linux-user/main.c |  1 -
>  tcg/tcg.c | 52 ++-
>  5 files changed, 22 insertions(+), 46 deletions(-)
> 
> diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
> index e378c2db73..f132033999 100644
> --- a/accel/tcg/tcg-all.c
> +++ b/accel/tcg/tcg-all.c
> @@ -111,17 +111,6 @@ static int tcg_init(MachineState *ms)
>  
>  tcg_exec_init(s->tb_size * 1024 * 1024, s->splitwx_enabled);
>  mttcg_enabled = s->mttcg_enabled;
> -
> -/*
> - * Initialize TCG regions only for softmmu.
> - *
> - * This needs to be done later for user mode, because the prologue
> - * generation needs to be delayed so that GUEST_BASE is already set.
> - */
> -#ifndef CONFIG_USER_ONLY
> -tcg_region_init();

Note that tcg_region_init() invokes tcg_n_regions() that depends on
qemu_tcg_mttcg_enabled() that evaluates mttcg_enabled. Likely you need
to move "mttcg_enabled = s->mttcg_enabled;" before tcg_exec_init() to
keep existing behaviour.

> -#endif /* !CONFIG_USER_ONLY */
> -
>  return 0;
>  }
>  
> diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
> index f32df8b240..b9057567f4 100644
> --- a/accel/tcg/translate-all.c
> +++ b/accel/tcg/translate-all.c
> @@ -1339,6 +1339,9 @@ void tcg_exec_init(unsigned long tb_size, int splitwx)
> splitwx, _fatal);
>  assert(ok);
>  
> +/* TODO: allocating regions is hand-in-glove with code_gen_buffer. */
> +tcg_region_init();
> +
>  #if defined(CONFIG_SOFTMMU)
>  /* There's no guest base to take into account, so go ahead and
> initialize the prologue now.  */
> diff --git a/bsd-user/main.c b/bsd-user/main.c
> index 798aba512c..3669d2b89e 100644
> --- a/bsd-user/main.c
> +++ b/bsd-user/main.c
> @@ -994,7 +994,6 @@ int main(int argc, char **argv)
> generating the prologue until now so that the prologue can take
> the real value of GUEST_BASE into account.  */
>  tcg_prologue_init(tcg_ctx);
> -tcg_region_init();
>  
>  /* build Task State */
>  memset(ts, 0, sizeof(TaskState));
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 4f4746dce8..1bc48ca954 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -850,7 +850,6 @@ int main(int argc, char **argv, char **envp)
> generating the prologue until now so that the prologue can take
> the real value of GUEST_BASE into account.  */
>  tcg_prologue_init(tcg_ctx);
> -tcg_region_init();
>  
>  target_cpu_copy_regs(env, regs);
>  
> diff --git a/tcg/tcg.c b/tcg/tcg.c
> index 2991112829..0a2e5710de 100644
> --- a/tcg/tcg.c
> +++ b/tcg/tcg.c
> @@ -1204,32 +1204,18 @@ TranslationBlock *tcg_tb_alloc(TCGContext *s)
>  
>  void tcg_prologue_init(TCGContext *s)
>  {
> -size_t prologue_size, total_size;
> -void *buf0, *buf1;
> +size_t prologue_size;
>  
>  /* Put the prologue at the beginning of code_gen_buffer.  */
> -buf0 = s->code_gen_buffer;
> -total_size = s->code_gen_buffer_size;
> -s->code_ptr = buf0;
> -s->code_buf = buf0;
> +tcg_region_assign(s, 0);
> +s->code_ptr = s->code_gen_ptr;
> +s->code_buf = s->code_gen_ptr;

Pardon me for asking a naive question, what's the difference between
s->code_buf and s->code_gen_buf and, respectively, s->code_ptr and
s->code_gen_ptr?

Thanks,
Roman

>  s->data_gen_ptr = NULL;
>  
> -/*
> - * The region trees are not yet configured, but tcg_splitwx_to_rx
> - * needs the bounds for an assert.
> - */
> -region.start = buf0;
> -region.end = buf0 + total_size;
> -
>  #ifndef CONFIG_TCG_INTERPRETER
> -tcg_qemu_tb_exec = (tcg_prologue_fn *)tcg_splitwx_to_rx(buf0);
> +tcg_qemu_tb_exec = (tcg_prologue_fn *)tcg_splitwx_to_rx(s->code_ptr);
>  #endif
>  
> -/* Compute a high-water mark, at which we voluntarily flush the buffer
> -   and start over.  The size here is arbitrary, significantly larger
> -   than we expect the code generation for any one opcode to require.  */
> -s->code_gen_highwater = s->code_gen_buffer + (total_size - 
> TCG_HIGHWATER);
> -
>  #ifdef TCG_TARGET_NEED_POOL_LABELS
>  s->pool_labels = NULL;
>  #endif
> @@ -1246,32 +1232,32 @@ void tcg_prologue_init(TCGContext *s)
>  }
>  #endif
>  
> -buf1 = s->code_ptr;
> +prologue_size = tcg_current_code_size(s);
> +
>  #ifndef CONFIG_TCG_INTERPRETER
> -flush_idcache_range((uintptr_t)tcg_splitwx_to_rx(buf0), (uintptr_t)buf0,
> -tcg_ptr_byte_diff(buf1, buf0));
> +

[PULL 04/11] hw/block/pflash_cfi02: Set rom_mode to true in pflash_setup_mappings()

2021-03-15 Thread Philippe Mathieu-Daudé
There is only one call to pflash_setup_mappings(). Convert 'rom_mode'
to boolean and set it to true directly within pflash_setup_mappings().

Reviewed-by: Bin Meng 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: David Edmondson 
Message-Id: <20210310170528.1184868-5-phi...@redhat.com>
---
 hw/block/pflash_cfi02.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 845f50ed99b..0eb868ecd3d 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -108,7 +108,7 @@ struct PFlashCFI02 {
 MemoryRegion mem;
 MemoryRegion *mem_mappings;/* array; one per mapping */
 MemoryRegion orig_mem;
-int rom_mode;
+bool rom_mode;
 int read_counter; /* used for lazy switch-back to rom mode */
 int sectors_to_erase;
 uint64_t erase_time_remaining;
@@ -181,12 +181,13 @@ static void pflash_setup_mappings(PFlashCFI02 *pfl)
  "pflash-alias", >orig_mem, 0, size);
 memory_region_add_subregion(>mem, i * size, 
>mem_mappings[i]);
 }
+pfl->rom_mode = true;
 }
 
 static void pflash_register_memory(PFlashCFI02 *pfl, int rom_mode)
 {
 memory_region_rom_device_set_romd(>orig_mem, rom_mode);
-pfl->rom_mode = rom_mode;
+pfl->rom_mode = !!rom_mode;
 }
 
 static size_t pflash_regions_count(PFlashCFI02 *pfl)
@@ -927,7 +928,6 @@ static void pflash_cfi02_realize(DeviceState *dev, Error 
**errp)
 pfl->sector_erase_map = bitmap_new(pfl->total_sectors);
 
 pflash_setup_mappings(pfl);
-pfl->rom_mode = 1;
 sysbus_init_mmio(SYS_BUS_DEVICE(dev), >mem);
 
 timer_init_ns(>timer, QEMU_CLOCK_VIRTUAL, pflash_timer, pfl);
-- 
2.26.2




[PULL 05/11] hw/block/pflash_cfi02: Open-code pflash_register_memory(rom=false)

2021-03-15 Thread Philippe Mathieu-Daudé
There is only one call to pflash_register_memory() with
rom_mode == false. As we want to modify pflash_register_memory()
in the next patch, open-code this trivial function in place for
the 'rom_mode == false' case.

Reviewed-by: Bin Meng 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: David Edmondson 
Message-Id: <20210310170528.1184868-6-phi...@redhat.com>
---
 hw/block/pflash_cfi02.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 0eb868ecd3d..897b7333222 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -467,8 +467,10 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 switch (pfl->wcycle) {
 case 0:
 /* Set the device in I/O access mode if required */
-if (pfl->rom_mode)
-pflash_register_memory(pfl, 0);
+if (pfl->rom_mode) {
+pfl->rom_mode = false;
+memory_region_rom_device_set_romd(>orig_mem, false);
+}
 pfl->read_counter = 0;
 /* We're in read mode */
 check_unlock0:
-- 
2.26.2




[PULL 03/11] hw/block/pflash_cfi02: Extract pflash_cfi02_fill_cfi_table()

2021-03-15 Thread Philippe Mathieu-Daudé
Fill the CFI table in out of DeviceRealize() in a new function:
pflash_cfi02_fill_cfi_table().

Reviewed-by: Bin Meng 
Reviewed-by: David Edmondson 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20210310170528.1184868-4-phi...@redhat.com>
---
 hw/block/pflash_cfi02.c | 193 +---
 1 file changed, 99 insertions(+), 94 deletions(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index fa981465e12..845f50ed99b 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -724,6 +724,104 @@ static const MemoryRegionOps pflash_cfi02_ops = {
 .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
+static void pflash_cfi02_fill_cfi_table(PFlashCFI02 *pfl, int nb_regions)
+{
+/* Hardcoded CFI table (mostly from SG29 Spansion flash) */
+const uint16_t pri_ofs = 0x40;
+/* Standard "QRY" string */
+pfl->cfi_table[0x10] = 'Q';
+pfl->cfi_table[0x11] = 'R';
+pfl->cfi_table[0x12] = 'Y';
+/* Command set (AMD/Fujitsu) */
+pfl->cfi_table[0x13] = 0x02;
+pfl->cfi_table[0x14] = 0x00;
+/* Primary extended table address */
+pfl->cfi_table[0x15] = pri_ofs;
+pfl->cfi_table[0x16] = pri_ofs >> 8;
+/* Alternate command set (none) */
+pfl->cfi_table[0x17] = 0x00;
+pfl->cfi_table[0x18] = 0x00;
+/* Alternate extended table (none) */
+pfl->cfi_table[0x19] = 0x00;
+pfl->cfi_table[0x1A] = 0x00;
+/* Vcc min */
+pfl->cfi_table[0x1B] = 0x27;
+/* Vcc max */
+pfl->cfi_table[0x1C] = 0x36;
+/* Vpp min (no Vpp pin) */
+pfl->cfi_table[0x1D] = 0x00;
+/* Vpp max (no Vpp pin) */
+pfl->cfi_table[0x1E] = 0x00;
+/* Timeout per single byte/word write (128 ms) */
+pfl->cfi_table[0x1F] = 0x07;
+/* Timeout for min size buffer write (NA) */
+pfl->cfi_table[0x20] = 0x00;
+/* Typical timeout for block erase (512 ms) */
+pfl->cfi_table[0x21] = 0x09;
+/* Typical timeout for full chip erase (4096 ms) */
+pfl->cfi_table[0x22] = 0x0C;
+/* Reserved */
+pfl->cfi_table[0x23] = 0x01;
+/* Max timeout for buffer write (NA) */
+pfl->cfi_table[0x24] = 0x00;
+/* Max timeout for block erase */
+pfl->cfi_table[0x25] = 0x0A;
+/* Max timeout for chip erase */
+pfl->cfi_table[0x26] = 0x0D;
+/* Device size */
+pfl->cfi_table[0x27] = ctz32(pfl->chip_len);
+/* Flash device interface (8 & 16 bits) */
+pfl->cfi_table[0x28] = 0x02;
+pfl->cfi_table[0x29] = 0x00;
+/* Max number of bytes in multi-bytes write */
+/*
+ * XXX: disable buffered write as it's not supported
+ * pfl->cfi_table[0x2A] = 0x05;
+ */
+pfl->cfi_table[0x2A] = 0x00;
+pfl->cfi_table[0x2B] = 0x00;
+/* Number of erase block regions */
+pfl->cfi_table[0x2c] = nb_regions;
+/* Erase block regions */
+for (int i = 0; i < nb_regions; ++i) {
+uint32_t sector_len_per_device = pfl->sector_len[i];
+pfl->cfi_table[0x2d + 4 * i] = pfl->nb_blocs[i] - 1;
+pfl->cfi_table[0x2e + 4 * i] = (pfl->nb_blocs[i] - 1) >> 8;
+pfl->cfi_table[0x2f + 4 * i] = sector_len_per_device >> 8;
+pfl->cfi_table[0x30 + 4 * i] = sector_len_per_device >> 16;
+}
+assert(0x2c + 4 * nb_regions < pri_ofs);
+
+/* Extended */
+pfl->cfi_table[0x00 + pri_ofs] = 'P';
+pfl->cfi_table[0x01 + pri_ofs] = 'R';
+pfl->cfi_table[0x02 + pri_ofs] = 'I';
+
+/* Extended version 1.0 */
+pfl->cfi_table[0x03 + pri_ofs] = '1';
+pfl->cfi_table[0x04 + pri_ofs] = '0';
+
+/* Address sensitive unlock required. */
+pfl->cfi_table[0x05 + pri_ofs] = 0x00;
+/* Erase suspend to read/write. */
+pfl->cfi_table[0x06 + pri_ofs] = 0x02;
+/* Sector protect not supported. */
+pfl->cfi_table[0x07 + pri_ofs] = 0x00;
+/* Temporary sector unprotect not supported. */
+pfl->cfi_table[0x08 + pri_ofs] = 0x00;
+
+/* Sector protect/unprotect scheme. */
+pfl->cfi_table[0x09 + pri_ofs] = 0x00;
+
+/* Simultaneous operation not supported. */
+pfl->cfi_table[0x0a + pri_ofs] = 0x00;
+/* Burst mode not supported. */
+pfl->cfi_table[0x0b + pri_ofs] = 0x00;
+/* Page mode not supported. */
+pfl->cfi_table[0x0c + pri_ofs] = 0x00;
+assert(0x0c + pri_ofs < ARRAY_SIZE(pfl->cfi_table));
+}
+
 static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
 {
 ERRP_GUARD();
@@ -837,100 +935,7 @@ static void pflash_cfi02_realize(DeviceState *dev, Error 
**errp)
 pfl->cmd = 0;
 pfl->status = 0;
 
-/* Hardcoded CFI table (mostly from SG29 Spansion flash) */
-const uint16_t pri_ofs = 0x40;
-/* Standard "QRY" string */
-pfl->cfi_table[0x10] = 'Q';
-pfl->cfi_table[0x11] = 'R';
-pfl->cfi_table[0x12] = 'Y';
-/* Command set (AMD/Fujitsu) */
-pfl->cfi_table[0x13] = 0x02;
-pfl->cfi_table[0x14] = 0x00;
-/* Primary extended table address */
-pfl->cfi_table[0x15] = pri_ofs;
-pfl->cfi_table[0x16] = pri_ofs >> 8;
-/* Alternate command set (none) */
-

[PULL 01/11] hw/block/pflash_cfi: Fix code style for checkpatch.pl

2021-03-15 Thread Philippe Mathieu-Daudé
We are going to move this code, fix its style first.

Reviewed-by: Bin Meng 
Reviewed-by: David Edmondson 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20210310170528.1184868-2-phi...@redhat.com>
---
 hw/block/pflash_cfi01.c | 36 
 hw/block/pflash_cfi02.c |  9 ++---
 2 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 526b70417de..248889c3d02 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -115,7 +115,8 @@ static const VMStateDescription vmstate_pflash = {
 }
 };
 
-/* Perform a CFI query based on the bank width of the flash.
+/*
+ * Perform a CFI query based on the bank width of the flash.
  * If this code is called we know we have a device_width set for
  * this flash.
  */
@@ -125,7 +126,8 @@ static uint32_t pflash_cfi_query(PFlashCFI01 *pfl, hwaddr 
offset)
 uint32_t resp = 0;
 hwaddr boff;
 
-/* Adjust incoming offset to match expected device-width
+/*
+ * Adjust incoming offset to match expected device-width
  * addressing. CFI query addresses are always specified in terms of
  * the maximum supported width of the device.  This means that x8
  * devices and x8/x16 devices in x8 mode behave differently.  For
@@ -141,7 +143,8 @@ static uint32_t pflash_cfi_query(PFlashCFI01 *pfl, hwaddr 
offset)
 if (boff >= sizeof(pfl->cfi_table)) {
 return 0;
 }
-/* Now we will construct the CFI response generated by a single
+/*
+ * Now we will construct the CFI response generated by a single
  * device, then replicate that for all devices that make up the
  * bus.  For wide parts used in x8 mode, CFI query responses
  * are different than native byte-wide parts.
@@ -185,7 +188,8 @@ static uint32_t pflash_devid_query(PFlashCFI01 *pfl, hwaddr 
offset)
 uint32_t resp;
 hwaddr boff;
 
-/* Adjust incoming offset to match expected device-width
+/*
+ * Adjust incoming offset to match expected device-width
  * addressing. Device ID read addresses are always specified in
  * terms of the maximum supported width of the device.  This means
  * that x8 devices and x8/x16 devices in x8 mode behave
@@ -198,7 +202,8 @@ static uint32_t pflash_devid_query(PFlashCFI01 *pfl, hwaddr 
offset)
 boff = offset >> (ctz32(pfl->bank_width) +
   ctz32(pfl->max_device_width) - ctz32(pfl->device_width));
 
-/* Mask off upper bits which may be used in to query block
+/*
+ * Mask off upper bits which may be used in to query block
  * or sector lock status at other addresses.
  * Offsets 2/3 are block lock status, is not emulated.
  */
@@ -297,7 +302,8 @@ static uint32_t pflash_read(PFlashCFI01 *pfl, hwaddr offset,
 case 0x60: /* Block /un)lock */
 case 0x70: /* Status Register */
 case 0xe8: /* Write block */
-/* Status register read.  Return status from each device in
+/*
+ * Status register read.  Return status from each device in
  * bank.
  */
 ret = pfl->status;
@@ -308,7 +314,8 @@ static uint32_t pflash_read(PFlashCFI01 *pfl, hwaddr offset,
 shift += pfl->device_width * 8;
 }
 } else if (!pfl->device_width && width > 2) {
-/* Handle 32 bit flash cases where device width is not
+/*
+ * Handle 32 bit flash cases where device width is not
  * set. (Existing behavior before device width added.)
  */
 ret |= pfl->status << 16;
@@ -340,7 +347,8 @@ static uint32_t pflash_read(PFlashCFI01 *pfl, hwaddr offset,
 break;
 }
 } else {
-/* If we have a read larger than the bank_width, combine multiple
+/*
+ * If we have a read larger than the bank_width, combine multiple
  * manufacturer/device ID queries into a single response.
  */
 int i;
@@ -367,7 +375,8 @@ static uint32_t pflash_read(PFlashCFI01 *pfl, hwaddr offset,
 ret = 0;
 }
 } else {
-/* If we have a read larger than the bank_width, combine multiple
+/*
+ * If we have a read larger than the bank_width, combine multiple
  * CFI queries into a single response.
  */
 int i;
@@ -544,7 +553,8 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
 
 break;
 case 0xe8:
-/* Mask writeblock size based on device width, or bank width if
+/*
+ * Mask writeblock size based on device width, or bank width if
  * device width not specified.
  */
 /* FIXME check @offset, @width */
@@ -718,7 +728,8 @@ static void pflash_cfi01_realize(DeviceState *dev, Error 
**errp)
 
 total_len = pfl->sector_len * pfl->nb_blocs;
 
-/* These are only used to 

[PULL 02/11] hw/block/pflash_cfi01: Extract pflash_cfi01_fill_cfi_table()

2021-03-15 Thread Philippe Mathieu-Daudé
Fill the CFI table in out of DeviceRealize() in a new function:
pflash_cfi01_fill_cfi_table().

Reviewed-by: Bin Meng 
Reviewed-by: David Edmondson 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20210310170528.1184868-3-phi...@redhat.com>
---
 hw/block/pflash_cfi01.c | 140 +---
 1 file changed, 73 insertions(+), 67 deletions(-)

diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 248889c3d02..779a62f3b06 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -704,30 +704,11 @@ static const MemoryRegionOps pflash_cfi01_ops = {
 .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
+static void pflash_cfi01_fill_cfi_table(PFlashCFI01 *pfl)
 {
-ERRP_GUARD();
-PFlashCFI01 *pfl = PFLASH_CFI01(dev);
-uint64_t total_len;
-int ret;
 uint64_t blocks_per_device, sector_len_per_device, device_len;
 int num_devices;
 
-if (pfl->sector_len == 0) {
-error_setg(errp, "attribute \"sector-length\" not specified or zero.");
-return;
-}
-if (pfl->nb_blocs == 0) {
-error_setg(errp, "attribute \"num-blocks\" not specified or zero.");
-return;
-}
-if (pfl->name == NULL) {
-error_setg(errp, "attribute \"name\" not specified.");
-return;
-}
-
-total_len = pfl->sector_len * pfl->nb_blocs;
-
 /*
  * These are only used to expose the parameters of each device
  * in the cfi_table[].
@@ -742,53 +723,6 @@ static void pflash_cfi01_realize(DeviceState *dev, Error 
**errp)
 }
 device_len = sector_len_per_device * blocks_per_device;
 
-memory_region_init_rom_device(
->mem, OBJECT(dev),
-_cfi01_ops,
-pfl,
-pfl->name, total_len, errp);
-if (*errp) {
-return;
-}
-
-pfl->storage = memory_region_get_ram_ptr(>mem);
-sysbus_init_mmio(SYS_BUS_DEVICE(dev), >mem);
-
-if (pfl->blk) {
-uint64_t perm;
-pfl->ro = !blk_supports_write_perm(pfl->blk);
-perm = BLK_PERM_CONSISTENT_READ | (pfl->ro ? 0 : BLK_PERM_WRITE);
-ret = blk_set_perm(pfl->blk, perm, BLK_PERM_ALL, errp);
-if (ret < 0) {
-return;
-}
-} else {
-pfl->ro = 0;
-}
-
-if (pfl->blk) {
-if (!blk_check_size_and_read_all(pfl->blk, pfl->storage, total_len,
- errp)) {
-vmstate_unregister_ram(>mem, DEVICE(pfl));
-return;
-}
-}
-
-/*
- * Default to devices being used at their maximum device width. This was
- * assumed before the device_width support was added.
- */
-if (!pfl->max_device_width) {
-pfl->max_device_width = pfl->device_width;
-}
-
-pfl->wcycle = 0;
-/*
- * The command 0x00 is not assigned by the CFI open standard,
- * but QEMU historically uses it for the READ_ARRAY command (0xff).
- */
-pfl->cmd = 0x00;
-pfl->status = 0x80; /* WSM ready */
 /* Hardcoded CFI table */
 /* Standard "QRY" string */
 pfl->cfi_table[0x10] = 'Q';
@@ -876,6 +810,78 @@ static void pflash_cfi01_realize(DeviceState *dev, Error 
**errp)
 pfl->cfi_table[0x3f] = 0x01; /* Number of protection fields */
 }
 
+static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
+{
+ERRP_GUARD();
+PFlashCFI01 *pfl = PFLASH_CFI01(dev);
+uint64_t total_len;
+int ret;
+
+if (pfl->sector_len == 0) {
+error_setg(errp, "attribute \"sector-length\" not specified or zero.");
+return;
+}
+if (pfl->nb_blocs == 0) {
+error_setg(errp, "attribute \"num-blocks\" not specified or zero.");
+return;
+}
+if (pfl->name == NULL) {
+error_setg(errp, "attribute \"name\" not specified.");
+return;
+}
+
+total_len = pfl->sector_len * pfl->nb_blocs;
+
+memory_region_init_rom_device(
+>mem, OBJECT(dev),
+_cfi01_ops,
+pfl,
+pfl->name, total_len, errp);
+if (*errp) {
+return;
+}
+
+pfl->storage = memory_region_get_ram_ptr(>mem);
+sysbus_init_mmio(SYS_BUS_DEVICE(dev), >mem);
+
+if (pfl->blk) {
+uint64_t perm;
+pfl->ro = !blk_supports_write_perm(pfl->blk);
+perm = BLK_PERM_CONSISTENT_READ | (pfl->ro ? 0 : BLK_PERM_WRITE);
+ret = blk_set_perm(pfl->blk, perm, BLK_PERM_ALL, errp);
+if (ret < 0) {
+return;
+}
+} else {
+pfl->ro = 0;
+}
+
+if (pfl->blk) {
+if (!blk_check_size_and_read_all(pfl->blk, pfl->storage, total_len,
+ errp)) {
+vmstate_unregister_ram(>mem, DEVICE(pfl));
+return;
+}
+}
+
+/*
+ * Default to devices being used at their maximum device width. This was
+ * assumed before the device_width support was added.
+ */
+if (!pfl->max_device_width) {
+

[PULL 00/11] pflash patches for 2021-03-16

2021-03-15 Thread Philippe Mathieu-Daudé
The following changes since commit 2615a5e433aeb812c300d3a48e1a88e1303e2339:

  Merge remote-tracking branch 
'remotes/stefanha-gitlab/tags/block-pull-request' into staging (2021-03-15 
19:23:00 +)

are available in the Git repository at:

  https://github.com/philmd/qemu.git tags/pflash-20210316

for you to fetch changes up to 3b6a1da064ac6ce5256f1f6f16870ea79c2422d0:

  hw/block/pflash_cfi: Replace DPRINTF with trace events (2021-03-16 00:28:33 
+0100)


Parallel NOR Flash patches queue

- Code movement to ease maintainability
- Tracing improvements


David Edmondson (2):
  hw/block/pflash_cfi01: Correct the type of PFlashCFI01.ro
  hw/block/pflash_cfi: Replace DPRINTF with trace events

Philippe Mathieu-Daudé (9):
  hw/block/pflash_cfi: Fix code style for checkpatch.pl
  hw/block/pflash_cfi01: Extract pflash_cfi01_fill_cfi_table()
  hw/block/pflash_cfi02: Extract pflash_cfi02_fill_cfi_table()
  hw/block/pflash_cfi02: Set rom_mode to true in pflash_setup_mappings()
  hw/block/pflash_cfi02: Open-code pflash_register_memory(rom=false)
  hw/block/pflash_cfi02: Rename register_memory(true) as mode_read_array
  hw/block/pflash_cfi02: Factor out pflash_reset_state_machine()
  hw/block/pflash_cfi02: Add DeviceReset method
  hw/block/pflash_cfi01: Clarify trace events

 hw/block/pflash_cfi01.c | 253 
 hw/block/pflash_cfi02.c | 316 
 hw/block/trace-events   |  40 +++--
 3 files changed, 320 insertions(+), 289 deletions(-)

-- 
2.26.2





Re: [PATCH v2 00/12] hw/block/pflash: Refactors around setting the device in read-array mode

2021-03-15 Thread Philippe Mathieu-Daudé
On 3/10/21 6:05 PM, Philippe Mathieu-Daudé wrote:
> I remembered this almost 2 years old series while reviewing
> David Edmondson's patches... (which are included at the end).
> 
> Basically we move things around to make the code easier to maintain.
> 
> David Edmondson (2):
>   hw/block/pflash_cfi01: Correct the type of PFlashCFI01.ro
>   hw/block/pflash_cfi: Replace DPRINTF with trace events
> 
> Philippe Mathieu-Daudé (10):
>   hw/block/pflash_cfi: Fix code style for checkpatch.pl
>   hw/block/pflash_cfi01: Extract pflash_cfi01_fill_cfi_table()
>   hw/block/pflash_cfi02: Extract pflash_cfi02_fill_cfi_table()
>   hw/block/pflash_cfi02: Set rom_mode to true in pflash_setup_mappings()
>   hw/block/pflash_cfi02: Open-code pflash_register_memory(rom=false)
>   hw/block/pflash_cfi02: Rename register_memory(true) as mode_read_array
>   hw/block/pflash_cfi02: Factor out pflash_reset_state_machine()
>   hw/block/pflash_cfi02: Add DeviceReset method
>   hw/block/pflash_cfi01: Clarify trace events
>   hw/block/pflash_cfi01: Extract pflash_mode_read_array()

Thanks, patches 1-10 & 12 queued to pflash-next.




Re: [PATCH v2 01/29] meson: Split out tcg/meson.build

2021-03-15 Thread Roman Bolshakov
On Sun, Mar 14, 2021 at 03:26:56PM -0600, Richard Henderson wrote:
> Reviewed-by: Philippe Mathieu-Daudé 
> Signed-off-by: Richard Henderson 
> ---

Reviewed-by: Roman Bolshakov 

Thanks,
Roman

>  meson.build |  9 ++---
>  tcg/meson.build | 13 +
>  2 files changed, 15 insertions(+), 7 deletions(-)
>  create mode 100644 tcg/meson.build
> 
> diff --git a/meson.build b/meson.build
> index a7d2dd429d..742f45c8d8 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -1936,14 +1936,8 @@ specific_ss.add(files('cpu.c', 'disas.c', 
> 'gdbstub.c'), capstone)
>  specific_ss.add(files('exec-vary.c'))
>  specific_ss.add(when: 'CONFIG_TCG', if_true: files(
>'fpu/softfloat.c',
> -  'tcg/optimize.c',
> -  'tcg/tcg-common.c',
> -  'tcg/tcg-op-gvec.c',
> -  'tcg/tcg-op-vec.c',
> -  'tcg/tcg-op.c',
> -  'tcg/tcg.c',
>  ))
> -specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: 
> files('disas/tci.c', 'tcg/tci.c'))
> +specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: 
> files('disas/tci.c'))
>  
>  subdir('backends')
>  subdir('disas')
> @@ -1953,6 +1947,7 @@ subdir('net')
>  subdir('replay')
>  subdir('semihosting')
>  subdir('hw')
> +subdir('tcg')
>  subdir('accel')
>  subdir('plugins')
>  subdir('bsd-user')
> diff --git a/tcg/meson.build b/tcg/meson.build
> new file mode 100644
> index 00..84064a341e
> --- /dev/null
> +++ b/tcg/meson.build
> @@ -0,0 +1,13 @@
> +tcg_ss = ss.source_set()
> +
> +tcg_ss.add(files(
> +  'optimize.c',
> +  'tcg.c',
> +  'tcg-common.c',
> +  'tcg-op.c',
> +  'tcg-op-gvec.c',
> +  'tcg-op-vec.c',
> +))
> +tcg_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('tci.c'))
> +
> +specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss)
> -- 
> 2.25.1
> 



[PATCH v3 2/5] tests/acceptance: Make pick_default_qemu_bin() more generic

2021-03-15 Thread Philippe Mathieu-Daudé
Make pick_default_qemu_bin() generic to find qemu-system or
qemu-user binaries.

Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/acceptance/avocado_qemu/__init__.py | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/tests/acceptance/avocado_qemu/__init__.py 
b/tests/acceptance/avocado_qemu/__init__.py
index 4f814047176..08b3fa1124f 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -48,7 +48,7 @@ def is_readable_executable_file(path):
 return os.path.isfile(path) and os.access(path, os.R_OK | os.X_OK)
 
 
-def pick_default_qemu_bin(arch=None):
+def pick_default_qemu_bin(bin_fmt, arch=None):
 """
 Picks the path of a QEMU binary, starting either in the current working
 directory or in the source tree root directory.
@@ -67,7 +67,7 @@ def pick_default_qemu_bin(arch=None):
 # qemu binary path does not match arch for powerpc, handle it
 if 'ppc64le' in arch:
 arch = 'ppc64'
-qemu_bin_relative_path = "./qemu-system-%s" % arch
+qemu_bin_relative_path = os.path.join(".", bin_fmt % arch)
 if is_readable_executable_file(qemu_bin_relative_path):
 return qemu_bin_relative_path
 
@@ -187,14 +187,14 @@ def require_accelerator(self, accelerator):
 self.cancel("%s accelerator does not seem to be "
 "available" % accelerator)
 
-def setUp(self):
+def setUp(self, bin_fmt):
 self.arch = self.params.get('arch',
 default=self._get_unique_tag_val('arch'))
 
 self.machine = self.params.get('machine',

default=self._get_unique_tag_val('machine'))
 
-default_qemu_bin = pick_default_qemu_bin(arch=self.arch)
+default_qemu_bin = pick_default_qemu_bin(bin_fmt, arch=self.arch)
 self.qemu_bin = self.params.get('qemu_bin',
 default=default_qemu_bin)
 if self.qemu_bin is None:
@@ -217,7 +217,7 @@ def fetch_asset(self, name,
 class Test(QemuBaseTest):
 def setUp(self):
 self._vms = {}
-super(Test, self).setUp()
+super(Test, self).setUp("qemu-system-%s")
 
 def _new_vm(self, *args):
 self._sd = tempfile.TemporaryDirectory(prefix="avo_qemu_sock_")
-- 
2.26.2




[PATCH v3 5/5] tests/acceptance: Add bFLT loader linux-user test

2021-03-15 Thread Philippe Mathieu-Daudé
Add a very quick test that runs a busybox binary in bFLT format:

  $ avocado --show=app run -t linux_user tests/acceptance/load_bflt.py
  JOB ID : db94d5960ce564c50904d666a7e259148c27e88f
  JOB LOG: ~/avocado/job-results/job-2019-06-25T10.52-db94d59/job.log
   (1/1) tests/acceptance/load_bflt.py:LoadBFLT.test_stm32: PASS (0.15 s)
  RESULTS: PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | 
CANCEL 0
  JOB TIME   : 0.54 s

Reviewed-by: Willian Rampazzo 
Signed-off-by: Philippe Mathieu-Daudé 
---
v3: Check for 'cpio' (thuth)
---
 tests/acceptance/load_bflt.py | 54 +++
 1 file changed, 54 insertions(+)
 create mode 100644 tests/acceptance/load_bflt.py

diff --git a/tests/acceptance/load_bflt.py b/tests/acceptance/load_bflt.py
new file mode 100644
index 000..f071a979d8e
--- /dev/null
+++ b/tests/acceptance/load_bflt.py
@@ -0,0 +1,54 @@
+# Test the bFLT loader format
+#
+# Copyright (C) 2019 Philippe Mathieu-Daudé 
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import os
+import bz2
+import subprocess
+
+from avocado import skipUnless
+from avocado_qemu import QemuUserTest
+from avocado_qemu import has_cmd
+
+
+class LoadBFLT(QemuUserTest):
+
+def extract_cpio(self, cpio_path):
+"""
+Extracts a cpio archive into the test workdir
+
+:param cpio_path: path to the cpio archive
+"""
+cwd = os.getcwd()
+os.chdir(self.workdir)
+with bz2.open(cpio_path, 'rb') as archive_cpio:
+subprocess.run(['cpio', '-i'], input=archive_cpio.read(),
+   stderr=subprocess.DEVNULL)
+os.chdir(cwd)
+
+@skipUnless(*has_cmd('cpio'))
+@skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
+def test_stm32(self):
+"""
+:avocado: tags=arch:arm
+:avocado: tags=linux_user
+:avocado: tags=quick
+"""
+# See https://elinux.org/STM32#User_Space
+rootfs_url = ('https://elinux.org/images/5/51/'
+  'Stm32_mini_rootfs.cpio.bz2')
+rootfs_hash = '9f065e6ba40cce7411ba757f924f30fcc57951e6'
+rootfs_path_bz2 = self.fetch_asset(rootfs_url, asset_hash=rootfs_hash)
+busybox_path = self.workdir + "/bin/busybox"
+
+self.extract_cpio(rootfs_path_bz2)
+
+res = self.run(busybox_path)
+ver = 'BusyBox v1.24.0.git (2015-02-03 22:17:13 CET) multi-call 
binary.'
+self.assertIn(ver, res.stdout_text)
+
+res = self.run(busybox_path, ['uname', '-a'])
+unm = 'armv7l GNU/Linux'
+self.assertIn(unm, res.stdout_text)
-- 
2.26.2




[PATCH v3 4/5] tests/acceptance: Share useful helpers from virtiofs_submounts test

2021-03-15 Thread Philippe Mathieu-Daudé
Move the useful has_cmd()/has_cmds() helpers from the virtiofs
test to the avocado_qemu public class.

Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/acceptance/avocado_qemu/__init__.py | 57 ++
 tests/acceptance/virtiofs_submounts.py| 59 +--
 2 files changed, 59 insertions(+), 57 deletions(-)

diff --git a/tests/acceptance/avocado_qemu/__init__.py 
b/tests/acceptance/avocado_qemu/__init__.py
index b471bee66e0..48c705fe3d2 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -11,6 +11,7 @@
 import logging
 import os
 import shutil
+import subprocess
 import sys
 import uuid
 import tempfile
@@ -45,6 +46,62 @@
 from qemu.accel import tcg_available
 from qemu.machine import QEMUMachine
 
+def has_cmd(name, args=None):
+"""
+This function is for use in a @avocado.skipUnless decorator, e.g.:
+
+@skipUnless(*has_cmd('sudo -n', ('sudo', '-n', 'true')))
+def test_something_that_needs_sudo(self):
+...
+"""
+
+if args is None:
+args = ('which', name)
+
+try:
+_, stderr, exitcode = run_cmd(args)
+except Exception as e:
+exitcode = -1
+stderr = str(e)
+
+if exitcode != 0:
+cmd_line = ' '.join(args)
+err = f'{name} required, but "{cmd_line}" failed: {stderr.strip()}'
+return (False, err)
+else:
+return (True, '')
+
+def has_cmds(*cmds):
+"""
+This function is for use in a @avocado.skipUnless decorator and
+allows checking for the availability of multiple commands, e.g.:
+
+@skipUnless(*has_cmds(('cmd1', ('cmd1', '--some-parameter')),
+  'cmd2', 'cmd3'))
+def test_something_that_needs_cmd1_and_cmd2(self):
+...
+"""
+
+for cmd in cmds:
+if isinstance(cmd, str):
+cmd = (cmd,)
+
+ok, errstr = has_cmd(*cmd)
+if not ok:
+return (False, errstr)
+
+return (True, '')
+
+def run_cmd(args):
+subp = subprocess.Popen(args,
+stdout=subprocess.PIPE,
+stderr=subprocess.PIPE,
+universal_newlines=True)
+stdout, stderr = subp.communicate()
+ret = subp.returncode
+
+return (stdout, stderr, ret)
+
 def is_readable_executable_file(path):
 return os.path.isfile(path) and os.access(path, os.R_OK | os.X_OK)
 
diff --git a/tests/acceptance/virtiofs_submounts.py 
b/tests/acceptance/virtiofs_submounts.py
index 46fa65392a1..201645cd740 100644
--- a/tests/acceptance/virtiofs_submounts.py
+++ b/tests/acceptance/virtiofs_submounts.py
@@ -6,67 +6,12 @@
 
 from avocado import skipUnless
 from avocado_qemu import LinuxTest, BUILD_DIR
+from avocado_qemu import has_cmds
+from avocado_qemu import run_cmd
 from avocado_qemu import wait_for_console_pattern
 from avocado.utils import ssh
 
 
-def run_cmd(args):
-subp = subprocess.Popen(args,
-stdout=subprocess.PIPE,
-stderr=subprocess.PIPE,
-universal_newlines=True)
-stdout, stderr = subp.communicate()
-ret = subp.returncode
-
-return (stdout, stderr, ret)
-
-def has_cmd(name, args=None):
-"""
-This function is for use in a @avocado.skipUnless decorator, e.g.:
-
-@skipUnless(*has_cmd('sudo -n', ('sudo', '-n', 'true')))
-def test_something_that_needs_sudo(self):
-...
-"""
-
-if args is None:
-args = ('which', name)
-
-try:
-_, stderr, exitcode = run_cmd(args)
-except Exception as e:
-exitcode = -1
-stderr = str(e)
-
-if exitcode != 0:
-cmd_line = ' '.join(args)
-err = f'{name} required, but "{cmd_line}" failed: {stderr.strip()}'
-return (False, err)
-else:
-return (True, '')
-
-def has_cmds(*cmds):
-"""
-This function is for use in a @avocado.skipUnless decorator and
-allows checking for the availability of multiple commands, e.g.:
-
-@skipUnless(*has_cmds(('cmd1', ('cmd1', '--some-parameter')),
-  'cmd2', 'cmd3'))
-def test_something_that_needs_cmd1_and_cmd2(self):
-...
-"""
-
-for cmd in cmds:
-if isinstance(cmd, str):
-cmd = (cmd,)
-
-ok, errstr = has_cmd(*cmd)
-if not ok:
-return (False, errstr)
-
-return (True, '')
-
-
 class VirtiofsSubmountsTest(LinuxTest):
 """
 :avocado: tags=arch:x86_64
-- 
2.26.2




[PATCH v3 0/5] tests/acceptance: Add bFLT loader linux-user test

2021-03-15 Thread Philippe Mathieu-Daudé
Since v2:
- rebased tests/acceptance/avocado_qemu/__init__.py patches
- extract has_cmd() from virtiofs_submounts.py
- check cpio availability with has_cmd()

Philippe Mathieu-Daudé (5):
  tests/acceptance: Extract QemuBaseTest from Test
  tests/acceptance: Make pick_default_qemu_bin() more generic
  tests/acceptance: Introduce QemuUserTest base class
  tests/acceptance: Share useful helpers from virtiofs_submounts test
  tests/acceptance: Add bFLT loader linux-user test

 tests/acceptance/avocado_qemu/__init__.py | 102 --
 tests/acceptance/load_bflt.py |  54 
 tests/acceptance/virtiofs_submounts.py|  59 +
 3 files changed, 151 insertions(+), 64 deletions(-)
 create mode 100644 tests/acceptance/load_bflt.py

-- 
2.26.2




Re: [PATCH v2 02/29] meson: Split out fpu/meson.build

2021-03-15 Thread Roman Bolshakov
On Sun, Mar 14, 2021 at 03:26:57PM -0600, Richard Henderson wrote:
> Reviewed-by: Philippe Mathieu-Daudé 
> Signed-off-by: Richard Henderson 
> ---

Reviewed-by: Roman Bolshakov 

Thanks,
Roman

>  meson.build | 4 +---
>  fpu/meson.build | 1 +
>  2 files changed, 2 insertions(+), 3 deletions(-)
>  create mode 100644 fpu/meson.build
> 
> diff --git a/meson.build b/meson.build
> index 742f45c8d8..bfa24b836e 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -1934,9 +1934,6 @@ subdir('softmmu')
>  common_ss.add(capstone)
>  specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
>  specific_ss.add(files('exec-vary.c'))
> -specific_ss.add(when: 'CONFIG_TCG', if_true: files(
> -  'fpu/softfloat.c',
> -))
>  specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: 
> files('disas/tci.c'))
>  
>  subdir('backends')
> @@ -1948,6 +1945,7 @@ subdir('replay')
>  subdir('semihosting')
>  subdir('hw')
>  subdir('tcg')
> +subdir('fpu')
>  subdir('accel')
>  subdir('plugins')
>  subdir('bsd-user')
> diff --git a/fpu/meson.build b/fpu/meson.build
> new file mode 100644
> index 00..1a9992ded5
> --- /dev/null
> +++ b/fpu/meson.build
> @@ -0,0 +1 @@
> +specific_ss.add(when: 'CONFIG_TCG', if_true: files('softfloat.c'))
> -- 
> 2.25.1
> 



[PATCH v3 3/5] tests/acceptance: Introduce QemuUserTest base class

2021-03-15 Thread Philippe Mathieu-Daudé
Similarly to the 'System' Test base class with methods for testing
system emulation, the QemuUserTest class contains methods useful to
test user-mode emulation.

Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/acceptance/avocado_qemu/__init__.py | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/tests/acceptance/avocado_qemu/__init__.py 
b/tests/acceptance/avocado_qemu/__init__.py
index 08b3fa1124f..b471bee66e0 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -20,6 +20,7 @@
 from avocado.utils import cloudinit
 from avocado.utils import datadrainer
 from avocado.utils import network
+from avocado.utils import process
 from avocado.utils import vmimage
 from avocado.utils.path import find_command
 
@@ -256,6 +257,19 @@ def fetch_asset(self, name,
 find_only=find_only,
 cancel_on_missing=cancel_on_missing)
 
+class QemuUserTest(QemuBaseTest):
+def setUp(self):
+self._ldpath = []
+super(QemuUserTest, self).setUp("qemu-%s")
+
+def add_ldpath(self, ldpath):
+self._ldpath += [os.path.abspath(ldpath)]
+
+def run(self, bin_path, args=[]):
+qemu_args = " ".join(["-L %s" % ldpath for ldpath in self._ldpath])
+bin_args = " ".join(args)
+return process.run("%s %s %s %s" % (self.qemu_bin, qemu_args,
+bin_path, bin_args))
 
 class LinuxTest(Test):
 """Facilitates having a cloud-image Linux based available.
-- 
2.26.2




[PATCH v3 1/5] tests/acceptance: Extract QemuBaseTest from Test

2021-03-15 Thread Philippe Mathieu-Daudé
The Avocado Test::fetch_asset() is handy to download artifacts
before running tests. The current class is named Test but only
tests system emulation. As we want to test user emulation,
refactor the common code as QemuBaseTest.

Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/acceptance/avocado_qemu/__init__.py | 23 ---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/tests/acceptance/avocado_qemu/__init__.py 
b/tests/acceptance/avocado_qemu/__init__.py
index df167b142cc..4f814047176 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -155,7 +155,7 @@ def exec_command_and_wait_for_pattern(test, command,
 """
 _console_interaction(test, success_message, failure_message, command + 
'\r')
 
-class Test(avocado.Test):
+class QemuBaseTest(avocado.Test):
 def _get_unique_tag_val(self, tag_name):
 """
 Gets a tag value, if unique for a key
@@ -188,8 +188,6 @@ def require_accelerator(self, accelerator):
 "available" % accelerator)
 
 def setUp(self):
-self._vms = {}
-
 self.arch = self.params.get('arch',
 default=self._get_unique_tag_val('arch'))
 
@@ -202,6 +200,25 @@ def setUp(self):
 if self.qemu_bin is None:
 self.cancel("No QEMU binary defined or found in the build tree")
 
+
+def fetch_asset(self, name,
+asset_hash=None, algorithm=None,
+locations=None, expire=None,
+find_only=False, cancel_on_missing=True):
+return super(QemuBaseTest, self).fetch_asset(name,
+asset_hash=asset_hash,
+algorithm=algorithm,
+locations=locations,
+expire=expire,
+find_only=find_only,
+cancel_on_missing=cancel_on_missing)
+
+# a.k.a. QemuSystemTest for system emulation...
+class Test(QemuBaseTest):
+def setUp(self):
+self._vms = {}
+super(Test, self).setUp()
+
 def _new_vm(self, *args):
 self._sd = tempfile.TemporaryDirectory(prefix="avo_qemu_sock_")
 vm = QEMUMachine(self.qemu_bin, sock_dir=self._sd.name)
-- 
2.26.2




Re: [PATCH v2 00/29] tcg: Workaround macOS 11.2 mprotect bug

2021-03-15 Thread Roman Bolshakov
On Sun, Mar 14, 2021 at 03:26:55PM -0600, Richard Henderson wrote:
> Changes for v2:
>   * Move tcg_init_ctx someplace more private (patch 29)
>   * Round result of tb_size based on qemu_get_host_physmem (patch 26)
> 
> Blurb for v1:
>   It took a few more patches than imagined to unify the two
>   places in which we manipulate the tcg code_gen buffer, but
>   the result is surely cleaner.
> 
>   There's a lot more that could be done to clean up this part
>   of tcg too.  I tried to not get too side-tracked, but didn't
>   wholly succeed.
> 
> 

Hi Richard,

Thanks for doing the changes!
I'm not sure if I'll find enough time for thorough review but the series
helps qemu on Big Sur 11.2.3, so:

Tested-by: Roman Bolshakov 

Regards,
Roman

> r~
> 
> 
> Richard Henderson (29):
>   meson: Split out tcg/meson.build
>   meson: Split out fpu/meson.build
>   tcg: Re-order tcg_region_init vs tcg_prologue_init
>   tcg: Remove error return from tcg_region_initial_alloc__locked
>   tcg: Split out tcg_region_initial_alloc
>   tcg: Split out tcg_region_prologue_set
>   tcg: Split out region.c
>   accel/tcg: Inline cpu_gen_init
>   accel/tcg: Move alloc_code_gen_buffer to tcg/region.c
>   accel/tcg: Rename tcg_init to tcg_init_machine
>   tcg: Create tcg_init
>   accel/tcg: Merge tcg_exec_init into tcg_init_machine
>   accel/tcg: Pass down max_cpus to tcg_init
>   tcg: Introduce tcg_max_ctxs
>   tcg: Move MAX_CODE_GEN_BUFFER_SIZE to tcg-target.h
>   tcg: Replace region.end with region.total_size
>   tcg: Rename region.start to region.after_prologue
>   tcg: Tidy tcg_n_regions
>   tcg: Tidy split_cross_256mb
>   tcg: Move in_code_gen_buffer and tests to region.c
>   tcg: Allocate code_gen_buffer into struct tcg_region_state
>   tcg: Return the map protection from alloc_code_gen_buffer
>   tcg: Sink qemu_madvise call to common code
>   tcg: Do not set guard pages in the rx buffer
>   util/osdep: Add qemu_mprotect_rw
>   tcg: Round the tb_size default from qemu_get_host_physmem
>   tcg: Merge buffer protection and guard page protection
>   tcg: When allocating for !splitwx, begin with PROT_NONE
>   tcg: Move tcg_init_ctx and tcg_ctx from accel/tcg/
> 
>  meson.build   |  13 +-
>  accel/tcg/internal.h  |   2 +
>  include/qemu/osdep.h  |   1 +
>  include/sysemu/tcg.h  |   2 -
>  include/tcg/tcg.h |  15 +-
>  tcg/aarch64/tcg-target.h  |   1 +
>  tcg/arm/tcg-target.h  |   1 +
>  tcg/i386/tcg-target.h |   2 +
>  tcg/internal.h|  40 ++
>  tcg/mips/tcg-target.h |   6 +
>  tcg/ppc/tcg-target.h  |   2 +
>  tcg/riscv/tcg-target.h|   1 +
>  tcg/s390/tcg-target.h |   3 +
>  tcg/sparc/tcg-target.h|   1 +
>  tcg/tci/tcg-target.h  |   1 +
>  accel/tcg/tcg-all.c   |  33 +-
>  accel/tcg/translate-all.c | 439 +
>  bsd-user/main.c   |   1 -
>  linux-user/main.c |   1 -
>  tcg/region.c  | 991 ++
>  tcg/tcg.c | 634 ++--
>  util/osdep.c  |   9 +
>  fpu/meson.build   |   1 +
>  tcg/meson.build   |  14 +
>  24 files changed, 1139 insertions(+), 1075 deletions(-)
>  create mode 100644 tcg/internal.h
>  create mode 100644 tcg/region.c
>  create mode 100644 fpu/meson.build
>  create mode 100644 tcg/meson.build
> 
> -- 
> 2.25.1
> 



Re: [PULL 18/27] target/mips: Extract MXU code to new mxu_translate.c file

2021-03-15 Thread Philippe Mathieu-Daudé
On 3/15/21 10:33 PM, Peter Maydell wrote:
> On Sat, 13 Mar 2021 at 19:58, Philippe Mathieu-Daudé  wrote:
>>
>> Extract 1600+ lines from the big translate.c into a new file.
>>
>> Reviewed-by: Richard Henderson 
>> Signed-off-by: Philippe Mathieu-Daudé 
> 
> This code motion caused Coverity to rescan this code, and
> it thinks there's a problem in this function (CID 1450831).
> It looks to me like it might be right...

Oops, our mails crossed :)

I wonder if this is a simple rescan or if target/mips/translate.c
is too big and Coverity bails out on it by timeout (this is what
Coccinelle does). Now the extracted code could finally get processed.

>> +/*
>> + *  D16MAX
>> + *Update XRa with the 16-bit-wise maximums of signed integers
>> + *contained in XRb and XRc.
>> + *
>> + *  D16MIN
>> + *Update XRa with the 16-bit-wise minimums of signed integers
>> + *contained in XRb and XRc.
>> + */
>> +static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
>> +{
>> +uint32_t pad, opc, XRc, XRb, XRa;
>> +
>> +pad = extract32(ctx->opcode, 21, 5);
>> +opc = extract32(ctx->opcode, 18, 3);
>> +XRc = extract32(ctx->opcode, 14, 4);
>> +XRb = extract32(ctx->opcode, 10, 4);
>> +XRa = extract32(ctx->opcode,  6, 4);
>> +
>> +if (unlikely(pad != 0)) {
>> +/* opcode padding incorrect -> do nothing */
>> +} else if (unlikely(XRc == 0)) {
>> +/* destination is zero register -> do nothing */
>> +} else if (unlikely((XRb == 0) && (XRa == 0))) {
>> +/* both operands zero registers -> just set destination to zero */
>> +tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
>> +} else if (unlikely((XRb == 0) || (XRa == 0))) {
> 
> In this block of code either XRb or XRa is zero...
> 
>> +/* exactly one operand is zero register - find which one is not...*/
>> +uint32_t XRx = XRb ? XRb : XRc;
>> +/* ...and do half-word-wise max/min with one operand 0 */
>> +TCGv_i32 t0 = tcg_temp_new();
>> +TCGv_i32 t1 = tcg_const_i32(0);
>> +
>> +/* the left half-word first */
>> +tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x);
>> +if (opc == OPC_MXU_D16MAX) {
>> +tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
>> +} else {
>> +tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
>> +}
> 
> but in these smax/smin calls we're clearly assuming that
> XRa is not zero.
> 
> There seems to be some confusion over which registers are
> the inputs and which is the output. The top-level function
> comment says XRa is the input and XRb/XRc the inputs.
> But the "destination is zero register" comment is against
> a check on XRc, and the "both operands zero" comment is
> against a check on XRa and XRb, as is the "one operand
> is zero" comment...
> 
>> +/*
>> + *  Q8MAX
>> + *Update XRa with the 8-bit-wise maximums of signed integers
>> + *contained in XRb and XRc.
>> + *
>> + *  Q8MIN
>> + *Update XRa with the 8-bit-wise minimums of signed integers
>> + *contained in XRb and XRc.
>> + */
>> +static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
>> +{
>> +uint32_t pad, opc, XRc, XRb, XRa;
>> +
>> +pad = extract32(ctx->opcode, 21, 5);
>> +opc = extract32(ctx->opcode, 18, 3);
>> +XRc = extract32(ctx->opcode, 14, 4);
>> +XRb = extract32(ctx->opcode, 10, 4);
>> +XRa = extract32(ctx->opcode,  6, 4);
>> +
>> +if (unlikely(pad != 0)) {
>> +/* opcode padding incorrect -> do nothing */
>> +} else if (unlikely(XRa == 0)) {
>> +/* destination is zero register -> do nothing */
>> +} else if (unlikely((XRb == 0) && (XRc == 0))) {
>> +/* both operands zero registers -> just set destination to zero */
>> +tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
>> +} else if (unlikely((XRb == 0) || (XRc == 0))) {
>> +/* exactly one operand is zero register - make it be the first...*/
>> +uint32_t XRx = XRb ? XRb : XRc;
> 
> Contrast this function, where the code and the comments are
> all in agreement that XRa is destination and XRb/XRc inputs.

Yes, from the spec XRa is the destination register, XRb/XRc are
the compared inputs. Unfortunately I couldn't sort the function
body code so I ended rewriting it.

Regards,

Phil.




[PATCH] target/mips/mxu: Rewrite D16MIN / D16MAX opcodes

2021-03-15 Thread Philippe Mathieu-Daudé
Coverity reported (CID 1450831) an array overrun in
gen_mxu_D16MAX_D16MIN():

  1103 } else if (unlikely((XRb == 0) || (XRa == 0))) {
  
  1112 if (opc == OPC_MXU_D16MAX) {
  1113 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
  1114 } else {
  1115 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
  1116 }

>>> Overrunning array "mxu_gpr" of 15 8-byte elements at element
index 4294967295 (byte offset 34359738367) using index "XRa - 1U"
(which evaluates to 4294967295).

Because we check if 'XRa == 0' then access 'XRa - 1' in array.

I figured it could be easier to rewrite this function to something
simpler rather than trying to understand it.

Cc: Craig Janeczek 
Fixes: bb84cbf3850 ("target/mips: MXU: Add handlers for max/min instructions")
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/mxu_translate.c | 116 
 1 file changed, 38 insertions(+), 78 deletions(-)

diff --git a/target/mips/mxu_translate.c b/target/mips/mxu_translate.c
index afc008f..8673a0139d4 100644
--- a/target/mips/mxu_translate.c
+++ b/target/mips/mxu_translate.c
@@ -1086,89 +1086,49 @@ static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
 static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
 {
 uint32_t pad, opc, XRc, XRb, XRa;
+TCGv_i32 b, c, bs, cs;
+TCGCond cond;
 
 pad = extract32(ctx->opcode, 21, 5);
-opc = extract32(ctx->opcode, 18, 3);
-XRc = extract32(ctx->opcode, 14, 4);
-XRb = extract32(ctx->opcode, 10, 4);
-XRa = extract32(ctx->opcode,  6, 4);
-
 if (unlikely(pad != 0)) {
 /* opcode padding incorrect -> do nothing */
-} else if (unlikely(XRc == 0)) {
-/* destination is zero register -> do nothing */
-} else if (unlikely((XRb == 0) && (XRa == 0))) {
-/* both operands zero registers -> just set destination to zero */
-tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
-} else if (unlikely((XRb == 0) || (XRa == 0))) {
-/* exactly one operand is zero register - find which one is not...*/
-uint32_t XRx = XRb ? XRb : XRc;
-/* ...and do half-word-wise max/min with one operand 0 */
-TCGv_i32 t0 = tcg_temp_new();
-TCGv_i32 t1 = tcg_const_i32(0);
-
-/* the left half-word first */
-tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x);
-if (opc == OPC_MXU_D16MAX) {
-tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
-} else {
-tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
-}
-
-/* the right half-word */
-tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x);
-/* move half-words to the leftmost position */
-tcg_gen_shli_i32(t0, t0, 16);
-/* t0 will be max/min of t0 and t1 */
-if (opc == OPC_MXU_D16MAX) {
-tcg_gen_smax_i32(t0, t0, t1);
-} else {
-tcg_gen_smin_i32(t0, t0, t1);
-}
-/* return resulting half-words to its original position */
-tcg_gen_shri_i32(t0, t0, 16);
-/* finally update the destination */
-tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
-
-tcg_temp_free(t1);
-tcg_temp_free(t0);
-} else if (unlikely(XRb == XRc)) {
-/* both operands same -> just set destination to one of them */
-tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-} else {
-/* the most general case */
-TCGv_i32 t0 = tcg_temp_new();
-TCGv_i32 t1 = tcg_temp_new();
-
-/* the left half-word first */
-tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x);
-tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x);
-if (opc == OPC_MXU_D16MAX) {
-tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
-} else {
-tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
-}
-
-/* the right half-word */
-tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x);
-tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x);
-/* move half-words to the leftmost position */
-tcg_gen_shli_i32(t0, t0, 16);
-tcg_gen_shli_i32(t1, t1, 16);
-/* t0 will be max/min of t0 and t1 */
-if (opc == OPC_MXU_D16MAX) {
-tcg_gen_smax_i32(t0, t0, t1);
-} else {
-tcg_gen_smin_i32(t0, t0, t1);
-}
-/* return resulting half-words to its original position */
-tcg_gen_shri_i32(t0, t0, 16);
-/* finally update the destination */
-tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
-
-tcg_temp_free(t1);
-tcg_temp_free(t0);
+return;
 }
+
+XRa = extract32(ctx->opcode,  6, 4);
+if (unlikely(XRa == 0)) {
+/* destination is zero register -> do nothing */
+return;
+}
+b = tcg_temp_new();
+c = tcg_temp_new();
+bs = tcg_temp_new();
+cs = tcg_temp_new();
+
+opc = extract32(ctx->opcode, 18, 3);
+cond = (opc == OPC_MXU_D16MAX) ? 

Re: Windows 10 won't run on default x86_64 machine anymore

2021-03-15 Thread Reinoud Zandijk
On Mon, Mar 15, 2021 at 06:53:02PM +0100, Igor Mammedov wrote:
> Windows 10 1607x64 boots fine when I test it with default machine.
> 
> So
>   1) can you provide full QEMU command line used
>   2) What Windows build do you use
>   3) is it existing guest image (i.e. installed in older QEMU version)

I've used:

qemu-system-x86_64 -m 4G -smp cores=2 -accel nvmm \
-snapshot \
-drive file=/home/reinoud/Downloads/Win10-demo.raw,format=raw \
-rtc base=localtime,clock=host \
-spice port=5924,disable-ticketing=on \
-vga qxl \
-usb -device usb-tablet \
-net nic -net tap,ifname=tap0,script=no &

If I add in '-M pc-i440fx-5.2' it works again with the accelerator. If I add
in '-M q35' it does work fine with or without the accelerator.

Surprisingly without accelerator ie with tcg the default machine does seem to
get to the login prompt. Is the ACPI data tailored to indicate an
accelerator/VM or is it static? Could it be that the CPU reported by my
machine is causing the issue? With the NVMM accelerator it passes on the hosts
CPU:

cpu0: "Intel(R) Celeron(R) 2957U @ 1.40GHz"
cpu0: Intel 4th gen Core, Xeon E3-12xx v3 (Haswell) (686-class), 1396.77 MHz
cpu0: family 0x6 model 0x45 stepping 0x1 (id 0x40651)

Running with NVMM gives the following warnings that might be relevant though
doesn't seem to bother the BSDs nor Linux last time I tried and Google tells
me they are power saving related MSRs:

qemu-system-x86_64: NVMM: Unexpected RDMSR 0x611, ignored
qemu-system-x86_64: NVMM: Unexpected RDMSR 0x641, ignored
qemu-system-x86_64: NVMM: Unexpected RDMSR 0x606, ignored
qemu-system-x86_64: NVMM: Unexpected RDMSR 0x606, ignored
qemu-system-x86_64: NVMM: Unexpected RDMSR 0x641, ignored
qemu-system-x86_64: NVMM: Unexpected RDMSR 0x611, ignored

I am not sure if that makes ACPI take a different route or not.

The Windows used is
Windows 10 Enterprise Evaluation
Build 17763.rs5_release.180914-1434
version 1809

The image file was downloaded pre-installed from Microsoft for Edge browser
evaluation. I used it first on Qemu 5.1 IIRC and it kept working in Qemu 5.2.

The NVMM accelerator was presented here before but is not yet committed. Its
API/construction is similar to WHPX.

As for the cause, I don't know; q35-6.0 works so why isn't pc-i440fx-6.0 ?

With regards,
Reinoud




Re: [PATCH v5 00/13] hw/block/nvme: metadata and end-to-end data protection support

2021-03-15 Thread Klaus Jensen
On Mar 10 10:53, Klaus Jensen wrote:
> From: Klaus Jensen 
> 
> This is v5 of a series that adds support for metadata and end-to-end
> data protection.
> 
> First, on the subject of metadata, in v1, support was restricted to
> extended logical blocks, which was pretty trivial to implement, but
> required special initialization and broke DULBE. In v2, metadata is
> always stored continuously at the end of the underlying block device.
> This has the advantage of not breaking DULBE since the data blocks
> remains aligned and allows bdrv_block_status to be used to determinate
> allocation status. It comes at the expense of complicating the extended
> LBA emulation, but on the other hand it also gains support for metadata
> transfered as a separate buffer.
> 
> The end-to-end data protection support blew up in terms of required
> changes. This is due to the fact that a bunch of new commands has been
> added to the device since v1 (zone append, compare, copy), and they all
> require various special handling for protection information. If
> potential reviewers would like it split up into multiple patches, each
> adding pi support to one command, shout out.
> 
> Support for metadata and end-to-end data protection is all joint work
> with Gollu Appalanaidu.
> 
> v5:
>   * add a required fix for zone management receive when metadata is
> involved
>   * add a couple of refactor patches for the zoned init code to make the
> format nvm patch more straight forward wrt. formatting of zoned
> namespaces.
> 

FYI, the SPDK e2edp test (tests/nvme/e2edp/nvme_dp) fails on this series
when metadata is more than 8 bytes. This is a bug in the test and I've
posted a fix upstream for this.

  https://review.spdk.io/gerrit/c/spdk/spdk/+/6891


--
k


signature.asc
Description: PGP signature


RE: [PATCH v8 29/35] Hexagon (target/hexagon) translation

2021-03-15 Thread Taylor Simpson

> -Original Message-
> From: Richard Henderson 
> Sent: Monday, March 15, 2021 8:32 AM
> To: Taylor Simpson ; qemu-devel@nongnu.org
> Cc: phi...@redhat.com; alex.ben...@linaro.org; laur...@vivier.eu;
> a...@rev.ng; Brian Cain 
> Subject: Re: [PATCH v8 29/35] Hexagon (target/hexagon) translation
>
> On 3/14/21 9:06 PM, Taylor Simpson wrote:
> >> Yes, but DISAS_NORETURN still means we've already exited.
> >>
> >> Just like calling abort() in C means that we won't reach any following 
> >> return statement.
> >
> > Then I'm missing something because the code emitted here does get executed.
>
> You really are missing the point.
>
> The code emitted here, for the NORETURN case, gets executed?  How do you know?

I can see the side effects.  For example, there is a call to 
gen_exec_counters(ctx), and I can see the counters being updated.

>   And if so, then *something* is returning when it shouldn't.
>
> The stop hook is for the use of all of the *other* DISAS_* codes, for which 
> we have not yet exited.
>
> There should be *nothing* to be done for NORETURN.  We have longjmp'ed
> away to the main loop already.  Anything that needed to be done must have been
> done before that point.

OK - I'll make sure everything is done during the packet generation and nothing 
is done during tb_stop.


Thanks,
Taylor





Re: Windows 10 won't run on default x86_64 machine anymore

2021-03-15 Thread Isaku Yamahata
On Mon, Mar 15, 2021 at 05:58:04PM +0100,
Reinoud Zandijk  wrote:

> I think its better to revert this and fix Linux ;) or make it a selectable
> feature as a workaround that's by default OFF :)

Anyway here is a patch to flip the default.
At the moment, this is compile-only tested to provide the change quickly
and make discussion progress.

>From 50deeed38832ceccfb68f78dd66de5a1741b2897 Mon Sep 17 00:00:00 2001
Message-Id: 
<50deeed38832ceccfb68f78dd66de5a1741b2897.1615845421.git.isaku.yamah...@intel.com>
From: Isaku Yamahata 
Date: Mon, 15 Mar 2021 14:42:33 -0700
Subject: [PATCH] ich9, piix4: flip default value for smm-compat

Make default value for smm-compat of ich9, piix4 true to keep old
behavior.
To get new (and more conformance to ACPI spec) behavior, explicitly
set "-global ICH9-LPC.smm-compat=off" or
"-global PIIX4_PM.smm-compat=off".

Reported-by: Reinoud Zandijk 
Fixes: 24cd04fce0 ("ich9, piix4: add property, smm-compat, to keep 
compatibility of SMM")
Signed-off-by: Isaku Yamahata 
---
 hw/acpi/piix4.c   | 2 +-
 hw/core/machine.c | 2 --
 hw/isa/lpc_ich9.c | 2 +-
 3 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 1efc0ded9f..34ade2c9bb 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -644,7 +644,7 @@ static Property piix4_pm_properties[] = {
  use_acpi_root_pci_hotplug, true),
 DEFINE_PROP_BOOL("memory-hotplug-support", PIIX4PMState,
  acpi_memory_hotplug.is_enabled, true),
-DEFINE_PROP_BOOL("smm-compat", PIIX4PMState, smm_compat, false),
+DEFINE_PROP_BOOL("smm-compat", PIIX4PMState, smm_compat, true),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 4386f57b5c..e644c4e07d 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -37,8 +37,6 @@
 #include "hw/virtio/virtio-pci.h"
 
 GlobalProperty hw_compat_5_2[] = {
-{ "ICH9-LPC", "smm-compat", "on"},
-{ "PIIX4_PM", "smm-compat", "on"},
 };
 const size_t hw_compat_5_2_len = G_N_ELEMENTS(hw_compat_5_2);
 
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 3963b73520..b7ff3a9747 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -775,7 +775,7 @@ static const VMStateDescription vmstate_ich9_lpc = {
 
 static Property ich9_lpc_properties[] = {
 DEFINE_PROP_BOOL("noreboot", ICH9LPCState, pin_strap.spkr_hi, true),
-DEFINE_PROP_BOOL("smm-compat", ICH9LPCState, pm.smm_compat, false),
+DEFINE_PROP_BOOL("smm-compat", ICH9LPCState, pm.smm_compat, true),
 DEFINE_PROP_BIT64("x-smi-broadcast", ICH9LPCState, smi_host_features,
   ICH9_LPC_SMI_F_BROADCAST_BIT, true),
 DEFINE_PROP_BIT64("x-smi-cpu-hotplug", ICH9LPCState, smi_host_features,
-- 
2.25.1



-- 
Isaku Yamahata 



Re: [PULL v2 0/5] Meson version update

2021-03-15 Thread Peter Maydell
On Mon, 15 Mar 2021 at 17:47, Paolo Bonzini  wrote:
>
> The following changes since commit 51204c2f188ec1e2a38f14718d38a3772f850a4b:
>
>   Merge remote-tracking branch 
> 'remotes/bkoppelmann2/tags/pull-tricore-20210314' into staging (2021-03-15 
> 15:34:27 +)
>
> are available in the Git repository at:
>
>   https://gitlab.com/bonzini/qemu.git tags/for-upstream-meson-0.57
>
> for you to fetch changes up to 57d42c3b774d0716b9ad1a5a576480521edc7201:
>
>   hexagon: use env keyword argument to pass PYTHONPATH (2021-03-15 18:06:21 
> +0100)
>
> v1->v2: rebased
>
> 
> Update Meson to 0.57.
>
> 
> Paolo Bonzini (5):
>   hexagon: do not specify executables as inputs
>   hexagon: do not specify Python scripts as inputs
>   meson: bump submodule to 0.57.1
>   meson: switch minimum meson version to 0.57.0
>   hexagon: use env keyword argument to pass PYTHONPATH

Fails to build, on at least x86-64, s390, ppc, aarch32, aarch64
Linux hosts:

make: Entering directory '/home/ubuntu/qemu/build/all'
(GIT="git" "/home/ubuntu/qemu/scripts/git-submodule.sh" update
ui/keycodemapdb tests/fp/berkeley-testfloat-3
tests/fp/berkeley-softfloat-3 meson dtc capstone slirp roms/SLOF)
config-host.mak is out-of-date, running configure
/usr/bin/ninja -v build.ninja && touch build.ninja.stamp
[0/1] /usr/bin/python3 /home/ubuntu/qemu/meson/meson.py --internal
regenerate /home/ubuntu/qemu /home/ubuntu/qemu/build/all --backend
ninja
WARNING: Regenerating configuration from scratch.
Reason: Coredata file
'/home/ubuntu/qemu/build/all/meson-private/coredata.dat' references
functions or classes that don't exist. This probably means that it was
generated with an old version of meson.
The Meson build system
Version: 0.57.1
Source dir: /home/ubuntu/qemu
Build dir: /home/ubuntu/qemu/build/all
Build type: native build

../../meson.build:1:0: ERROR: Value "true" (of type "string") for
combo option "Localization of the GTK+ user interface" is not one of
the choices. Possible choices are (as string): "enabled", "disabled",
"auto".

A full log can be found at /home/ubuntu/qemu/build/all/meson-logs/meson-log.txt
FAILED: build.ninja
/usr/bin/python3 /home/ubuntu/qemu/meson/meson.py --internal
regenerate /home/ubuntu/qemu /home/ubuntu/qemu/build/all --backend
ninja
ninja: error: rebuilding 'build.ninja': subcommand failed
/usr/bin/ninja -v build.ninja && touch build.ninja.stamp

(repeats same error another 3 times)

thanks
-- PMM



Re: [PULL 0/1] Block patches

2021-03-15 Thread Peter Maydell
On Mon, 15 Mar 2021 at 09:51, Stefan Hajnoczi  wrote:
>
> The following changes since commit 6157b0e19721aadb4c7fdcfe57b2924af6144b14:
>
>   Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-6.0-pull-=
> request' into staging (2021-03-14 17:47:49 +)
>
> are available in the Git repository at:
>
>   https://gitlab.com/stefanha/qemu.git tags/block-pull-request
>
> for you to fetch changes up to fb0b154c801e3447e505de420195fb7038695941:
>
>   virtio-blk: Respect discard granularity (2021-03-15 09:48:53 +)
>
> 
> Pull request
>
> 
>


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/6.0
for any user-visible changes.

-- PMM



[PATCH v2] Hexagon (target/hexagon) TCG generation cleanup

2021-03-15 Thread Taylor Simpson
Simplify TCG generation of hex_reg_written

Address feedback from Richard Henderson 

Signed-off-by: Taylor Simpson 
---
 target/hexagon/genptr.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 7481f4c..349b949 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -43,9 +43,15 @@ static inline void gen_log_predicated_reg_write(int rnum, 
TCGv val, int slot)
 tcg_gen_movcond_tl(TCG_COND_EQ, hex_new_value[rnum], slot_mask, zero,
val, hex_new_value[rnum]);
 #if HEX_DEBUG
-/* Do this so HELPER(debug_commit_end) will know */
-tcg_gen_movcond_tl(TCG_COND_EQ, hex_reg_written[rnum], slot_mask, zero,
-   one, hex_reg_written[rnum]);
+/*
+ * Do this so HELPER(debug_commit_end) will know
+ *
+ * Note that slot_mask indicates the value is not written
+ * (i.e., slot was cancelled), so we create a true/false value before
+ * or'ing with hex_reg_written[rnum].
+ */
+tcg_gen_setcond_tl(TCG_COND_EQ, slot_mask, slot_mask, zero);
+tcg_gen_or_tl(hex_reg_written[rnum], hex_reg_written[rnum], slot_mask);
 #endif
 
 tcg_temp_free(one);
-- 
2.7.4




Re: Windows 10 won't run on default x86_64 machine anymore

2021-03-15 Thread Michael S. Tsirkin
On Mon, Mar 15, 2021 at 05:58:04PM +0100, Reinoud Zandijk wrote:
> Hi,
> 
> with the introduction of the following patch from 17th of February, Win10
> won't boot anymore without explicitly setting the machine to be 5.2 compatible
> like pc-1440fx-5.2. The default 6.0 will cause it to panic and gives as reason
> only "ACPI error".


Thanks for the report!
Could you provide a bit more detail please?
Which windows version is used, which qemu command line, etc etc.

Also does this only affect pre-installed guests? what if you
install a fresh copy of windows?

> It might work to counter a bug in Linux but this is not the place to do the
> patch. The BSDs don't care and will boot fine with full ACPI regardless of the
> machine chosen. Windows 10 however DOES care and gets confused.
> 
> I think its better to revert this and fix Linux ;) or make it a selectable
> feature as a workaround that's by default OFF :)
> 
> With regards,
> Reinoud
> 
> 
> The patch concerned is:
> 
> commit 6be8cf56bc8bda2ed9a070bdb04446191f31acc9
> Author: Isaku Yamahata 
> Date:   Wed Feb 17 21:51:12 2021 -0800
> 
> acpi/core: always set SCI_EN when SMM isn't supported
> 
> If SMM is not supported, ACPI fixed hardware doesn't support
> legacy-mode. ACPI-only platform. Where SCI_EN in PM1_CNT register is
> always set.
> The bit tells OS legacy mode(SCI_EN cleared) or ACPI mode(SCI_EN set).
> 
> With the next patch (setting fadt.smi_cmd = 0 when smm isn't enabled),
> guest Linux tries to switch to ACPI mode, finds smi_cmd = 0, and then
> fails to initialize acpi subsystem. This patch proactively fixes it.
> 
> This patch changes guest ABI. To keep compatibility, use
> "smm-compat" introduced by earlier patch. If the property is true,
> disable new behavior.
> 
> ACPI spec 4.8.10.1 PM1 Event Grouping
> PM1 Eanble Registers
> > For ACPI-only platforms (where SCI_EN is always set)
> 
> Reviewed-by: Igor Mammedov 
> Signed-off-by: Isaku Yamahata 
> Message-Id:
> <500f62081626997e46f96377393d3662211763a8.1613615732.git.isaku.yamah...@intel.com>
> Reviewed-by: Michael S. Tsirkin 
> Signed-off-by: Michael S. Tsirkin 
> 
>  hw/acpi/core.c | 11 ++-
>  hw/acpi/ich9.c |  2 +-
>  hw/acpi/piix4.c|  3 ++-
>  hw/core/machine.c  |  5 -
>  hw/isa/vt82c686.c  |  2 +-
>  include/hw/acpi/acpi.h |  4 +++-
>  6 files changed, 21 insertions(+), 6 deletions(-)
> 
> 





[Bug 1919253] [NEW] QEMU doesn't build reproducibly anymore in 5.2.0

2021-03-15 Thread Apteryx
Public bug reported:

It used to be that building QEMU 5.1.0 twice in a row, using Guix, would
result in bit-for-bit identical results.

Starting with 5.2.0, this is no longer true.  Here's a summary of which
files have non-determinism:

Here's a summary of the differing files:

$ diff -r /gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0{,-check}
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-aarch64 and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-aarch64 
differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-aarch64_be and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-aarch64_be
 differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-alpha and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-alpha 
differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-arm and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-arm differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-armeb and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-armeb 
differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-cris and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-cris 
differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-edid and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-edid 
differ
Binary files /gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-ga 
and /gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-ga 
differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-hppa and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-hppa 
differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-i386 and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-i386 
differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-img and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-img differ
Binary files /gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-io 
and /gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-io 
differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-keymap and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-keymap 
differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-m68k and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-m68k 
differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-microblaze and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-microblaze
 differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-microblazeel 
and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-microblazeel
 differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-mips and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-mips 
differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-mips64 and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-mips64 
differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-mips64el and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-mips64el 
differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-mipsel and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-mipsel 
differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-mipsn32 and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-mipsn32 
differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-mipsn32el and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-mipsn32el 
differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-nbd and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-nbd differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-nios2 and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-nios2 
differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-or1k and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-or1k 
differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-ppc and 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0-check/bin/qemu-ppc differ
Binary files 
/gnu/store/l286mbanw78qgbn54gs5j23qm0v9abhw-qemu-5.2.0/bin/qemu-ppc64 and 

RE: [PATCH] Hexagon (target/hexagon) TCG generation cleanup

2021-03-15 Thread Taylor Simpson


> -Original Message-
> From: Richard Henderson 
> Sent: Monday, March 15, 2021 8:40 AM
> To: Taylor Simpson ; qemu-devel@nongnu.org
> Cc: phi...@redhat.com
> Subject: Re: [PATCH] Hexagon (target/hexagon) TCG generation cleanup
>
> On 3/14/21 10:54 PM, Taylor Simpson wrote:
> > Simplify TCG generation of hex_reg_written
> >
> > Address feedback from Richard Henderson
> <
> >
> > Signed-off-by: Taylor Simpson 
> > ---
> >   target/hexagon/genptr.c | 12 +---
> >   1 file changed, 9 insertions(+), 3 deletions(-)
> >
> > diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
> > index 7481f4c..0ad63fe 100644
> > --- a/target/hexagon/genptr.c
> > +++ b/target/hexagon/genptr.c
> > @@ -43,9 +43,15 @@ static inline void gen_log_predicated_reg_write(int
> rnum, TCGv val, int slot)
> >   tcg_gen_movcond_tl(TCG_COND_EQ, hex_new_value[rnum],
> slot_mask, zero,
> >  val, hex_new_value[rnum]);
> >   #if HEX_DEBUG
> > -/* Do this so HELPER(debug_commit_end) will know */
> > -tcg_gen_movcond_tl(TCG_COND_EQ, hex_reg_written[rnum],
> slot_mask, zero,
> > -   one, hex_reg_written[rnum]);
> > +/*
> > + * Do this so HELPER(debug_commit_end) will know
> > + *
> > + * Note that slot_mask indicates the value is not written
> > + * (i.e., slot was cancelled), so we negate the value before
> > + * or'ing with hex_reg_written[rnum].
> > + */
> > +tcg_gen_xori_tl(slot_mask, slot_mask, 1 << slot);
> > +tcg_gen_or_tl(hex_reg_written[rnum], hex_reg_written[rnum],
> slot_mask);
>
> reg_written appears to be a boolean, not a mask of any kind.
> I think you want
>
>  tcg_gen_setcond_i32(TCG_COND_EQ, slot_mask, slot_mask, zero);
>
> and not the xor.

I'm treating it as a zero/non-zero value.  The change works because the usage 
in op_helper.c is
if (env->reg_written[i]) ...

I'll change the xor to setcond to make it more clear.


Thanks,
Taylor




Re: [PATCH 12/38] target/riscv: SIMD 16-bit Miscellaneous Instructions

2021-03-15 Thread Alistair Francis
On Fri, Feb 12, 2021 at 10:28 AM LIU Zhiwei  wrote:
>
> Signed-off-by: LIU Zhiwei 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/helper.h   |  12 ++
>  target/riscv/insn32.decode  |  13 ++
>  target/riscv/insn_trans/trans_rvp.c.inc |  42 ++
>  target/riscv/packed_helper.c| 167 
>  4 files changed, 234 insertions(+)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index 6bb601b436..866484e37d 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -1228,3 +1228,15 @@ DEF_HELPER_3(umul8, i64, env, tl, tl)
>  DEF_HELPER_3(umulx8, i64, env, tl, tl)
>  DEF_HELPER_3(khm8, tl, env, tl, tl)
>  DEF_HELPER_3(khmx8, tl, env, tl, tl)
> +
> +DEF_HELPER_3(smin16, tl, env, tl, tl)
> +DEF_HELPER_3(umin16, tl, env, tl, tl)
> +DEF_HELPER_3(smax16, tl, env, tl, tl)
> +DEF_HELPER_3(umax16, tl, env, tl, tl)
> +DEF_HELPER_3(sclip16, tl, env, tl, tl)
> +DEF_HELPER_3(uclip16, tl, env, tl, tl)
> +DEF_HELPER_2(kabs16, tl, env, tl)
> +DEF_HELPER_2(clrs16, tl, env, tl)
> +DEF_HELPER_2(clz16, tl, env, tl)
> +DEF_HELPER_2(clo16, tl, env, tl)
> +DEF_HELPER_2(swap16, tl, env, tl)
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index 9d165efba9..bc9d5fc967 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -42,6 +42,7 @@
>  imm rs1 rd
>  imm rd
>  rd rs1 rs2
> +   rd rs1
>  imm rs1 rs2
>  imm rd
>   shamt rs1 rd
> @@ -695,3 +696,15 @@ umul8  1011100  . . 000 . 111 @r
>  umulx8 1011101  . . 000 . 111 @r
>  khm8   1000111  . . 000 . 111 @r
>  khmx8  100  . . 000 . 111 @r
> +
> +smin16 100  . . 000 . 111 @r
> +umin16 1001000  . . 000 . 111 @r
> +smax16 101  . . 000 . 111 @r
> +umax16 1001001  . . 000 . 111 @r
> +sclip16110  0 . 000 . 111 @sh4
> +uclip16110  1 . 000 . 111 @sh4
> +kabs16 1010110  10001 . 000 . 111 @r2
> +clrs16 1010111  01000 . 000 . 111 @r2
> +clz16  1010111  01001 . 000 . 111 @r2
> +clo16  1010111  01011 . 000 . 111 @r2
> +swap16 1010110  11001 . 000 . 111 @r2
> diff --git a/target/riscv/insn_trans/trans_rvp.c.inc 
> b/target/riscv/insn_trans/trans_rvp.c.inc
> index 336f3418b1..56fb8b2523 100644
> --- a/target/riscv/insn_trans/trans_rvp.c.inc
> +++ b/target/riscv/insn_trans/trans_rvp.c.inc
> @@ -444,3 +444,45 @@ GEN_RVP_R_D64_OOL(umul8);
>  GEN_RVP_R_D64_OOL(umulx8);
>  GEN_RVP_R_OOL(khm8);
>  GEN_RVP_R_OOL(khmx8);
> +
> +/* SIMD 16-bit Miscellaneous Instructions */
> +GEN_RVP_R_OOL(smin16);
> +GEN_RVP_R_OOL(umin16);
> +GEN_RVP_R_OOL(smax16);
> +GEN_RVP_R_OOL(umax16);
> +GEN_RVP_SHIFTI(sclip16, sclip16, NULL);
> +GEN_RVP_SHIFTI(uclip16, uclip16, NULL);
> +
> +/* Out of line helpers for R2 format */
> +static bool
> +r2_ool(DisasContext *ctx, arg_r2 *a,
> +   void (* fn)(TCGv, TCGv_ptr, TCGv))
> +{
> +TCGv src1, dst;
> +if (!has_ext(ctx, RVP)) {
> +return false;
> +}
> +
> +src1 = tcg_temp_new();
> +dst = tcg_temp_new();
> +
> +gen_get_gpr(src1, a->rs1);
> +fn(dst, cpu_env, src1);
> +gen_set_gpr(a->rd, dst);
> +
> +tcg_temp_free(src1);
> +tcg_temp_free(dst);
> +return true;
> +}
> +
> +#define GEN_RVP_R2_OOL(NAME)   \
> +static bool trans_##NAME(DisasContext *s, arg_r2 *a)   \
> +{  \
> +return r2_ool(s, a, gen_helper_##NAME);\
> +}
> +
> +GEN_RVP_R2_OOL(kabs16);
> +GEN_RVP_R2_OOL(clrs16);
> +GEN_RVP_R2_OOL(clz16);
> +GEN_RVP_R2_OOL(clo16);
> +GEN_RVP_R2_OOL(swap16);
> diff --git a/target/riscv/packed_helper.c b/target/riscv/packed_helper.c
> index 56baefeb8e..a6ab011ace 100644
> --- a/target/riscv/packed_helper.c
> +++ b/target/riscv/packed_helper.c
> @@ -920,3 +920,170 @@ static inline void do_khmx8(CPURISCVState *env, void 
> *vd, void *va,
>  }
>
>  RVPR(khmx8, 2, 1);
> +
> +/* SIMD 16-bit Miscellaneous Instructions */
> +static inline void do_smin16(CPURISCVState *env, void *vd, void *va,
> + void *vb, uint8_t i)
> +{
> +int16_t *d = vd, *a = va, *b = vb;
> +
> +d[i] = (a[i] < b[i]) ? a[i] : b[i];
> +}
> +
> +RVPR(smin16, 1, 2);
> +
> +static inline void do_umin16(CPURISCVState *env, void *vd, void *va,
> + void *vb, uint8_t i)
> +{
> +uint16_t *d = vd, *a = va, *b = vb;
> +
> +d[i] = (a[i] < b[i]) ? a[i] : b[i];
> +}
> +
> +RVPR(umin16, 1, 2);
> +
> +static inline void do_smax16(CPURISCVState *env, void *vd, void *va,
> + void *vb, uint8_t i)
> +{
> +int16_t *d = vd, *a = va, *b = vb;
> +
> +d[i] = (a[i] > b[i]) ? a[i] : b[i];
> +}
> +
> +RVPR(smax16, 1, 2);
> +
> +static inline 

Re: [PATCH 09/38] target/riscv: SIMD 8-bit Compare Instructions

2021-03-15 Thread Alistair Francis
On Fri, Feb 12, 2021 at 10:22 AM LIU Zhiwei  wrote:
>
> Signed-off-by: LIU Zhiwei 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/helper.h   |  6 
>  target/riscv/insn32.decode  |  6 
>  target/riscv/insn_trans/trans_rvp.c.inc |  7 
>  target/riscv/packed_helper.c| 46 +
>  4 files changed, 65 insertions(+)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index f41f9a..4d9c36609c 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -1208,3 +1208,9 @@ DEF_HELPER_3(scmplt16, tl, env, tl, tl)
>  DEF_HELPER_3(scmple16, tl, env, tl, tl)
>  DEF_HELPER_3(ucmplt16, tl, env, tl, tl)
>  DEF_HELPER_3(ucmple16, tl, env, tl, tl)
> +
> +DEF_HELPER_3(cmpeq8, tl, env, tl, tl)
> +DEF_HELPER_3(scmplt8, tl, env, tl, tl)
> +DEF_HELPER_3(scmple8, tl, env, tl, tl)
> +DEF_HELPER_3(ucmplt8, tl, env, tl, tl)
> +DEF_HELPER_3(ucmple8, tl, env, tl, tl)
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index f3cd508396..7519df7e20 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -675,3 +675,9 @@ scmplt16   110  . . 000 . 111 @r
>  scmple16   0001110  . . 000 . 111 @r
>  ucmplt16   0010110  . . 000 . 111 @r
>  ucmple16   000  . . 000 . 111 @r
> +
> +cmpeq8 0100111  . . 000 . 111 @r
> +scmplt8111  . . 000 . 111 @r
> +scmple8000  . . 000 . 111 @r
> +ucmplt80010111  . . 000 . 111 @r
> +ucmple8001  . . 000 . 111 @r
> diff --git a/target/riscv/insn_trans/trans_rvp.c.inc 
> b/target/riscv/insn_trans/trans_rvp.c.inc
> index 6438dfb776..6eb9e83c6f 100644
> --- a/target/riscv/insn_trans/trans_rvp.c.inc
> +++ b/target/riscv/insn_trans/trans_rvp.c.inc
> @@ -376,3 +376,10 @@ GEN_RVP_R_OOL(scmplt16);
>  GEN_RVP_R_OOL(scmple16);
>  GEN_RVP_R_OOL(ucmplt16);
>  GEN_RVP_R_OOL(ucmple16);
> +
> +/* SIMD 8-bit Compare Instructions */
> +GEN_RVP_R_OOL(cmpeq8);
> +GEN_RVP_R_OOL(scmplt8);
> +GEN_RVP_R_OOL(scmple8);
> +GEN_RVP_R_OOL(ucmplt8);
> +GEN_RVP_R_OOL(ucmple8);
> diff --git a/target/riscv/packed_helper.c b/target/riscv/packed_helper.c
> index 30b916b5ad..ff86e015e4 100644
> --- a/target/riscv/packed_helper.c
> +++ b/target/riscv/packed_helper.c
> @@ -677,3 +677,49 @@ static inline void do_ucmple16(CPURISCVState *env, void 
> *vd, void *va,
>  }
>
>  RVPR(ucmple16, 1, 2);
> +
> +/* SIMD 8-bit Compare Instructions */
> +static inline void do_cmpeq8(CPURISCVState *env, void *vd, void *va,
> + void *vb, uint8_t i)
> +{
> +uint8_t *d = vd, *a = va, *b = vb;
> +d[i] = (a[i] == b[i]) ? 0xff : 0x0;
> +}
> +
> +RVPR(cmpeq8, 1, 1);
> +
> +static inline void do_scmplt8(CPURISCVState *env, void *vd, void *va,
> +   void *vb, uint8_t i)
> +{
> +int8_t *d = vd, *a = va, *b = vb;
> +d[i] = (a[i] < b[i]) ? 0xff : 0x0;
> +}
> +
> +RVPR(scmplt8, 1, 1);
> +
> +static inline void do_scmple8(CPURISCVState *env, void *vd, void *va,
> +   void *vb, uint8_t i)
> +{
> +int8_t *d = vd, *a = va, *b = vb;
> +d[i] = (a[i] <= b[i]) ? 0xff : 0x0;
> +}
> +
> +RVPR(scmple8, 1, 1);
> +
> +static inline void do_ucmplt8(CPURISCVState *env, void *vd, void *va,
> +   void *vb, uint8_t i)
> +{
> +uint8_t *d = vd, *a = va, *b = vb;
> +d[i] = (a[i] < b[i]) ? 0xff : 0x0;
> +}
> +
> +RVPR(ucmplt8, 1, 1);
> +
> +static inline void do_ucmple8(CPURISCVState *env, void *vd, void *va,
> +   void *vb, uint8_t i)
> +{
> +uint8_t *d = vd, *a = va, *b = vb;
> +d[i] = (a[i] <= b[i]) ? 0xff : 0x0;
> +}
> +
> +RVPR(ucmple8, 1, 1);
> --
> 2.17.1
>



Re: [PATCH 11/38] target/riscv: SIMD 8-bit Multiply Instructions

2021-03-15 Thread Alistair Francis
On Fri, Feb 12, 2021 at 10:26 AM LIU Zhiwei  wrote:
>
> Signed-off-by: LIU Zhiwei 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/helper.h   |  7 ++
>  target/riscv/insn32.decode  |  7 ++
>  target/riscv/insn_trans/trans_rvp.c.inc |  8 +++
>  target/riscv/packed_helper.c| 93 +
>  4 files changed, 115 insertions(+)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index bc60712bd9..6bb601b436 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -1221,3 +1221,10 @@ DEF_HELPER_3(umul16, i64, env, tl, tl)
>  DEF_HELPER_3(umulx16, i64, env, tl, tl)
>  DEF_HELPER_3(khm16, tl, env, tl, tl)
>  DEF_HELPER_3(khmx16, tl, env, tl, tl)
> +
> +DEF_HELPER_3(smul8, i64, env, tl, tl)
> +DEF_HELPER_3(smulx8, i64, env, tl, tl)
> +DEF_HELPER_3(umul8, i64, env, tl, tl)
> +DEF_HELPER_3(umulx8, i64, env, tl, tl)
> +DEF_HELPER_3(khm8, tl, env, tl, tl)
> +DEF_HELPER_3(khmx8, tl, env, tl, tl)
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index 38519a477c..9d165efba9 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -688,3 +688,10 @@ umul16 1011000  . . 000 . 111 @r
>  umulx161011001  . . 000 . 111 @r
>  khm16  111  . . 000 . 111 @r
>  khmx16 1001011  . . 000 . 111 @r
> +
> +smul8  1010100  . . 000 . 111 @r
> +smulx8 1010101  . . 000 . 111 @r
> +umul8  1011100  . . 000 . 111 @r
> +umulx8 1011101  . . 000 . 111 @r
> +khm8   1000111  . . 000 . 111 @r
> +khmx8  100  . . 000 . 111 @r
> diff --git a/target/riscv/insn_trans/trans_rvp.c.inc 
> b/target/riscv/insn_trans/trans_rvp.c.inc
> index 7e5bf9041d..336f3418b1 100644
> --- a/target/riscv/insn_trans/trans_rvp.c.inc
> +++ b/target/riscv/insn_trans/trans_rvp.c.inc
> @@ -436,3 +436,11 @@ GEN_RVP_R_D64_OOL(umul16);
>  GEN_RVP_R_D64_OOL(umulx16);
>  GEN_RVP_R_OOL(khm16);
>  GEN_RVP_R_OOL(khmx16);
> +
> +/* SIMD 8-bit Multiply Instructions */
> +GEN_RVP_R_D64_OOL(smul8);
> +GEN_RVP_R_D64_OOL(smulx8);
> +GEN_RVP_R_D64_OOL(umul8);
> +GEN_RVP_R_D64_OOL(umulx8);
> +GEN_RVP_R_OOL(khm8);
> +GEN_RVP_R_OOL(khmx8);
> diff --git a/target/riscv/packed_helper.c b/target/riscv/packed_helper.c
> index 13fed2c4d1..56baefeb8e 100644
> --- a/target/riscv/packed_helper.c
> +++ b/target/riscv/packed_helper.c
> @@ -827,3 +827,96 @@ static inline void do_khmx16(CPURISCVState *env, void 
> *vd, void *va,
>  }
>
>  RVPR(khmx16, 2, 2);
> +
> +/* SIMD 8-bit Multiply Instructions */
> +static inline void do_smul8(CPURISCVState *env, void *vd, void *va, void *vb)
> +{
> +int16_t *d = vd;
> +int8_t *a = va, *b = vb;
> +d[H2(0)] = (int16_t)a[H1(0)] * b[H1(0)];
> +d[H2(1)] = (int16_t)a[H1(1)] * b[H1(1)];
> +d[H2(2)] = (int16_t)a[H1(2)] * b[H1(2)];
> +d[H2(3)] = (int16_t)a[H1(3)] * b[H1(3)];
> +}
> +
> +RVPR64(smul8);
> +
> +static inline void do_smulx8(CPURISCVState *env, void *vd, void *va, void 
> *vb)
> +{
> +int16_t *d = vd;
> +int8_t *a = va, *b = vb;
> +d[H2(0)] = (int16_t)a[H1(0)] * b[H1(1)];
> +d[H2(1)] = (int16_t)a[H1(1)] * b[H1(0)];
> +d[H2(2)] = (int16_t)a[H1(2)] * b[H1(3)];
> +d[H2(3)] = (int16_t)a[H1(3)] * b[H1(2)];
> +}
> +
> +RVPR64(smulx8);
> +
> +static inline void do_umul8(CPURISCVState *env, void *vd, void *va, void *vb)
> +{
> +uint16_t *d = vd;
> +uint8_t *a = va, *b = vb;
> +d[H2(0)] = (uint16_t)a[H1(0)] * b[H1(0)];
> +d[H2(1)] = (uint16_t)a[H1(1)] * b[H1(1)];
> +d[H2(2)] = (uint16_t)a[H1(2)] * b[H1(2)];
> +d[H2(3)] = (uint16_t)a[H1(3)] * b[H1(3)];
> +}
> +
> +RVPR64(umul8);
> +
> +static inline void do_umulx8(CPURISCVState *env, void *vd, void *va, void 
> *vb)
> +{
> +uint16_t *d = vd;
> +uint8_t *a = va, *b = vb;
> +d[H2(0)] = (uint16_t)a[H1(0)] * b[H1(1)];
> +d[H2(1)] = (uint16_t)a[H1(1)] * b[H1(0)];
> +d[H2(2)] = (uint16_t)a[H1(2)] * b[H1(3)];
> +d[H2(3)] = (uint16_t)a[H1(3)] * b[H1(2)];
> +}
> +
> +RVPR64(umulx8);
> +
> +static inline void do_khm8(CPURISCVState *env, void *vd, void *va,
> +   void *vb, uint8_t i)
> +{
> +int8_t *d = vd, *a = va, *b = vb;
> +
> +if (a[i] == INT8_MIN && b[i] == INT8_MIN) {
> +env->vxsat = 1;
> +d[i] = INT8_MAX;
> +} else {
> +d[i] = (int16_t)a[i] * b[i] >> 7;
> +}
> +}
> +
> +RVPR(khm8, 1, 1);
> +
> +static inline void do_khmx8(CPURISCVState *env, void *vd, void *va,
> +void *vb, uint8_t i)
> +{
> +int8_t *d = vd, *a = va, *b = vb;
> +/*
> + * t[x] = ra.B[x] s* rb.B[y];
> + * rt.B[x] = SAT.Q7(t[x] s>> 7);
> + *
> + * (RV32: (x,y)=(3,2),(2,3),
> + *  (1,0),(0,1),
> + * (RV64: (x,y)=(7,6),(6,7),(5,4),(4,5),
> + *  (3,2),(2,3),(1,0),(0,1))
> + 

Re: [PULL 18/27] target/mips: Extract MXU code to new mxu_translate.c file

2021-03-15 Thread Peter Maydell
On Sat, 13 Mar 2021 at 19:58, Philippe Mathieu-Daudé  wrote:
>
> Extract 1600+ lines from the big translate.c into a new file.
>
> Reviewed-by: Richard Henderson 
> Signed-off-by: Philippe Mathieu-Daudé 

This code motion caused Coverity to rescan this code, and
it thinks there's a problem in this function (CID 1450831).
It looks to me like it might be right...


> +/*
> + *  D16MAX
> + *Update XRa with the 16-bit-wise maximums of signed integers
> + *contained in XRb and XRc.
> + *
> + *  D16MIN
> + *Update XRa with the 16-bit-wise minimums of signed integers
> + *contained in XRb and XRc.
> + */
> +static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
> +{
> +uint32_t pad, opc, XRc, XRb, XRa;
> +
> +pad = extract32(ctx->opcode, 21, 5);
> +opc = extract32(ctx->opcode, 18, 3);
> +XRc = extract32(ctx->opcode, 14, 4);
> +XRb = extract32(ctx->opcode, 10, 4);
> +XRa = extract32(ctx->opcode,  6, 4);
> +
> +if (unlikely(pad != 0)) {
> +/* opcode padding incorrect -> do nothing */
> +} else if (unlikely(XRc == 0)) {
> +/* destination is zero register -> do nothing */
> +} else if (unlikely((XRb == 0) && (XRa == 0))) {
> +/* both operands zero registers -> just set destination to zero */
> +tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
> +} else if (unlikely((XRb == 0) || (XRa == 0))) {

In this block of code either XRb or XRa is zero...

> +/* exactly one operand is zero register - find which one is not...*/
> +uint32_t XRx = XRb ? XRb : XRc;
> +/* ...and do half-word-wise max/min with one operand 0 */
> +TCGv_i32 t0 = tcg_temp_new();
> +TCGv_i32 t1 = tcg_const_i32(0);
> +
> +/* the left half-word first */
> +tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x);
> +if (opc == OPC_MXU_D16MAX) {
> +tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
> +} else {
> +tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
> +}

but in these smax/smin calls we're clearly assuming that
XRa is not zero.

There seems to be some confusion over which registers are
the inputs and which is the output. The top-level function
comment says XRa is the input and XRb/XRc the inputs.
But the "destination is zero register" comment is against
a check on XRc, and the "both operands zero" comment is
against a check on XRa and XRb, as is the "one operand
is zero" comment...

> +/*
> + *  Q8MAX
> + *Update XRa with the 8-bit-wise maximums of signed integers
> + *contained in XRb and XRc.
> + *
> + *  Q8MIN
> + *Update XRa with the 8-bit-wise minimums of signed integers
> + *contained in XRb and XRc.
> + */
> +static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
> +{
> +uint32_t pad, opc, XRc, XRb, XRa;
> +
> +pad = extract32(ctx->opcode, 21, 5);
> +opc = extract32(ctx->opcode, 18, 3);
> +XRc = extract32(ctx->opcode, 14, 4);
> +XRb = extract32(ctx->opcode, 10, 4);
> +XRa = extract32(ctx->opcode,  6, 4);
> +
> +if (unlikely(pad != 0)) {
> +/* opcode padding incorrect -> do nothing */
> +} else if (unlikely(XRa == 0)) {
> +/* destination is zero register -> do nothing */
> +} else if (unlikely((XRb == 0) && (XRc == 0))) {
> +/* both operands zero registers -> just set destination to zero */
> +tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
> +} else if (unlikely((XRb == 0) || (XRc == 0))) {
> +/* exactly one operand is zero register - make it be the first...*/
> +uint32_t XRx = XRb ? XRb : XRc;

Contrast this function, where the code and the comments are
all in agreement that XRa is destination and XRb/XRc inputs.

thanks
-- PMM



Re: Windows 10 won't run on default x86_64 machine anymore

2021-03-15 Thread Isaku Yamahata
On Mon, Mar 15, 2021 at 05:19:17PM +,
"Daniel P. Berrangé"  wrote:

> On Mon, Mar 15, 2021 at 05:58:04PM +0100, Reinoud Zandijk wrote:
> > Hi,
> > 
> > with the introduction of the following patch from 17th of February, Win10
> > won't boot anymore without explicitly setting the machine to be 5.2 
> > compatible
> > like pc-1440fx-5.2. The default 6.0 will cause it to panic and gives as 
> > reason
> > only "ACPI error".
> > 
> > It might work to counter a bug in Linux but this is not the place to do the
> > patch. The BSDs don't care and will boot fine with full ACPI regardless of 
> > the
> > machine chosen. Windows 10 however DOES care and gets confused.
> > 
> > I think its better to revert this and fix Linux ;) or make it a selectable
> > feature as a workaround that's by default OFF :)
> 
> I'm copying the people involved in creating/reviewing the commit you
> mention below.
> 
> I've also added this regression to the 6.0 issues list, since being
> able to boot current Windows guests with the default machine type
> should be considered a release blocker IMHO.
> 
>https://wiki.qemu.org/Planning/6.0#Not_fixed_yet

It's about ACPI spec conformance. What qemu command line is used?
Smi is explicitly disabled (property smm=off), but guest requires legacy bios 
mode?
What about enabling smm mode? or "-global PIIX4_PM.smm-compat=on"
(or "-global ICH9-LPC.smm-compat=on" if you use q35)

Thanks,
Isaku Yamahata
-- 
Isaku Yamahata 



Re: [PATCH 08/38] target/riscv: SIMD 16-bit Compare Instructions

2021-03-15 Thread Alistair Francis
On Fri, Feb 12, 2021 at 10:20 AM LIU Zhiwei  wrote:
>
> Signed-off-by: LIU Zhiwei 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/helper.h   |  6 
>  target/riscv/insn32.decode  |  6 
>  target/riscv/insn_trans/trans_rvp.c.inc |  7 
>  target/riscv/packed_helper.c| 46 +
>  4 files changed, 65 insertions(+)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index 0ecd4d53f9..f41f9a 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -1202,3 +1202,9 @@ DEF_HELPER_3(sll8, tl, env, tl, tl)
>  DEF_HELPER_3(ksll8, tl, env, tl, tl)
>  DEF_HELPER_3(kslra8, tl, env, tl, tl)
>  DEF_HELPER_3(kslra8_u, tl, env, tl, tl)
> +
> +DEF_HELPER_3(cmpeq16, tl, env, tl, tl)
> +DEF_HELPER_3(scmplt16, tl, env, tl, tl)
> +DEF_HELPER_3(scmple16, tl, env, tl, tl)
> +DEF_HELPER_3(ucmplt16, tl, env, tl, tl)
> +DEF_HELPER_3(ucmple16, tl, env, tl, tl)
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index cc782fcde5..f3cd508396 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -669,3 +669,9 @@ ksll8  0110110  . . 000 . 111 @r
>  kslli8 010  01... . 000 . 111 @sh3
>  kslra8 010  . . 000 . 111 @r
>  kslra8_u   0110111  . . 000 . 111 @r
> +
> +cmpeq160100110  . . 000 . 111 @r
> +scmplt16   110  . . 000 . 111 @r
> +scmple16   0001110  . . 000 . 111 @r
> +ucmplt16   0010110  . . 000 . 111 @r
> +ucmple16   000  . . 000 . 111 @r
> diff --git a/target/riscv/insn_trans/trans_rvp.c.inc 
> b/target/riscv/insn_trans/trans_rvp.c.inc
> index 12a64849eb..6438dfb776 100644
> --- a/target/riscv/insn_trans/trans_rvp.c.inc
> +++ b/target/riscv/insn_trans/trans_rvp.c.inc
> @@ -369,3 +369,10 @@ GEN_RVP_SHIFTI(slli8, sll8, tcg_gen_vec_shl8i_i64);
>  GEN_RVP_SHIFTI(srai8_u, sra8_u, NULL);
>  GEN_RVP_SHIFTI(srli8_u, srl8_u, NULL);
>  GEN_RVP_SHIFTI(kslli8, ksll8, NULL);
> +
> +/* SIMD 16-bit Compare Instructions */
> +GEN_RVP_R_OOL(cmpeq16);
> +GEN_RVP_R_OOL(scmplt16);
> +GEN_RVP_R_OOL(scmple16);
> +GEN_RVP_R_OOL(ucmplt16);
> +GEN_RVP_R_OOL(ucmple16);
> diff --git a/target/riscv/packed_helper.c b/target/riscv/packed_helper.c
> index ab9ebc472b..30b916b5ad 100644
> --- a/target/riscv/packed_helper.c
> +++ b/target/riscv/packed_helper.c
> @@ -631,3 +631,49 @@ static inline void do_kslra8_u(CPURISCVState *env, void 
> *vd, void *va,
>  }
>
>  RVPR(kslra8_u, 1, 1);
> +
> +/* SIMD 16-bit Compare Instructions */
> +static inline void do_cmpeq16(CPURISCVState *env, void *vd, void *va,
> +  void *vb, uint8_t i)
> +{
> +uint16_t *d = vd, *a = va, *b = vb;
> +d[i] = (a[i] == b[i]) ? 0x : 0x0;
> +}
> +
> +RVPR(cmpeq16, 1, 2);
> +
> +static inline void do_scmplt16(CPURISCVState *env, void *vd, void *va,
> +   void *vb, uint8_t i)
> +{
> +int16_t *d = vd, *a = va, *b = vb;
> +d[i] = (a[i] < b[i]) ? 0x : 0x0;
> +}
> +
> +RVPR(scmplt16, 1, 2);
> +
> +static inline void do_scmple16(CPURISCVState *env, void *vd, void *va,
> +   void *vb, uint8_t i)
> +{
> +int16_t *d = vd, *a = va, *b = vb;
> +d[i] = (a[i] <= b[i]) ? 0x : 0x0;
> +}
> +
> +RVPR(scmple16, 1, 2);
> +
> +static inline void do_ucmplt16(CPURISCVState *env, void *vd, void *va,
> +   void *vb, uint8_t i)
> +{
> +uint16_t *d = vd, *a = va, *b = vb;
> +d[i] = (a[i] < b[i]) ? 0x : 0x0;
> +}
> +
> +RVPR(ucmplt16, 1, 2);
> +
> +static inline void do_ucmple16(CPURISCVState *env, void *vd, void *va,
> +   void *vb, uint8_t i)
> +{
> +uint16_t *d = vd, *a = va, *b = vb;
> +d[i] = (a[i] <= b[i]) ? 0x : 0x0;
> +}
> +
> +RVPR(ucmple16, 1, 2);
> --
> 2.17.1
>



Re: [PATCH 07/38] target/riscv: SIMD 8-bit Shift Instructions

2021-03-15 Thread Alistair Francis
On Fri, Feb 12, 2021 at 10:18 AM LIU Zhiwei  wrote:
>
> Signed-off-by: LIU Zhiwei 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/helper.h   |   9 +++
>  target/riscv/insn32.decode  |  17 
>  target/riscv/insn_trans/trans_rvp.c.inc |  16 
>  target/riscv/packed_helper.c| 102 
>  4 files changed, 144 insertions(+)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index 20bf400ac2..0ecd4d53f9 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -1193,3 +1193,12 @@ DEF_HELPER_3(sll16, tl, env, tl, tl)
>  DEF_HELPER_3(ksll16, tl, env, tl, tl)
>  DEF_HELPER_3(kslra16, tl, env, tl, tl)
>  DEF_HELPER_3(kslra16_u, tl, env, tl, tl)
> +
> +DEF_HELPER_3(sra8, tl, env, tl, tl)
> +DEF_HELPER_3(sra8_u, tl, env, tl, tl)
> +DEF_HELPER_3(srl8, tl, env, tl, tl)
> +DEF_HELPER_3(srl8_u, tl, env, tl, tl)
> +DEF_HELPER_3(sll8, tl, env, tl, tl)
> +DEF_HELPER_3(ksll8, tl, env, tl, tl)
> +DEF_HELPER_3(kslra8, tl, env, tl, tl)
> +DEF_HELPER_3(kslra8_u, tl, env, tl, tl)
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index 6f053bfeb7..cc782fcde5 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -24,6 +24,7 @@
>
>  %sh1020:10
>  %sh420:4
> +%sh320:3
>  %csr20:12
>  %rm 12:3
>  %nf 29:3 !function=ex_plus_1
> @@ -61,6 +62,7 @@
>
>  @sh  ..  .. .  ... . ...   shamt=%sh10  
> %rs1 %rd
>  @sh4 ..  .. .  ... . ...   shamt=%sh4  
> %rs1 %rd
> +@sh3 ..  .. .  ... . ...   shamt=%sh3  
> %rs1 %rd
>  @csr    .  ... . ...   %csr %rs1 
> %rd
>
>  @atom_ld . aq:1 rl:1 .  . ...  rs2=0 %rs1 
> %rd
> @@ -652,3 +654,18 @@ ksll16 0110010  . . 000 . 111 @r
>  kslli160111010  1 . 000 . 111 @sh4
>  kslra160101011  . . 000 . 111 @r
>  kslra16_u  0110011  . . 000 . 111 @r
> +
> +sra8   0101100  . . 000 . 111 @r
> +sra8_u 0110100  . . 000 . 111 @r
> +srai8  000  00... . 000 . 111 @sh3
> +srai8_u000  01... . 000 . 111 @sh3
> +srl8   0101101  . . 000 . 111 @r
> +srl8_u 0110101  . . 000 . 111 @r
> +srli8  001  00... . 000 . 111 @sh3
> +srli8_u001  01... . 000 . 111 @sh3
> +sll8   0101110  . . 000 . 111 @r
> +slli8  010  00... . 000 . 111 @sh3
> +ksll8  0110110  . . 000 . 111 @r
> +kslli8 010  01... . 000 . 111 @sh3
> +kslra8 010  . . 000 . 111 @r
> +kslra8_u   0110111  . . 000 . 111 @r
> diff --git a/target/riscv/insn_trans/trans_rvp.c.inc 
> b/target/riscv/insn_trans/trans_rvp.c.inc
> index 848edab7e5..12a64849eb 100644
> --- a/target/riscv/insn_trans/trans_rvp.c.inc
> +++ b/target/riscv/insn_trans/trans_rvp.c.inc
> @@ -353,3 +353,19 @@ GEN_RVP_SHIFTI(slli16, sll16, tcg_gen_vec_shl16i_i64);
>  GEN_RVP_SHIFTI(srai16_u, sra16_u, NULL);
>  GEN_RVP_SHIFTI(srli16_u, srl16_u, NULL);
>  GEN_RVP_SHIFTI(kslli16, ksll16, NULL);
> +
> +/* SIMD 8-bit Shift Instructions */
> +GEN_RVP_SHIFT(sra8, tcg_gen_gvec_sars, 0);
> +GEN_RVP_SHIFT(srl8, tcg_gen_gvec_shrs, 0);
> +GEN_RVP_SHIFT(sll8, tcg_gen_gvec_shls, 0);
> +GEN_RVP_R_OOL(sra8_u);
> +GEN_RVP_R_OOL(srl8_u);
> +GEN_RVP_R_OOL(ksll8);
> +GEN_RVP_R_OOL(kslra8);
> +GEN_RVP_R_OOL(kslra8_u);
> +GEN_RVP_SHIFTI(srai8, sra8, tcg_gen_vec_sar8i_i64);
> +GEN_RVP_SHIFTI(srli8, srl8, tcg_gen_vec_shr8i_i64);
> +GEN_RVP_SHIFTI(slli8, sll8, tcg_gen_vec_shl8i_i64);
> +GEN_RVP_SHIFTI(srai8_u, sra8_u, NULL);
> +GEN_RVP_SHIFTI(srli8_u, srl8_u, NULL);
> +GEN_RVP_SHIFTI(kslli8, ksll8, NULL);
> diff --git a/target/riscv/packed_helper.c b/target/riscv/packed_helper.c
> index 7e31c2fe46..ab9ebc472b 100644
> --- a/target/riscv/packed_helper.c
> +++ b/target/riscv/packed_helper.c
> @@ -529,3 +529,105 @@ static inline void do_kslra16_u(CPURISCVState *env, 
> void *vd, void *va,
>  }
>
>  RVPR(kslra16_u, 1, 2);
> +
> +/* SIMD 8-bit Shift Instructions */
> +static inline void do_sra8(CPURISCVState *env, void *vd, void *va,
> +   void *vb, uint8_t i)
> +{
> +int8_t *d = vd, *a = va;
> +uint8_t shift = *(uint8_t *)vb & 0x7;
> +d[i] = a[i] >> shift;
> +}
> +
> +RVPR(sra8, 1, 1);
> +
> +static inline void do_srl8(CPURISCVState *env, void *vd, void *va,
> +   void *vb, uint8_t i)
> +{
> +uint8_t *d = vd, *a = va;
> +uint8_t shift = *(uint8_t *)vb & 0x7;
> +d[i] = a[i] >> shift;
> +}
> +
> +RVPR(srl8, 1, 1);
> +
> +static inline void do_sll8(CPURISCVState *env, void *vd, void *va,
> +   void *vb, uint8_t i)
> +{
> +uint8_t *d = vd, *a = 

Re: [PATCH 06/38] target/riscv: SIMD 16-bit Shift Instructions

2021-03-15 Thread Alistair Francis
On Fri, Feb 12, 2021 at 10:16 AM LIU Zhiwei  wrote:
>
> Signed-off-by: LIU Zhiwei 
> ---
>  target/riscv/helper.h   |   9 ++
>  target/riscv/insn32.decode  |  17 
>  target/riscv/insn_trans/trans_rvp.c.inc | 115 
>  target/riscv/packed_helper.c| 104 +
>  4 files changed, 245 insertions(+)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index a69a6b4e84..20bf400ac2 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -1184,3 +1184,12 @@ DEF_HELPER_3(rsub8, tl, env, tl, tl)
>  DEF_HELPER_3(ursub8, tl, env, tl, tl)
>  DEF_HELPER_3(ksub8, tl, env, tl, tl)
>  DEF_HELPER_3(uksub8, tl, env, tl, tl)
> +
> +DEF_HELPER_3(sra16, tl, env, tl, tl)
> +DEF_HELPER_3(sra16_u, tl, env, tl, tl)
> +DEF_HELPER_3(srl16, tl, env, tl, tl)
> +DEF_HELPER_3(srl16_u, tl, env, tl, tl)
> +DEF_HELPER_3(sll16, tl, env, tl, tl)
> +DEF_HELPER_3(ksll16, tl, env, tl, tl)
> +DEF_HELPER_3(kslra16, tl, env, tl, tl)
> +DEF_HELPER_3(kslra16_u, tl, env, tl, tl)
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index 358dd1fa10..6f053bfeb7 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -23,6 +23,7 @@
>  %rd7:5
>
>  %sh1020:10
> +%sh420:4
>  %csr20:12
>  %rm 12:3
>  %nf 29:3 !function=ex_plus_1
> @@ -59,6 +60,7 @@
>  @j     . ...   imm=%imm_j  
> %rd
>
>  @sh  ..  .. .  ... . ...   shamt=%sh10  
> %rs1 %rd
> +@sh4 ..  .. .  ... . ...   shamt=%sh4  
> %rs1 %rd
>  @csr    .  ... . ...   %csr %rs1 
> %rd
>
>  @atom_ld . aq:1 rl:1 .  . ...  rs2=0 %rs1 
> %rd
> @@ -635,3 +637,18 @@ rsub8  101  . . 000 . 111 @r
>  ursub8 0010101  . . 000 . 111 @r
>  ksub8  0001101  . . 000 . 111 @r
>  uksub8 0011101  . . 000 . 111 @r
> +
> +sra16  0101000  . . 000 . 111 @r
> +sra16_u011  . . 000 . 111 @r
> +srai16 0111000  0 . 000 . 111 @sh4
> +srai16_u   0111000  1 . 000 . 111 @sh4
> +srl16  0101001  . . 000 . 111 @r
> +srl16_u0110001  . . 000 . 111 @r
> +srli16 0111001  0 . 000 . 111 @sh4
> +srli16_u   0111001  1 . 000 . 111 @sh4
> +sll16  0101010  . . 000 . 111 @r
> +slli16 0111010  0 . 000 . 111 @sh4
> +ksll16 0110010  . . 000 . 111 @r
> +kslli160111010  1 . 000 . 111 @sh4
> +kslra160101011  . . 000 . 111 @r
> +kslra16_u  0110011  . . 000 . 111 @r
> diff --git a/target/riscv/insn_trans/trans_rvp.c.inc 
> b/target/riscv/insn_trans/trans_rvp.c.inc
> index 109f560ec9..848edab7e5 100644
> --- a/target/riscv/insn_trans/trans_rvp.c.inc
> +++ b/target/riscv/insn_trans/trans_rvp.c.inc
> @@ -238,3 +238,118 @@ GEN_RVP_R_OOL(rsub8);
>  GEN_RVP_R_OOL(ursub8);
>  GEN_RVP_R_OOL(ksub8);
>  GEN_RVP_R_OOL(uksub8);
> +
> +/* 16-bit Shift Instructions */
> +static bool rvp_shift_ool(DisasContext *ctx, arg_r *a,
> +  gen_helper_rvp_r *fn, target_ulong mask)
> +{
> +TCGv src1, src2, dst;
> +
> +src1 = tcg_temp_new();
> +src2 = tcg_temp_new();
> +dst = tcg_temp_new();
> +
> +gen_get_gpr(src1, a->rs1);
> +gen_get_gpr(src2, a->rs2);
> +tcg_gen_andi_tl(src2, src2, mask);
> +
> +fn(dst, cpu_env, src1, src2);
> +gen_set_gpr(a->rd, dst);
> +
> +tcg_temp_free(src1);
> +tcg_temp_free(src2);
> +tcg_temp_free(dst);
> +return true;
> +}
> +
> +typedef void GenGvecShift(unsigned, uint32_t, uint32_t, TCGv_i32,
> +  uint32_t, uint32_t);
> +static inline bool
> +rvp_shift(DisasContext *ctx, arg_r *a, uint8_t vece,
> +  GenGvecShift *f64, gen_helper_rvp_r *fn,
> +  uint8_t mask)
> +{
> +if (!has_ext(ctx, RVP)) {
> +return false;
> +}
> +
> +#ifdef TARGET_RISCV64

Hmm

I don't want to add any more #defines on the RISC-V xlen. We are
trying to make the QEMU RISC-V implementation xlen independent.

Can you use `riscv_cpu_is_32bit(env)` instead, here are everywhere
else you add a #define TARGET... ?

Alistair

> +if (a->rd && a->rs1 && a->rs2) {
> +TCGv_i32 shift = tcg_temp_new_i32();
> +tcg_gen_extrl_i64_i32(shift, cpu_gpr[a->rs2]);
> +tcg_gen_andi_i32(shift, shift, mask);
> +f64(vece, offsetof(CPURISCVState, gpr[a->rd]),
> +offsetof(CPURISCVState, gpr[a->rs1]),
> +shift, 8, 8);
> +tcg_temp_free_i32(shift);
> +return true;
> +}
> +#endif
> +return rvp_shift_ool(ctx, a, fn, mask);
> +}
> +
> +#define GEN_RVP_SHIFT(NAME, GVEC, VECE)   

Re: [Qemu-devel] [PATCH 5/6] target/mips: MXU: Add handlers for max/min instructions

2021-03-15 Thread Philippe Mathieu-Daudé
On Tue, Dec 25, 2018 at 8:35 PM Richard Henderson
 wrote:
>
> Sorry I missed the original post, but:
>
> > +} else if (unlikely((XRb == 0) && (XRc == 0))) {
> > +/* both operands zero registers -> just set destination to zero */
> > +tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
> > +} else if (unlikely((XRb == 0) || (XRc == 0))) {
> > +/* exactly one operand is zero register - find which one is 
> > not...*/
> > +uint32_t XRx = XRb ? XRb : XRc;
> > +/* ...and do max/min operation with one operand 0 */
> > +if (opc == OPC_MXU_S32MAX) {
> > +tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
> > +} else {
> > +tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
> > +}
> > +} else if (unlikely(XRb == XRc)) {
> > +/* both operands same -> just set destination to one of them */
> > +tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
>
> You should not special case unlikely events, especially when ...
>
> > +} else {
> > +/* the most general case */
> > +if (opc == OPC_MXU_S32MAX) {
> > +tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
> > +   mxu_gpr[XRc - 1]);
> > +} else {
> > +tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
> > +   mxu_gpr[XRc - 1]);
> > +}
>
> ... the normal case will handle those special cases just fine.

Also because we have now 3 Coverity CID:

 *** CID 1450831:(OVERRUN)
in gen_mxu_D16MAX_D16MIN()
1107 TCGv_i32 t0 = tcg_temp_new();
1108 TCGv_i32 t1 = tcg_const_i32(0);
1109
1110 /* the left half-word first */
 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x);
1112 if (opc == OPC_MXU_D16MAX) {
>>> CID 1450831:(OVERRUN)
>>> Overrunning array "mxu_gpr" of 15 8-byte elements at element index 
>>> 4294967295 (byte offset 34359738367) using index "XRa - 1U" (which 
>>> evaluates to 4294967295).
1113 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);

>>> CID 1450831:(OVERRUN)
>>> Overrunning array "mxu_gpr" of 15 8-byte elements at element index 
>>> 4294967295 (byte offset 34359738367) using index "XRa - 1U" (which 
>>> evaluates to 4294967295).
1114 } else {
1115 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
1116 }
1117
1118 /* the right half-word */
1119 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x);

1125 } else {
1126 tcg_gen_smin_i32(t0, t0, t1);
1127 }
1128 /* return resulting half-words to its original position */
1129 tcg_gen_shri_i32(t0, t0, 16);
1130 /* finally update the destination */
>>> CID 1450831:(OVERRUN)
>>> Overrunning array "mxu_gpr" of 15 8-byte elements at element index 
>>> 4294967295 (byte offset 34359738367) using index "XRa - 1U" (which 
>>> evaluates to 4294967295).
1131 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1132
1133 tcg_temp_free(t1);
1134 tcg_temp_free(t0);
1135 } else if (unlikely(XRb == XRc)) {
1136 /* both operands same -> just set destination to one of them */



Re: [PATCH 05/38] target/riscv: 8-bit Addition & Subtraction Instruction

2021-03-15 Thread Alistair Francis
On Fri, Feb 12, 2021 at 10:14 AM LIU Zhiwei  wrote:
>
> Signed-off-by: LIU Zhiwei 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/helper.h   |  9 +++
>  target/riscv/insn32.decode  | 11 
>  target/riscv/insn_trans/trans_rvp.c.inc | 79 +
>  target/riscv/packed_helper.c| 73 +++
>  4 files changed, 172 insertions(+)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index 6d622c732a..a69a6b4e84 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -1175,3 +1175,12 @@ DEF_HELPER_3(rstsa16, tl, env, tl, tl)
>  DEF_HELPER_3(urstsa16, tl, env, tl, tl)
>  DEF_HELPER_3(kstsa16, tl, env, tl, tl)
>  DEF_HELPER_3(ukstsa16, tl, env, tl, tl)
> +
> +DEF_HELPER_3(radd8, tl, env, tl, tl)
> +DEF_HELPER_3(uradd8, tl, env, tl, tl)
> +DEF_HELPER_3(kadd8, tl, env, tl, tl)
> +DEF_HELPER_3(ukadd8, tl, env, tl, tl)
> +DEF_HELPER_3(rsub8, tl, env, tl, tl)
> +DEF_HELPER_3(ursub8, tl, env, tl, tl)
> +DEF_HELPER_3(ksub8, tl, env, tl, tl)
> +DEF_HELPER_3(uksub8, tl, env, tl, tl)
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index 8815e90476..358dd1fa10 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -624,3 +624,14 @@ rstsa161011011  . . 010 . 111 @r
>  urstsa16   1101011  . . 010 . 111 @r
>  kstsa161100011  . . 010 . 111 @r
>  ukstsa16   1110011  . . 010 . 111 @r
> +
> +add8   0100100  . . 000 . 111 @r
> +radd8  100  . . 000 . 111 @r
> +uradd8 0010100  . . 000 . 111 @r
> +kadd8  0001100  . . 000 . 111 @r
> +ukadd8 0011100  . . 000 . 111 @r
> +sub8   0100101  . . 000 . 111 @r
> +rsub8  101  . . 000 . 111 @r
> +ursub8 0010101  . . 000 . 111 @r
> +ksub8  0001101  . . 000 . 111 @r
> +uksub8 0011101  . . 000 . 111 @r
> diff --git a/target/riscv/insn_trans/trans_rvp.c.inc 
> b/target/riscv/insn_trans/trans_rvp.c.inc
> index 0885a4fd45..109f560ec9 100644
> --- a/target/riscv/insn_trans/trans_rvp.c.inc
> +++ b/target/riscv/insn_trans/trans_rvp.c.inc
> @@ -159,3 +159,82 @@ GEN_RVP_R_OOL(rstsa16);
>  GEN_RVP_R_OOL(urstsa16);
>  GEN_RVP_R_OOL(kstsa16);
>  GEN_RVP_R_OOL(ukstsa16);
> +
> +/* 8-bit Addition & Subtraction Instructions */
> +/*
> + *  Copied from tcg-op-gvec.c.
> + *
> + *  Perform a vector addition using normal addition and a mask.  The mask
> + *  should be the sign bit of each lane.  This 6-operation form is more
> + *  efficient than separate additions when there are 4 or more lanes in
> + *  the 64-bit operation.
> + */
> +
> +static void gen_simd_add_mask(TCGv d, TCGv a, TCGv b, TCGv m)
> +{
> +TCGv t1 = tcg_temp_new();
> +TCGv t2 = tcg_temp_new();
> +TCGv t3 = tcg_temp_new();
> +
> +tcg_gen_andc_tl(t1, a, m);
> +tcg_gen_andc_tl(t2, b, m);
> +tcg_gen_xor_tl(t3, a, b);
> +tcg_gen_add_tl(d, t1, t2);
> +tcg_gen_and_tl(t3, t3, m);
> +tcg_gen_xor_tl(d, d, t3);
> +
> +tcg_temp_free(t1);
> +tcg_temp_free(t2);
> +tcg_temp_free(t3);
> +}
> +
> +static void tcg_gen_simd_add8(TCGv d, TCGv a, TCGv b)
> +{
> +TCGv m = tcg_const_tl((target_ulong)dup_const(MO_8, 0x80));
> +gen_simd_add_mask(d, a, b, m);
> +tcg_temp_free(m);
> +}
> +
> +GEN_RVP_R_INLINE(add8, add, 0, trans_add);
> +
> +/*
> + *  Copied from tcg-op-gvec.c.
> + *
> + *  Perform a vector subtraction using normal subtraction and a mask.
> + *  Compare gen_addv_mask above.
> + */
> +static void gen_simd_sub_mask(TCGv d, TCGv a, TCGv b, TCGv m)
> +{
> +TCGv t1 = tcg_temp_new();
> +TCGv t2 = tcg_temp_new();
> +TCGv t3 = tcg_temp_new();
> +
> +tcg_gen_or_tl(t1, a, m);
> +tcg_gen_andc_tl(t2, b, m);
> +tcg_gen_eqv_tl(t3, a, b);
> +tcg_gen_sub_tl(d, t1, t2);
> +tcg_gen_and_tl(t3, t3, m);
> +tcg_gen_xor_tl(d, d, t3);
> +
> +tcg_temp_free(t1);
> +tcg_temp_free(t2);
> +tcg_temp_free(t3);
> +}
> +
> +static void tcg_gen_simd_sub8(TCGv d, TCGv a, TCGv b)
> +{
> +TCGv m = tcg_const_tl((target_ulong)dup_const(MO_8, 0x80));
> +gen_simd_sub_mask(d, a, b, m);
> +tcg_temp_free(m);
> +}
> +
> +GEN_RVP_R_INLINE(sub8, sub, 0, trans_sub);
> +
> +GEN_RVP_R_OOL(radd8);
> +GEN_RVP_R_OOL(uradd8);
> +GEN_RVP_R_OOL(kadd8);
> +GEN_RVP_R_OOL(ukadd8);
> +GEN_RVP_R_OOL(rsub8);
> +GEN_RVP_R_OOL(ursub8);
> +GEN_RVP_R_OOL(ksub8);
> +GEN_RVP_R_OOL(uksub8);
> diff --git a/target/riscv/packed_helper.c b/target/riscv/packed_helper.c
> index b84abaaf25..62db072204 100644
> --- a/target/riscv/packed_helper.c
> +++ b/target/riscv/packed_helper.c
> @@ -352,3 +352,76 @@ static inline void do_ukstsa16(CPURISCVState *env, void 
> *vd, void *va,
>  }
>
>  RVPR(ukstsa16, 2, 2);
> +
> +/* 8-bit Addition & Subtraction Instructions */
> +static 

Re: [PATCH] hw/core: Only build guest-loader if libfdt is available

2021-03-15 Thread Alistair Francis
On Mon, Mar 15, 2021 at 1:15 PM Philippe Mathieu-Daudé
 wrote:
>
> Add a Kconfig entry for guest-loader so we can optionally deselect
> it (default is built in), and add a Meson dependency on libfdt.
>
> This fixes when building with --disable-fdt:
>
>   /usr/bin/ld: libcommon.fa.p/hw_core_guest-loader.c.o: in function 
> `loader_insert_platform_data':
>   hw/core/guest-loader.c:56: undefined reference to `qemu_fdt_add_subnode'
>   /usr/bin/ld: hw/core/guest-loader.c:57: undefined reference to 
> `qemu_fdt_setprop'
>   /usr/bin/ld: hw/core/guest-loader.c:61: undefined reference to 
> `qemu_fdt_setprop_string_array'
>   /usr/bin/ld: hw/core/guest-loader.c:68: undefined reference to 
> `qemu_fdt_setprop_string'
>   /usr/bin/ld: hw/core/guest-loader.c:74: undefined reference to 
> `qemu_fdt_setprop_string_array'
>   collect2: error: ld returned 1 exit status
>
> Fixes: a33ff6d2c6b ("hw/core: implement a guest-loader to support static 
> hypervisor guests")
> Reported-by: Christian Borntraeger 
> Tested-by: Christian Borntraeger 
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/core/Kconfig | 5 +
>  hw/core/meson.build | 3 +--
>  2 files changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/hw/core/Kconfig b/hw/core/Kconfig
> index fdf03514d7d..9397503656d 100644
> --- a/hw/core/Kconfig
> +++ b/hw/core/Kconfig
> @@ -11,6 +11,11 @@ config GENERIC_LOADER
>  bool
>  default y
>
> +config GUEST_LOADER
> +bool
> +default y
> +depends on TCG
> +
>  config OR_IRQ
>  bool
>
> diff --git a/hw/core/meson.build b/hw/core/meson.build
> index 9cd72edf513..59f1605bb07 100644
> --- a/hw/core/meson.build
> +++ b/hw/core/meson.build
> @@ -16,6 +16,7 @@
>  common_ss.add(files('cpu.c'))
>  common_ss.add(when: 'CONFIG_FITLOADER', if_true: files('loader-fit.c'))
>  common_ss.add(when: 'CONFIG_GENERIC_LOADER', if_true: 
> files('generic-loader.c'))
> +common_ss.add(when: ['CONFIG_GUEST_LOADER', fdt], if_true: 
> files('guest-loader.c'))
>  common_ss.add(when: 'CONFIG_OR_IRQ', if_true: files('or-irq.c'))
>  common_ss.add(when: 'CONFIG_PLATFORM_BUS', if_true: files('platform-bus.c'))
>  common_ss.add(when: 'CONFIG_PTIMER', if_true: files('ptimer.c'))
> @@ -37,8 +38,6 @@
>'clock-vmstate.c',
>  ))
>
> -softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('guest-loader.c'))
> -
>  specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: files(
>'machine-qmp-cmds.c',
>'numa.c',
> --
> 2.26.2
>
>



Re: [PATCH] Hexagon (target/hexagon) fix typo in comment

2021-03-15 Thread Philippe Mathieu-Daudé
On 3/15/21 8:46 PM, Richard Henderson wrote:
> On 3/14/21 10:55 PM, Taylor Simpson wrote:
>> Signed-of-by: Taylor Simpson
>> ---
>>   target/hexagon/op_helper.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> Queued.

Can you s/Signed-of-by/Signed-off-by/ ? ;)



Re: [PATCH] linux-user: Use signed lengths in uaccess.c

2021-03-15 Thread Laurent Vivier
Le 15/03/2021 à 21:40, Richard Henderson a écrit :
> Partially revert 09f679b62dff, but only for the length arguments.
> Instead of reverting to long, use ssize_t.  Reinstate the > 0 check
> in unlock_user.
> 
> Fixes: 09f679b62dff
> Reported-by: Coverity (CID 1446711)
> Signed-off-by: Richard Henderson 
> ---
>  linux-user/qemu.h| 15 +--
>  linux-user/uaccess.c | 12 ++--
>  2 files changed, 15 insertions(+), 12 deletions(-)
> 
> diff --git a/linux-user/qemu.h b/linux-user/qemu.h
> index 52c981710b..74e06e7121 100644
> --- a/linux-user/qemu.h
> +++ b/linux-user/qemu.h
> @@ -627,8 +627,8 @@ static inline bool access_ok(CPUState *cpu, int type,
>   * buffers between the target and host.  These internally perform
>   * locking/unlocking of the memory.
>   */
> -int copy_from_user(void *hptr, abi_ulong gaddr, size_t len);
> -int copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
> +int copy_from_user(void *hptr, abi_ulong gaddr, ssize_t len);
> +int copy_to_user(abi_ulong gaddr, void *hptr, ssize_t len);
>  
>  /* Functions for accessing guest memory.  The tget and tput functions
> read/write single values, byteswapping as necessary.  The lock_user 
> function
> @@ -638,16 +638,19 @@ int copy_to_user(abi_ulong gaddr, void *hptr, size_t 
> len);
>  
>  /* Lock an area of guest memory into the host.  If copy is true then the
> host area will have the same contents as the guest.  */
> -void *lock_user(int type, abi_ulong guest_addr, size_t len, bool copy);
> +void *lock_user(int type, abi_ulong guest_addr, ssize_t len, bool copy);
>  
>  /* Unlock an area of guest memory.  The first LEN bytes must be
> flushed back to guest memory. host_ptr = NULL is explicitly
> allowed and does nothing. */
>  #ifndef DEBUG_REMAP
> -static inline void unlock_user(void *host_ptr, abi_ulong guest_addr, size_t 
> len)
> -{ }
> +static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
> +   ssize_t len)
> +{
> +/* no-op */
> +}
>  #else
> -void unlock_user(void *host_ptr, abi_ulong guest_addr, long len);
> +void unlock_user(void *host_ptr, abi_ulong guest_addr, ssize_t len);
>  #endif
>  
>  /* Return the length of a string in target memory or -TARGET_EFAULT if
> diff --git a/linux-user/uaccess.c b/linux-user/uaccess.c
> index c696913016..82b833b8f1 100644
> --- a/linux-user/uaccess.c
> +++ b/linux-user/uaccess.c
> @@ -4,7 +4,7 @@
>  
>  #include "qemu.h"
>  
> -void *lock_user(int type, abi_ulong guest_addr, size_t len, bool copy)
> +void *lock_user(int type, abi_ulong guest_addr, ssize_t len, bool copy)
>  {
>  void *host_addr;
>  
> @@ -24,7 +24,7 @@ void *lock_user(int type, abi_ulong guest_addr, size_t len, 
> bool copy)
>  }
>  
>  #ifdef DEBUG_REMAP
> -void unlock_user(void *host_ptr, abi_ulong guest_addr, size_t len);
> +void unlock_user(void *host_ptr, abi_ulong guest_addr, ssize_t len);

The semicolon has been added by 687ca797893c ("linux-user: Move lock_user et al 
out of line")
perhaps it's time to remove it?

Reviewed-by: Laurent Vivier 



Re: [PATCH] migration: Move populate_vfio_info() into a separate file

2021-03-15 Thread Philippe Mathieu-Daudé
Hi Thomas,

+Alex

On 3/15/21 8:07 PM, Thomas Huth wrote:
> The CONFIG_VFIO switch only works in target specific code. Since
> migration/migration.c is common code, the #ifdef does not have
> the intended behavior here. Move the related code to a separate
> file now which gets compiled via specific_ss instead.
> 
> Fixes: 3710586caa ("qapi: Add VFIO devices migration stats in Migration 
> stats")
> Signed-off-by: Thomas Huth 
> ---
>  migration/meson.build |  3 ++-
>  migration/migration.c | 15 ---
>  migration/migration.h |  2 ++
>  migration/special.c   | 25 +
>  4 files changed, 29 insertions(+), 16 deletions(-)
>  create mode 100644 migration/special.c
> 
> diff --git a/migration/meson.build b/migration/meson.build
> index 9645f44005..e1f72f6ba0 100644
> --- a/migration/meson.build
> +++ b/migration/meson.build
> @@ -30,4 +30,5 @@ softmmu_ss.add(when: ['CONFIG_RDMA', rdma], if_true: 
> files('rdma.c'))
>  softmmu_ss.add(when: 'CONFIG_LIVE_BLOCK_MIGRATION', if_true: 
> files('block.c'))
>  softmmu_ss.add(when: zstd, if_true: files('multifd-zstd.c'))
>  
> -specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: files('dirtyrate.c', 
> 'ram.c'))
> +specific_ss.add(when: 'CONFIG_SOFTMMU',
> +if_true: files('dirtyrate.c', 'ram.c', 'special.c'))

Why not simply name this migration/vfio.c? That way we do not start
mixed bag of everything target specific.

Otherwise LGTM.




[PULL 3/5] m68k: add an interrupt controller

2021-03-15 Thread Laurent Vivier
A (generic) copy of the GLUE device we already have for q800 to use with
the m68k-virt machine.
The q800 one would disappear in the future as q800 uses actually the djMEMC
controller.

Signed-off-by: Laurent Vivier 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Message-Id: <20210312214145.2936082-4-laur...@vivier.eu>
---
 include/hw/intc/m68k_irqc.h |  41 +
 hw/intc/m68k_irqc.c | 119 
 hw/intc/Kconfig |   3 +
 hw/intc/meson.build |   1 +
 4 files changed, 164 insertions(+)
 create mode 100644 include/hw/intc/m68k_irqc.h
 create mode 100644 hw/intc/m68k_irqc.c

diff --git a/include/hw/intc/m68k_irqc.h b/include/hw/intc/m68k_irqc.h
new file mode 100644
index ..dbcfcfc2e000
--- /dev/null
+++ b/include/hw/intc/m68k_irqc.h
@@ -0,0 +1,41 @@
+/*
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ *
+ * QEMU Motorola 680x0 IRQ Controller
+ *
+ * (c) 2020 Laurent Vivier 
+ *
+ */
+
+#ifndef M68K_IRQC_H
+#define M68K_IRQC_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_M68K_IRQC "m68k-irq-controller"
+#define M68K_IRQC(obj) OBJECT_CHECK(M68KIRQCState, (obj), \
+TYPE_M68K_IRQC)
+
+#define M68K_IRQC_AUTOVECTOR_BASE 25
+
+enum {
+M68K_IRQC_LEVEL_1 = 0,
+M68K_IRQC_LEVEL_2,
+M68K_IRQC_LEVEL_3,
+M68K_IRQC_LEVEL_4,
+M68K_IRQC_LEVEL_5,
+M68K_IRQC_LEVEL_6,
+M68K_IRQC_LEVEL_7,
+};
+#define M68K_IRQC_LEVEL_NUM (M68K_IRQC_LEVEL_7 - M68K_IRQC_LEVEL_1 + 1)
+
+typedef struct M68KIRQCState {
+SysBusDevice parent_obj;
+
+uint8_t ipr;
+
+/* statistics */
+uint64_t stats_irq_count[M68K_IRQC_LEVEL_NUM];
+} M68KIRQCState;
+
+#endif
diff --git a/hw/intc/m68k_irqc.c b/hw/intc/m68k_irqc.c
new file mode 100644
index ..2133d2a698ab
--- /dev/null
+++ b/hw/intc/m68k_irqc.c
@@ -0,0 +1,119 @@
+/*
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ *
+ * QEMU Motorola 680x0 IRQ Controller
+ *
+ * (c) 2020 Laurent Vivier 
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "migration/vmstate.h"
+#include "monitor/monitor.h"
+#include "hw/nmi.h"
+#include "hw/intc/intc.h"
+#include "hw/intc/m68k_irqc.h"
+
+
+static bool m68k_irqc_get_statistics(InterruptStatsProvider *obj,
+ uint64_t **irq_counts, unsigned int 
*nb_irqs)
+{
+M68KIRQCState *s = M68K_IRQC(obj);
+
+*irq_counts = s->stats_irq_count;
+*nb_irqs = ARRAY_SIZE(s->stats_irq_count);
+return true;
+}
+
+static void m68k_irqc_print_info(InterruptStatsProvider *obj, Monitor *mon)
+{
+M68KIRQCState *s = M68K_IRQC(obj);
+monitor_printf(mon, "m68k-irqc: ipr=0x%x\n", s->ipr);
+}
+
+static void m68k_set_irq(void *opaque, int irq, int level)
+{
+M68KIRQCState *s = opaque;
+M68kCPU *cpu = M68K_CPU(first_cpu);
+int i;
+
+if (level) {
+s->ipr |= 1 << irq;
+s->stats_irq_count[irq]++;
+} else {
+s->ipr &= ~(1 << irq);
+}
+
+for (i = M68K_IRQC_LEVEL_7; i >= M68K_IRQC_LEVEL_1; i--) {
+if ((s->ipr >> i) & 1) {
+m68k_set_irq_level(cpu, i + 1, i + M68K_IRQC_AUTOVECTOR_BASE);
+return;
+}
+}
+m68k_set_irq_level(cpu, 0, 0);
+}
+
+static void m68k_irqc_reset(DeviceState *d)
+{
+M68KIRQCState *s = M68K_IRQC(d);
+int i;
+
+s->ipr = 0;
+for (i = 0; i < ARRAY_SIZE(s->stats_irq_count); i++) {
+s->stats_irq_count[i] = 0;
+}
+}
+
+static void m68k_irqc_instance_init(Object *obj)
+{
+qdev_init_gpio_in(DEVICE(obj), m68k_set_irq, M68K_IRQC_LEVEL_NUM);
+}
+
+static void m68k_nmi(NMIState *n, int cpu_index, Error **errp)
+{
+m68k_set_irq(n, M68K_IRQC_LEVEL_7, 1);
+}
+
+static const VMStateDescription vmstate_m68k_irqc = {
+.name = "m68k-irqc",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT8(ipr, M68KIRQCState),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static void m68k_irqc_class_init(ObjectClass *oc, void *data)
+ {
+DeviceClass *dc = DEVICE_CLASS(oc);
+NMIClass *nc = NMI_CLASS(oc);
+InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(oc);
+
+nc->nmi_monitor_handler = m68k_nmi;
+dc->reset = m68k_irqc_reset;
+dc->vmsd = _m68k_irqc;
+ic->get_statistics = m68k_irqc_get_statistics;
+ic->print_info = m68k_irqc_print_info;
+}
+
+static const TypeInfo m68k_irqc_type_info = {
+.name = TYPE_M68K_IRQC,
+.parent = TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(M68KIRQCState),
+.instance_init = m68k_irqc_instance_init,
+.class_init = m68k_irqc_class_init,
+.interfaces = (InterfaceInfo[]) {
+ { TYPE_NMI },
+ { TYPE_INTERRUPT_STATS_PROVIDER },
+ { }
+},
+};
+
+static void q800_irq_register_types(void)
+{
+type_register_static(_irqc_type_info);
+}
+
+type_init(q800_irq_register_types);
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index 

Re: [PATCH] linux-user: Use signed lengths in uaccess.c

2021-03-15 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20210315204004.2025219-1-richard.hender...@linaro.org/



Hi,

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

Type: series
Message-id: 20210315204004.2025219-1-richard.hender...@linaro.org
Subject: [PATCH] linux-user: Use signed lengths in uaccess.c

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] 
patchew/20210315204004.2025219-1-richard.hender...@linaro.org -> 
patchew/20210315204004.2025219-1-richard.hender...@linaro.org
Switched to a new branch 'test'
cabd5c4 linux-user: Use signed lengths in uaccess.c

=== OUTPUT BEGIN ===
ERROR: externs should be avoided in .c files
#77: FILE: linux-user/uaccess.c:27:
+void unlock_user(void *host_ptr, abi_ulong guest_addr, ssize_t len);

total: 1 errors, 0 warnings, 81 lines checked

Commit cabd5c49328f (linux-user: Use signed lengths in uaccess.c) has style 
problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


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

[PULL 5/5] m68k: add Virtual M68k Machine

2021-03-15 Thread Laurent Vivier
The machine is based on Goldfish interfaces defined by Google
for Android simulator. It uses Goldfish-rtc (timer and RTC),
Goldfish-pic (PIC) and Goldfish-tty (for serial port and early tty).

The machine is created with 128 virtio-mmio bus, and they can
be used to use serial console, GPU, disk, NIC, HID, ...

Signed-off-by: Laurent Vivier 
Reviewed-by: Richard Henderson 
Tested-by: Philippe Mathieu-Daudé 
Message-Id: <20210312214145.2936082-6-laur...@vivier.eu>
---
 default-configs/devices/m68k-softmmu.mak  |   1 +
 .../standard-headers/asm-m68k/bootinfo-virt.h |  18 +
 hw/m68k/virt.c| 313 ++
 MAINTAINERS   |  13 +
 hw/m68k/Kconfig   |   9 +
 hw/m68k/meson.build   |   1 +
 6 files changed, 355 insertions(+)
 create mode 100644 include/standard-headers/asm-m68k/bootinfo-virt.h
 create mode 100644 hw/m68k/virt.c

diff --git a/default-configs/devices/m68k-softmmu.mak 
b/default-configs/devices/m68k-softmmu.mak
index 6629fd2aa330..7f8619e42786 100644
--- a/default-configs/devices/m68k-softmmu.mak
+++ b/default-configs/devices/m68k-softmmu.mak
@@ -8,3 +8,4 @@ CONFIG_AN5206=y
 CONFIG_MCF5208=y
 CONFIG_NEXTCUBE=y
 CONFIG_Q800=y
+CONFIG_M68K_VIRT=y
diff --git a/include/standard-headers/asm-m68k/bootinfo-virt.h 
b/include/standard-headers/asm-m68k/bootinfo-virt.h
new file mode 100644
index ..81be1e092497
--- /dev/null
+++ b/include/standard-headers/asm-m68k/bootinfo-virt.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+** asm/bootinfo-virt.h -- Virtual-m68k-specific boot information definitions
+*/
+
+#ifndef _UAPI_ASM_M68K_BOOTINFO_VIRT_H
+#define _UAPI_ASM_M68K_BOOTINFO_VIRT_H
+
+#define BI_VIRT_QEMU_VERSION   0x8000
+#define BI_VIRT_GF_PIC_BASE0x8001
+#define BI_VIRT_GF_RTC_BASE0x8002
+#define BI_VIRT_GF_TTY_BASE0x8003
+#define BI_VIRT_VIRTIO_BASE0x8004
+#define BI_VIRT_CTRL_BASE  0x8005
+
+#define VIRT_BOOTI_VERSION MK_BI_VERSION(2, 0)
+
+#endif /* _UAPI_ASM_M68K_BOOTINFO_MAC_H */
diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c
new file mode 100644
index ..e9a5d4c69b97
--- /dev/null
+++ b/hw/m68k/virt.c
@@ -0,0 +1,313 @@
+/*
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ *
+ * QEMU Vitual M68K Machine
+ *
+ * (c) 2020 Laurent Vivier 
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qemu-common.h"
+#include "sysemu/sysemu.h"
+#include "cpu.h"
+#include "hw/hw.h"
+#include "hw/boards.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "elf.h"
+#include "hw/loader.h"
+#include "ui/console.h"
+#include "exec/address-spaces.h"
+#include "hw/sysbus.h"
+#include "standard-headers/asm-m68k/bootinfo.h"
+#include "standard-headers/asm-m68k/bootinfo-virt.h"
+#include "bootinfo.h"
+#include "net/net.h"
+#include "qapi/error.h"
+#include "sysemu/qtest.h"
+#include "sysemu/runstate.h"
+#include "sysemu/reset.h"
+
+#include "hw/intc/m68k_irqc.h"
+#include "hw/misc/virt_ctrl.h"
+#include "hw/char/goldfish_tty.h"
+#include "hw/rtc/goldfish_rtc.h"
+#include "hw/intc/goldfish_pic.h"
+#include "hw/virtio/virtio-mmio.h"
+#include "hw/virtio/virtio-blk.h"
+
+/*
+ * 6 goldfish-pic for CPU IRQ #1 to IRQ #6
+ * CPU IRQ #1 -> PIC #1
+ *   IRQ #1 to IRQ #31 -> unused
+ *   IRQ #32 -> goldfish-tty
+ * CPU IRQ #2 -> PIC #2
+ *   IRQ #1 to IRQ #32 -> virtio-mmio from 1 to 32
+ * CPU IRQ #3 -> PIC #3
+ *   IRQ #1 to IRQ #32 -> virtio-mmio from 33 to 64
+ * CPU IRQ #4 -> PIC #4
+ *   IRQ #1 to IRQ #32 -> virtio-mmio from 65 to 96
+ * CPU IRQ #5 -> PIC #5
+ *   IRQ #1 to IRQ #32 -> virtio-mmio from 97 to 128
+ * CPU IRQ #6 -> PIC #6
+ *   IRQ #1 -> goldfish-rtc
+ *   IRQ #2 to IRQ #32 -> unused
+ * CPU IRQ #7 -> NMI
+ */
+
+#define PIC_IRQ_BASE(num) (8 + (num - 1) * 32)
+#define PIC_IRQ(num, irq) (PIC_IRQ_BASE(num) + irq - 1)
+#define PIC_GPIO(pic_irq) (qdev_get_gpio_in(pic_dev[(pic_irq - 8) / 32], \
+(pic_irq - 8) % 32))
+
+#define VIRT_GF_PIC_MMIO_BASE 0xff00 /* MMIO: 0xff00 - 0xff005fff 
*/
+#define VIRT_GF_PIC_IRQ_BASE  1  /* IRQ: #1 -> #6 */
+#define VIRT_GF_PIC_NB6
+
+/* 2 goldfish-rtc (and timer) */
+#define VIRT_GF_RTC_MMIO_BASE 0xff006000 /* MMIO: 0xff006000 - 0xff007fff 
*/
+#define VIRT_GF_RTC_IRQ_BASE  PIC_IRQ(6, 1)  /* PIC: #6, IRQ: #1 */
+#define VIRT_GF_RTC_NB2
+
+/* 1 goldfish-tty */
+#define VIRT_GF_TTY_MMIO_BASE 0xff008000 /* MMIO: 0xff008000 - 0xff008fff 
*/
+#define VIRT_GF_TTY_IRQ_BASE  PIC_IRQ(1, 32) /* PIC: #1, IRQ: #32 */
+
+/* 1 virt-ctrl */
+#define VIRT_CTRL_MMIO_BASE 0xff009000/* MMIO: 0xff009000 - 0xff009fff */
+#define VIRT_CTRL_IRQ_BASE  PIC_IRQ(1, 1) /* PIC: #1, IRQ: #1 */
+
+/*
+ * virtio-mmio size is 0x200 bytes
+ * we use 4 goldfish-pic to attach 

[PULL 1/5] hw/char: add goldfish-tty

2021-03-15 Thread Laurent Vivier
Implement the goldfish tty device as defined in

https://android.googlesource.com/platform/external/qemu/+/master/docs/GOLDFISH-VIRTUAL-HARDWARE.TXT

and based on the kernel driver code:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/tty/goldfish.c

Signed-off-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Message-Id: <20210312214145.2936082-2-laur...@vivier.eu>
---
 include/hw/char/goldfish_tty.h |  35 
 hw/char/goldfish_tty.c | 285 +
 hw/char/Kconfig|   3 +
 hw/char/meson.build|   2 +
 hw/char/trace-events   |  10 ++
 5 files changed, 335 insertions(+)
 create mode 100644 include/hw/char/goldfish_tty.h
 create mode 100644 hw/char/goldfish_tty.c

diff --git a/include/hw/char/goldfish_tty.h b/include/hw/char/goldfish_tty.h
new file mode 100644
index ..b9dd67362a68
--- /dev/null
+++ b/include/hw/char/goldfish_tty.h
@@ -0,0 +1,35 @@
+/*
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ *
+ * Goldfish TTY
+ *
+ * (c) 2020 Laurent Vivier 
+ *
+ */
+
+#ifndef HW_CHAR_GOLDFISH_TTY_H
+#define HW_CHAR_GOLDFISH_TTY_H
+
+#include "qemu/fifo8.h"
+#include "chardev/char-fe.h"
+
+#define TYPE_GOLDFISH_TTY "goldfish_tty"
+OBJECT_DECLARE_SIMPLE_TYPE(GoldfishTTYState, GOLDFISH_TTY)
+
+#define GOLFISH_TTY_BUFFER_SIZE 128
+
+struct GoldfishTTYState {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+qemu_irq irq;
+CharBackend chr;
+
+uint32_t data_len;
+uint64_t data_ptr;
+bool int_enabled;
+
+Fifo8 rx_fifo;
+};
+
+#endif
diff --git a/hw/char/goldfish_tty.c b/hw/char/goldfish_tty.c
new file mode 100644
index ..8365a1876145
--- /dev/null
+++ b/hw/char/goldfish_tty.c
@@ -0,0 +1,285 @@
+/*
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ *
+ * Goldfish TTY
+ *
+ * (c) 2020 Laurent Vivier 
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties-system.h"
+#include "hw/sysbus.h"
+#include "migration/vmstate.h"
+#include "chardev/char-fe.h"
+#include "qemu/log.h"
+#include "trace.h"
+#include "exec/address-spaces.h"
+#include "hw/char/goldfish_tty.h"
+
+#define GOLDFISH_TTY_VERSION 1
+
+/* registers */
+
+enum {
+REG_PUT_CHAR  = 0x00,
+REG_BYTES_READY   = 0x04,
+REG_CMD   = 0x08,
+REG_DATA_PTR  = 0x10,
+REG_DATA_LEN  = 0x14,
+REG_DATA_PTR_HIGH = 0x18,
+REG_VERSION   = 0x20,
+};
+
+/* commands */
+
+enum {
+CMD_INT_DISABLE   = 0x00,
+CMD_INT_ENABLE= 0x01,
+CMD_WRITE_BUFFER  = 0x02,
+CMD_READ_BUFFER   = 0x03,
+};
+
+static uint64_t goldfish_tty_read(void *opaque, hwaddr addr,
+  unsigned size)
+{
+GoldfishTTYState *s = opaque;
+uint64_t value = 0;
+
+switch (addr) {
+case REG_BYTES_READY:
+value = fifo8_num_used(>rx_fifo);
+break;
+case REG_VERSION:
+value = GOLDFISH_TTY_VERSION;
+break;
+default:
+qemu_log_mask(LOG_UNIMP,
+  "%s: unimplemented register read 0x%02"HWADDR_PRIx"\n",
+  __func__, addr);
+break;
+}
+
+trace_goldfish_tty_read(s, addr, size, value);
+
+return value;
+}
+
+static void goldfish_tty_cmd(GoldfishTTYState *s, uint32_t cmd)
+{
+uint32_t to_copy;
+uint8_t *buf;
+uint8_t data_out[GOLFISH_TTY_BUFFER_SIZE];
+int len;
+uint64_t ptr;
+
+switch (cmd) {
+case CMD_INT_DISABLE:
+if (s->int_enabled) {
+if (!fifo8_is_empty(>rx_fifo)) {
+qemu_set_irq(s->irq, 0);
+}
+s->int_enabled = false;
+}
+break;
+case CMD_INT_ENABLE:
+if (!s->int_enabled) {
+if (!fifo8_is_empty(>rx_fifo)) {
+qemu_set_irq(s->irq, 1);
+}
+s->int_enabled = true;
+}
+break;
+case CMD_WRITE_BUFFER:
+len = s->data_len;
+ptr = s->data_ptr;
+while (len) {
+to_copy = MIN(GOLFISH_TTY_BUFFER_SIZE, len);
+
+address_space_rw(_space_memory, ptr,
+ MEMTXATTRS_UNSPECIFIED, data_out, to_copy, 0);
+qemu_chr_fe_write_all(>chr, data_out, to_copy);
+
+len -= to_copy;
+ptr += to_copy;
+}
+break;
+case CMD_READ_BUFFER:
+len = s->data_len;
+ptr = s->data_ptr;
+while (len && !fifo8_is_empty(>rx_fifo)) {
+buf = (uint8_t *)fifo8_pop_buf(>rx_fifo, len, _copy);
+address_space_rw(_space_memory, ptr,
+MEMTXATTRS_UNSPECIFIED, buf, to_copy, 1);
+
+len -= to_copy;
+ptr += to_copy;
+}
+if (s->int_enabled && fifo8_is_empty(>rx_fifo)) {
+qemu_set_irq(s->irq, 0);
+}
+break;
+}
+}
+
+static void goldfish_tty_write(void *opaque, hwaddr addr,
+ 

[PULL 4/5] m68k: add a system controller

2021-03-15 Thread Laurent Vivier
Add a system controller for the m68k-virt machine.
This controller allows the kernel to power off or reset the machine.

Signed-off-by: Laurent Vivier 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Message-Id: <20210312214145.2936082-5-laur...@vivier.eu>
---
 docs/specs/virt-ctlr.txt|  26 +++
 include/hw/misc/virt_ctrl.h |  22 ++
 hw/misc/virt_ctrl.c | 151 
 hw/misc/Kconfig |   3 +
 hw/misc/meson.build |   3 +
 hw/misc/trace-events|   7 ++
 6 files changed, 212 insertions(+)
 create mode 100644 docs/specs/virt-ctlr.txt
 create mode 100644 include/hw/misc/virt_ctrl.h
 create mode 100644 hw/misc/virt_ctrl.c

diff --git a/docs/specs/virt-ctlr.txt b/docs/specs/virt-ctlr.txt
new file mode 100644
index ..24d38084f7fd
--- /dev/null
+++ b/docs/specs/virt-ctlr.txt
@@ -0,0 +1,26 @@
+Virtual System Controller
+=
+
+This device is a simple interface defined for the pure virtual machine with no
+hardware reference implementation to allow the guest kernel to send command
+to the host hypervisor.
+
+The specification can evolve, the current state is defined as below.
+
+This is a MMIO mapped device using 256 bytes.
+
+Two 32bit registers are defined:
+
+1- the features register (read-only, address 0x00)
+
+   This register allows the device to report features supported by the
+   controller.
+   The only feature supported for the moment is power control (0x01).
+
+2- the command register (write-only, address 0x04)
+
+   This register allows the kernel to send the commands to the hypervisor.
+   The implemented commands are part of the power control feature and
+   are reset (1), halt (2) and panic (3).
+   A basic command, no-op (0), is always present and can be used to test the
+   register access. This command has no effect.
diff --git a/include/hw/misc/virt_ctrl.h b/include/hw/misc/virt_ctrl.h
new file mode 100644
index ..edfadc469505
--- /dev/null
+++ b/include/hw/misc/virt_ctrl.h
@@ -0,0 +1,22 @@
+/*
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ *
+ * Virt system Controller
+ */
+
+#ifndef VIRT_CTRL_H
+#define VIRT_CTRL_H
+
+#define TYPE_VIRT_CTRL "virt-ctrl"
+OBJECT_DECLARE_SIMPLE_TYPE(VirtCtrlState, VIRT_CTRL)
+
+struct VirtCtrlState {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+qemu_irq irq;
+
+uint32_t irq_enabled;
+};
+
+#endif
diff --git a/hw/misc/virt_ctrl.c b/hw/misc/virt_ctrl.c
new file mode 100644
index ..2ea01bd7a1f0
--- /dev/null
+++ b/hw/misc/virt_ctrl.c
@@ -0,0 +1,151 @@
+/*
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ *
+ * Virt system Controller
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/sysbus.h"
+#include "migration/vmstate.h"
+#include "qemu/log.h"
+#include "trace.h"
+#include "sysemu/runstate.h"
+#include "hw/misc/virt_ctrl.h"
+
+enum {
+REG_FEATURES = 0x00,
+REG_CMD  = 0x04,
+};
+
+#define FEAT_POWER_CTRL 0x0001
+
+enum {
+CMD_NOOP,
+CMD_RESET,
+CMD_HALT,
+CMD_PANIC,
+};
+
+static uint64_t virt_ctrl_read(void *opaque, hwaddr addr, unsigned size)
+{
+VirtCtrlState *s = opaque;
+uint64_t value = 0;
+
+switch (addr) {
+case REG_FEATURES:
+value = FEAT_POWER_CTRL;
+break;
+default:
+qemu_log_mask(LOG_UNIMP,
+  "%s: unimplemented register read 0x%02"HWADDR_PRIx"\n",
+  __func__, addr);
+break;
+}
+
+trace_virt_ctrl_write(s, addr, size, value);
+
+return value;
+}
+
+static void virt_ctrl_write(void *opaque, hwaddr addr, uint64_t value,
+unsigned size)
+{
+VirtCtrlState *s = opaque;
+
+trace_virt_ctrl_write(s, addr, size, value);
+
+switch (addr) {
+case REG_CMD:
+switch (value) {
+case CMD_NOOP:
+break;
+case CMD_RESET:
+qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+break;
+case CMD_HALT:
+qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
+break;
+case CMD_PANIC:
+qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC);
+break;
+}
+break;
+default:
+qemu_log_mask(LOG_UNIMP,
+  "%s: unimplemented register write 0x%02"HWADDR_PRIx"\n",
+  __func__, addr);
+break;
+}
+}
+
+static const MemoryRegionOps virt_ctrl_ops = {
+.read = virt_ctrl_read,
+.write = virt_ctrl_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.valid.max_access_size = 4,
+.impl.max_access_size = 4,
+};
+
+static void virt_ctrl_reset(DeviceState *dev)
+{
+VirtCtrlState *s = VIRT_CTRL(dev);
+
+trace_virt_ctrl_reset(s);
+}
+
+static void virt_ctrl_realize(DeviceState *dev, Error **errp)
+{
+VirtCtrlState *s = VIRT_CTRL(dev);
+
+

[PULL 2/5] hw/intc: add goldfish-pic

2021-03-15 Thread Laurent Vivier
Implement the goldfish pic device as defined in

https://android.googlesource.com/platform/external/qemu/+/master/docs/GOLDFISH-VIRTUAL-HARDWARE.TXT

Signed-off-by: Laurent Vivier 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Message-Id: <20210312214145.2936082-3-laur...@vivier.eu>
---
 include/hw/intc/goldfish_pic.h |  33 +
 hw/intc/goldfish_pic.c | 219 +
 hw/intc/Kconfig|   3 +
 hw/intc/meson.build|   1 +
 hw/intc/trace-events   |   8 ++
 5 files changed, 264 insertions(+)
 create mode 100644 include/hw/intc/goldfish_pic.h
 create mode 100644 hw/intc/goldfish_pic.c

diff --git a/include/hw/intc/goldfish_pic.h b/include/hw/intc/goldfish_pic.h
new file mode 100644
index ..ad13ab37fc3e
--- /dev/null
+++ b/include/hw/intc/goldfish_pic.h
@@ -0,0 +1,33 @@
+/*
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ *
+ * Goldfish PIC
+ *
+ * (c) 2020 Laurent Vivier 
+ *
+ */
+
+#ifndef HW_INTC_GOLDFISH_PIC_H
+#define HW_INTC_GOLDFISH_PIC_H
+
+#define TYPE_GOLDFISH_PIC "goldfish_pic"
+OBJECT_DECLARE_SIMPLE_TYPE(GoldfishPICState, GOLDFISH_PIC)
+
+#define GOLDFISH_PIC_IRQ_NB 32
+
+struct GoldfishPICState {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+qemu_irq irq;
+
+uint32_t pending;
+uint32_t enabled;
+
+/* statistics */
+uint64_t stats_irq_count[32];
+/* for tracing */
+uint8_t idx;
+};
+
+#endif
diff --git a/hw/intc/goldfish_pic.c b/hw/intc/goldfish_pic.c
new file mode 100644
index ..e3b43a69f163
--- /dev/null
+++ b/hw/intc/goldfish_pic.c
@@ -0,0 +1,219 @@
+/*
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ *
+ * Goldfish PIC
+ *
+ * (c) 2020 Laurent Vivier 
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/sysbus.h"
+#include "migration/vmstate.h"
+#include "monitor/monitor.h"
+#include "qemu/log.h"
+#include "trace.h"
+#include "hw/intc/intc.h"
+#include "hw/intc/goldfish_pic.h"
+
+/* registers */
+
+enum {
+REG_STATUS  = 0x00,
+REG_IRQ_PENDING = 0x04,
+REG_IRQ_DISABLE_ALL = 0x08,
+REG_DISABLE = 0x0c,
+REG_ENABLE  = 0x10,
+};
+
+static bool goldfish_pic_get_statistics(InterruptStatsProvider *obj,
+uint64_t **irq_counts,
+unsigned int *nb_irqs)
+{
+GoldfishPICState *s = GOLDFISH_PIC(obj);
+
+*irq_counts = s->stats_irq_count;
+*nb_irqs = ARRAY_SIZE(s->stats_irq_count);
+return true;
+}
+
+static void goldfish_pic_print_info(InterruptStatsProvider *obj, Monitor *mon)
+{
+GoldfishPICState *s = GOLDFISH_PIC(obj);
+monitor_printf(mon, "goldfish-pic.%d: pending=0x%08x enabled=0x%08x\n",
+   s->idx, s->pending, s->enabled);
+}
+
+static void goldfish_pic_update(GoldfishPICState *s)
+{
+if (s->pending & s->enabled) {
+qemu_irq_raise(s->irq);
+} else {
+qemu_irq_lower(s->irq);
+}
+}
+
+static void goldfish_irq_request(void *opaque, int irq, int level)
+{
+GoldfishPICState *s = opaque;
+
+trace_goldfish_irq_request(s, s->idx, irq, level);
+
+if (level) {
+s->pending |= 1 << irq;
+s->stats_irq_count[irq]++;
+} else {
+s->pending &= ~(1 << irq);
+}
+goldfish_pic_update(s);
+}
+
+static uint64_t goldfish_pic_read(void *opaque, hwaddr addr,
+  unsigned size)
+{
+GoldfishPICState *s = opaque;
+uint64_t value = 0;
+
+switch (addr) {
+case REG_STATUS:
+/* The number of pending interrupts (0 to 32) */
+value = ctpop32(s->pending & s->enabled);
+break;
+case REG_IRQ_PENDING:
+/* The pending interrupt mask */
+value = s->pending & s->enabled;
+break;
+default:
+qemu_log_mask(LOG_UNIMP,
+  "%s: unimplemented register read 0x%02"HWADDR_PRIx"\n",
+  __func__, addr);
+break;
+}
+
+trace_goldfish_pic_read(s, s->idx, addr, size, value);
+
+return value;
+}
+
+static void goldfish_pic_write(void *opaque, hwaddr addr,
+   uint64_t value, unsigned size)
+{
+GoldfishPICState *s = opaque;
+
+trace_goldfish_pic_write(s, s->idx, addr, size, value);
+
+switch (addr) {
+case REG_IRQ_DISABLE_ALL:
+s->enabled = 0;
+s->pending = 0;
+break;
+case REG_DISABLE:
+s->enabled &= ~value;
+break;
+case REG_ENABLE:
+s->enabled |= value;
+break;
+default:
+qemu_log_mask(LOG_UNIMP,
+  "%s: unimplemented register write 0x%02"HWADDR_PRIx"\n",
+  __func__, addr);
+break;
+}
+goldfish_pic_update(s);
+}
+
+static const MemoryRegionOps goldfish_pic_ops = {
+.read = goldfish_pic_read,
+.write = goldfish_pic_write,
+.endianness 

[PULL 0/5] M68k for 6.0 patches

2021-03-15 Thread Laurent Vivier
The following changes since commit e7c6a8cf9f5c82aa152273e1c9e80d07b1b0c32c:

  Merge remote-tracking branch 'remotes/philmd/tags/avr-20210315' into stagin=
g (2021-03-15 16:59:55 +)

are available in the Git repository at:

  git://github.com/vivier/qemu-m68k.git tags/m68k-for-6.0-pull-request

for you to fetch changes up to e1cecdca559d552bc5ab282696301858a97c3e8c:

  m68k: add Virtual M68k Machine (2021-03-15 21:03:06 +0100)


m68k pull request 20210315

Add m68k virt machine



Laurent Vivier (5):
  hw/char: add goldfish-tty
  hw/intc: add goldfish-pic
  m68k: add an interrupt controller
  m68k: add a system controller
  m68k: add Virtual M68k Machine

 docs/specs/virt-ctlr.txt  |  26 ++
 default-configs/devices/m68k-softmmu.mak  |   1 +
 include/hw/char/goldfish_tty.h|  35 ++
 include/hw/intc/goldfish_pic.h|  33 ++
 include/hw/intc/m68k_irqc.h   |  41 +++
 include/hw/misc/virt_ctrl.h   |  22 ++
 .../standard-headers/asm-m68k/bootinfo-virt.h |  18 +
 hw/char/goldfish_tty.c| 285 
 hw/intc/goldfish_pic.c| 219 
 hw/intc/m68k_irqc.c   | 119 +++
 hw/m68k/virt.c| 313 ++
 hw/misc/virt_ctrl.c   | 151 +
 MAINTAINERS   |  13 +
 hw/char/Kconfig   |   3 +
 hw/char/meson.build   |   2 +
 hw/char/trace-events  |  10 +
 hw/intc/Kconfig   |   6 +
 hw/intc/meson.build   |   2 +
 hw/intc/trace-events  |   8 +
 hw/m68k/Kconfig   |   9 +
 hw/m68k/meson.build   |   1 +
 hw/misc/Kconfig   |   3 +
 hw/misc/meson.build   |   3 +
 hw/misc/trace-events  |   7 +
 24 files changed, 1330 insertions(+)
 create mode 100644 docs/specs/virt-ctlr.txt
 create mode 100644 include/hw/char/goldfish_tty.h
 create mode 100644 include/hw/intc/goldfish_pic.h
 create mode 100644 include/hw/intc/m68k_irqc.h
 create mode 100644 include/hw/misc/virt_ctrl.h
 create mode 100644 include/standard-headers/asm-m68k/bootinfo-virt.h
 create mode 100644 hw/char/goldfish_tty.c
 create mode 100644 hw/intc/goldfish_pic.c
 create mode 100644 hw/intc/m68k_irqc.c
 create mode 100644 hw/m68k/virt.c
 create mode 100644 hw/misc/virt_ctrl.c

--=20
2.29.2




[PATCH] linux-user: Use signed lengths in uaccess.c

2021-03-15 Thread Richard Henderson
Partially revert 09f679b62dff, but only for the length arguments.
Instead of reverting to long, use ssize_t.  Reinstate the > 0 check
in unlock_user.

Fixes: 09f679b62dff
Reported-by: Coverity (CID 1446711)
Signed-off-by: Richard Henderson 
---
 linux-user/qemu.h| 15 +--
 linux-user/uaccess.c | 12 ++--
 2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 52c981710b..74e06e7121 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -627,8 +627,8 @@ static inline bool access_ok(CPUState *cpu, int type,
  * buffers between the target and host.  These internally perform
  * locking/unlocking of the memory.
  */
-int copy_from_user(void *hptr, abi_ulong gaddr, size_t len);
-int copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
+int copy_from_user(void *hptr, abi_ulong gaddr, ssize_t len);
+int copy_to_user(abi_ulong gaddr, void *hptr, ssize_t len);
 
 /* Functions for accessing guest memory.  The tget and tput functions
read/write single values, byteswapping as necessary.  The lock_user function
@@ -638,16 +638,19 @@ int copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
 
 /* Lock an area of guest memory into the host.  If copy is true then the
host area will have the same contents as the guest.  */
-void *lock_user(int type, abi_ulong guest_addr, size_t len, bool copy);
+void *lock_user(int type, abi_ulong guest_addr, ssize_t len, bool copy);
 
 /* Unlock an area of guest memory.  The first LEN bytes must be
flushed back to guest memory. host_ptr = NULL is explicitly
allowed and does nothing. */
 #ifndef DEBUG_REMAP
-static inline void unlock_user(void *host_ptr, abi_ulong guest_addr, size_t 
len)
-{ }
+static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
+   ssize_t len)
+{
+/* no-op */
+}
 #else
-void unlock_user(void *host_ptr, abi_ulong guest_addr, long len);
+void unlock_user(void *host_ptr, abi_ulong guest_addr, ssize_t len);
 #endif
 
 /* Return the length of a string in target memory or -TARGET_EFAULT if
diff --git a/linux-user/uaccess.c b/linux-user/uaccess.c
index c696913016..82b833b8f1 100644
--- a/linux-user/uaccess.c
+++ b/linux-user/uaccess.c
@@ -4,7 +4,7 @@
 
 #include "qemu.h"
 
-void *lock_user(int type, abi_ulong guest_addr, size_t len, bool copy)
+void *lock_user(int type, abi_ulong guest_addr, ssize_t len, bool copy)
 {
 void *host_addr;
 
@@ -24,7 +24,7 @@ void *lock_user(int type, abi_ulong guest_addr, size_t len, 
bool copy)
 }
 
 #ifdef DEBUG_REMAP
-void unlock_user(void *host_ptr, abi_ulong guest_addr, size_t len);
+void unlock_user(void *host_ptr, abi_ulong guest_addr, ssize_t len);
 {
 void *host_ptr_conv;
 
@@ -35,7 +35,7 @@ void unlock_user(void *host_ptr, abi_ulong guest_addr, size_t 
len);
 if (host_ptr == host_ptr_conv) {
 return;
 }
-if (len != 0) {
+if (len > 0) {
 memcpy(host_ptr_conv, host_ptr, len);
 }
 g_free(host_ptr);
@@ -48,14 +48,14 @@ void *lock_user_string(abi_ulong guest_addr)
 if (len < 0) {
 return NULL;
 }
-return lock_user(VERIFY_READ, guest_addr, (size_t)len + 1, 1);
+return lock_user(VERIFY_READ, guest_addr, len + 1, 1);
 }
 
 /* copy_from_user() and copy_to_user() are usually used to copy data
  * buffers between the target and host.  These internally perform
  * locking/unlocking of the memory.
  */
-int copy_from_user(void *hptr, abi_ulong gaddr, size_t len)
+int copy_from_user(void *hptr, abi_ulong gaddr, ssize_t len)
 {
 int ret = 0;
 void *ghptr = lock_user(VERIFY_READ, gaddr, len, 1);
@@ -69,7 +69,7 @@ int copy_from_user(void *hptr, abi_ulong gaddr, size_t len)
 return ret;
 }
 
-int copy_to_user(abi_ulong gaddr, void *hptr, size_t len)
+int copy_to_user(abi_ulong gaddr, void *hptr, ssize_t len)
 {
 int ret = 0;
 void *ghptr = lock_user(VERIFY_WRITE, gaddr, len, 0);
-- 
2.25.1




Re: [PATCH 8/9] hw/9pfs/9p-synth: Replaced qemu_mutex_lock with QEMU_LOCK_GUARD

2021-03-15 Thread Greg Kurz
On Mon, 15 Mar 2021 17:07:50 +0100
Christian Schoenebeck  wrote:

> On Samstag, 13. März 2021 08:51:21 CET Greg Kurz wrote:
> > On Sat, 13 Mar 2021 07:43:38 +0200
> > 
> > Mahmoud Mandour  wrote:
> > > Thanks for the fast review. I asked on the QEMU IRC channel
> > > before committing whether to put all the changes into one patch
> > > or split them and was instructed that it was better to split them up.
> > > But in any case I was open to both ways and you can decide
> > > on the best way to go.
> > 
> > People only do inline replies here. Please don't top-post for the
> > sake of clarity.
> > 
> > So, the instructions to split the patches is obviously the way to go. The
> > question here is rather : will each subsystem maintainer pick up patches
> > from this series or will only one maintainer pick up all the patches after
> > they have been acked by the other maintainers ?
> 
> We need a call here. :)
> 
> Soft freeze is tomorrow, so will one submaintainer handle this series all 
> together or should each submaintainer handle only their specific patches?
> 

I see that some of Mahmoud's patches in Dave Gilbert's latest PR, so I
guess you can go ahead and merge this one in the 9p tree.

> > > On Thu, Mar 11, 2021 at 1:59 PM Christian Schoenebeck <
> > > 
> > > qemu_...@crudebyte.com> wrote:
> > > > On Donnerstag, 11. März 2021 12:52:45 CET Greg Kurz wrote:
> > > > > On Thu, 11 Mar 2021 11:49:06 +0100
> > > > > 
> > > > > Christian Schoenebeck  wrote:
> > > > > > On Donnerstag, 11. März 2021 04:15:37 CET Mahmoud Mandour wrote:
> > > > > > > Replaced a call to qemu_mutex_lock and its respective call to
> > > > > > > qemu_mutex_unlock and used QEMU_LOCK_GUARD macro in their place.
> > > > > > > This simplifies the code by removing the call required to unlock
> > > > > > > and also eliminates goto paths.
> > > > > > > 
> > > > > > > Signed-off-by: Mahmoud Mandour 
> > > > > > > ---
> > > > > > > 
> > > > > > >  hw/9pfs/9p-synth.c | 12 
> > > > > > >  1 file changed, 4 insertions(+), 8 deletions(-)
> > > > > > > 
> > > > > > > diff --git a/hw/9pfs/9p-synth.c b/hw/9pfs/9p-synth.c
> > > > > > > index 7eb210ffa8..473ef914b0 100644
> > > > > > > --- a/hw/9pfs/9p-synth.c
> > > > > > > +++ b/hw/9pfs/9p-synth.c
> > > > > > > @@ -79,11 +79,11 @@ int qemu_v9fs_synth_mkdir(V9fsSynthNode
> > > > > > > *parent,
> > > > 
> > > > int
> > > > 
> > > > > > > mode, if (!parent) {
> > > > > > > 
> > > > > > >  parent = _root;
> > > > > > >  
> > > > > > >  }
> > > > > > > 
> > > > > > > -qemu_mutex_lock(_mutex);
> > > > > > > +QEMU_LOCK_GUARD(_mutex);
> > > > > > > 
> > > > > > >  QLIST_FOREACH(tmp, >child, sibling) {
> > > > > > >  
> > > > > > >  if (!strcmp(tmp->name, name)) {
> > > > > > >  
> > > > > > >  ret = EEXIST;
> > > > > > > 
> > > > > > > -goto err_out;
> > > > > > > +return ret;
> > > > > > > 
> > > > > > >  }
> > > > > > >  
> > > > > > >  }
> > > > > > >  /* Add the name */
> > > > > > > 
> > > > > > > @@ -94,8 +94,6 @@ int qemu_v9fs_synth_mkdir(V9fsSynthNode *parent,
> > > > 
> > > > int
> > > > 
> > > > > > > mode, node->attr, node->attr->inode);
> > > > > > > 
> > > > > > >  *result = node;
> > > > > > >  ret = 0;
> > > > > > > 
> > > > > > > -err_out:
> > > > > > > -qemu_mutex_unlock(_mutex);
> > > > > > > 
> > > > > > >  return ret;
> > > > > > >  
> > > > > > >  }
> > > > > > > 
> > > > > > > @@ -116,11 +114,11 @@ int qemu_v9fs_synth_add_file(V9fsSynthNode
> > > > > > > *parent,
> > > > > > > int mode, parent = _root;
> > > > > > > 
> > > > > > >  }
> > > > > > > 
> > > > > > > -qemu_mutex_lock(_mutex);
> > > > > > > +QEMU_LOCK_GUARD(_mutex);
> > > > > > > 
> > > > > > >  QLIST_FOREACH(tmp, >child, sibling) {
> > > > > > >  
> > > > > > >  if (!strcmp(tmp->name, name)) {
> > > > > > >  
> > > > > > >  ret = EEXIST;
> > > > > > > 
> > > > > > > -goto err_out;
> > > > > > > +return ret;
> > > > > > > 
> > > > > > >  }
> > > > > > >  
> > > > > > >  }
> > > > > > >  /* Add file type and remove write bits */
> > > > > > > 
> > > > > > > @@ -136,8 +134,6 @@ int qemu_v9fs_synth_add_file(V9fsSynthNode
> > > > 
> > > > *parent,
> > > > 
> > > > > > > int
> > > > > > > mode, pstrcpy(node->name, sizeof(node->name), name);
> > > > > > > 
> > > > > > >  QLIST_INSERT_HEAD_RCU(>child, node, sibling);
> > > > > > >  ret = 0;
> > > > > > > 
> > > > > > > -err_out:
> > > > > > > -qemu_mutex_unlock(_mutex);
> > > > > > > 
> > > > > > >  return ret;
> > > > > > >  
> > > > > > >  }
> > > > > > 
> > > > > > Reviewed-by: Christian Schoenebeck 
> > > > > > 
> > > > > > Greg, I suggest I'll push this onto my queue as you seem to be busy.
> > > > > 
> > > > > This cleanup spans over multiple subsystems but I think it makes more
> > > > > sense to keep all these patches together. Let's wait 

[PULL 9/9] migration: Replaced qemu_mutex_lock calls with QEMU_LOCK_GUARD

2021-03-15 Thread Dr. David Alan Gilbert (git)
From: Mahmoud Mandour 

Replaced various qemu_mutex_lock calls and their respective
qemu_mutex_unlock calls with QEMU_LOCK_GUARD macro. This simplifies
the code by eliminating the respective qemu_mutex_unlock calls.

Signed-off-by: Mahmoud Mandour 
Message-Id: <20210311031538.5325-7-ma.mando...@gmail.com>
Reviewed-by: Dr. David Alan Gilbert 
Signed-off-by: Dr. David Alan Gilbert 
---
 migration/migration.c | 6 ++
 migration/ram.c   | 6 ++
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index a5ddf43559..36768391b6 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -323,7 +323,7 @@ static int migrate_send_rp_message(MigrationIncomingState 
*mis,
 int ret = 0;
 
 trace_migrate_send_rp_message((int)message_type, len);
-qemu_mutex_lock(>rp_mutex);
+QEMU_LOCK_GUARD(>rp_mutex);
 
 /*
  * It's possible that the file handle got lost due to network
@@ -331,7 +331,7 @@ static int migrate_send_rp_message(MigrationIncomingState 
*mis,
  */
 if (!mis->to_src_file) {
 ret = -EIO;
-goto error;
+return ret;
 }
 
 qemu_put_be16(mis->to_src_file, (unsigned int)message_type);
@@ -342,8 +342,6 @@ static int migrate_send_rp_message(MigrationIncomingState 
*mis,
 /* It's possible that qemu file got error during sending */
 ret = qemu_file_get_error(mis->to_src_file);
 
-error:
-qemu_mutex_unlock(>rp_mutex);
 return ret;
 }
 
diff --git a/migration/ram.c b/migration/ram.c
index 72143da0ac..52537f14ac 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -819,7 +819,7 @@ static inline bool migration_bitmap_clear_dirty(RAMState 
*rs,
 {
 bool ret;
 
-qemu_mutex_lock(>bitmap_mutex);
+QEMU_LOCK_GUARD(>bitmap_mutex);
 
 /*
  * Clear dirty bitmap if needed.  This _must_ be called before we
@@ -852,7 +852,6 @@ static inline bool migration_bitmap_clear_dirty(RAMState 
*rs,
 if (ret) {
 rs->migration_dirty_pages--;
 }
-qemu_mutex_unlock(>bitmap_mutex);
 
 return ret;
 }
@@ -3275,7 +3274,7 @@ static void decompress_data_with_multi_threads(QEMUFile 
*f,
 int idx, thread_count;
 
 thread_count = migrate_decompress_threads();
-qemu_mutex_lock(_done_lock);
+QEMU_LOCK_GUARD(_done_lock);
 while (true) {
 for (idx = 0; idx < thread_count; idx++) {
 if (decomp_param[idx].done) {
@@ -3295,7 +3294,6 @@ static void decompress_data_with_multi_threads(QEMUFile 
*f,
 qemu_cond_wait(_done_cond, _done_lock);
 }
 }
-qemu_mutex_unlock(_done_lock);
 }
 
  /*
-- 
2.30.2




Re: [PATCH 0/6] pc: support user provided NIC naming/indexing

2021-03-15 Thread Igor Mammedov
On Mon, 15 Mar 2021 11:36:49 -0700 (PDT)
no-re...@patchew.org wrote:

> Patchew URL: 
> https://patchew.org/QEMU/20210315180102.3008391-1-imamm...@redhat.com/
> 
> 
> 
> Hi,
> 
> This series seems to have some coding style problems. See output below for
> more information:
> 
> Type: series
> Message-id: 20210315180102.3008391-1-imamm...@redhat.com
> Subject: [PATCH 0/6] pc: support user provided NIC naming/indexing
> 
> === TEST SCRIPT BEGIN ===
> #!/bin/bash
> git rev-parse base > /dev/null || exit 0
> git config --local diff.renamelimit 0
> git config --local diff.renames True
> git config --local diff.algorithm histogram
> ./scripts/checkpatch.pl --mailback base..
> === TEST SCRIPT END ===
> 
> Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
> From https://github.com/patchew-project/qemu
>  * [new tag] patchew/20210315180102.3008391-1-imamm...@redhat.com -> 
> patchew/20210315180102.3008391-1-imamm...@redhat.com
> Switched to a new branch 'test'
> c0692b4 tests: acpi: update expected blobs
> 1a843d9 pci: acpi: add _DSM method to PCI devices
> 6b55586 acpi: add aml_to_decimalstring() and aml_call6() helpers
> 7b887f4 pci: acpi: ensure that acpi-index is unique
> 4056291 pci: introduce apci-index property for PCI device
> 9bd3a1b tests: acpi: temporary whitelist DSDT changes
> 
> === OUTPUT BEGIN ===
> 1/6 Checking commit 9bd3a1b94c0f (tests: acpi: temporary whitelist DSDT 
> changes)
> 2/6 Checking commit 40562915acde (pci: introduce apci-index property for PCI 
> device)
> ERROR: Macros with complex values should be enclosed in parenthesis
> #284: FILE: include/hw/acpi/pcihp.h:77:
> +#define VMSTATE_PCI_HOTPLUG(pcihp, state, test_pcihp, test_acpi_index) \
>  VMSTATE_UINT32_TEST(pcihp.hotplug_select, state, \
>  test_pcihp), \
>  VMSTATE_STRUCT_ARRAY_TEST(pcihp.acpi_pcihp_pci_status, state, \
>ACPI_PCIHP_MAX_HOTPLUG_BUS, \
>test_pcihp, 1, \
>vmstate_acpi_pcihp_pci_status, \
> -  AcpiPciHpPciStatus)
> +  AcpiPciHpPciStatus), \
> +VMSTATE_UINT32_TEST(pcihp.acpi_index, state, \
> +test_acpi_index)
probably false positive
(I don't know what's wrong here and how to fix it)

> total: 1 errors, 0 warnings, 197 lines checked
> 
> Patch 2/6 has style problems, please review.  If any of these errors
> are false positives report them to the maintainer, see
> CHECKPATCH in MAINTAINERS.

below warnings are intentional to follow comments style we use within 
aml-build.c

> 3/6 Checking commit 7b887f42419a (pci: acpi: ensure that acpi-index is unique)
> 4/6 Checking commit 6b555869ad66 (acpi: add aml_to_decimalstring() and 
> aml_call6() helpers)
> WARNING: Block comments use a leading /* on a separate line
> #27: FILE: hw/acpi/aml-build.c:640:
> +Aml *var = aml_opcode(0x97 /* ToDecimalStringOp */);
> 
> WARNING: Block comments use a leading /* on a separate line
> #32: FILE: hw/acpi/aml-build.c:645:
> +build_append_byte(var->buf, 0x00 /* NullNameOp */);
> 
> total: 0 errors, 2 warnings, 55 lines checked
> 
> Patch 4/6 has style problems, please review.  If any of these errors
> are false positives report them to the maintainer, see
> CHECKPATCH in MAINTAINERS.
> 5/6 Checking commit 1a843d9de55e (pci: acpi: add _DSM method to PCI devices)
> WARNING: Block comments use a leading /* on a separate line
> #127: FILE: hw/i386/acpi-build.c:568:
> +1 /* have supported functions */ |
> 
> total: 0 errors, 1 warnings, 140 lines checked
> 
> Patch 5/6 has style problems, please review.  If any of these errors
> are false positives report them to the maintainer, see
> CHECKPATCH in MAINTAINERS.
> 6/6 Checking commit c0692b4b7df0 (tests: acpi: update expected blobs)
> === OUTPUT END ===
> 
> Test command exited with code: 1
> 
> 
> The full log is available at
> http://patchew.org/logs/20210315180102.3008391-1-imamm...@redhat.com/testing.checkpatch/?type=message.
> ---
> Email generated automatically by Patchew [https://patchew.org/].
> Please send your feedback to patchew-de...@redhat.com




[PULL 6/9] migration/tls: fix inverted semantics in multifd_channel_connect

2021-03-15 Thread Dr. David Alan Gilbert (git)
From: Hao Wang 

Function multifd_channel_connect() return "true" to indicate failure,
which is rather confusing. Fix that.

Signed-off-by: Hao Wang 
Message-Id: <20210209104237.2250941-2-wanghao...@huawei.com>
Reviewed-by: Daniel P. Berrangé 
Reviewed-by: Chuan Zheng 
Signed-off-by: Dr. David Alan Gilbert 
---
 migration/multifd.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/migration/multifd.c b/migration/multifd.c
index 1a1e589064..2a1ea85ade 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -798,9 +798,9 @@ static bool multifd_channel_connect(MultiFDSendParams *p,
  * function after the TLS handshake,
  * so we mustn't call multifd_send_thread until then
  */
-return false;
-} else {
 return true;
+} else {
+return false;
 }
 } else {
 /* update for tls qio channel */
@@ -808,10 +808,10 @@ static bool multifd_channel_connect(MultiFDSendParams *p,
 qemu_thread_create(>thread, p->name, multifd_send_thread, p,
QEMU_THREAD_JOINABLE);
}
-   return false;
+   return true;
 }
 
-return true;
+return false;
 }
 
 static void multifd_new_send_channel_cleanup(MultiFDSendParams *p,
@@ -844,7 +844,7 @@ static void multifd_new_send_channel_async(QIOTask *task, 
gpointer opaque)
 p->c = QIO_CHANNEL(sioc);
 qio_channel_set_delay(p->c, false);
 p->running = true;
-if (multifd_channel_connect(p, sioc, local_err)) {
+if (!multifd_channel_connect(p, sioc, local_err)) {
 goto cleanup;
 }
 return;
-- 
2.30.2




Re: [PATCH] hw/i8254: fix vmstate load

2021-03-15 Thread Dr. David Alan Gilbert
* Pavel Dovgalyuk (pavel.dovgal...@ispras.ru) wrote:
> QEMU timer of channel 0 in i8254 is used to raise irq
> at the specified moment of time. This irq can be disabled
> with irq_disabled flag. But when vmstate of the pit is
> loaded, timer may be rearmed despite the disabled interrupts.
> This patch adds irq_disabled flag check to fix that.
> 
> Signed-off-by: Pavel Dovgalyuk 

Hi Pavel,
  I'm curious, did you see this cause a problem on a particular guest
OS?

Dave

> ---
>  hw/timer/i8254.c |2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/timer/i8254.c b/hw/timer/i8254.c
> index c01ee2c72a..c8388ea432 100644
> --- a/hw/timer/i8254.c
> +++ b/hw/timer/i8254.c
> @@ -324,7 +324,7 @@ static void pit_post_load(PITCommonState *s)
>  {
>  PITChannelState *sc = >channels[0];
>  
> -if (sc->next_transition_time != -1) {
> +if (sc->next_transition_time != -1 && !sc->irq_disabled) {
>  timer_mod(sc->irq_timer, sc->next_transition_time);
>  } else {
>  timer_del(sc->irq_timer);
> 
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




[PULL 8/9] monitor: Replaced qemu_mutex_lock calls with QEMU_LOCK_GUARD

2021-03-15 Thread Dr. David Alan Gilbert (git)
From: Mahmoud Mandour 

Removed various qemu_mutex_lock and their respective qemu_mutex_unlock
calls and used lock guard macros (QEMU_LOCK_GUARD and
WITH_QEMU_LOCK_GUARD). This simplifies the code by
eliminating qemu_mutex_unlock calls.

Signed-off-by: Mahmoud Mandour 
Message-Id: <20210311031538.5325-6-ma.mando...@gmail.com>
Reviewed-by: Dr. David Alan Gilbert 
Signed-off-by: Dr. David Alan Gilbert 
---
 monitor/monitor.c |  8 ++--
 monitor/qmp.c | 51 ++-
 2 files changed, 26 insertions(+), 33 deletions(-)

diff --git a/monitor/monitor.c b/monitor/monitor.c
index e94f532cf5..640496e562 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -349,7 +349,7 @@ monitor_qapi_event_queue_no_reenter(QAPIEvent event, QDict 
*qdict)
 evconf = _qapi_event_conf[event];
 trace_monitor_protocol_event_queue(event, qdict, evconf->rate);
 
-qemu_mutex_lock(_lock);
+QEMU_LOCK_GUARD(_lock);
 
 if (!evconf->rate) {
 /* Unthrottled event */
@@ -391,8 +391,6 @@ monitor_qapi_event_queue_no_reenter(QAPIEvent event, QDict 
*qdict)
 timer_mod_ns(evstate->timer, now + evconf->rate);
 }
 }
-
-qemu_mutex_unlock(_lock);
 }
 
 void qapi_event_emit(QAPIEvent event, QDict *qdict)
@@ -447,7 +445,7 @@ static void monitor_qapi_event_handler(void *opaque)
 MonitorQAPIEventConf *evconf = _qapi_event_conf[evstate->event];
 
 trace_monitor_protocol_event_handler(evstate->event, evstate->qdict);
-qemu_mutex_lock(_lock);
+QEMU_LOCK_GUARD(_lock);
 
 if (evstate->qdict) {
 int64_t now = qemu_clock_get_ns(monitor_get_event_clock());
@@ -462,8 +460,6 @@ static void monitor_qapi_event_handler(void *opaque)
 timer_free(evstate->timer);
 g_free(evstate);
 }
-
-qemu_mutex_unlock(_lock);
 }
 
 static unsigned int qapi_event_throttle_hash(const void *key)
diff --git a/monitor/qmp.c b/monitor/qmp.c
index 2326bd7f9b..2b0308f933 100644
--- a/monitor/qmp.c
+++ b/monitor/qmp.c
@@ -76,7 +76,7 @@ static void monitor_qmp_cleanup_req_queue_locked(MonitorQMP 
*mon)
 
 static void monitor_qmp_cleanup_queue_and_resume(MonitorQMP *mon)
 {
-qemu_mutex_lock(>qmp_queue_lock);
+QEMU_LOCK_GUARD(>qmp_queue_lock);
 
 /*
  * Same condition as in monitor_qmp_dispatcher_co(), but before
@@ -103,7 +103,6 @@ static void monitor_qmp_cleanup_queue_and_resume(MonitorQMP 
*mon)
 monitor_resume(>common);
 }
 
-qemu_mutex_unlock(>qmp_queue_lock);
 }
 
 void qmp_send_response(MonitorQMP *mon, const QDict *rsp)
@@ -179,7 +178,7 @@ static QMPRequest 
*monitor_qmp_requests_pop_any_with_lock(void)
 Monitor *mon;
 MonitorQMP *qmp_mon;
 
-qemu_mutex_lock(_lock);
+QEMU_LOCK_GUARD(_lock);
 
 QTAILQ_FOREACH(mon, _list, entry) {
 if (!monitor_is_qmp(mon)) {
@@ -205,8 +204,6 @@ static QMPRequest 
*monitor_qmp_requests_pop_any_with_lock(void)
 QTAILQ_INSERT_TAIL(_list, mon, entry);
 }
 
-qemu_mutex_unlock(_lock);
-
 return req_obj;
 }
 
@@ -376,30 +373,30 @@ static void handle_qmp_command(void *opaque, QObject 
*req, Error *err)
 req_obj->err = err;
 
 /* Protect qmp_requests and fetching its length. */
-qemu_mutex_lock(>qmp_queue_lock);
+WITH_QEMU_LOCK_GUARD(>qmp_queue_lock) {
 
-/*
- * Suspend the monitor when we can't queue more requests after
- * this one.  Dequeuing in monitor_qmp_dispatcher_co() or
- * monitor_qmp_cleanup_queue_and_resume() will resume it.
- * Note that when OOB is disabled, we queue at most one command,
- * for backward compatibility.
- */
-if (!qmp_oob_enabled(mon) ||
-mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX - 1) {
-monitor_suspend(>common);
-}
+/*
+ * Suspend the monitor when we can't queue more requests after
+ * this one.  Dequeuing in monitor_qmp_dispatcher_co() or
+ * monitor_qmp_cleanup_queue_and_resume() will resume it.
+ * Note that when OOB is disabled, we queue at most one command,
+ * for backward compatibility.
+ */
+if (!qmp_oob_enabled(mon) ||
+mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX - 1) {
+monitor_suspend(>common);
+}
 
-/*
- * Put the request to the end of queue so that requests will be
- * handled in time order.  Ownership for req_obj, req,
- * etc. will be delivered to the handler side.
- */
-trace_monitor_qmp_in_band_enqueue(req_obj, mon,
-  mon->qmp_requests->length);
-assert(mon->qmp_requests->length < QMP_REQ_QUEUE_LEN_MAX);
-g_queue_push_tail(mon->qmp_requests, req_obj);
-qemu_mutex_unlock(>qmp_queue_lock);
+/*
+ * Put the request to the end of queue so that requests will be
+ * handled in time order.  Ownership for req_obj, req,
+ * etc. will be delivered to the handler side.
+ */
+

[PULL 7/9] migration/tls: add error handling in multifd_tls_handshake_thread

2021-03-15 Thread Dr. David Alan Gilbert (git)
From: Hao Wang 

If any error happens during multifd send thread creating (e.g. channel broke
because new domain is destroyed by the dst), multifd_tls_handshake_thread
may exit silently, leaving main migration thread hanging (ram_save_setup ->
multifd_send_sync_main -> qemu_sem_wait(>sem_sync)).
Fix that by adding error handling in multifd_tls_handshake_thread.

Signed-off-by: Hao Wang 
Message-Id: <20210209104237.2250941-3-wanghao...@huawei.com>
Reviewed-by: Daniel P. Berrangé 
Reviewed-by: Chuan Zheng 
Signed-off-by: Dr. David Alan Gilbert 
---
 migration/multifd.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/migration/multifd.c b/migration/multifd.c
index 2a1ea85ade..03527c564c 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -739,7 +739,16 @@ static void multifd_tls_outgoing_handshake(QIOTask *task,
 } else {
 trace_multifd_tls_outgoing_handshake_complete(ioc);
 }
-multifd_channel_connect(p, ioc, err);
+
+if (!multifd_channel_connect(p, ioc, err)) {
+/*
+ * Error happen, mark multifd_send_thread status as 'quit' although it
+ * is not created, and then tell who pay attention to me.
+ */
+p->quit = true;
+qemu_sem_post(_send_state->channels_ready);
+qemu_sem_post(>sem_sync);
+}
 }
 
 static void *multifd_tls_handshake_thread(void *opaque)
-- 
2.30.2




[PULL 4/9] virtiofsd: Don't allow empty paths in lookup_name()

2021-03-15 Thread Dr. David Alan Gilbert (git)
From: Greg Kurz 

When passed an empty filename, lookup_name() returns the inode of
the parent directory, unless the parent is the root in which case
the st_dev doesn't match and lo_find() returns NULL. This is
because lookup_name() passes AT_EMPTY_PATH down to fstatat() or
statx().

This behavior doesn't quite make sense because users of lookup_name()
then pass the name to unlinkat(), renameat() or renameat2(), all of
which will always fail on empty names.

Drop AT_EMPTY_PATH from the flags in lookup_name() so that it has
the consistent behavior of "returning an existing child inode or
NULL" for all directories.

Signed-off-by: Greg Kurz 
Message-Id: <20210312141003.819108-2-gr...@kaod.org>
Reviewed-by: Connor Kuehl 
Reviewed-by: Vivek Goyal 
Signed-off-by: Dr. David Alan Gilbert 
---
 tools/virtiofsd/passthrough_ll.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
index b07101d8eb..cf453eea9b 100644
--- a/tools/virtiofsd/passthrough_ll.c
+++ b/tools/virtiofsd/passthrough_ll.c
@@ -1330,8 +1330,7 @@ static struct lo_inode *lookup_name(fuse_req_t req, 
fuse_ino_t parent,
 return NULL;
 }
 
-res = do_statx(lo, dir->fd, name, ,
-   AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, _id);
+res = do_statx(lo, dir->fd, name, , AT_SYMLINK_NOFOLLOW, _id);
 lo_inode_put(lo, );
 if (res == -1) {
 return NULL;
-- 
2.30.2




Re: [PATCH 7/7] block/nbd: stop manipulating in_flight counter

2021-03-15 Thread Vladimir Sementsov-Ogievskiy

15.03.2021 09:06, Roman Kagan wrote:

As the reconnect logic no longer interferes with drained sections, it
appears unnecessary to explicitly manipulate the in_flight counter.

Fixes: 5ad81b4946 ("nbd: Restrict connection_co reentrance")


And here you actually allow qemu_aio_coroutine_enter() call in 
nbd_client_attach_aio_context_bh() to enter connection_co in any yield point 
which is possible during drained section. The analysis should be done to be 
sure that all these yield points are safe for reentering by external 
qemu_aio_coroutine_enter(). (By external I mean not by the actual enter() we 
are waiting for at the yield() point. For example qemu_channel_yield() supports 
reentering.. And therefore (as I understand after fast looking through) 
nbd_read() should support reentering too..


--
Best regards,
Vladimir



[PULL 5/9] virtiofsd: Convert some functions to return bool

2021-03-15 Thread Dr. David Alan Gilbert (git)
From: Greg Kurz 

Both currently only return 0 or 1.

Signed-off-by: Greg Kurz 
Message-Id: <20210312141003.819108-3-gr...@kaod.org>
Reviewed-by: Connor Kuehl 
Reviewed-by: Vivek Goyal 
Signed-off-by: Dr. David Alan Gilbert 
---
 tools/virtiofsd/passthrough_ll.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
index cf453eea9b..b144320e48 100644
--- a/tools/virtiofsd/passthrough_ll.c
+++ b/tools/virtiofsd/passthrough_ll.c
@@ -223,17 +223,17 @@ static struct lo_inode *lo_find(struct lo_data *lo, 
struct stat *st,
 static int xattr_map_client(const struct lo_data *lo, const char *client_name,
 char **out_name);
 
-static int is_dot_or_dotdot(const char *name)
+static bool is_dot_or_dotdot(const char *name)
 {
 return name[0] == '.' &&
(name[1] == '\0' || (name[1] == '.' && name[2] == '\0'));
 }
 
 /* Is `path` a single path component that is not "." or ".."? */
-static int is_safe_path_component(const char *path)
+static bool is_safe_path_component(const char *path)
 {
 if (strchr(path, '/')) {
-return 0;
+return false;
 }
 
 return !is_dot_or_dotdot(path);
-- 
2.30.2




[PULL 2/9] virtiofsd: Add qemu version and copyright info

2021-03-15 Thread Dr. David Alan Gilbert (git)
From: Vivek Goyal 

Option "-V" currently displays the fuse protocol version virtiofsd is
using. For example, I see this.

$ ./virtiofsd -V
"using FUSE kernel interface version 7.33"

People also want to know software version of virtiofsd so that they can
figure out if a certain fix is part of currently running virtiofsd or
not. Eric Ernst ran into this issue.

David Gilbert thinks that it probably is best that we simply carry the
qemu version and display that information given we are part of qemu
tree.

So this patch enhances version information and also adds qemu version
and copyright info. Not sure if copyright information is supposed
to be displayed along with version info. Given qemu-storage-daemon
and other utilities are doing it, so I continued with same pattern.
This is how now output looks like.

$ ./virtiofsd -V
virtiofsd version 5.2.50 (v5.2.0-2357-gcbcf09872a-dirty)
Copyright (c) 2003-2020 Fabrice Bellard and the QEMU Project developers
using FUSE kernel interface version 7.33

Reported-by: Eric Ernst 
Signed-off-by: Vivek Goyal 
Message-Id: <20210303195339.gb3...@redhat.com>
Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Sergio Lopez 
Signed-off-by: Dr. David Alan Gilbert 
---
 tools/virtiofsd/passthrough_ll.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
index fc7e1b1e8e..851c25ef20 100644
--- a/tools/virtiofsd/passthrough_ll.c
+++ b/tools/virtiofsd/passthrough_ll.c
@@ -37,6 +37,8 @@
 
 #include "qemu/osdep.h"
 #include "qemu/timer.h"
+#include "qemu-version.h"
+#include "qemu-common.h"
 #include "fuse_virtio.h"
 #include "fuse_log.h"
 #include "fuse_lowlevel.h"
@@ -3666,6 +3668,11 @@ static void fuse_lo_data_cleanup(struct lo_data *lo)
 free(lo->source);
 }
 
+static void qemu_version(void)
+{
+printf("virtiofsd version " QEMU_FULL_VERSION "\n" QEMU_COPYRIGHT "\n");
+}
+
 int main(int argc, char *argv[])
 {
 struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
@@ -3737,6 +3744,7 @@ int main(int argc, char *argv[])
 ret = 0;
 goto err_out1;
 } else if (opts.show_version) {
+qemu_version();
 fuse_lowlevel_version();
 ret = 0;
 goto err_out1;
-- 
2.30.2




[PULL 3/9] virtiofsd: Don't allow empty filenames

2021-03-15 Thread Dr. David Alan Gilbert (git)
From: Greg Kurz 

POSIX.1-2017 clearly stipulates that empty filenames aren't
allowed ([1] and [2]). Since virtiofsd is supposed to mirror
the host file system hierarchy and the host can be assumed to
be linux, we don't really expect clients to pass requests with
an empty path in it. If they do so anyway, this would eventually
cause an error when trying to create/lookup the actual inode
on the underlying POSIX filesystem. But this could still confuse
some code that wouldn't be ready to cope with this.

Filter out empty names coming from the client at the top level,
so that the rest doesn't have to care about it. This is done
everywhere we already call is_safe_path_component(), but
in a separate helper since the usual error for empty path
names is ENOENT instead of EINVAL.

[1] 
https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_170
[2] 
https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13

Signed-off-by: Greg Kurz 
Message-Id: <20210312141003.819108-4-gr...@kaod.org>
Reviewed-by: Connor Kuehl 
Signed-off-by: Dr. David Alan Gilbert 
---
 tools/virtiofsd/passthrough_ll.c | 35 
 1 file changed, 35 insertions(+)

diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
index 851c25ef20..b07101d8eb 100644
--- a/tools/virtiofsd/passthrough_ll.c
+++ b/tools/virtiofsd/passthrough_ll.c
@@ -239,6 +239,11 @@ static int is_safe_path_component(const char *path)
 return !is_dot_or_dotdot(path);
 }
 
+static bool is_empty(const char *name)
+{
+return name[0] == '\0';
+}
+
 static struct lo_data *lo_data(fuse_req_t req)
 {
 return (struct lo_data *)fuse_req_userdata(req);
@@ -1085,6 +1090,11 @@ static void lo_lookup(fuse_req_t req, fuse_ino_t parent, 
const char *name)
 fuse_log(FUSE_LOG_DEBUG, "lo_lookup(parent=%" PRIu64 ", name=%s)\n", 
parent,
  name);
 
+if (is_empty(name)) {
+fuse_reply_err(req, ENOENT);
+return;
+}
+
 /*
  * Don't use is_safe_path_component(), allow "." and ".." for NFS export
  * support.
@@ -1176,6 +1186,11 @@ static void lo_mknod_symlink(fuse_req_t req, fuse_ino_t 
parent,
 struct fuse_entry_param e;
 struct lo_cred old = {};
 
+if (is_empty(name)) {
+fuse_reply_err(req, ENOENT);
+return;
+}
+
 if (!is_safe_path_component(name)) {
 fuse_reply_err(req, EINVAL);
 return;
@@ -1248,6 +1263,11 @@ static void lo_link(fuse_req_t req, fuse_ino_t ino, 
fuse_ino_t parent,
 char procname[64];
 int saverr;
 
+if (is_empty(name)) {
+fuse_reply_err(req, ENOENT);
+return;
+}
+
 if (!is_safe_path_component(name)) {
 fuse_reply_err(req, EINVAL);
 return;
@@ -1326,6 +1346,11 @@ static void lo_rmdir(fuse_req_t req, fuse_ino_t parent, 
const char *name)
 struct lo_inode *inode;
 struct lo_data *lo = lo_data(req);
 
+if (is_empty(name)) {
+fuse_reply_err(req, ENOENT);
+return;
+}
+
 if (!is_safe_path_component(name)) {
 fuse_reply_err(req, EINVAL);
 return;
@@ -1355,6 +1380,11 @@ static void lo_rename(fuse_req_t req, fuse_ino_t parent, 
const char *name,
 struct lo_inode *newinode = NULL;
 struct lo_data *lo = lo_data(req);
 
+if (is_empty(name) || is_empty(newname)) {
+fuse_reply_err(req, ENOENT);
+return;
+}
+
 if (!is_safe_path_component(name) || !is_safe_path_component(newname)) {
 fuse_reply_err(req, EINVAL);
 return;
@@ -1408,6 +1438,11 @@ static void lo_unlink(fuse_req_t req, fuse_ino_t parent, 
const char *name)
 struct lo_inode *inode;
 struct lo_data *lo = lo_data(req);
 
+if (is_empty(name)) {
+fuse_reply_err(req, ENOENT);
+return;
+}
+
 if (!is_safe_path_component(name)) {
 fuse_reply_err(req, EINVAL);
 return;
-- 
2.30.2




[PULL 0/9] virtiofs and migration queue

2021-03-15 Thread Dr. David Alan Gilbert (git)
From: "Dr. David Alan Gilbert" 

The following changes since commit e7c6a8cf9f5c82aa152273e1c9e80d07b1b0c32c:

  Merge remote-tracking branch 'remotes/philmd/tags/avr-20210315' into staging 
(2021-03-15 16:59:55 +)

are available in the Git repository at:

  https://gitlab.com/dagrh/qemu.git tags/pull-virtiofs-20210315

for you to fetch changes up to 373969507a3dc7de2d291da7e1bd03acf46ec643:

  migration: Replaced qemu_mutex_lock calls with QEMU_LOCK_GUARD (2021-03-15 
20:01:55 +)


virtiofs and migration pull 2021-03-15

Signed-off-by: Dr. David Alan Gilbert 


Greg Kurz (4):
  virtiofsd: Release vu_dispatch_lock when stopping queue
  virtiofsd: Don't allow empty filenames
  virtiofsd: Don't allow empty paths in lookup_name()
  virtiofsd: Convert some functions to return bool

Hao Wang (2):
  migration/tls: fix inverted semantics in multifd_channel_connect
  migration/tls: add error handling in multifd_tls_handshake_thread

Mahmoud Mandour (2):
  monitor: Replaced qemu_mutex_lock calls with QEMU_LOCK_GUARD
  migration: Replaced qemu_mutex_lock calls with QEMU_LOCK_GUARD

Vivek Goyal (1):
  virtiofsd: Add qemu version and copyright info

 migration/migration.c|  6 ++---
 migration/multifd.c  | 21 +++-
 migration/ram.c  |  6 ++---
 monitor/monitor.c|  8 ++-
 monitor/qmp.c| 51 +++
 tools/virtiofsd/fuse_virtio.c|  6 +
 tools/virtiofsd/passthrough_ll.c | 52 
 7 files changed, 98 insertions(+), 52 deletions(-)




[PULL 1/9] virtiofsd: Release vu_dispatch_lock when stopping queue

2021-03-15 Thread Dr. David Alan Gilbert (git)
From: Greg Kurz 

QEMU can stop a virtqueue by sending a VHOST_USER_GET_VRING_BASE request
to virtiofsd. As with all other vhost-user protocol messages, the thread
that runs the main event loop in virtiofsd takes the vu_dispatch lock in
write mode. This ensures that no other thread can access virtqueues or
memory tables at the same time.

In the case of VHOST_USER_GET_VRING_BASE, the main thread basically
notifies the queue thread that it should terminate and waits for its
termination:

main()
 virtio_loop()
  vu_dispatch_wrlock()
  vu_dispatch()
   vu_process_message()
vu_get_vring_base_exec()
 fv_queue_cleanup_thread()
  pthread_join()

Unfortunately, the queue thread ends up calling virtio_send_msg()
at some point, which itself needs to grab the lock:

fv_queue_thread()
 g_list_foreach()
  fv_queue_worker()
   fuse_session_process_buf_int()
do_release()
 lo_release()
  fuse_reply_err()
   send_reply()
send_reply_iov()
 fuse_send_reply_iov_nofree()
  fuse_send_msg()
   virtio_send_msg()
vu_dispatch_rdlock() <-- Deadlock !

Simply have the main thread to release the lock before going to
sleep and take it back afterwards. A very similar patch was already
sent by Vivek Goyal sometime back:

https://listman.redhat.com/archives/virtio-fs/2021-January/msg00073.html

The only difference here is that this done in fv_queue_set_started()
because fv_queue_cleanup_thread() can also be called from virtio_loop()
without the lock being held.

Signed-off-by: Greg Kurz 
Reviewed-by: Vivek Goyal 
Reviewed-by: Stefan Hajnoczi 
Message-Id: <20210312092212.782255-8-gr...@kaod.org>
Signed-off-by: Dr. David Alan Gilbert 
---
 tools/virtiofsd/fuse_virtio.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
index 523ee64fb7..3e13997406 100644
--- a/tools/virtiofsd/fuse_virtio.c
+++ b/tools/virtiofsd/fuse_virtio.c
@@ -792,7 +792,13 @@ static void fv_queue_set_started(VuDev *dev, int qidx, 
bool started)
 assert(0);
 }
 } else {
+/*
+ * Temporarily drop write-lock taken in virtio_loop() so that
+ * the queue thread doesn't block in virtio_send_msg().
+ */
+vu_dispatch_unlock(vud);
 fv_queue_cleanup_thread(vud, qidx);
+vu_dispatch_wrlock(vud);
 }
 }
 
-- 
2.30.2




Re: [PATCH 6/7] block/nbd: decouple reconnect from drain

2021-03-15 Thread Vladimir Sementsov-Ogievskiy

15.03.2021 09:06, Roman Kagan wrote:

The reconnection logic doesn't need to stop while in a drained section.
Moreover it has to be active during the drained section, as the requests
that were caught in-flight with the connection to the server broken can
only usefully get drained if the connection is restored.  Otherwise such
requests can only either stall resulting in a deadlock (before
8c517de24a), or be aborted defeating the purpose of the reconnection
machinery (after 8c517de24a).

Since the pieces of the reconnection logic are now properly migrated
from one aio_context to another, it appears safe to just stop messing
with the drained section in the reconnection code.

Fixes: 5ad81b4946 ("nbd: Restrict connection_co reentrance")


I'd not think that it "fixes" it. Behavior changes.. But 5ad81b4946 didn't 
introduce any bugs.


Fixes: 8c517de24a ("block/nbd: fix drain dead-lock because of nbd 
reconnect-delay")


And here..

1. There is an existing problem (unrelated to nbd) in Qemu that long io request 
which we have to wait for at drained_begin may trigger a dead lock 
(https://lists.gnu.org/archive/html/qemu-devel/2020-09/msg01339.html)

2. So, when we have nbd reconnect (and therefore long io requests) we simply 
trigger this deadlock.. That's why I decided to cancel the requests (assuming 
they will most probably fail anyway).

I agree that nbd driver is wrong place for fixing the problem described in 
(https://lists.gnu.org/archive/html/qemu-devel/2020-09/msg01339.html), but if 
you just revert 8c517de24a, you'll see the deadlock again..



--
Best regards,
Vladimir



Re: [PATCH 3/7] block/nbd: assert attach/detach runs in the proper context

2021-03-15 Thread Roman Kagan
On Mon, Mar 15, 2021 at 07:41:32PM +0300, Vladimir Sementsov-Ogievskiy wrote:
> 15.03.2021 09:06, Roman Kagan wrote:
> > Document (via a comment and an assert) that
> > nbd_client_detach_aio_context and nbd_client_attach_aio_context_bh run
> > in the desired aio_context
> > 
> > Signed-off-by: Roman Kagan 
> > ---
> >   block/nbd.c | 12 
> >   1 file changed, 12 insertions(+)
> > 
> > diff --git a/block/nbd.c b/block/nbd.c
> > index 1d8edb5b21..658b827d24 100644
> > --- a/block/nbd.c
> > +++ b/block/nbd.c
> > @@ -241,6 +241,12 @@ static void 
> > nbd_client_detach_aio_context(BlockDriverState *bs)
> >   {
> >   BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
> > +/*
> > + * This runs in the (old, about to be detached) aio context of the @bs 
> > so
> > + * accessing the stuff on @s is concurrency-free.
> > + */
> > +assert(qemu_get_current_aio_context() == bdrv_get_aio_context(bs));
> 
> Hmm. I don't think so. The handler is called from 
> bdrv_set_aio_context_ignore(), which have the assertion 
> g_assert(qemu_get_current_aio_context() == qemu_get_aio_context());. There is 
> also a comment above bdrv_set_aio_context_ignore() "The caller must own the 
> AioContext lock for the old AioContext of bs".
> 
> So, we are not in the home context of bs here. We are in the main aio context 
> and we hold AioContext lock of old bs context.

You're absolutely right.  I'm wondering where I got the idea of this
assertion from...

> 
> > +
> >   /* Timer is deleted in nbd_client_co_drain_begin() */
> >   assert(!s->reconnect_delay_timer);
> >   /*
> > @@ -258,6 +264,12 @@ static void nbd_client_attach_aio_context_bh(void 
> > *opaque)
> >   BlockDriverState *bs = opaque;
> >   BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
> > +/*
> > + * This runs in the (new, just attached) aio context of the @bs so
> > + * accessing the stuff on @s is concurrency-free.
> > + */
> > +assert(qemu_get_current_aio_context() == bdrv_get_aio_context(bs));
> 
> This is correct just because we are in a BH, scheduled for this
> context (I hope we can't reattach some third context prior to entering
> the BH in the second:). So, I don't think this assertion really adds
> something.

Indeed.

> > +
> >   if (s->connection_co) {
> >   /*
> >* The node is still drained, so we know the coroutine has 
> > yielded in
> > 
> 
> I'm not sure that the asserted fact gives us "concurrency-free". For
> this we also need to ensure that all other things in the driver are
> always called in same aio context.. Still, it's a general assumption
> we have when writing block drivers "everything in one aio context, so
> don't care".. Sometime it leads to bugs, as some things are still
> called even from non-coroutine context. Also, Paolo said
> (https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg03814.html)
> that many iothreads will send requests to bs, and the code in driver
> should be thread safe. I don't have good understanding of all these
> things, and what I have is:
> 
> For now (at least we don't have problems in Rhel based downstream) it
> maybe OK to think that in block-driver everything is protected by
> AioContext lock and all concurrency we have inside block driver is
> switching between coroutines but never real parallelism. But in
> general it's not so, and with multiqueue it's not so.. So, I'd not put
> such a comment :)

So the patch is bogus in every respect; let's just drop it.

I hope it doesn't invalidate completely the rest of the series though.

Meanwhile I certainly need to update my idea of concurrency assumptions
in the block layer.

Thanks,
Roman.



[RFC v2 13/13] vhost: Use VRING_AVAIL_F_NO_INTERRUPT at device call on shadow virtqueue

2021-03-15 Thread Eugenio Pérez
Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost-shadow-virtqueue.c | 28 +++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/vhost-shadow-virtqueue.c 
b/hw/virtio/vhost-shadow-virtqueue.c
index 7df98fc43f..e3879a4622 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -71,10 +71,35 @@ typedef struct VhostShadowVirtqueue {
 /* Next head to consume from device */
 uint16_t used_idx;
 
+/* Cache for the exposed notification flag */
+bool notification;
+
 /* Descriptors copied from guest */
 vring_desc_t descs[];
 } VhostShadowVirtqueue;
 
+static void vhost_shadow_vq_set_notification(VhostShadowVirtqueue *svq,
+ bool enable)
+{
+uint16_t notification_flag;
+
+if (svq->notification == enable) {
+return;
+}
+
+notification_flag = virtio_tswap16(svq->vdev, VRING_AVAIL_F_NO_INTERRUPT);
+
+svq->notification = enable;
+if (enable) {
+svq->vring.avail->flags &= ~notification_flag;
+} else {
+svq->vring.avail->flags |= notification_flag;
+}
+
+/* Make sure device reads our flag */
+smp_mb();
+}
+
 static void vhost_vring_write_descs(VhostShadowVirtqueue *svq,
 const struct iovec *iovec,
 size_t num, bool more_descs, bool write)
@@ -251,7 +276,7 @@ static void 
vhost_shadow_vq_handle_call_no_test(EventNotifier *n)
 do {
 unsigned i = 0;
 
-/* TODO: Use VRING_AVAIL_F_NO_INTERRUPT */
+vhost_shadow_vq_set_notification(svq, false);
 while (true) {
 g_autofree VirtQueueElement *elem = vhost_shadow_vq_get_buf(svq);
 if (!elem) {
@@ -269,6 +294,7 @@ static void 
vhost_shadow_vq_handle_call_no_test(EventNotifier *n)
 svq->masked_notifier.signaled = true;
 event_notifier_set(svq->masked_notifier.n);
 }
+vhost_shadow_vq_set_notification(svq, true);
 } while (vhost_shadow_vq_more_used(svq));
 
 if (masked_notifier) {
-- 
2.27.0




[RFC v2 12/13] vhost: Check for device VRING_USED_F_NO_NOTIFY at shadow virtqueue kick

2021-03-15 Thread Eugenio Pérez
Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost-shadow-virtqueue.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/vhost-shadow-virtqueue.c 
b/hw/virtio/vhost-shadow-virtqueue.c
index 68ed0f2740..7df98fc43f 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -145,6 +145,15 @@ static void vhost_shadow_vq_add(VhostShadowVirtqueue *svq,
 svq->ring_id_maps[qemu_head] = elem;
 }
 
+static void vhost_shadow_vq_kick(VhostShadowVirtqueue *svq)
+{
+/* Make sure we are reading updated device flag */
+smp_rmb();
+if (!(svq->vring.used->flags & VRING_USED_F_NO_NOTIFY)) {
+event_notifier_set(>kick_notifier);
+}
+}
+
 /* Handle guest->device notifications */
 static void vhost_handle_guest_kick(EventNotifier *n)
 {
@@ -174,7 +183,7 @@ static void vhost_handle_guest_kick(EventNotifier *n)
 }
 
 vhost_shadow_vq_add(svq, elem);
-event_notifier_set(>kick_notifier);
+vhost_shadow_vq_kick(svq);
 }
 
 virtio_queue_set_notification(svq->vq, true);
-- 
2.27.0




Re: [PATCH] Hexagon (target/hexagon) remove unnecessary semicolons

2021-03-15 Thread Richard Henderson

On 3/14/21 10:55 PM, Taylor Simpson wrote:

Address feedback from Richard Henderson <

Signed-off-by: Taylor Simpson
---
  target/hexagon/gen_tcg.h | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)


Queued.


r~



[RFC v2 08/13] virtio: Add vhost_shadow_vq_get_vring_addr

2021-03-15 Thread Eugenio Pérez
It reports the shadow virtqueue address from qemu virtual address space

Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost-shadow-virtqueue.h |  2 ++
 hw/virtio/vhost-shadow-virtqueue.c | 24 +++-
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/vhost-shadow-virtqueue.h 
b/hw/virtio/vhost-shadow-virtqueue.h
index 2ca4b92b12..d82c35bccf 100644
--- a/hw/virtio/vhost-shadow-virtqueue.h
+++ b/hw/virtio/vhost-shadow-virtqueue.h
@@ -19,6 +19,8 @@ typedef struct VhostShadowVirtqueue VhostShadowVirtqueue;
 
 void vhost_shadow_vq_mask(VhostShadowVirtqueue *svq, EventNotifier *masked);
 void vhost_shadow_vq_unmask(VhostShadowVirtqueue *svq);
+void vhost_shadow_vq_get_vring_addr(const VhostShadowVirtqueue *svq,
+struct vhost_vring_addr *addr);
 
 bool vhost_shadow_vq_start(struct vhost_dev *dev,
unsigned idx,
diff --git a/hw/virtio/vhost-shadow-virtqueue.c 
b/hw/virtio/vhost-shadow-virtqueue.c
index b6bab438d6..1460d1d5d1 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -17,6 +17,9 @@
 
 /* Shadow virtqueue to relay notifications */
 typedef struct VhostShadowVirtqueue {
+/* Shadow vring */
+struct vring vring;
+
 /* Shadow kick notifier, sent to vhost */
 EventNotifier kick_notifier;
 /* Shadow call notifier, sent to vhost */
@@ -51,6 +54,9 @@ typedef struct VhostShadowVirtqueue {
 
 /* Virtio device */
 VirtIODevice *vdev;
+
+/* Descriptors copied from guest */
+vring_desc_t descs[];
 } VhostShadowVirtqueue;
 
 /* Forward guest notifications */
@@ -132,6 +138,19 @@ void vhost_shadow_vq_unmask(VhostShadowVirtqueue *svq)
 qemu_event_wait(>masked_notifier.is_free);
 }
 
+/*
+ * Get the shadow vq vring address.
+ * @svq Shadow virtqueue
+ * @addr Destination to store address
+ */
+void vhost_shadow_vq_get_vring_addr(const VhostShadowVirtqueue *svq,
+struct vhost_vring_addr *addr)
+{
+addr->desc_user_addr = (uint64_t)svq->vring.desc;
+addr->avail_user_addr = (uint64_t)svq->vring.avail;
+addr->used_user_addr = (uint64_t)svq->vring.used;
+}
+
 /*
  * Restore the vhost guest to host notifier, i.e., disables svq effect.
  */
@@ -262,7 +281,9 @@ void vhost_shadow_vq_stop(struct vhost_dev *dev,
 VhostShadowVirtqueue *vhost_shadow_vq_new(struct vhost_dev *dev, int idx)
 {
 int vq_idx = dev->vq_index + idx;
-g_autofree VhostShadowVirtqueue *svq = g_new0(VhostShadowVirtqueue, 1);
+unsigned num = virtio_queue_get_num(dev->vdev, vq_idx);
+size_t ring_size = vring_size(num, VRING_DESC_ALIGN_SIZE);
+g_autofree VhostShadowVirtqueue *svq = g_malloc0(sizeof(*svq) + ring_size);
 int r;
 
 r = event_notifier_init(>kick_notifier, 0);
@@ -279,6 +300,7 @@ VhostShadowVirtqueue *vhost_shadow_vq_new(struct vhost_dev 
*dev, int idx)
 goto err_init_call_notifier;
 }
 
+vring_init(>vring, num, svq->descs, VRING_DESC_ALIGN_SIZE);
 svq->vq = virtio_get_queue(dev->vdev, vq_idx);
 svq->vdev = dev->vdev;
 event_notifier_set_handler(>call_notifier,
-- 
2.27.0




[RFC v2 11/13] vhost: Shadow virtqueue buffers forwarding

2021-03-15 Thread Eugenio Pérez
Initial version of shadow virtqueue that actually forward buffers.

It reuses the VirtQueue code for the device part. The driver part is
based on Linux's virtio_ring driver, but with stripped functionality
and optimizations so it's easier to review.

These will be added in later commits.

Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost-shadow-virtqueue.c | 212 +++--
 hw/virtio/vhost.c  | 113 ++-
 2 files changed, 312 insertions(+), 13 deletions(-)

diff --git a/hw/virtio/vhost-shadow-virtqueue.c 
b/hw/virtio/vhost-shadow-virtqueue.c
index 1460d1d5d1..68ed0f2740 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -9,6 +9,7 @@
 
 #include "hw/virtio/vhost-shadow-virtqueue.h"
 #include "hw/virtio/vhost.h"
+#include "hw/virtio/virtio-access.h"
 
 #include "standard-headers/linux/vhost_types.h"
 
@@ -55,11 +56,96 @@ typedef struct VhostShadowVirtqueue {
 /* Virtio device */
 VirtIODevice *vdev;
 
+/* Map for returning guest's descriptors */
+VirtQueueElement **ring_id_maps;
+
+/* Next head to expose to device */
+uint16_t avail_idx_shadow;
+
+/* Next free descriptor */
+uint16_t free_head;
+
+/* Last seen used idx */
+uint16_t shadow_used_idx;
+
+/* Next head to consume from device */
+uint16_t used_idx;
+
 /* Descriptors copied from guest */
 vring_desc_t descs[];
 } VhostShadowVirtqueue;
 
-/* Forward guest notifications */
+static void vhost_vring_write_descs(VhostShadowVirtqueue *svq,
+const struct iovec *iovec,
+size_t num, bool more_descs, bool write)
+{
+uint16_t i = svq->free_head, last = svq->free_head;
+unsigned n;
+uint16_t flags = write ? virtio_tswap16(svq->vdev, VRING_DESC_F_WRITE) : 0;
+vring_desc_t *descs = svq->vring.desc;
+
+if (num == 0) {
+return;
+}
+
+for (n = 0; n < num; n++) {
+if (more_descs || (n + 1 < num)) {
+descs[i].flags = flags | virtio_tswap16(svq->vdev,
+VRING_DESC_F_NEXT);
+} else {
+descs[i].flags = flags;
+}
+descs[i].addr = virtio_tswap64(svq->vdev, (hwaddr)iovec[n].iov_base);
+descs[i].len = virtio_tswap32(svq->vdev, iovec[n].iov_len);
+
+last = i;
+i = virtio_tswap16(svq->vdev, descs[i].next);
+}
+
+svq->free_head = virtio_tswap16(svq->vdev, descs[last].next);
+}
+
+static unsigned vhost_shadow_vq_add_split(VhostShadowVirtqueue *svq,
+  VirtQueueElement *elem)
+{
+int head;
+unsigned avail_idx;
+vring_avail_t *avail = svq->vring.avail;
+
+head = svq->free_head;
+
+/* We need some descriptors here */
+assert(elem->out_num || elem->in_num);
+
+vhost_vring_write_descs(svq, elem->out_sg, elem->out_num,
+elem->in_num > 0, false);
+vhost_vring_write_descs(svq, elem->in_sg, elem->in_num, false, true);
+
+/*
+ * Put entry in available array (but don't update avail->idx until they
+ * do sync).
+ */
+avail_idx = svq->avail_idx_shadow & (svq->vring.num - 1);
+avail->ring[avail_idx] = virtio_tswap16(svq->vdev, head);
+svq->avail_idx_shadow++;
+
+/* Expose descriptors to device */
+smp_wmb();
+avail->idx = virtio_tswap16(svq->vdev, svq->avail_idx_shadow);
+
+return head;
+
+}
+
+static void vhost_shadow_vq_add(VhostShadowVirtqueue *svq,
+VirtQueueElement *elem)
+{
+unsigned qemu_head = vhost_shadow_vq_add_split(svq, elem);
+
+svq->ring_id_maps[qemu_head] = elem;
+}
+
+/* Handle guest->device notifications */
 static void vhost_handle_guest_kick(EventNotifier *n)
 {
 VhostShadowVirtqueue *svq = container_of(n, VhostShadowVirtqueue,
@@ -69,7 +155,72 @@ static void vhost_handle_guest_kick(EventNotifier *n)
 return;
 }
 
-event_notifier_set(>kick_notifier);
+/* Make available as many buffers as possible */
+do {
+if (virtio_queue_get_notification(svq->vq)) {
+/* No more notifications until process all available */
+virtio_queue_set_notification(svq->vq, false);
+}
+
+while (true) {
+VirtQueueElement *elem;
+if (virtio_queue_full(svq->vq)) {
+break;
+}
+
+elem = virtqueue_pop(svq->vq, sizeof(*elem));
+if (!elem) {
+break;
+}
+
+vhost_shadow_vq_add(svq, elem);
+event_notifier_set(>kick_notifier);
+}
+
+virtio_queue_set_notification(svq->vq, true);
+} while (!virtio_queue_empty(svq->vq));
+}
+
+static bool vhost_shadow_vq_more_used(VhostShadowVirtqueue *svq)
+{
+if (svq->used_idx != svq->shadow_used_idx) {
+return true;
+}
+
+/* Get used idx must not be reordered */
+

[RFC v2 09/13] virtio: Add virtio_queue_full

2021-03-15 Thread Eugenio Pérez
Check if all descriptors of the queue are available. In other words, is
the complete opposite of virtio_queue_empty: If the queue is full, the
driver cannot transfer more buffers to the device until the latter
make some as used.

In Shadow vq this situation happens with the correct guest network
driver, since the rx queue is filled for the device to write. Since
Shadow Virtqueue forward the available ones blindly, it will call the
driver forever for them, reaching the point where no more descriptors
are available.

While a straightforward solution is to keep the count of them in SVQ,
this specific issue is the only need for that counter. Exposing this
check helps to keep the SVQ simpler storing as little status as
possible.

Signed-off-by: Eugenio Pérez 
---
 include/hw/virtio/virtio.h |  2 ++
 hw/virtio/virtio.c | 18 --
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index c2c7cee993..899c5e3506 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -232,6 +232,8 @@ int virtio_queue_ready(VirtQueue *vq);
 
 int virtio_queue_empty(VirtQueue *vq);
 
+bool virtio_queue_full(const VirtQueue *vq);
+
 /* Host binding interface.  */
 
 uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr);
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index a86b3f9c26..e9a4d9ffae 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -670,6 +670,20 @@ int virtio_queue_empty(VirtQueue *vq)
 }
 }
 
+/*
+ * virtio_queue_full:
+ * @vq The #VirtQueue
+ *
+ * Check if all descriptors of the queue are available. In other words, is the
+ * complete opposite of virtio_queue_empty: If the queue is full, the driver
+ * cannot transfer more buffers to the device until the latter make some as
+ * used.
+ */
+bool virtio_queue_full(const VirtQueue *vq)
+{
+return vq->inuse >= vq->vring.num;
+}
+
 static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem,
unsigned int len)
 {
@@ -1439,7 +1453,7 @@ static void *virtqueue_split_pop(VirtQueue *vq, size_t sz)
 
 max = vq->vring.num;
 
-if (vq->inuse >= vq->vring.num) {
+if (unlikely(virtio_queue_full(vq))) {
 virtio_error(vdev, "Virtqueue size exceeded");
 goto done;
 }
@@ -1574,7 +1588,7 @@ static void *virtqueue_packed_pop(VirtQueue *vq, size_t 
sz)
 
 max = vq->vring.num;
 
-if (vq->inuse >= vq->vring.num) {
+if (unlikely(virtio_queue_full(vq))) {
 virtio_error(vdev, "Virtqueue size exceeded");
 goto done;
 }
-- 
2.27.0




[RFC v2 06/13] vhost: Route host->guest notification through shadow virtqueue

2021-03-15 Thread Eugenio Pérez
On one hand it uses a mutex to synchronize guest masking with SVQ start
and stop, because otherwise guest mask could race with the SVQ
stop code, sending an incorrect call notifier to vhost device. This
would prevent further communication.

On the other hand it needs to add an event to synchronize guest
unmasking with call handling. Not doing that way could cause the guest
to receive notifications after its unmask call. This could be done
through the mutex but the event solution is cheaper for the buffer
forwarding.

Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost-shadow-virtqueue.h |   3 +
 include/hw/virtio/vhost.h  |   1 +
 hw/virtio/vhost-shadow-virtqueue.c | 127 +
 hw/virtio/vhost.c  |  29 ++-
 4 files changed, 157 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/vhost-shadow-virtqueue.h 
b/hw/virtio/vhost-shadow-virtqueue.h
index c891c6510d..2ca4b92b12 100644
--- a/hw/virtio/vhost-shadow-virtqueue.h
+++ b/hw/virtio/vhost-shadow-virtqueue.h
@@ -17,6 +17,9 @@
 
 typedef struct VhostShadowVirtqueue VhostShadowVirtqueue;
 
+void vhost_shadow_vq_mask(VhostShadowVirtqueue *svq, EventNotifier *masked);
+void vhost_shadow_vq_unmask(VhostShadowVirtqueue *svq);
+
 bool vhost_shadow_vq_start(struct vhost_dev *dev,
unsigned idx,
VhostShadowVirtqueue *svq);
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 7ffdf9aea0..2f556bd3d5 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -29,6 +29,7 @@ struct vhost_virtqueue {
 unsigned long long used_phys;
 unsigned used_size;
 bool notifier_is_masked;
+QemuRecMutex masked_mutex;
 EventNotifier masked_notifier;
 struct vhost_dev *dev;
 };
diff --git a/hw/virtio/vhost-shadow-virtqueue.c 
b/hw/virtio/vhost-shadow-virtqueue.c
index 3e43399e9c..8f6ffa729a 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -32,8 +32,22 @@ typedef struct VhostShadowVirtqueue {
  */
 EventNotifier host_notifier;
 
+/* (Possible) masked notifier */
+struct {
+EventNotifier *n;
+
+/*
+ * Event to confirm unmasking.
+ * set when the masked notifier has no uses
+ */
+QemuEvent is_free;
+} masked_notifier;
+
 /* Virtio queue shadowing */
 VirtQueue *vq;
+
+/* Virtio device */
+VirtIODevice *vdev;
 } VhostShadowVirtqueue;
 
 /* Forward guest notifications */
@@ -49,6 +63,70 @@ static void vhost_handle_guest_kick(EventNotifier *n)
 event_notifier_set(>kick_notifier);
 }
 
+/* Forward vhost notifications */
+static void vhost_shadow_vq_handle_call_no_test(EventNotifier *n)
+{
+VhostShadowVirtqueue *svq = container_of(n, VhostShadowVirtqueue,
+ call_notifier);
+EventNotifier *masked_notifier;
+
+/* Signal start of using masked notifier */
+qemu_event_reset(>masked_notifier.is_free);
+masked_notifier = qatomic_load_acquire(>masked_notifier.n);
+if (!masked_notifier) {
+qemu_event_set(>masked_notifier.is_free);
+}
+
+if (!masked_notifier) {
+unsigned n = virtio_get_queue_index(svq->vq);
+virtio_queue_invalidate_signalled_used(svq->vdev, n);
+virtio_notify_irqfd(svq->vdev, svq->vq);
+} else {
+event_notifier_set(svq->masked_notifier.n);
+}
+
+if (masked_notifier) {
+/* Signal not using it anymore */
+qemu_event_set(>masked_notifier.is_free);
+}
+}
+
+static void vhost_shadow_vq_handle_call(EventNotifier *n)
+{
+
+if (likely(event_notifier_test_and_clear(n))) {
+vhost_shadow_vq_handle_call_no_test(n);
+}
+}
+
+/*
+ * Mask the shadow virtqueue.
+ *
+ * It can be called from a guest masking vmexit or shadow virtqueue start
+ * through QMP.
+ *
+ * @vq Shadow virtqueue
+ * @masked Masked notifier to signal instead of guest
+ */
+void vhost_shadow_vq_mask(VhostShadowVirtqueue *svq, EventNotifier *masked)
+{
+qatomic_store_release(>masked_notifier.n, masked);
+}
+
+/*
+ * Unmask the shadow virtqueue.
+ *
+ * It can be called from a guest unmasking vmexit or shadow virtqueue start
+ * through QMP.
+ *
+ * @vq Shadow virtqueue
+ */
+void vhost_shadow_vq_unmask(VhostShadowVirtqueue *svq)
+{
+qatomic_store_release(>masked_notifier.n, NULL);
+qemu_event_wait(>masked_notifier.is_free);
+}
+
 /*
  * Restore the vhost guest to host notifier, i.e., disables svq effect.
  */
@@ -103,8 +181,39 @@ bool vhost_shadow_vq_start(struct vhost_dev *dev,
 goto err_set_vring_kick;
 }
 
+/* Set vhost call */
+file.fd = event_notifier_get_fd(>call_notifier),
+r = dev->vhost_ops->vhost_set_vring_call(dev, );
+if (unlikely(r != 0)) {
+error_report("Couldn't set call fd: %s", strerror(errno));
+goto err_set_vring_call;
+}
+
+
+/*
+ * Lock to avoid a race condition between guest setting masked 

  1   2   3   4   5   6   >