Re: [PATCH 07/26] target/avr: Mark some helpers noreturn

2021-06-20 Thread Michael Rolnik
Reviewed-by: Michael Rolnik 


On Mon, Jun 21, 2021 at 4:34 AM Richard Henderson <
richard.hender...@linaro.org> wrote:

> All of these helpers end with cpu_loop_exit.
>
> Cc: Michael Rolnik 
> Signed-off-by: Richard Henderson 
> ---
>  target/avr/helper.h | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/target/avr/helper.h b/target/avr/helper.h
> index 8e1ae7fda0..4d02e648fa 100644
> --- a/target/avr/helper.h
> +++ b/target/avr/helper.h
> @@ -19,10 +19,10 @@
>   */
>
>  DEF_HELPER_1(wdr, void, env)
> -DEF_HELPER_1(debug, void, env)
> -DEF_HELPER_1(break, void, env)
> -DEF_HELPER_1(sleep, void, env)
> -DEF_HELPER_1(unsupported, void, env)
> +DEF_HELPER_1(debug, noreturn, env)
> +DEF_HELPER_1(break, noreturn, env)
> +DEF_HELPER_1(sleep, noreturn, env)
> +DEF_HELPER_1(unsupported, noreturn, env)
>  DEF_HELPER_3(outb, void, env, i32, i32)
>  DEF_HELPER_2(inb, tl, env, i32)
>  DEF_HELPER_3(fullwr, void, env, i32, i32)
> --
> 2.25.1
>
>

-- 
Best Regards,
Michael Rolnik


Re: [PATCH v2 3/3] target/avr: Convert to TranslatorOps

2021-06-20 Thread Michael Rolnik
Reviewed-by: Michael Rolnik 
Tested-by: Michael Rolnik 

On Mon, Jun 21, 2021 at 12:50 AM Richard Henderson <
richard.hender...@linaro.org> wrote:

> Signed-off-by: Richard Henderson 
> ---
>  target/avr/translate.c | 234 ++---
>  1 file changed, 128 insertions(+), 106 deletions(-)
>
> diff --git a/target/avr/translate.c b/target/avr/translate.c
> index 66e9882422..c06ce45bc7 100644
> --- a/target/avr/translate.c
> +++ b/target/avr/translate.c
> @@ -2897,113 +2897,131 @@ static bool canonicalize_skip(DisasContext *ctx)
>  return true;
>  }
>
> -void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int
> max_insns)
> +static void gen_breakpoint(DisasContext *ctx)
>  {
> +canonicalize_skip(ctx);
> +tcg_gen_movi_tl(cpu_pc, ctx->npc);
> +gen_helper_debug(cpu_env);
> +ctx->base.is_jmp = DISAS_NORETURN;
> +}
> +
> +static void avr_tr_init_disas_context(DisasContextBase *dcbase, CPUState
> *cs)
> +{
> +DisasContext *ctx = container_of(dcbase, DisasContext, base);
>  CPUAVRState *env = cs->env_ptr;
> -DisasContext ctx1 = {
> -.base.tb = tb,
> -.base.is_jmp = DISAS_NEXT,
> -.base.pc_first = tb->pc,
> -.base.pc_next = tb->pc,
> -.base.singlestep_enabled = cs->singlestep_enabled,
> -.cs = cs,
> -.env = env,
> -.memidx = 0,
> -.skip_cond = TCG_COND_NEVER,
> -};
> -DisasContext *ctx = 
> -target_ulong pc_start = tb->pc / 2;
> -int num_insns = 0;
> +uint32_t tb_flags = ctx->base.tb->flags;
>
> -if (tb->flags & TB_FLAGS_FULL_ACCESS) {
> -/*
> - * This flag is set by ST/LD instruction we will regenerate it
> ONLY
> - * with mem/cpu memory access instead of mem access
> - */
> -max_insns = 1;
> -}
> -if (ctx->base.singlestep_enabled) {
> -max_insns = 1;
> -}
> +ctx->cs = cs;
> +ctx->env = env;
> +ctx->npc = ctx->base.pc_first / 2;
>
> -gen_tb_start(tb);
> -
> -ctx->npc = pc_start;
> -if (tb->flags & TB_FLAGS_SKIP) {
> +ctx->skip_cond = TCG_COND_NEVER;
> +if (tb_flags & TB_FLAGS_SKIP) {
>  ctx->skip_cond = TCG_COND_ALWAYS;
>  ctx->skip_var0 = cpu_skip;
>  }
>
> -do {
> -TCGLabel *skip_label = NULL;
> -
> -/* translate current instruction */
> -tcg_gen_insn_start(ctx->npc);
> -num_insns++;
> -
> +if (tb_flags & TB_FLAGS_FULL_ACCESS) {
>  /*
> - * this is due to some strange GDB behavior
> - * let's assume main has address 0x100
> - * b main   - sets breakpoint at address 0x0100 (code)
> - * b *0x100 - sets breakpoint at address 0x00800100 (data)
> + * This flag is set by ST/LD instruction we will regenerate it
> ONLY
> + * with mem/cpu memory access instead of mem access
>   */
> -if (unlikely(!ctx->base.singlestep_enabled &&
> -(cpu_breakpoint_test(cs, OFFSET_CODE + ctx->npc * 2, BP_ANY)
> ||
> - cpu_breakpoint_test(cs, OFFSET_DATA + ctx->npc * 2,
> BP_ANY {
> -canonicalize_skip(ctx);
> -tcg_gen_movi_tl(cpu_pc, ctx->npc);
> -gen_helper_debug(cpu_env);
> -goto done_generating;
> -}
> +ctx->base.max_insns = 1;
> +}
> +}
>
> -/* Conditionally skip the next instruction, if indicated.  */
> -if (ctx->skip_cond != TCG_COND_NEVER) {
> -skip_label = gen_new_label();
> -if (ctx->skip_var0 == cpu_skip) {
> -/*
> - * Copy cpu_skip so that we may zero it before the branch.
> - * This ensures that cpu_skip is non-zero after the label
> - * if and only if the skipped insn itself sets a skip.
> - */
> -ctx->free_skip_var0 = true;
> -ctx->skip_var0 = tcg_temp_new();
> -tcg_gen_mov_tl(ctx->skip_var0, cpu_skip);
> -tcg_gen_movi_tl(cpu_skip, 0);
> -}
> -if (ctx->skip_var1 == NULL) {
> -tcg_gen_brcondi_tl(ctx->skip_cond, ctx->skip_var0,
> -   0, skip_label);
> -} else {
> -tcg_gen_brcond_tl(ctx->skip_cond, ctx->skip_var0,
> -  ctx->skip_var1, skip_label);
> -ctx->skip_var1 = NULL;
> -}
> -if (ctx->free_skip_var0) {
> -tcg_temp_free(ctx->skip_var0);
> -ctx->free_skip_var0 = false;
> -}
> -ctx->skip_cond = TCG_COND_NEVER;
> -ctx->skip_var0 = NULL;
> -}
> +static void avr_tr_tb_start(DisasContextBase *db, CPUState *cs)
> +{
> +}
>
> -translate(ctx);
> +static void avr_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
> +{
> +DisasContext *ctx = container_of(dcbase, DisasContext, base);
>
> -if (skip_label) {
> 

RE: [PATCH v2] ui/gtk: Allow user to select monitor number to display qemu in full screen through new gtk display option

2021-06-20 Thread Khor, Swee Aun
Hi Markus,
Thanks for include Graphic maintainer and the coding style comments.  Yes, 
sweeaun is my name 

For  "full screen" be "full-screen" or even "fullscreen"? These 3 words have 
been being used in QEMU repo, but full-screen mostly used for variable/member.
Thus, I felt full screen should be fine to be used as documentation. What do 
you think?
Example:
"FullScreen" in hw/arm/nseries.c
"toggle full screen" in softmmu/vl.c 
""full-screen" in /qemu-options.hx

For subsequence questions:
" Your new option argument seems to count monitors from 1, while GTK counts 
them from zero.  Why the difference?"
sweeaun: It is due to gtk_window_fullscreen_on_monitor monitor index is started 
from zero. I am not using zero as starting index of new option argument to make 
easier for user. Example, if there is 2 monitors, then argument option can be 
monitor 1 or 2. Last number will matched with total monitors which can avoid 
confusion for user. That is my thought.   

"Your documentation states that @monitor applies only "in full screen", but 
this code is not guarded by if (opts->full_screen).  Why is that okay?"
sweeaun: It doesn’t need to be guarded by if (opts->full_screen), as 
gtk_window_fullscreen_on_monitor will enable the full screen by itself.  

"From gdk_display_get_n_monitors()'s documentation: "The returned number is 
valid until the next emission of the “monitor-added” or “monitor-removed” 
signal."  This suggests monitors can come and go at any time.  If they can, 
what happens when the monitor we're trying to use here has gone away since we 
called gdk_display_get_n_monitors()?"
sweeaun: Based on my observation, when specific monitor device disconnected 
after QEMU launched on it, QEMU application will not be visible but QEMU 
application still running and screen framebuffer size is not being changed at 
all. QEMU application will be visible once you connect back the monitor. 
Yes the return number from gdk_display_get_n_monitors() will minus 1 compared 
to previous once 1 monitor has been disconnected. 

Regards,
SweeAun

-Original Message-
From: Markus Armbruster  
Sent: Friday, June 18, 2021 7:07 PM
To: Khor, Swee Aun 
Cc: qemu-devel@nongnu.org; Romli, Khairul Anuar 
; ebl...@redhat.com; Kasireddy, Vivek 
; Gerd Hoffmann 
Subject: Re: [PATCH v2] ui/gtk: Allow user to select monitor number to display 
qemu in full screen through new gtk display option

You neglected to cc: the Graphics maintainer.  I'm doing that for you now.

sweeaun  writes:

>  -display gtk,monitor=
>
> Signed-off-by: sweeaun 

Your commit message is formatted badly.  What about this:

ui/gtk: New -display gtk parameter 'monitor'.

This lets the user select monitor number to display QEMU in full
screen with -display gtk,monitor=.

Furthermore, you're Signed-off-by line may be off.  It should be of the form

Signed-off-by: REAL NAME 

Is "sweeaun" your real name?

> ---
>  qapi/ui.json|  4 +++-
>  qemu-options.hx |  2 +-
>  ui/gtk.c| 15 +++
>  3 files changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/qapi/ui.json b/qapi/ui.json index 1052ca9c38..1616f3ffbd 
> 100644
> --- a/qapi/ui.json
> +++ b/qapi/ui.json
> @@ -1035,13 +1035,15 @@
>  #   assuming the guest will resize the display to match
>  #   the window size then.  Otherwise it defaults to "off".
>  #   Since 3.1
> +# @monitor: Monitor number to display qemu in full screen.

We spell it QEMU.

Should "full screen" be "full-screen" or even "fullscreen"?

>  #
>  # Since: 2.12
>  #
>  ##
>  { 'struct'  : 'DisplayGTK',
>'data': { '*grab-on-hover' : 'bool',
> -'*zoom-to-fit'   : 'bool'  } }
> +'*zoom-to-fit'   : 'bool',
> +'*monitor' : 'int' } }

Best to make your addition "blend in" like this

   { 'struct'  : 'DisplayGTK',
 'data': { '*grab-on-hover' : 'bool',
   '*zoom-to-fit'   : 'bool',
   '*monitor'   : 'int' } }

>  
>  ##
>  # @DisplayEGLHeadless:
> diff --git a/qemu-options.hx b/qemu-options.hx index 
> 14258784b3..e4b89b6a72 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -1787,7 +1787,7 @@ DEF("display", HAS_ARG, QEMU_OPTION_display,
>  "[,window_close=on|off][,gl=on|core|es|off]\n"
>  #endif
>  #if defined(CONFIG_GTK)
> -"-display gtk[,grab_on_hover=on|off][,gl=on|off]|\n"
> +"-display gtk[,grab_on_hover=on|off][,gl=on|off][,monitor=]\n"
>  #endif
>  #if defined(CONFIG_VNC)
>  "-display vnc=[,]\n"
> diff --git a/ui/gtk.c b/ui/gtk.c
> index 98046f577b..84da126611 100644
> --- a/ui/gtk.c
> +++ b/ui/gtk.c
> @@ -2268,6 +2268,21 @@ static void gtk_display_init(DisplayState *ds, 
> DisplayOptions *opts)
>  gtk_menu_item_activate(GTK_MENU_ITEM(s->grab_on_hover_item));
>  }
>  gd_clipboard_init(s);
> +
> +if (opts->u.gtk.has_monitor) {
> +int n_monitor;
> +n_monitor = 

[Bug 1914117] Re: Short files returned via FTP on Qemu with various architectures and OSes

2021-06-20 Thread Thomas Huth
** Changed in: qemu
   Status: Incomplete => In Progress

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

Title:
  Short files returned via FTP on Qemu with various architectures and
  OSes

Status in QEMU:
  In Progress

Bug description:
  
  Qemu 5.2 on Mac OS X Big Sur.

  I originally thought that it might be caused by the home-brew version of 
Qemu, but this evening I have removed the brew edition and compiled from 
scratch (using Ninja & Xcode compiler). 
  Still getting the same problem,.

  On the following architectures: 
  arm64, amd64 and sometimes i386 running NetBSD host OS; 
  i386 running OpenBSD host OS:

  I have seen a consistent problem with FTP returning short files. The
  file will be a couple of bytes too short. I do not believe this is a
  problem with the OS. Downloading the perl source code from CPAN does
  not work properly, nor does downloading bind from isc. I've tried this
  on different architectures as above.

  (Qemu 4.2 on Ubuntu/x86_64 with NetBSD/i386 seems to function fine. My
  gut feel is there is something not right on the Mac OS version of Qemu
  or a bug in 5.2 - obviously in the network layer somewhere. If you
  have anything you want me to try, please let me know - happy to help
  get a resolution.)

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



Re: [PATCH 00/18] vhost-vDPA multiqueue

2021-06-20 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20210621041650.5826-1-jasow...@redhat.com/



Hi,

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

Type: series
Message-id: 20210621041650.5826-1-jasow...@redhat.com
Subject: [PATCH 00/18] vhost-vDPA multiqueue

=== 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/20210621041650.5826-1-jasow...@redhat.com -> 
patchew/20210621041650.5826-1-jasow...@redhat.com
Switched to a new branch 'test'
f8fa9a3 vhost-vdpa: multiqueue support
8f59a43 virtio-net: vhost control virtqueue support
ec75ba0 virito-net: use "qps" instead of "queues" when possible
2bd3467 vhost-net: control virtqueue support
8276601 net: introduce control client
816e0a6 vhost-vdpa: let net_vhost_vdpa_init() returns NetClientState *
3033ddd vhost-vdpa: prepare for the multiqueue support
d3460f2 vhost-vdpa: classify one time request
3f6db79 vhost-vdpa: open device fd in net_init_vhost_vdpa()
7596feb vhost-vdpa: remove the unncessary queue_index assignment
ce7d8de vhost-vdpa: fix the wrong assertion in vhost_vdpa_init()
a8bc70a vhost-vdpa: tweak the error label in vhost_vdpa_add()
263c865 vhost-vdpa: fix leaking of vhost_net in vhost_vdpa_add()
32b4c0e vhost-vdpa: don't cleanup twice in vhost_vdpa_add()
fbc405c vhost-vdpa: remove the unnecessary check in vhost_vdpa_add()
7a12106 vhost_net: do not assume nvqs is always 2
1a9f738 vhost: use unsigned int for nvqs
5dff074 vhost_net: remove the meaningless assignment in vhost_net_start_one()

=== OUTPUT BEGIN ===
1/18 Checking commit 5dff074a8095 (vhost_net: remove the meaningless assignment 
in vhost_net_start_one())
2/18 Checking commit 1a9f7380e8f0 (vhost: use unsigned int for nvqs)
3/18 Checking commit 7a12106db152 (vhost_net: do not assume nvqs is always 2)
4/18 Checking commit fbc405c2ccec (vhost-vdpa: remove the unnecessary check in 
vhost_vdpa_add())
5/18 Checking commit 32b4c0e1f95c (vhost-vdpa: don't cleanup twice in 
vhost_vdpa_add())
6/18 Checking commit 263c8652e706 (vhost-vdpa: fix leaking of vhost_net in 
vhost_vdpa_add())
7/18 Checking commit a8bc70a72c41 (vhost-vdpa: tweak the error label in 
vhost_vdpa_add())
8/18 Checking commit ce7d8de36520 (vhost-vdpa: fix the wrong assertion in 
vhost_vdpa_init())
9/18 Checking commit 7596feb74e23 (vhost-vdpa: remove the unncessary 
queue_index assignment)
10/18 Checking commit 3f6db79bbb54 (vhost-vdpa: open device fd in 
net_init_vhost_vdpa())
11/18 Checking commit d3460f2b8886 (vhost-vdpa: classify one time request)
12/18 Checking commit 3033ddd3df9e (vhost-vdpa: prepare for the multiqueue 
support)
13/18 Checking commit 816e0a62ed3b (vhost-vdpa: let net_vhost_vdpa_init() 
returns NetClientState *)
14/18 Checking commit 8276601ad80d (net: introduce control client)
15/18 Checking commit 2bd3467c7183 (vhost-net: control virtqueue support)
16/18 Checking commit ec75ba0c5758 (virito-net: use "qps" instead of "queues" 
when possible)
WARNING: Block comments use a leading /* on a separate line
#294: FILE: hw/net/virtio-net.c:1420:
+/* stop the backend before changing the number of qps to avoid handling a

total: 0 errors, 1 warnings, 457 lines checked

Patch 16/18 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
17/18 Checking commit 8f59a439ccf2 (virtio-net: vhost control virtqueue support)
WARNING: Block comments use a leading /* on a separate line
#55: FILE: hw/net/virtio-net.c:3373:
+/* Figure out the datapath queue pairs since the bakcend could

total: 0 errors, 1 warnings, 51 lines checked

Patch 17/18 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
18/18 Checking commit f8fa9a3e2c56 (vhost-vdpa: multiqueue support)
ERROR: braces {} are necessary for all arms of this statement
#176: FILE: net/vhost-vdpa.c:284:
+if (!ncs[i])
[...]

ERROR: braces {} are necessary for all arms of this statement
#183: FILE: net/vhost-vdpa.c:291:
+if (!nc)
[...]

total: 2 errors, 0 warnings, 165 lines checked

Patch 18/18 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/20210621041650.5826-1-jasow...@redhat.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

[Bug 717929] Re: Serial communication between VMs problematic

2021-06-20 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

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

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

Title:
  Serial communication between VMs problematic

Status in QEMU:
  Expired

Bug description:
  Hello,

  I want to setup serial communication between VM hosts but I have found
  it quite difficult...:

  ...because when trying unix sockets:

  - host A has serial device as unix socket (bind)
  - host B has serial device as client of unix socket
  - host A is down thus not unix socket does exist
  - host B can't be started because cannot read the socket:

  error: Failed to start domain opd1s02
  error: internal error Process exited while reading console log output: char 
device redirected to /dev/pts/0
  connect(unix:/tmp/test.sock): Connection refused
  chardev: opening backend "socket" failed

  Can that work like the cable is not plugged in? So host B can start
  and when the socket would exist it would connect to it?

  ...and when using pty and host device combination one cannot predict
  pty device under /dev/pts, it would be nice if would be possible to
  define exact device name.

  Tested on Fedora 14.

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



[Bug 1090602] Re: RFE: Allow specifying usb-host device by serial number

2021-06-20 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

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

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

Title:
  RFE: Allow specifying usb-host device by serial number

Status in QEMU:
  Expired

Bug description:
  Currently you can pass through a host USB device to the guest like

-device usb-host,vendorid=0x1234,productid=0x5678

  Which is all well and good, but has problems if you are trying to
  assign to identical USB devices to the same guest.

  It would be useful if there was an additional option that allow
  matching against the device's serial number, which should allow
  differentiating between two devices with the same product+vendor.

  This was originally filed at
  https://bugzilla.redhat.com/show_bug.cgi?id=640332

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



[Bug 1272252] Re: qemu-img ftp/http convert

2021-06-20 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

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

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

Title:
  qemu-img ftp/http convert

Status in QEMU:
  Expired

Bug description:
  Converting images with ftp or http as source could be done a lot
  faster. The way it works now (qemu 1.7.50) is significantly slower
  than the optimal way.

  FTP - how it works now
  1. Connect and login to ftp-server. Ask for size of file.
  2. Get a chunk of data using rest+retr
  3. Goto step 1 again in a loop until all data is retrieved

  FTP - better solution
  1. Connect and login to ftp-server. Dont ask for size of file.
  2. Retrieve all remaining data
  3. Goto step 1 again if disconnected/io error (max NN errors etc)

  
  Http - how it works now
  1. Connect to webserver and ask for size of file / http HEAD.
  2. Get a chunk of data using http Range.
  3. Goto step 1 again in a loop until all data is retrieved.

  Http - better solution
  1. Connect to webserver.
  2. Retrieve all remaining data.
  3. Goto step 1 again if disconnected/io error (max NN errors).

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



[Bug 1309034] Re: A way not to grab keyboards or mice

2021-06-20 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

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

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

Title:
  A way not to grab keyboards or mice

Status in QEMU:
  Expired

Bug description:
  I set up the window manager to move windows with Alt-Btn1, and to
  iconify windows with Shift-Btn1. But since qemu grabs keyboards and
  mice, I can't move or iconify the qemu window.

  I tried not to grab anything, by inserting return, just beginnig of
  ui/sdl.c:sdl_grab_start() as follows:

  static void sdl_grab_start(void)
  {
  return;
  /*

  It is comfortable. I'm glad if you make a way not to grab.
  Environment variables, options, etc are welcome.

  Current command line is:
  QEMU_AUDIO_DRV=pa /usr/local/bin/qemu-system-x86_64 -enable-kvm -hda 
/dosc/win8_x64.img -soundhw hda -boot c -m 2G -cpu Nehalem,+sep -usb -usbdevice 
tablet -display sdl -rtc base=localtime

  qemu version is:
  luna:linux % qemu-system-x86_64 --version
  QEMU emulator version 1.7.93, Copyright (c) 2003-2008 Fabrice Bellard
  luna:linux % 

  Host: slackware64 14.1
  Host Environment: xfce4 / sawfish
  Guest: Windows 8.1 x64

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



[Bug 1502884] Re: Super important feature req: QEMU VNC server: Introduce a keyboard "norepeat" option!

2021-06-20 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

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

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

Title:
  Super important feature req: QEMU VNC server: Introduce a keyboard
  "norepeat" option!

Status in QEMU:
  Expired

Bug description:
  Hi,

  A big issue when using QEMU's VNC server (VNC KVM) is that, when
  there's a network lag, unintended keypresses go through to the QEMU
  guest VM.

  This is frequently "enter" keypresses, causing all kinds of unintended
  consequences in the VM. So basically it's extremely dangerous.

  This is because the VNC protocol's keyboard interaction is implemented
  in terms of key down - key up events, making the server's keyboard
  autorepeat kick in when it should not.

  
  For this reason, it would be great if QEMU's VNC server part would be 
enhanced with an option such that when a VNC protocol key down is received, 
then locally that is treated as one single keypress only (I don't know how that 
should be implemented but I guess either as an immediate key down - key up 
sequence locally, or key down + key up after say 0.05 seconds), instead of 
waiting for the key up event from the VNC client.

  Thanks!

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



[Bug 1724590] Re: Usermode networking hostfwd only listens on IPv4

2021-06-20 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

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

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

Title:
  Usermode networking hostfwd only listens on IPv4

Status in QEMU:
  Expired

Bug description:
  When forwarding ports in usermode networking (-net user,hostfwd=),
  QEMU binds to IPv4 only. Therefore, connecting to the port over IPv6
  results in 'connection refused'.

  I experienced this in QEMU 2.10.1, but it looks to still be present in
  the current master (861cd431c99e56ddb5953ca1da164a9c32b477ca), since
  slirp_hostfwd in net/slirp.c uses in_addr instead of in6_addr.

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



[Bug 1751264] Re: qemu-img convert issue in a tmpfs partition

2021-06-20 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

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

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

Title:
  qemu-img convert issue in a tmpfs partition

Status in QEMU:
  Expired

Bug description:
  qemu-img convert command is slow when the file to convert is located
  in a tmpfs formatted partition.

  v2.1.0 on debian/jessie x64, ext4: 10m14s
  v2.1.0 on debian/jessie x64, tmpfs: 10m15s

  v2.1.0 on debian/stretch x64, ext4: 11m9s
  v2.1.0 on debian/stretch x64, tmpfs: 10m21.362s

  v2.8.0 on debian/jessie x64, ext4: 10m21s
  v2.8.0 on debian/jessie x64, tmpfs: Too long (50min+)

  v2.8.0 on debian/stretch x64, ext4: 10m42s
  v2.8.0 on debian/stretch x64, tmpfs: Too long (50min+)

  It seems that the issue is caused by this commit :
  https://github.com/qemu/qemu/commit/690c7301600162421b928c7f26fd488fd8fa464e

  In order to reproduce this bug :

  1/ mount a tmpfs partition : mount -t tmpfs tmpfs /tmp
  2/ get a vmdk file (we used a 15GB image) and put it on /tmp
  3/ run the 'qemu-img convert -O qcow2 /tmp/file.vmdk /path/to/destination' 
command

  When we trace the process, we can see that there's a lseek loop which
  is very slow (compare to outside a tmpfs partition).

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



[Bug 813546] Re: option to disable PS/2 mouse

2021-06-20 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

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

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

Title:
  option to disable PS/2 mouse

Status in QEMU:
  Expired

Bug description:
  Adds an option to disable the PS/2 mouse.

  This is useful to work around bugs in PS/2 drivers in some system or
  testing system without a PS/2 mouse present.

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



[Bug 903365] Re: [feature request] bind nat (-net user) to other interface (like eth0:2)

2021-06-20 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

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

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

Title:
  [feature request] bind nat (-net user) to other interface (like
  eth0:2)

Status in QEMU:
  Expired

Bug description:
  -net user mode is very nice because it does not require any changes in
  host system. However if host system has muplitple IPs You cant use it,
  or even switch to another. Qemu should be able to "bind" to eth0:1
  eth0:2 so that outgoing traffic uses this interface and thus other IP.

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



[Bug 1815009] Re: Qemu evdev multiple guests/host switch

2021-06-20 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

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

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

Title:
  Qemu evdev multiple guests/host switch

Status in QEMU:
  Expired

Bug description:
  Hello,

  Qemu up to version 3.1

  it would be nice if passed through evdev can be switched (using lctrl
  + rctrl) through all running guests configured for evdev passthrough
  and the host. Currently, only the last started guest and host can be
  switched only so the previously started guests can't be controlled.

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



[Bug 1749016] Re: VHDX BAT and Metadata Region Header Required Bit Not Set

2021-06-20 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

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

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

Title:
  VHDX BAT and Metadata Region Header Required Bit Not Set

Status in QEMU:
  Expired

Bug description:
  When converting a VMDK to VHDX the resulting VHDX's Region table has a
  small error. According to the VHDX specification the BAT and Metadata
  entries for the region header required bit should be set to 1.  In a
  VHDX created by qemu-img, this bit is not set.

  See Table 4: Known Region Properties of the VHDX specification.

  The structure format is as following from Structure 4: Region Table
  Entry:

  struct VHDX_REGION_TABLE_ENTRY {
  GUID Guid;
  UINT64 FileOffset;
  UINT32 Length;
  UINT32 Required:1;
  UINT32 Reserved:31;
  }

  The Required bit for VHDX specified BAT and Metadata Regions Required
  bit in the entry is not set as required in the current specification.

  VHDX Region Table in a valid VHDX

  Offset(h)00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
  0x0003   72 65 67 69 AE 8C 6B C6 02 00 00 00 00 00 00 00
  0x00030010   66 77 C2 2D 23 F6 00 42 9D 64 11 5E 9B FD 4A 08
  0x00030020   00 00 30 00 00 00 00 00 00 00 10 00 01 00 00 00  
  0x00030030   06 A2 7C 8B 90 47 9A 4B B8 FE 57 5F 05 0F 88 6E
  0x00030040   00 00 20 00 00 00 00 00 00 00 10 00 01 00 00 00

  VHDX Region Table in a VHDX converted by qemu-img from VMDK

  Offset(h)00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
  0x0003   72 65 67 69 AE 8C 6B C6 02 00 00 00 00 00 00 00
  0x00030010   66 77 C2 2D 23 F6 00 42 9D 64 11 5E 9B FD 4A 08
  0x00030020   00 00 30 00 00 00 00 00 00 00 10 00 00 00 00 00  
  0x00030030   06 A2 7C 8B 90 47 9A 4B B8 FE 57 5F 05 0F 88 6E
  0x00030040   00 00 20 00 00 00 00 00 00 00 10 00 00 00 00 00

  The fist bit at 0x0003002A and 0x0003004A should be set to 1.

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



[Bug 1378407] Re: [feature request] Partition table wrapper for single-filesystem images

2021-06-20 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

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

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

Title:
  [feature request] Partition table wrapper for single-filesystem images

Status in QEMU:
  Expired

Bug description:
  Suppose you have a single filesystem image. It would be nice if QEMU
  could generate a virtual partition table for it and make it available
  to the guest as a partitioned disk. Otherwise you have to use
  workarounds like this:
  
wiki.archlinux.org/index.php/QEMU#Simulate_virtual_disk_with_MBR_using_linear_RAID

  It should be relatively easy to do on top of existing vvfat code.

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



[Bug 1184089] Re: [Feature request] loadvm snapshot as read-only

2021-06-20 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

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

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

Title:
  [Feature request] loadvm snapshot as read-only

Status in QEMU:
  Expired

Bug description:
  There are many ways to take and manage snapshots in QEMU, but one main
  feature that's missing is the ability to 'loadvm' a LIVE snapshot and
  have all future changes redirected to a temporary file.  This would
  effectively be combining the -loadvm and -snapshot switches and make
  the snapshot read-only.  With this feature, users would be provided a
  "sandbox" and be able to start and restart the same live snapshot
  without corrupting the image in doing so.

  I found a lot of discussion about this topic on the mailing list years
  ago, including some patch submissions, but none of the conversations
  panned out.

  http://lists.gnu.org/archive/html/qemu-discuss/2011-10/msg00011.html
  http://copilotco.com/mail-archives/qemu.2008/msg00072.html
  http://web.archiveorange.com/archive/v/1XS1vcusGInZKG2e0ImX
  http://marc.info/?l=qemu-devel=117191084713590

  What would it take for this feature to be added, and can we use the
  patches submitted by Eddie Kohler to enable this feature?

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



[Bug 1801933] Re: default memory parameter too small on x86_64 today

2021-06-20 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

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

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

Title:
  default memory parameter too small on x86_64 today

Status in QEMU:
  Expired

Bug description:
  Launching a centos74 iso VM today does not work anymore on x86_64
  without increasing the size of the memory parameter. For example with
  this command :

  $ /opt/qemu-3.0.0/bin/qemu-system-x86_64 --curses   -enable-kvm -drive
  file=file.dd,index=0,media=disk -drive file=centos-
  x86_64.iso,index=1,media=cdrom

  [3.047614] Failed to execute /init
  [3.048315] Kernel panic - not syncing: No init found.  Try passing init= 
option to kernel. See Linux Documentation/init.txt for guidance.
  [3.049258] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 
3.10.0-693.21.1.el7.x86

  Increasing the size from the default 128MiB to 512MiB let the VM works 
without problem.
  So, ok, it's not a qemu problem, it's more a "User problem" and interface 
problem for me.
  But it push me in the end to launch VirtualBox instead of qemu, because the 
default parameter does not work anymore... And I had no time to investigate why 
it does not work because the message is not visible.
  Debian iso with the same command line for example show a message to tell me 
that there is not enough memory, so it help me to track the real issue behind.

  But... In the end, I think today, the default memory parameter on x86_64 is 
too small and it can lead some people like me to switch to VirtualBox.
  VirtualBox, in the wizard is set by default to 4MiB Ram size, which tell 
you... Ok I need to put more. And, you know that 4MiB is not enough in the end.

  Regards,

  Johann

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



[PATCH 16/18] virito-net: use "qps" instead of "queues" when possible

2021-06-20 Thread Jason Wang
Most of the time, "queues" really means queue pairs. So this patch
switch to use "qps" to avoid confusion.

Signed-off-by: Jason Wang 
---
 hw/net/virtio-net.c| 150 -
 include/hw/virtio/virtio-net.h |   4 +-
 2 files changed, 77 insertions(+), 77 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 614660274c..36bd197087 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -54,7 +54,7 @@
 #define VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE 256
 #define VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE 256
 
-/* for now, only allow larger queues; with virtio-1, guest can downsize */
+/* for now, only allow larger qps; with virtio-1, guest can downsize */
 #define VIRTIO_NET_RX_QUEUE_MIN_SIZE VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE
 #define VIRTIO_NET_TX_QUEUE_MIN_SIZE VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE
 
@@ -131,7 +131,7 @@ static void virtio_net_get_config(VirtIODevice *vdev, 
uint8_t *config)
 int ret = 0;
 memset(, 0 , sizeof(struct virtio_net_config));
 virtio_stw_p(vdev, , n->status);
-virtio_stw_p(vdev, _virtqueue_pairs, n->max_queues);
+virtio_stw_p(vdev, _virtqueue_pairs, n->max_qps);
 virtio_stw_p(vdev, , n->net_conf.mtu);
 memcpy(netcfg.mac, n->mac, ETH_ALEN);
 virtio_stl_p(vdev, , n->net_conf.speed);
@@ -243,7 +243,7 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t 
status)
 {
 VirtIODevice *vdev = VIRTIO_DEVICE(n);
 NetClientState *nc = qemu_get_queue(n->nic);
-int queues = n->multiqueue ? n->max_queues : 1;
+int qps = n->multiqueue ? n->max_qps : 1;
 
 if (!get_vhost_net(nc->peer)) {
 return;
@@ -266,7 +266,7 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t 
status)
 /* Any packets outstanding? Purge them to avoid touching rings
  * when vhost is running.
  */
-for (i = 0;  i < queues; i++) {
+for (i = 0;  i < qps; i++) {
 NetClientState *qnc = qemu_get_subqueue(n->nic, i);
 
 /* Purge both directions: TX and RX. */
@@ -285,14 +285,14 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t 
status)
 }
 
 n->vhost_started = 1;
-r = vhost_net_start(vdev, n->nic->ncs, queues, 0);
+r = vhost_net_start(vdev, n->nic->ncs, qps, 0);
 if (r < 0) {
 error_report("unable to start vhost net: %d: "
  "falling back on userspace virtio", -r);
 n->vhost_started = 0;
 }
 } else {
-vhost_net_stop(vdev, n->nic->ncs, queues, 0);
+vhost_net_stop(vdev, n->nic->ncs, qps, 0);
 n->vhost_started = 0;
 }
 }
@@ -309,11 +309,11 @@ static int virtio_net_set_vnet_endian_one(VirtIODevice 
*vdev,
 }
 
 static bool virtio_net_set_vnet_endian(VirtIODevice *vdev, NetClientState *ncs,
-   int queues, bool enable)
+   int qps, bool enable)
 {
 int i;
 
-for (i = 0; i < queues; i++) {
+for (i = 0; i < qps; i++) {
 if (virtio_net_set_vnet_endian_one(vdev, ncs[i].peer, enable) < 0 &&
 enable) {
 while (--i >= 0) {
@@ -330,7 +330,7 @@ static bool virtio_net_set_vnet_endian(VirtIODevice *vdev, 
NetClientState *ncs,
 static void virtio_net_vnet_endian_status(VirtIONet *n, uint8_t status)
 {
 VirtIODevice *vdev = VIRTIO_DEVICE(n);
-int queues = n->multiqueue ? n->max_queues : 1;
+int qps = n->multiqueue ? n->max_qps : 1;
 
 if (virtio_net_started(n, status)) {
 /* Before using the device, we tell the network backend about the
@@ -339,14 +339,14 @@ static void virtio_net_vnet_endian_status(VirtIONet *n, 
uint8_t status)
  * virtio-net code.
  */
 n->needs_vnet_hdr_swap = virtio_net_set_vnet_endian(vdev, n->nic->ncs,
-queues, true);
+qps, true);
 } else if (virtio_net_started(n, vdev->status)) {
 /* After using the device, we need to reset the network backend to
  * the default (guest native endianness), otherwise the guest may
  * lose network connectivity if it is rebooted into a different
  * endianness.
  */
-virtio_net_set_vnet_endian(vdev, n->nic->ncs, queues, false);
+virtio_net_set_vnet_endian(vdev, n->nic->ncs, qps, false);
 }
 }
 
@@ -368,12 +368,12 @@ static void virtio_net_set_status(struct VirtIODevice 
*vdev, uint8_t status)
 virtio_net_vnet_endian_status(n, status);
 virtio_net_vhost_status(n, status);
 
-for (i = 0; i < n->max_queues; i++) {
+for (i = 0; i < n->max_qps; i++) {
 NetClientState *ncs = qemu_get_subqueue(n->nic, i);
 bool queue_started;
 q = >vqs[i];
 
-if ((!n->multiqueue && i != 0) || i >= n->curr_queues) {
+if ((!n->multiqueue && i != 0) || i >= n->curr_qps) {
 queue_status = 0;
 

[Bug 1719689] Re: [feature request] add flag to treat warnings as errors

2021-06-20 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

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

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

Title:
  [feature request] add flag to treat warnings as errors

Status in QEMU:
  Expired

Bug description:
  Since booting could potentially take a lot of time and warnings are
  likely to indicate that something is wrong, it would be useful to have
  a command line flag which would abort the boot if there are any
  warnings.

  An example might be network configuration. The following output most
  likely indicates that there is something the user has to fix before
  starting and being able to use the guest os.

  Warning: hub port hub0port0 has no peer
  Warning: vlan 0 with no nics
  Warning: netdev hub0port0 has no peer
  Warning: requested NIC (anonymous, model vitrio-net-device) was not created 
(not supported by this machine?)

  Ideally, there would be an option the user could pass which would
  cause qemu to print these warnings then exit, rather than boot the
  kernel.

  Alternatively, or additionally, a dry run option would be helpful for
  the same purpose: making sure qemu get to the booting the kernel stage
  with everything in working order so that you do not have to wait for
  the kernel to boot and then shut down while debugging things like
  networking (things which can be debugged (at least partially) without
  booting, or trying to boot, the guest os).

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



[Bug 1659267] Re: It's not possible to start a VM with a network cable unplugged

2021-06-20 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

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

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

Title:
  It's not possible to start a VM with a network cable unplugged

Status in QEMU:
  Expired

Bug description:
  There should be a command line (sub)option to unplug a network cable.
  While from the monitor interface I can issue:

  set_link virtio-net-pci.0 off

  There's no way to fire a VM from command line with that cable already 
unplugged.
  As an example, virtualbox can do it.

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



[PATCH 17/18] virtio-net: vhost control virtqueue support

2021-06-20 Thread Jason Wang
This patch implements the control virtqueue support for vhost. This
requires virtio-net to figure out the datapath queue pairs and control
virtqueue via is_datapath and pass the number of those two types
of virtqueues to vhost_net_start()/vhost_net_stop().

Signed-off-by: Jason Wang 
---
 hw/net/virtio-net.c| 20 +---
 include/hw/virtio/virtio-net.h |  1 +
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 36bd197087..5074b521cf 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -244,6 +244,7 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t 
status)
 VirtIODevice *vdev = VIRTIO_DEVICE(n);
 NetClientState *nc = qemu_get_queue(n->nic);
 int qps = n->multiqueue ? n->max_qps : 1;
+int cvq = n->max_ncs - n->max_qps;
 
 if (!get_vhost_net(nc->peer)) {
 return;
@@ -285,14 +286,14 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t 
status)
 }
 
 n->vhost_started = 1;
-r = vhost_net_start(vdev, n->nic->ncs, qps, 0);
+r = vhost_net_start(vdev, n->nic->ncs, qps, cvq);
 if (r < 0) {
 error_report("unable to start vhost net: %d: "
  "falling back on userspace virtio", -r);
 n->vhost_started = 0;
 }
 } else {
-vhost_net_stop(vdev, n->nic->ncs, qps, 0);
+vhost_net_stop(vdev, n->nic->ncs, qps, cvq);
 n->vhost_started = 0;
 }
 }
@@ -3367,7 +3368,20 @@ static void virtio_net_device_realize(DeviceState *dev, 
Error **errp)
 return;
 }
 
-n->max_qps = MAX(n->nic_conf.peers.queues, 1);
+n->max_ncs = MAX(n->nic_conf.peers.queues, 1);
+
+/* Figure out the datapath queue pairs since the bakcend could
+ * provide control queue via peers as well.
+ */
+if (n->nic_conf.peers.queues) {
+for (i = 0; i < n->max_ncs; i++) {
+if (n->nic_conf.peers.ncs[i]->is_datapath) {
+++n->max_qps;
+}
+}
+}
+n->max_qps = MAX(n->max_qps, 1);
+
 if (n->max_qps * 2 + 1 > VIRTIO_QUEUE_MAX) {
 error_setg(errp, "Invalid number of qps (= %" PRIu32 "), "
"must be a positive integer less than %d.",
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index a9b6dc252e..ed4659c189 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -194,6 +194,7 @@ struct VirtIONet {
 NICConf nic_conf;
 DeviceState *qdev;
 int multiqueue;
+uint16_t max_ncs;
 uint16_t max_qps;
 uint16_t curr_qps;
 size_t config_size;
-- 
2.25.1




[Bug 1731277] Re: Provide target specific qemu man pages

2021-06-20 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

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

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

Title:
  Provide target specific qemu man pages

Status in QEMU:
  Expired

Bug description:
  Right now, all qemu target binaries (qemu-system-...) share the same
  man page.

  The current man page is primarily focused on x86, and therefore the
  information given is entirely wrong for e.g. arm, powerpc or s390x.

  NAME
 qemu-doc - QEMU Emulator User Documentation

  SYNOPSIS
 qemu-system-i386 [options] [disk_image]

  DESCRIPTION
 The QEMU PC System emulator simulates the following peripherals:

 -   i440FX host PCI bridge and PIIX3 PCI to ISA bridge

 -   Cirrus CLGD 5446 PCI VGA card or dummy VGA card with Bochs VESA 
extensions (hardware level, including all non
 standard modes).

 -   PS/2 mouse and keyboard

 -   2 PCI IDE interfaces with hard disk and CD-ROM support

 -   Floppy disk

  ...

  We should have target specific man pages, with the common
  options/settings factored out, so they are included in all target
  specific man pages.

  "man qemu-system-s390x" should give s390x specific (+common)
  information and "man qemu-system-x86_64" should contain x86 specific
  (+common) information.

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



[Bug 1817268] Re: Input/output error during migration

2021-06-20 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

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

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

Title:
  Input/output error during migration

Status in QEMU:
  Expired

Bug description:
  Operating system: Ubuntu 18.04.2 LTS
  qemu version: 2.11.1, but also reproduced with 3.1.0 (compiled manually).
  virsh --version: 4.0.0

  Hello,

  I am having an issue with migration of UEFI virtual machines. If the
  --copy-storage-inc and the --tunnelled libvirt flags are used
  together, the migration fails. The same command for non-uefi virtual
  machines (e.g the same libvirt xml without the  and 
  tags) works.

  The command/output error is:

  virsh migrate --verbose --live --p2p --tunnelled --copy-storage-inc 
--change-protection --abort-on-error testuefi qemu+tcp:///system
  error: internal error: qemu unexpectedly closed the monitor: Receiving block 
device images
  2019-02-21T16:20:15.263261Z qemu-system-x86_64: error while loading state 
section id 2(block)
  2019-02-21T16:20:15.263996Z qemu-system-x86_64: load of migration failed: 
Input/output error

  If I remove one of the --tunnelled or the --copy-storage-inc flag, it
  works, for example:

  virsh migrate --verbose --live --p2p --copy-storage-inc --change-protection 
--abort-on-error testuefi qemu+tcp:///system
  Migration: [100 %]

  virsh migrate --verbose --live --p2p --tunnelled --change-protection 
--abort-on-error testuefi qemu+tcp:///system
  Migration: [100 %]

  I have no idea why those two flags combined together produce an error,
  and only for UEFI virtual machines.

  here is the libvirt xml definition:

  
testuefi
ce12de05-ec09-4b4b-a27a-47003a511bda
CentOS 4.5 (32-bit)
2097152
1048576
2

  878


  /machine


  
Apache Software Foundation
CloudStack KVM Hypervisor
ce12de05-ec09-4b4b-a27a-47003a511bda
  


  hvm
  /usr/share/OVMF/OVMF_CODE.fd
  /var/lib/libvirt/qemu/nvram/testuefi_VARS.fd
  
  
  


  
  
  


  Westmere
  
  
  
  
  
  


destroy
restart
destroy

  /usr/bin/kvm-spice
  



  
  
  




  
  





  
  


  
  

  
  


  
  







  
  


  


  
  



  
  


  
  

  
  

  
  



  
  


  

  

  Here is the qemu command on the destination host:

  LC_ALL=C
  PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  QEMU_AUDIO_DRV=none /usr/bin/kvm-spice -name guest=testuefi-VM,debug-
  threads=on -S -object
  secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-14
  -testuefi-VM/master-key.aes -machine pc-i440fx-2.11,accel=kvm,usb=off
  ,dump-guest-core=off -cpu Skylake-
  Server,vmx=on,pcid=on,ssbd=on,hypervisor=on -drive
  file=/usr/share/OVMF/OVMF_CODE.fd,if=pflash,format=raw,unit=0,readonly=on
  -drive file=/var/lib/libvirt/qemu/nvram/testuefi-
  VM_VARS.fd,if=pflash,format=raw,unit=1 -m 1024 -realtime mlock=off
  -smp 1,sockets=1,cores=1,threads=1 -uuid b340b117-1704-4ccf-
  93a7-21303b12dd7f -smbios 'type=1,manufacturer=Apache Software
  Foundation,product=CloudStack KVM Hypervisor,uuid=b340b117-1704-4ccf-
  93a7-21303b12dd7f' -no-user-config -nodefaults -chardev
  socket,id=charmonitor,path=/var/lib/libvirt/qemu/domain-14-testuefi-
  VM/monitor.sock,server,nowait -mon
  chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown
  -boot strict=on -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2
  -drive
  file=/var/lib/libvirt/images/testmigration.qcow2,format=qcow2,if=none,id
  =drive-virtio-disk0,cache=none -device virtio-blk-
  pci,scsi=off,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,id=virtio-
  disk0,bootindex=2 -drive if=none,id=drive-
  ide0-1-0,readonly=on,cache=none -device ide-cd,bus=ide.1,unit=0,drive
  =drive-ide0-1-0,id=ide0-1-0,bootindex=1 -netdev
  tap,fd=35,id=hostnet0,vhost=on,vhostfd=37 -device virtio-net-
  pci,netdev=hostnet0,id=net0,mac=06:a0:66:00:00:0c,bus=pci.0,addr=0x3
  -chardev pty,id=charserial0 -device isa-
  serial,chardev=charserial0,id=serial0 -device usb-
  tablet,id=input0,bus=usb.0,port=1 -vnc
  vnc=unix:/var/run/qemu/b340b117-1704-4ccf-93a7-21303b12dd7f.sock
  -device cirrus-vga,id=video0,bus=pci.0,addr=0x2 -incoming defer -msg
  timestamp=on

  Thanks,

To manage notifications about this bug go to:

[PATCH 13/18] vhost-vdpa: let net_vhost_vdpa_init() returns NetClientState *

2021-06-20 Thread Jason Wang
This patch switches to let net_vhost_vdpa_init() to return
NetClientState *. This is used for the callers to allocate multiqueue
NetClientState for multiqueue support.

Signed-off-by: Jason Wang 
---
 net/vhost-vdpa.c | 19 ---
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index e63a54a938..cc11b2ec40 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -156,8 +156,10 @@ static NetClientInfo net_vhost_vdpa_info = {
 .has_ufo = vhost_vdpa_has_ufo,
 };
 
-static int net_vhost_vdpa_init(NetClientState *peer, const char *device,
-   const char *name, int vdpa_device_fd)
+static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
+   const char *device,
+   const char *name,
+   int vdpa_device_fd)
 {
 NetClientState *nc = NULL;
 VhostVDPAState *s;
@@ -171,8 +173,9 @@ static int net_vhost_vdpa_init(NetClientState *peer, const 
char *device,
 ret = vhost_vdpa_add(nc, (void *)>vhost_vdpa);
 if (ret) {
 qemu_del_net_client(nc);
+return NULL;
 }
-return ret;
+return nc;
 }
 
 static int net_vhost_check_net(void *opaque, QemuOpts *opts, Error **errp)
@@ -197,7 +200,8 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char 
*name,
 NetClientState *peer, Error **errp)
 {
 const NetdevVhostVDPAOptions *opts;
-int vdpa_device_fd, ret;
+int vdpa_device_fd;
+NetClientState *nc;
 
 assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA);
 opts = >u.vhost_vdpa;
@@ -212,10 +216,11 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char 
*name,
 return -errno;
 }
 
-ret = net_vhost_vdpa_init(peer, TYPE_VHOST_VDPA, name, vdpa_device_fd);
-if (ret) {
+nc = net_vhost_vdpa_init(peer, TYPE_VHOST_VDPA, name, vdpa_device_fd);
+if (!nc) {
 qemu_close(vdpa_device_fd);
+return -1;
 }
 
-return ret;
+return 0;
 }
-- 
2.25.1




[PATCH 15/18] vhost-net: control virtqueue support

2021-06-20 Thread Jason Wang
We assume there's no cvq in the past, this is not true when we need
control virtqueue support for vhost-user backends. So this patch
implements the control virtqueue support for vhost-net. As datapath,
the control virtqueue is also required to be coupled with the
NetClientState. The vhost_net_start/stop() are tweaked to accept the
number of datapath queue pairs plus the the number of control
virtqueue for us to start and stop the vhost device.

Signed-off-by: Jason Wang 
---
 hw/net/vhost_net.c  | 43 ++---
 hw/net/virtio-net.c |  4 ++--
 include/net/vhost_net.h |  6 --
 3 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index ef1370bd92..fe2fd7e3d5 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -311,11 +311,14 @@ static void vhost_net_stop_one(struct vhost_net *net,
 }
 
 int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
-int total_queues)
+int data_qps, int cvq)
 {
 BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(dev)));
 VirtioBusState *vbus = VIRTIO_BUS(qbus);
 VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
+int total_notifiers = data_qps * 2 + cvq;
+VirtIONet *n = VIRTIO_NET(dev);
+int nvhosts = data_qps + cvq;
 struct vhost_net *net;
 int r, e, i;
 NetClientState *peer;
@@ -325,9 +328,14 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
 return -ENOSYS;
 }
 
-for (i = 0; i < total_queues; i++) {
+for (i = 0; i < nvhosts; i++) {
+
+if (i < data_qps) {
+peer = qemu_get_peer(ncs, i);
+} else { /* Control Virtqueue */
+peer = qemu_get_peer(ncs, n->max_qps);
+}
 
-peer = qemu_get_peer(ncs, i);
 net = get_vhost_net(peer);
 vhost_net_set_vq_index(net, i * 2);
 
@@ -340,14 +348,18 @@ int vhost_net_start(VirtIODevice *dev, NetClientState 
*ncs,
 }
  }
 
-r = k->set_guest_notifiers(qbus->parent, total_queues * 2, true);
+r = k->set_guest_notifiers(qbus->parent, total_notifiers, true);
 if (r < 0) {
 error_report("Error binding guest notifier: %d", -r);
 goto err;
 }
 
-for (i = 0; i < total_queues; i++) {
-peer = qemu_get_peer(ncs, i);
+for (i = 0; i < nvhosts; i++) {
+if (i < data_qps) {
+peer = qemu_get_peer(ncs, i);
+} else {
+peer = qemu_get_peer(ncs, n->max_qps);
+}
 r = vhost_net_start_one(get_vhost_net(peer), dev);
 
 if (r < 0) {
@@ -371,7 +383,7 @@ err_start:
 peer = qemu_get_peer(ncs , i);
 vhost_net_stop_one(get_vhost_net(peer), dev);
 }
-e = k->set_guest_notifiers(qbus->parent, total_queues * 2, false);
+e = k->set_guest_notifiers(qbus->parent, total_notifiers, false);
 if (e < 0) {
 fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", e);
 fflush(stderr);
@@ -381,18 +393,27 @@ err:
 }
 
 void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs,
-int total_queues)
+int data_qps, int cvq)
 {
 BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(dev)));
 VirtioBusState *vbus = VIRTIO_BUS(qbus);
 VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
+VirtIONet *n = VIRTIO_NET(dev);
+NetClientState *peer;
+int total_notifiers = data_qps * 2 + cvq;
+int nvhosts = data_qps + cvq;
 int i, r;
 
-for (i = 0; i < total_queues; i++) {
-vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev);
+for (i = 0; i < nvhosts; i++) {
+if (i < data_qps) {
+peer = qemu_get_peer(ncs, i);
+} else {
+peer = qemu_get_peer(ncs, n->max_qps);
+}
+vhost_net_stop_one(get_vhost_net(peer), dev);
 }
 
-r = k->set_guest_notifiers(qbus->parent, total_queues * 2, false);
+r = k->set_guest_notifiers(qbus->parent, total_notifiers, false);
 if (r < 0) {
 fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", r);
 fflush(stderr);
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index bd7958b9f0..614660274c 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -285,14 +285,14 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t 
status)
 }
 
 n->vhost_started = 1;
-r = vhost_net_start(vdev, n->nic->ncs, queues);
+r = vhost_net_start(vdev, n->nic->ncs, queues, 0);
 if (r < 0) {
 error_report("unable to start vhost net: %d: "
  "falling back on userspace virtio", -r);
 n->vhost_started = 0;
 }
 } else {
-vhost_net_stop(vdev, n->nic->ncs, queues);
+vhost_net_stop(vdev, n->nic->ncs, queues, 0);
 n->vhost_started = 0;
 }
 }
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index fba40cf695..e656e38af9 100644
--- a/include/net/vhost_net.h
+++ 

[PATCH 11/18] vhost-vdpa: classify one time request

2021-06-20 Thread Jason Wang
Vhost-vdpa uses one device multiqueue queue (pairs) model. So we need
to classify the one time request (e.g SET_OWNER) and make sure those
request were only called once per device.

This is used for multiqueue support.

Signed-off-by: Jason Wang 
---
 hw/virtio/vhost-vdpa.c | 51 --
 include/hw/virtio/vhost-vdpa.h |  1 +
 2 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 61ba313331..397f47bc11 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -265,6 +265,13 @@ static void vhost_vdpa_add_status(struct vhost_dev *dev, 
uint8_t status)
 vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, );
 }
 
+static bool vhost_vdpa_one_time_request(struct vhost_dev *dev)
+{
+struct vhost_vdpa *v = dev->opaque;
+
+return v->index != 0;
+}
+
 static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque)
 {
 struct vhost_vdpa *v;
@@ -277,6 +284,10 @@ static int vhost_vdpa_init(struct vhost_dev *dev, void 
*opaque)
 v->listener = vhost_vdpa_memory_listener;
 v->msg_type = VHOST_IOTLB_MSG_V2;
 
+if (vhost_vdpa_one_time_request(dev)) {
+return 0;
+}
+
 vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
VIRTIO_CONFIG_S_DRIVER);
 
@@ -387,6 +398,10 @@ static int vhost_vdpa_memslots_limit(struct vhost_dev *dev)
 static int vhost_vdpa_set_mem_table(struct vhost_dev *dev,
 struct vhost_memory *mem)
 {
+if (vhost_vdpa_one_time_request(dev)) {
+return 0;
+}
+
 trace_vhost_vdpa_set_mem_table(dev, mem->nregions, mem->padding);
 if (trace_event_get_state_backends(TRACE_VHOST_VDPA_SET_MEM_TABLE) &&
 trace_event_get_state_backends(TRACE_VHOST_VDPA_DUMP_REGIONS)) {
@@ -410,6 +425,11 @@ static int vhost_vdpa_set_features(struct vhost_dev *dev,
uint64_t features)
 {
 int ret;
+
+if (vhost_vdpa_one_time_request(dev)) {
+return 0;
+}
+
 trace_vhost_vdpa_set_features(dev, features);
 ret = vhost_vdpa_call(dev, VHOST_SET_FEATURES, );
 uint8_t status = 0;
@@ -429,6 +449,10 @@ static int vhost_vdpa_set_backend_cap(struct vhost_dev 
*dev)
 0x1ULL << VHOST_BACKEND_F_IOTLB_BATCH;
 int r;
 
+if (vhost_vdpa_one_time_request(dev)) {
+return 0;
+}
+
 if (vhost_vdpa_call(dev, VHOST_GET_BACKEND_FEATURES, )) {
 return 0;
 }
@@ -458,6 +482,10 @@ static int vhost_vdpa_reset_device(struct vhost_dev *dev)
 int ret;
 uint8_t status = 0;
 
+if (vhost_vdpa_one_time_request(dev)) {
+return 0;
+}
+
 ret = vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, );
 trace_vhost_vdpa_reset_device(dev, status);
 return ret;
@@ -545,11 +573,21 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, 
bool started)
 {
 struct vhost_vdpa *v = dev->opaque;
 trace_vhost_vdpa_dev_start(dev, started);
+
 if (started) {
-uint8_t status = 0;
-memory_listener_register(>listener, _space_memory);
 vhost_vdpa_host_notifiers_init(dev);
 vhost_vdpa_set_vring_ready(dev);
+} else {
+vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs);
+}
+
+if (vhost_vdpa_one_time_request(dev)) {
+return 0;
+}
+
+if (started) {
+uint8_t status = 0;
+memory_listener_register(>listener, _space_memory);
 vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
 vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, );
 
@@ -558,7 +596,6 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool 
started)
 vhost_vdpa_reset_device(dev);
 vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
VIRTIO_CONFIG_S_DRIVER);
-vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs);
 memory_listener_unregister(>listener);
 
 return 0;
@@ -568,6 +605,10 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, 
bool started)
 static int vhost_vdpa_set_log_base(struct vhost_dev *dev, uint64_t base,
  struct vhost_log *log)
 {
+if (vhost_vdpa_one_time_request(dev)) {
+return 0;
+}
+
 trace_vhost_vdpa_set_log_base(dev, base, log->size, log->refcnt, log->fd,
   log->log);
 return vhost_vdpa_call(dev, VHOST_SET_LOG_BASE, );
@@ -633,6 +674,10 @@ static int vhost_vdpa_get_features(struct vhost_dev *dev,
 
 static int vhost_vdpa_set_owner(struct vhost_dev *dev)
 {
+if (vhost_vdpa_one_time_request(dev)) {
+return 0;
+}
+
 trace_vhost_vdpa_set_owner(dev);
 return vhost_vdpa_call(dev, VHOST_SET_OWNER, NULL);
 }
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
index 9188226d8b..e98e327f12 100644
--- a/include/hw/virtio/vhost-vdpa.h
+++ b/include/hw/virtio/vhost-vdpa.h
@@ -21,6 +21,7 @@ typedef struct VhostVDPAHostNotifier {

[PATCH 14/18] net: introduce control client

2021-06-20 Thread Jason Wang
This patch introduces a boolean for the device has control queue which
can accepts control command via network queue.

The first user would be the control virtqueue support for vhost.

Signed-off-by: Jason Wang 
---
 include/net/net.h |  5 +
 net/net.c | 24 +---
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/include/net/net.h b/include/net/net.h
index 5d1508081f..4f400b8a09 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -103,6 +103,7 @@ struct NetClientState {
 int vnet_hdr_len;
 bool is_netdev;
 bool do_not_pad; /* do not pad to the minimum ethernet frame length */
+bool is_datapath;
 QTAILQ_HEAD(, NetFilterState) filters;
 };
 
@@ -134,6 +135,10 @@ NetClientState *qemu_new_net_client(NetClientInfo *info,
 NetClientState *peer,
 const char *model,
 const char *name);
+NetClientState *qemu_new_net_control_client(NetClientInfo *info,
+NetClientState *peer,
+const char *model,
+const char *name);
 NICState *qemu_new_nic(NetClientInfo *info,
NICConf *conf,
const char *model,
diff --git a/net/net.c b/net/net.c
index 76bbb7c31b..fcaf9c7715 100644
--- a/net/net.c
+++ b/net/net.c
@@ -237,7 +237,8 @@ static void qemu_net_client_setup(NetClientState *nc,
   NetClientState *peer,
   const char *model,
   const char *name,
-  NetClientDestructor *destructor)
+  NetClientDestructor *destructor,
+  bool is_datapath)
 {
 nc->info = info;
 nc->model = g_strdup(model);
@@ -256,6 +257,7 @@ static void qemu_net_client_setup(NetClientState *nc,
 
 nc->incoming_queue = qemu_new_net_queue(qemu_deliver_packet_iov, nc);
 nc->destructor = destructor;
+nc->is_datapath = is_datapath;
 QTAILQ_INIT(>filters);
 }
 
@@ -270,7 +272,23 @@ NetClientState *qemu_new_net_client(NetClientInfo *info,
 
 nc = g_malloc0(info->size);
 qemu_net_client_setup(nc, info, peer, model, name,
-  qemu_net_client_destructor);
+  qemu_net_client_destructor, true);
+
+return nc;
+}
+
+NetClientState *qemu_new_net_control_client(NetClientInfo *info,
+NetClientState *peer,
+const char *model,
+const char *name)
+{
+NetClientState *nc;
+
+assert(info->size >= sizeof(NetClientState));
+
+nc = g_malloc0(info->size);
+qemu_net_client_setup(nc, info, peer, model, name,
+  qemu_net_client_destructor, false);
 
 return nc;
 }
@@ -295,7 +313,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
 
 for (i = 0; i < queues; i++) {
 qemu_net_client_setup(>ncs[i], info, peers[i], model, name,
-  NULL);
+  NULL, true);
 nic->ncs[i].queue_index = i;
 }
 
-- 
2.25.1




[PATCH 18/18] vhost-vdpa: multiqueue support

2021-06-20 Thread Jason Wang
This patch implements the multiqueue support for vhost-vdpa. This is
done simply by reading the number of queue pairs from the config space
and initialize the datapath and control path net client.

Signed-off-by: Jason Wang 
---
 hw/net/virtio-net.c |  3 +-
 net/vhost-vdpa.c| 98 -
 2 files changed, 91 insertions(+), 10 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 5074b521cf..2c2ed98c0b 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3370,7 +3370,8 @@ static void virtio_net_device_realize(DeviceState *dev, 
Error **errp)
 
 n->max_ncs = MAX(n->nic_conf.peers.queues, 1);
 
-/* Figure out the datapath queue pairs since the bakcend could
+/*
+ * Figure out the datapath queue pairs since the bakcend could
  * provide control queue via peers as well.
  */
 if (n->nic_conf.peers.queues) {
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index cc11b2ec40..048344b4bc 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -18,6 +18,7 @@
 #include "qemu/error-report.h"
 #include "qemu/option.h"
 #include "qapi/error.h"
+#include 
 #include 
 #include 
 #include "standard-headers/linux/virtio_net.h"
@@ -52,6 +53,8 @@ const int vdpa_feature_bits[] = {
 VIRTIO_NET_F_HOST_UFO,
 VIRTIO_NET_F_MRG_RXBUF,
 VIRTIO_NET_F_MTU,
+VIRTIO_NET_F_MQ,
+VIRTIO_NET_F_CTRL_VQ,
 VIRTIO_F_IOMMU_PLATFORM,
 VIRTIO_F_RING_PACKED,
 VIRTIO_NET_F_RSS,
@@ -82,7 +85,8 @@ static int vhost_vdpa_net_check_device_id(struct vhost_net 
*net)
 return ret;
 }
 
-static int vhost_vdpa_add(NetClientState *ncs, void *be)
+static int vhost_vdpa_add(NetClientState *ncs, void *be, int qp_index,
+  int nvqs)
 {
 VhostNetOptions options;
 struct vhost_net *net = NULL;
@@ -95,7 +99,7 @@ static int vhost_vdpa_add(NetClientState *ncs, void *be)
 options.net_backend = ncs;
 options.opaque  = be;
 options.busyloop_timeout = 0;
-options.nvqs = 2;
+options.nvqs = nvqs;
 
 net = vhost_net_init();
 if (!net) {
@@ -159,18 +163,28 @@ static NetClientInfo net_vhost_vdpa_info = {
 static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
const char *device,
const char *name,
-   int vdpa_device_fd)
+   int vdpa_device_fd,
+   int qp_index,
+   int nvqs,
+   bool is_datapath)
 {
 NetClientState *nc = NULL;
 VhostVDPAState *s;
 int ret = 0;
 assert(name);
-nc = qemu_new_net_client(_vhost_vdpa_info, peer, device, name);
+if (is_datapath) {
+nc = qemu_new_net_client(_vhost_vdpa_info, peer, device,
+ name);
+} else {
+nc = qemu_new_net_control_client(_vhost_vdpa_info, peer,
+ device, name);
+}
 snprintf(nc->info_str, sizeof(nc->info_str), TYPE_VHOST_VDPA);
 s = DO_UPCAST(VhostVDPAState, nc, nc);
 
 s->vhost_vdpa.device_fd = vdpa_device_fd;
-ret = vhost_vdpa_add(nc, (void *)>vhost_vdpa);
+s->vhost_vdpa.index = qp_index;
+ret = vhost_vdpa_add(nc, (void *)>vhost_vdpa, qp_index, nvqs);
 if (ret) {
 qemu_del_net_client(nc);
 return NULL;
@@ -196,12 +210,52 @@ static int net_vhost_check_net(void *opaque, QemuOpts 
*opts, Error **errp)
 return 0;
 }
 
+static int vhost_vdpa_get_max_qps(int fd, int *has_cvq, Error **errp)
+{
+unsigned long config_size = offsetof(struct vhost_vdpa_config, buf);
+struct vhost_vdpa_config *config;
+__virtio16 *max_qps;
+uint64_t features;
+int ret;
+
+ret = ioctl(fd, VHOST_GET_FEATURES, );
+if (ret) {
+error_setg(errp, "Fail to query features from vhost-vDPA device");
+return ret;
+}
+
+if (features & (1 << VIRTIO_NET_F_CTRL_VQ)) {
+*has_cvq = 1;
+} else {
+*has_cvq = 0;
+}
+
+if (features & (1 << VIRTIO_NET_F_MQ)) {
+config = g_malloc0(config_size + sizeof(*max_qps));
+config->off = offsetof(struct virtio_net_config, max_virtqueue_pairs);
+config->len = sizeof(*max_qps);
+
+ret = ioctl(fd, VHOST_VDPA_GET_CONFIG, config);
+if (ret) {
+error_setg(errp, "Fail to get config from vhost-vDPA device");
+return -ret;
+}
+
+max_qps = (__virtio16 *)>buf;
+
+return lduw_le_p(max_qps);
+}
+
+return 1;
+}
+
 int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
 NetClientState *peer, Error **errp)
 {
 const NetdevVhostVDPAOptions *opts;
 int vdpa_device_fd;
-NetClientState *nc;
+NetClientState **ncs, *nc;
+int qps, i, has_cvq = 0;
 
 assert(netdev->type == 

[PATCH 07/18] vhost-vdpa: tweak the error label in vhost_vdpa_add()

2021-06-20 Thread Jason Wang
Introduce new error label to avoid the unnecessary checking of net
pointer.

Fixes: 1e0a84ea49b68 ("vhost-vdpa: introduce vhost-vdpa net client")
Signed-off-by: Jason Wang 
---
 net/vhost-vdpa.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 21f09c546f..0da7bc347a 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -100,19 +100,18 @@ static int vhost_vdpa_add(NetClientState *ncs, void *be)
 net = vhost_net_init();
 if (!net) {
 error_report("failed to init vhost_net for queue");
-goto err;
+goto err_init;
 }
 s->vhost_net = net;
 ret = vhost_vdpa_net_check_device_id(net);
 if (ret) {
-goto err;
+goto err_check;
 }
 return 0;
-err:
-if (net) {
-vhost_net_cleanup(net);
-g_free(net);
-}
+err_check:
+vhost_net_cleanup(net);
+g_free(net);
+err_init:
 return -1;
 }
 
-- 
2.25.1




[PATCH 12/18] vhost-vdpa: prepare for the multiqueue support

2021-06-20 Thread Jason Wang
Unlike vhost-kernel, vhost-vdpa adapts a single device multiqueue
model. So we need to simply use virtqueue index as the vhost virtqueue
index. This is a must for multiqueue to work for vhost-vdpa.

Signed-off-by: Jason Wang 
---
 hw/virtio/vhost-vdpa.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 397f47bc11..e7e6b23108 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -495,8 +495,8 @@ static int vhost_vdpa_get_vq_index(struct vhost_dev *dev, 
int idx)
 {
 assert(idx >= dev->vq_index && idx < dev->vq_index + dev->nvqs);
 
-trace_vhost_vdpa_get_vq_index(dev, idx, idx - dev->vq_index);
-return idx - dev->vq_index;
+trace_vhost_vdpa_get_vq_index(dev, idx, idx);
+return idx;
 }
 
 static int vhost_vdpa_set_vring_ready(struct vhost_dev *dev)
-- 
2.25.1




[PATCH 04/18] vhost-vdpa: remove the unnecessary check in vhost_vdpa_add()

2021-06-20 Thread Jason Wang
The VhostVDPAState is just allocated by qemu_new_net_client() via
g_malloc0() in net_vhost_vdpa_init(). So s->vhost_net is NULL for
sure, let's remove this unnecessary check in vhost_vdpa_add().

Signed-off-by: Jason Wang 
---
 net/vhost-vdpa.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 18b45ad777..728e63ff54 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -112,10 +112,6 @@ static int vhost_vdpa_add(NetClientState *ncs, void *be)
 error_report("failed to init vhost_net for queue");
 goto err;
 }
-if (s->vhost_net) {
-vhost_net_cleanup(s->vhost_net);
-g_free(s->vhost_net);
-}
 s->vhost_net = net;
 ret = vhost_vdpa_net_check_device_id(net);
 if (ret) {
-- 
2.25.1




[PATCH 09/18] vhost-vdpa: remove the unncessary queue_index assignment

2021-06-20 Thread Jason Wang
The queue_index of NetClientState should be assigned in set_netdev()
afterwards, so trying to net_vhost_vdpa_init() is meaningless. This
patch removes this.

Signed-off-by: Jason Wang 
---
 net/vhost-vdpa.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 87b181a74e..572aed4ca2 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -166,7 +166,6 @@ static int net_vhost_vdpa_init(NetClientState *peer, const 
char *device,
 assert(name);
 nc = qemu_new_net_client(_vhost_vdpa_info, peer, device, name);
 snprintf(nc->info_str, sizeof(nc->info_str), TYPE_VHOST_VDPA);
-nc->queue_index = 0;
 s = DO_UPCAST(VhostVDPAState, nc, nc);
 vdpa_device_fd = qemu_open_old(vhostdev, O_RDWR);
 if (vdpa_device_fd == -1) {
-- 
2.25.1




[PATCH 08/18] vhost-vdpa: fix the wrong assertion in vhost_vdpa_init()

2021-06-20 Thread Jason Wang
Vhost_vdpa_add() can fail for various reasons, so the assertion of the
succeed is wrong. Instead, we should free the NetClientState and
propagate the error to the caller

Signed-off-by: Jason Wang 
---
 net/vhost-vdpa.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 0da7bc347a..87b181a74e 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -174,7 +174,10 @@ static int net_vhost_vdpa_init(NetClientState *peer, const 
char *device,
 }
 s->vhost_vdpa.device_fd = vdpa_device_fd;
 ret = vhost_vdpa_add(nc, (void *)>vhost_vdpa);
-assert(s->vhost_net);
+if (ret) {
+qemu_close(vdpa_device_fd);
+qemu_del_net_client(nc);
+}
 return ret;
 }
 
-- 
2.25.1




[PATCH 10/18] vhost-vdpa: open device fd in net_init_vhost_vdpa()

2021-06-20 Thread Jason Wang
This path switches to open device fd in net_init_vhost_vpda(). This is
used to prepare for the multiqueue support.

Signed-off-by: Jason Wang 
---
 net/vhost-vdpa.c | 23 +++
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 572aed4ca2..e63a54a938 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -157,24 +157,19 @@ static NetClientInfo net_vhost_vdpa_info = {
 };
 
 static int net_vhost_vdpa_init(NetClientState *peer, const char *device,
-   const char *name, const char *vhostdev)
+   const char *name, int vdpa_device_fd)
 {
 NetClientState *nc = NULL;
 VhostVDPAState *s;
-int vdpa_device_fd = -1;
 int ret = 0;
 assert(name);
 nc = qemu_new_net_client(_vhost_vdpa_info, peer, device, name);
 snprintf(nc->info_str, sizeof(nc->info_str), TYPE_VHOST_VDPA);
 s = DO_UPCAST(VhostVDPAState, nc, nc);
-vdpa_device_fd = qemu_open_old(vhostdev, O_RDWR);
-if (vdpa_device_fd == -1) {
-return -errno;
-}
+
 s->vhost_vdpa.device_fd = vdpa_device_fd;
 ret = vhost_vdpa_add(nc, (void *)>vhost_vdpa);
 if (ret) {
-qemu_close(vdpa_device_fd);
 qemu_del_net_client(nc);
 }
 return ret;
@@ -202,6 +197,7 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char 
*name,
 NetClientState *peer, Error **errp)
 {
 const NetdevVhostVDPAOptions *opts;
+int vdpa_device_fd, ret;
 
 assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA);
 opts = >u.vhost_vdpa;
@@ -210,5 +206,16 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char 
*name,
   (char *)name, errp)) {
 return -1;
 }
-return net_vhost_vdpa_init(peer, TYPE_VHOST_VDPA, name, opts->vhostdev);
+
+vdpa_device_fd = qemu_open_old(opts->vhostdev, O_RDWR);
+if (vdpa_device_fd == -1) {
+return -errno;
+}
+
+ret = net_vhost_vdpa_init(peer, TYPE_VHOST_VDPA, name, vdpa_device_fd);
+if (ret) {
+qemu_close(vdpa_device_fd);
+}
+
+return ret;
 }
-- 
2.25.1




[PATCH 02/18] vhost: use unsigned int for nvqs

2021-06-20 Thread Jason Wang
Switch to use unsigned int for nvqs since it's not expected to be
negative.

Signed-off-by: Jason Wang 
---
 include/hw/virtio/vhost.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 21a9a52088..ddd7d3d594 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -71,7 +71,7 @@ struct vhost_dev {
 int n_tmp_sections;
 MemoryRegionSection *tmp_sections;
 struct vhost_virtqueue *vqs;
-int nvqs;
+unsigned int nvqs;
 /* the first virtqueue which would be used by this vhost dev */
 int vq_index;
 /* if non-zero, minimum required value for max_queues */
-- 
2.25.1




[PATCH 05/18] vhost-vdpa: don't cleanup twice in vhost_vdpa_add()

2021-06-20 Thread Jason Wang
The previous vhost_net_cleanup is sufficient for freeing, calling
vhost_vdpa_del() in this case will lead an extra round of free. Note
that this kind of "double free" is safe since vhost_dev_cleanup() zero
the whole structure.

Signed-off-by: Jason Wang 
---
 net/vhost-vdpa.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 728e63ff54..f5689a7c32 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -82,16 +82,6 @@ static int vhost_vdpa_net_check_device_id(struct vhost_net 
*net)
 return ret;
 }
 
-static void vhost_vdpa_del(NetClientState *ncs)
-{
-VhostVDPAState *s;
-assert(ncs->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
-s = DO_UPCAST(VhostVDPAState, nc, ncs);
-if (s->vhost_net) {
-vhost_net_cleanup(s->vhost_net);
-}
-}
-
 static int vhost_vdpa_add(NetClientState *ncs, void *be)
 {
 VhostNetOptions options;
@@ -122,7 +112,6 @@ err:
 if (net) {
 vhost_net_cleanup(net);
 }
-vhost_vdpa_del(ncs);
 return -1;
 }
 
-- 
2.25.1




[PATCH 06/18] vhost-vdpa: fix leaking of vhost_net in vhost_vdpa_add()

2021-06-20 Thread Jason Wang
Fixes: 1e0a84ea49b68 ("vhost-vdpa: introduce vhost-vdpa net client")
Signed-off-by: Jason Wang 
---
 net/vhost-vdpa.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index f5689a7c32..21f09c546f 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -111,6 +111,7 @@ static int vhost_vdpa_add(NetClientState *ncs, void *be)
 err:
 if (net) {
 vhost_net_cleanup(net);
+g_free(net);
 }
 return -1;
 }
-- 
2.25.1




[PATCH 03/18] vhost_net: do not assume nvqs is always 2

2021-06-20 Thread Jason Wang
This patch switches to initialize dev.nvqs from the VhostNetOptions
instead of assuming it was 2. This is useful for implementing control
virtqueue support which will be a single vhost_net structure with a
single cvq.

Signed-off-by: Jason Wang 
---
 hw/net/vhost_net.c  | 2 +-
 include/net/vhost_net.h | 1 +
 net/tap.c   | 1 +
 net/vhost-user.c| 1 +
 net/vhost-vdpa.c| 1 +
 5 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 6bd4184f96..ef1370bd92 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -163,9 +163,9 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
 goto fail;
 }
 net->nc = options->net_backend;
+net->dev.nvqs = options->nvqs;
 
 net->dev.max_queues = 1;
-net->dev.nvqs = 2;
 net->dev.vqs = net->vqs;
 
 if (backend_kernel) {
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index 172b0051d8..fba40cf695 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -14,6 +14,7 @@ typedef struct VhostNetOptions {
 VhostBackendType backend_type;
 NetClientState *net_backend;
 uint32_t busyloop_timeout;
+unsigned int nvqs;
 void *opaque;
 } VhostNetOptions;
 
diff --git a/net/tap.c b/net/tap.c
index f5686bbf77..f716be3e3f 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -749,6 +749,7 @@ static void net_init_tap_one(const NetdevTapOptions *tap, 
NetClientState *peer,
 qemu_set_nonblock(vhostfd);
 }
 options.opaque = (void *)(uintptr_t)vhostfd;
+options.nvqs = 2;
 
 s->vhost_net = vhost_net_init();
 if (!s->vhost_net) {
diff --git a/net/vhost-user.c b/net/vhost-user.c
index ffbd94d944..b93918c5a4 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -85,6 +85,7 @@ static int vhost_user_start(int queues, NetClientState *ncs[],
 options.net_backend = ncs[i];
 options.opaque  = be;
 options.busyloop_timeout = 0;
+options.nvqs = 2;
 net = vhost_net_init();
 if (!net) {
 error_report("failed to init vhost_net for queue %d", i);
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 19187dce8c..18b45ad777 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -105,6 +105,7 @@ static int vhost_vdpa_add(NetClientState *ncs, void *be)
 options.net_backend = ncs;
 options.opaque  = be;
 options.busyloop_timeout = 0;
+options.nvqs = 2;
 
 net = vhost_net_init();
 if (!net) {
-- 
2.25.1




[PATCH 01/18] vhost_net: remove the meaningless assignment in vhost_net_start_one()

2021-06-20 Thread Jason Wang
The nvqs and vqs has been initialized during vhost_net_init() and is
not expected to change during the life cycle of vhost_net
structure. So this patch removes the meaningless assignment.

Signed-off-by: Jason Wang 
---
 hw/net/vhost_net.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 44c1ed92dc..6bd4184f96 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -238,9 +238,6 @@ static int vhost_net_start_one(struct vhost_net *net,
 struct vhost_vring_file file = { };
 int r;
 
-net->dev.nvqs = 2;
-net->dev.vqs = net->vqs;
-
 r = vhost_dev_enable_notifiers(>dev, dev);
 if (r < 0) {
 goto fail_notifiers;
-- 
2.25.1




[PATCH 00/18] vhost-vDPA multiqueue

2021-06-20 Thread Jason Wang
Hi All:

This patch implements the multiqueue support for vhost-vDPA. The most
important requirement the control virtqueue support. The virtio-net
and vhost-net core are tweak to support control virtqueue as if what
data queue pairs are done: a dedicated vhost_net device which is
coupled with the NetClientState is intrdouced so most of the existing
vhost codes could be reused with minor changes. With the control
virtqueue, vhost-vDPA are extend to support creating and destroying
multiqueue queue pairs plus the control virtqueue.

Tests are done via the vp_vdpa driver in L1 guest.

Please reivew.

Thanks

Jason Wang (18):
  vhost_net: remove the meaningless assignment in vhost_net_start_one()
  vhost: use unsigned int for nvqs
  vhost_net: do not assume nvqs is always 2
  vhost-vdpa: remove the unnecessary check in vhost_vdpa_add()
  vhost-vdpa: don't cleanup twice in vhost_vdpa_add()
  vhost-vdpa: fix leaking of vhost_net in vhost_vdpa_add()
  vhost-vdpa: tweak the error label in vhost_vdpa_add()
  vhost-vdpa: fix the wrong assertion in vhost_vdpa_init()
  vhost-vdpa: remove the unncessary queue_index assignment
  vhost-vdpa: open device fd in net_init_vhost_vdpa()
  vhost-vdpa: classify one time request
  vhost-vdpa: prepare for the multiqueue support
  vhost-vdpa: let net_vhost_vdpa_init() returns NetClientState *
  net: introduce control client
  vhost-net: control virtqueue support
  virito-net: use "qps" instead of "queues" when possible
  virtio-net: vhost control virtqueue support
  vhost-vdpa: multiqueue support

 hw/net/vhost_net.c |  48 +++---
 hw/net/virtio-net.c| 165 ++---
 hw/virtio/vhost-vdpa.c |  55 ++-
 include/hw/virtio/vhost-vdpa.h |   1 +
 include/hw/virtio/vhost.h  |   2 +-
 include/hw/virtio/virtio-net.h |   5 +-
 include/net/net.h  |   5 +
 include/net/vhost_net.h|   7 +-
 net/net.c  |  24 -
 net/tap.c  |   1 +
 net/vhost-user.c   |   1 +
 net/vhost-vdpa.c   | 150 +++---
 12 files changed, 326 insertions(+), 138 deletions(-)

-- 
2.25.1




Re: [PATCH v2 01/11] linux-user: handle /proc/self/exe for execve

2021-06-20 Thread Takashi Yamamoto
On Sun, Jun 20, 2021 at 11:14 PM Laurent Vivier  wrote:
>
> Le 31/05/2021 à 07:50, YAMAMOTO Takashi a écrit :
> > It seems somehow common to execve /proc/self/exe in docker
> > or golang community these days.
> > At least, moby "reexec" and runc "libcontainer" do that.
> >
> > Signed-off-by: YAMAMOTO Takashi 
> > ---
> >  linux-user/syscall.c | 7 ++-
> >  1 file changed, 6 insertions(+), 1 deletion(-)
> >
> > diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> > index c9f812091c..a2b03ecb8b 100644
> > --- a/linux-user/syscall.c
> > +++ b/linux-user/syscall.c
> > @@ -8470,6 +8470,7 @@ static abi_long do_syscall1(void *cpu_env, int num, 
> > abi_long arg1,
> >  #endif
> >  case TARGET_NR_execve:
> >  {
> > +const char *path;
> >  char **argp, **envp;
> >  int argc, envc;
> >  abi_ulong gp;
> > @@ -8537,7 +8538,11 @@ static abi_long do_syscall1(void *cpu_env, int num, 
> > abi_long arg1,
> >   * before the execve completes and makes it the other
> >   * program's problem.
> >   */
> > -ret = get_errno(safe_execve(p, argp, envp));
> > +path = p;
> > +if (is_proc_myself(path, "exe")) {
> > +path = exec_path;
> > +}
> > +ret = get_errno(safe_execve(path, argp, envp));
> >  unlock_user(p, arg1, 0);
> >
> >  goto execve_end;
> >
>
> The problem here is QEMU can fail to execute the file directly.

i don't understand this sentence. can you explain a bit?

>
> The binary can be launched with binfmt_misc and the 'O' flag:
>
>  ``O`` - open-binary
> Legacy behavior of binfmt_misc is to pass the full path
> of the binary to the interpreter as an argument. When this flag is
> included, binfmt_misc will open the file for reading and pass its
> descriptor as an argument, instead of the full path, thus allowing
> the interpreter to execute non-readable binaries. This feature
> should be used with care - the interpreter has to be trusted not 
> to
> emit the contents of the non-readable binary.
>
> You should use do_openat() (that resolves the /proc/self/exe path) and 
> fexecve().

i thought there was an issue with the approach. but i don't remember
what it was.
maybe i will retry it.

>
> Thanks,
> Laurent



[PATCH 19/26] target/rx: Use translator_use_goto_tb

2021-06-20 Thread Richard Henderson
Just use translator_use_goto_tb directly at the one call site,
rather than maintaining a local wrapper.

Cc: Yoshinori Sato 
Signed-off-by: Richard Henderson 
---
 target/rx/translate.c | 11 +--
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/target/rx/translate.c b/target/rx/translate.c
index 9ea941c630..2443406de5 100644
--- a/target/rx/translate.c
+++ b/target/rx/translate.c
@@ -143,18 +143,9 @@ void rx_cpu_dump_state(CPUState *cs, FILE *f, int flags)
 }
 }
 
-static bool use_goto_tb(DisasContext *dc, target_ulong dest)
-{
-if (unlikely(dc->base.singlestep_enabled)) {
-return false;
-} else {
-return true;
-}
-}
-
 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
 {
-if (use_goto_tb(dc, dest)) {
+if (translator_use_goto_tb(>base, dest)) {
 tcg_gen_goto_tb(n);
 tcg_gen_movi_i32(cpu_pc, dest);
 tcg_gen_exit_tb(dc->base.tb, n);
-- 
2.25.1




[PATCH 24/26] target/tricore: Use translator_use_goto_tb

2021-06-20 Thread Richard Henderson
Just use translator_use_goto_tb directly at the one call site,
rather than maintaining a local wrapper.

Cc: Bastian Koppelmann 
Signed-off-by: Richard Henderson 
---
 target/tricore/translate.c | 17 ++---
 1 file changed, 2 insertions(+), 15 deletions(-)

diff --git a/target/tricore/translate.c b/target/tricore/translate.c
index 2a814263de..09465ea013 100644
--- a/target/tricore/translate.c
+++ b/target/tricore/translate.c
@@ -3225,19 +3225,6 @@ static inline void gen_save_pc(target_ulong pc)
 tcg_gen_movi_tl(cpu_PC, pc);
 }
 
-static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
-{
-if (unlikely(ctx->base.singlestep_enabled)) {
-return false;
-}
-
-#ifndef CONFIG_USER_ONLY
-return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-return true;
-#endif
-}
-
 static void generate_qemu_excp(DisasContext *ctx, int excp)
 {
 TCGv_i32 tmp = tcg_const_i32(excp);
@@ -3246,9 +3233,9 @@ static void generate_qemu_excp(DisasContext *ctx, int 
excp)
 tcg_temp_free(tmp);
 }
 
-static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
+static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
 {
-if (use_goto_tb(ctx, dest)) {
+if (translator_use_goto_tb(>base, dest)) {
 tcg_gen_goto_tb(n);
 gen_save_pc(dest);
 tcg_gen_exit_tb(ctx->base.tb, n);
-- 
2.25.1




[PATCH 25/26] target/tricore: Use tcg_gen_lookup_and_goto_ptr

2021-06-20 Thread Richard Henderson
The non-single-step case of gen_goto_tb may use
tcg_gen_lookup_and_goto_ptr to indirectly chain.

Cc: Bastian Koppelmann 
Signed-off-by: Richard Henderson 
---
 target/tricore/translate.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/tricore/translate.c b/target/tricore/translate.c
index 09465ea013..865020754d 100644
--- a/target/tricore/translate.c
+++ b/target/tricore/translate.c
@@ -3243,8 +3243,9 @@ static void gen_goto_tb(DisasContext *ctx, int n, 
target_ulong dest)
 gen_save_pc(dest);
 if (ctx->base.singlestep_enabled) {
 generate_qemu_excp(ctx, EXCP_DEBUG);
+} else {
+tcg_gen_lookup_and_goto_ptr();
 }
-tcg_gen_exit_tb(NULL, 0);
 }
 }
 
-- 
2.25.1




[PATCH 21/26] target/s390x: Remove use_exit_tb

2021-06-20 Thread Richard Henderson
We have not needed to end a TB for I/O since ba3e7926691
("icount: clean up cpu_can_io at the entry to the block").

In use_goto_tb, the check for singlestep_enabled is in the
generic translator_use_goto_tb.  In s390x_tr_tb_stop, the
check for singlestep_enabled is in the preceeding do_debug test.

Which leaves only FLAG_MASK_PER: fold that test alone into
the two callers of use_exit tb.

Cc: David Hildenbrand 
Signed-off-by: Richard Henderson 
---
 target/s390x/translate.c | 11 ++-
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index 4bb5d82a37..de7d846461 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -685,16 +685,9 @@ static void gen_op_calc_cc(DisasContext *s)
 set_cc_static(s);
 }
 
-static bool use_exit_tb(DisasContext *s)
-{
-return s->base.singlestep_enabled ||
-(tb_cflags(s->base.tb) & CF_LAST_IO) ||
-(s->base.tb->flags & FLAG_MASK_PER);
-}
-
 static bool use_goto_tb(DisasContext *s, uint64_t dest)
 {
-if (unlikely(use_exit_tb(s))) {
+if (unlikely(s->base.tb->flags & FLAG_MASK_PER)) {
 return false;
 }
 return translator_use_goto_tb(>base, dest);
@@ -6634,7 +6627,7 @@ static void s390x_tr_tb_stop(DisasContextBase *dcbase, 
CPUState *cs)
 /* Exit the TB, either by raising a debug exception or by return.  */
 if (dc->do_debug) {
 gen_exception(EXCP_DEBUG);
-} else if (use_exit_tb(dc) ||
+} else if ((dc->base.tb->flags & FLAG_MASK_PER) ||
dc->base.is_jmp == DISAS_PC_STALE_NOCHAIN) {
 tcg_gen_exit_tb(NULL, 0);
 } else {
-- 
2.25.1




[PATCH 16/26] target/openrisc: Use translator_use_goto_tb

2021-06-20 Thread Richard Henderson
Reorder the cases in openrisc_tr_tb_stop to make this easier to read.

Cc: Stafford Horne 
Signed-off-by: Richard Henderson 
---
 target/openrisc/translate.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index a9c81f8bd5..2d142d8577 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -1720,16 +1720,17 @@ static void openrisc_tr_tb_stop(DisasContextBase 
*dcbase, CPUState *cs)
 /* fallthru */
 
 case DISAS_TOO_MANY:
-if (unlikely(dc->base.singlestep_enabled)) {
-tcg_gen_movi_tl(cpu_pc, jmp_dest);
-gen_exception(dc, EXCP_DEBUG);
-} else if ((dc->base.pc_first ^ jmp_dest) & TARGET_PAGE_MASK) {
-tcg_gen_movi_tl(cpu_pc, jmp_dest);
-tcg_gen_lookup_and_goto_ptr();
-} else {
+if (translator_use_goto_tb(>base, jmp_dest)) {
 tcg_gen_goto_tb(0);
 tcg_gen_movi_tl(cpu_pc, jmp_dest);
 tcg_gen_exit_tb(dc->base.tb, 0);
+break;
+}
+tcg_gen_movi_tl(cpu_pc, jmp_dest);
+if (unlikely(dc->base.singlestep_enabled)) {
+gen_exception(dc, EXCP_DEBUG);
+} else {
+tcg_gen_lookup_and_goto_ptr();
 }
 break;
 
-- 
2.25.1




[PATCH 23/26] target/sparc: Use translator_use_goto_tb

2021-06-20 Thread Richard Henderson
Cc: Mark Cave-Ayland 
Signed-off-by: Richard Henderson 
---
 target/sparc/translate.c | 19 +--
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 4bfa3179f8..fb0c242606 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -339,23 +339,14 @@ static inline TCGv gen_dest_gpr(DisasContext *dc, int reg)
 }
 }
 
-static inline bool use_goto_tb(DisasContext *s, target_ulong pc,
-   target_ulong npc)
+static bool use_goto_tb(DisasContext *s, target_ulong pc, target_ulong npc)
 {
-if (unlikely(s->base.singlestep_enabled || singlestep)) {
-return false;
-}
-
-#ifndef CONFIG_USER_ONLY
-return (pc & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK) &&
-   (npc & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK);
-#else
-return true;
-#endif
+return translator_use_goto_tb(>base, pc) &&
+   translator_use_goto_tb(>base, npc);
 }
 
-static inline void gen_goto_tb(DisasContext *s, int tb_num,
-   target_ulong pc, target_ulong npc)
+static void gen_goto_tb(DisasContext *s, int tb_num,
+target_ulong pc, target_ulong npc)
 {
 if (use_goto_tb(s, pc, npc))  {
 /* jump to same page: we can use a direct jump */
-- 
2.25.1




[PATCH 26/26] target/xtensa: Use translator_use_goto_tb

2021-06-20 Thread Richard Henderson
Cc: Max Filippov 
Signed-off-by: Richard Henderson 
---
 target/xtensa/translate.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
index 14028d307d..ac42f5efdc 100644
--- a/target/xtensa/translate.c
+++ b/target/xtensa/translate.c
@@ -406,11 +406,7 @@ static void gen_jump(DisasContext *dc, TCGv dest)
 
 static int adjust_jump_slot(DisasContext *dc, uint32_t dest, int slot)
 {
-if (((dc->base.pc_first ^ dest) & TARGET_PAGE_MASK) != 0) {
-return -1;
-} else {
-return slot;
-}
+return translator_use_goto_tb(>base, dest) ? slot : -1;
 }
 
 static void gen_jumpi(DisasContext *dc, uint32_t dest, int slot)
-- 
2.25.1




[PATCH 17/26] target/ppc: Use translator_use_goto_tb

2021-06-20 Thread Richard Henderson
Cc: David Gibson 
Signed-off-by: Richard Henderson 
---
 target/ppc/translate.c | 10 +-
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index f65d1e81ea..0fb09f2301 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -4302,15 +4302,7 @@ static inline void gen_update_cfar(DisasContext *ctx, 
target_ulong nip)
 
 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
 {
-if (unlikely(ctx->singlestep_enabled)) {
-return false;
-}
-
-#ifndef CONFIG_USER_ONLY
-return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-return true;
-#endif
+return translator_use_goto_tb(>base, dest);
 }
 
 static void gen_lookup_and_goto_ptr(DisasContext *ctx)
-- 
2.25.1




[PATCH 18/26] target/riscv: Use translator_use_goto_tb

2021-06-20 Thread Richard Henderson
Just use translator_use_goto_tb directly at the one call site,
rather than maintaining a local wrapper.

Cc: qemu-ri...@nongnu.org
Signed-off-by: Richard Henderson 
---
 target/riscv/translate.c | 20 +---
 1 file changed, 1 insertion(+), 19 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index c6e8739614..ecd3764338 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -168,29 +168,11 @@ static void gen_exception_inst_addr_mis(DisasContext *ctx)
 generate_exception_mtval(ctx, RISCV_EXCP_INST_ADDR_MIS);
 }
 
-static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
-{
-if (unlikely(ctx->base.singlestep_enabled)) {
-return false;
-}
-
-#ifndef CONFIG_USER_ONLY
-return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-return true;
-#endif
-}
-
 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
 {
-if (use_goto_tb(ctx, dest)) {
-/* chaining is only allowed when the jump is to the same page */
+if (translator_use_goto_tb(>base, dest)) {
 tcg_gen_goto_tb(n);
 tcg_gen_movi_tl(cpu_pc, dest);
-
-/* No need to check for single stepping here as use_goto_tb() will
- * return false in case of single stepping.
- */
 tcg_gen_exit_tb(ctx->base.tb, n);
 } else {
 tcg_gen_movi_tl(cpu_pc, dest);
-- 
2.25.1




[PATCH 11/26] target/m68k: Use translator_use_goto_tb

2021-06-20 Thread Richard Henderson
Just use translator_use_goto_tb directly at the one call site,
rather than maintaining a local wrapper.

Cc: Laurent Vivier 
Signed-off-by: Richard Henderson 
---
 target/m68k/translate.c | 12 +---
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index f0c5bf9154..05b96fdda7 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -1520,16 +1520,6 @@ static void gen_exit_tb(DisasContext *s)
 }   \
 } while (0)
 
-static inline bool use_goto_tb(DisasContext *s, uint32_t dest)
-{
-#ifndef CONFIG_USER_ONLY
-return (s->base.pc_first & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)
-|| (s->base.pc_next & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-return true;
-#endif
-}
-
 /* Generate a jump to an immediate address.  */
 static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
 {
@@ -1537,7 +1527,7 @@ static void gen_jmp_tb(DisasContext *s, int n, uint32_t 
dest)
 update_cc_op(s);
 tcg_gen_movi_i32(QREG_PC, dest);
 gen_singlestep_exception(s);
-} else if (use_goto_tb(s, dest)) {
+} else if (translator_use_goto_tb(>base, dest)) {
 tcg_gen_goto_tb(n);
 tcg_gen_movi_i32(QREG_PC, dest);
 tcg_gen_exit_tb(s->base.tb, n);
-- 
2.25.1




[PATCH 20/26] target/s390x: Use translator_use_goto_tb

2021-06-20 Thread Richard Henderson
Cc: David Hildenbrand 
Signed-off-by: Richard Henderson 
---
 target/s390x/translate.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index e243624d2a..4bb5d82a37 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -697,12 +697,7 @@ static bool use_goto_tb(DisasContext *s, uint64_t dest)
 if (unlikely(use_exit_tb(s))) {
 return false;
 }
-#ifndef CONFIG_USER_ONLY
-return (dest & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK) ||
-   (dest & TARGET_PAGE_MASK) == (s->base.pc_next & TARGET_PAGE_MASK);
-#else
-return true;
-#endif
+return translator_use_goto_tb(>base, dest);
 }
 
 static void account_noninline_branch(DisasContext *s, int cc_op)
-- 
2.25.1




[PATCH 14/26] target/mips: Fix missing else in gen_goto_tb

2021-06-20 Thread Richard Henderson
Do not emit dead code for the singlestep_enabled case,
after having exited the TB with a debug exception.

Cc: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/mips/tcg/translate.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index d59986b340..99827ee740 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -5030,8 +5030,9 @@ static void gen_goto_tb(DisasContext *ctx, int n, 
target_ulong dest)
 if (ctx->base.singlestep_enabled) {
 save_cpu_state(ctx, 0);
 gen_helper_raise_exception_debug(cpu_env);
+} else {
+tcg_gen_lookup_and_goto_ptr();
 }
-tcg_gen_lookup_and_goto_ptr();
 }
 }
 
-- 
2.25.1




[PATCH 07/26] target/avr: Mark some helpers noreturn

2021-06-20 Thread Richard Henderson
All of these helpers end with cpu_loop_exit.

Cc: Michael Rolnik 
Signed-off-by: Richard Henderson 
---
 target/avr/helper.h | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/avr/helper.h b/target/avr/helper.h
index 8e1ae7fda0..4d02e648fa 100644
--- a/target/avr/helper.h
+++ b/target/avr/helper.h
@@ -19,10 +19,10 @@
  */
 
 DEF_HELPER_1(wdr, void, env)
-DEF_HELPER_1(debug, void, env)
-DEF_HELPER_1(break, void, env)
-DEF_HELPER_1(sleep, void, env)
-DEF_HELPER_1(unsupported, void, env)
+DEF_HELPER_1(debug, noreturn, env)
+DEF_HELPER_1(break, noreturn, env)
+DEF_HELPER_1(sleep, noreturn, env)
+DEF_HELPER_1(unsupported, noreturn, env)
 DEF_HELPER_3(outb, void, env, i32, i32)
 DEF_HELPER_2(inb, tl, env, i32)
 DEF_HELPER_3(fullwr, void, env, i32, i32)
-- 
2.25.1




[PATCH 08/26] target/cris: Use translator_use_goto_tb

2021-06-20 Thread Richard Henderson
The test for singlestepping is done in translator_use_goto_tb,
so we may elide it from cris_tr_tb_stop.

Cc: Edgar E. Iglesias 
Signed-off-by: Richard Henderson 
---
 target/cris/translate.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index 3200819f32..33ad76c0a8 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -517,7 +517,7 @@ static void t_gen_swapr(TCGv d, TCGv s)
 
 static bool use_goto_tb(DisasContext *dc, target_ulong dest)
 {
-return ((dest ^ dc->base.pc_first) & TARGET_PAGE_MASK) == 0;
+return translator_use_goto_tb(>base, dest);
 }
 
 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
@@ -3275,8 +3275,7 @@ static void cris_tr_tb_stop(DisasContextBase *dcbase, 
CPUState *cpu)
  * Use a conditional branch if either taken or not-taken path
  * can use goto_tb.  If neither can, then treat it as indirect.
  */
-if (likely(!dc->base.singlestep_enabled)
-&& (use_goto_tb(dc, dc->jmp_pc) || use_goto_tb(dc, npc))) {
+if (use_goto_tb(dc, dc->jmp_pc) || use_goto_tb(dc, npc)) {
 TCGLabel *not_taken = gen_new_label();
 
 tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, not_taken);
-- 
2.25.1




[PATCH 13/26] target/mips: Use translator_use_goto_tb

2021-06-20 Thread Richard Henderson
Just use translator_use_goto_tb directly at the one call site,
rather than maintaining a local wrapper.

Cc: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/mips/tcg/translate.c | 17 ++---
 1 file changed, 2 insertions(+), 15 deletions(-)

diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index 797eba4434..d59986b340 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -5019,22 +5019,9 @@ static void gen_trap(DisasContext *ctx, uint32_t opc,
 tcg_temp_free(t1);
 }
 
-static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
+static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
 {
-if (unlikely(ctx->base.singlestep_enabled)) {
-return false;
-}
-
-#ifndef CONFIG_USER_ONLY
-return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-return true;
-#endif
-}
-
-static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
-{
-if (use_goto_tb(ctx, dest)) {
+if (translator_use_goto_tb(>base, dest)) {
 tcg_gen_goto_tb(n);
 gen_save_pc(dest);
 tcg_gen_exit_tb(ctx->base.tb, n);
-- 
2.25.1




[PATCH 15/26] target/nios2: Use translator_use_goto_tb

2021-06-20 Thread Richard Henderson
Just use translator_use_goto_tb directly at the one call site,
rather than maintaining a local wrapper.

Cc: Chris Wulff 
Cc: Marek Vasut 
Signed-off-by: Richard Henderson 
---
 target/nios2/translate.c | 15 +--
 1 file changed, 1 insertion(+), 14 deletions(-)

diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 276643cee0..2e2c83f3ad 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -150,24 +150,11 @@ static void t_gen_helper_raise_exception(DisasContext *dc,
 dc->base.is_jmp = DISAS_NORETURN;
 }
 
-static bool use_goto_tb(DisasContext *dc, uint32_t dest)
-{
-if (unlikely(dc->base.singlestep_enabled)) {
-return false;
-}
-
-#ifndef CONFIG_USER_ONLY
-return (dc->base.pc_first & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-return true;
-#endif
-}
-
 static void gen_goto_tb(DisasContext *dc, int n, uint32_t dest)
 {
 const TranslationBlock *tb = dc->base.tb;
 
-if (use_goto_tb(dc, dest)) {
+if (translator_use_goto_tb(>base, dest)) {
 tcg_gen_goto_tb(n);
 tcg_gen_movi_tl(cpu_R[R_PC], dest);
 tcg_gen_exit_tb(tb, n);
-- 
2.25.1




[PATCH 22/26] target/sh4: Use translator_use_goto_tb

2021-06-20 Thread Richard Henderson
Cc: Yoshinori Sato 
Signed-off-by: Richard Henderson 
---
 target/sh4/translate.c | 11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/target/sh4/translate.c b/target/sh4/translate.c
index 9312790623..9ac9bc722e 100644
--- a/target/sh4/translate.c
+++ b/target/sh4/translate.c
@@ -225,17 +225,12 @@ static inline bool use_exit_tb(DisasContext *ctx)
 return (ctx->tbflags & GUSA_EXCLUSIVE) != 0;
 }
 
-static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
+static bool use_goto_tb(DisasContext *ctx, target_ulong dest)
 {
-/* Use a direct jump if in same page and singlestep not enabled */
-if (unlikely(ctx->base.singlestep_enabled || use_exit_tb(ctx))) {
+if (use_exit_tb(ctx)) {
 return false;
 }
-#ifndef CONFIG_USER_ONLY
-return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-return true;
-#endif
+return translator_use_goto_tb(>base, dest);
 }
 
 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
-- 
2.25.1




[PATCH 05/26] target/arm: Use translator_use_goto_tb

2021-06-20 Thread Richard Henderson
Put a wrapper in translate.h, which also checks for ss_active.
The ss_active test was incorrectly missing from the a32 version.

Cc: qemu-...@nongnu.org
Signed-off-by: Richard Henderson 
---
 target/arm/translate.h | 13 +
 target/arm/translate-a64.c | 22 +-
 target/arm/translate.c | 10 --
 3 files changed, 14 insertions(+), 31 deletions(-)

diff --git a/target/arm/translate.h b/target/arm/translate.h
index 2821b325e3..3a62f50faf 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -116,6 +116,19 @@ typedef struct DisasContext {
 TCGv_i64 tmp_a64[TMP_A64_MAX];
 } DisasContext;
 
+static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
+{
+/*
+ * No direct tb linking with singlestep.
+ * This handles the ARM debug architecture kind; the QEMU kind
+ * is handled inside translator_use_goto_tb.
+ */
+if (s->ss_active) {
+return false;
+}
+return translator_use_goto_tb(>base, dest);
+}
+
 typedef struct DisasCompare {
 TCGCond cond;
 TCGv_i32 value;
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 7f74d0e81a..ac58a86e59 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -386,32 +386,12 @@ static void gen_step_complete_exception(DisasContext *s)
 s->base.is_jmp = DISAS_NORETURN;
 }
 
-static inline bool use_goto_tb(DisasContext *s, int n, uint64_t dest)
-{
-/* No direct tb linking with singlestep (either QEMU's or the ARM
- * debug architecture kind) or deterministic io
- */
-if (s->base.singlestep_enabled || s->ss_active ||
-(tb_cflags(s->base.tb) & CF_LAST_IO)) {
-return false;
-}
-
-#ifndef CONFIG_USER_ONLY
-/* Only link tbs from inside the same guest page */
-if ((s->base.tb->pc & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
-return false;
-}
-#endif
-
-return true;
-}
-
 static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
 {
 const TranslationBlock *tb;
 
 tb = s->base.tb;
-if (use_goto_tb(s, n, dest)) {
+if (use_goto_tb(s, dest)) {
 tcg_gen_goto_tb(n);
 gen_a64_set_pc_im(dest);
 tcg_gen_exit_tb(tb, n);
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 9e2cca7707..3ac7943d86 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -2511,16 +2511,6 @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
 return 1;
 }
 
-static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
-{
-#ifndef CONFIG_USER_ONLY
-return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
-   ((s->base.pc_next - 1) & TARGET_PAGE_MASK) == (dest & 
TARGET_PAGE_MASK);
-#else
-return true;
-#endif
-}
-
 static void gen_goto_ptr(void)
 {
 tcg_gen_lookup_and_goto_ptr();
-- 
2.25.1




[PATCH 03/26] target/alpha: Remove in_superpage

2021-06-20 Thread Richard Henderson
The number of links across (normal) pages using this is low,
and it will shortly violate the contract for breakpoints.

Signed-off-by: Richard Henderson 
---
 target/alpha/translate.c | 24 ++--
 1 file changed, 2 insertions(+), 22 deletions(-)

diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index 70ba4a67c7..6ea19a1d4c 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -439,24 +439,9 @@ static DisasJumpType gen_store_conditional(DisasContext 
*ctx, int ra, int rb,
 return DISAS_NEXT;
 }
 
-static bool in_superpage(DisasContext *ctx, int64_t addr)
-{
-#ifndef CONFIG_USER_ONLY
-return ((ctx->tbflags & ENV_FLAG_PS_USER) == 0
-&& addr >> TARGET_VIRT_ADDR_SPACE_BITS == -1
-&& ((addr >> 41) & 3) == 2);
-#else
-return false;
-#endif
-}
-
 static bool use_goto_tb(DisasContext *ctx, uint64_t dest)
 {
 #ifndef CONFIG_USER_ONLY
-/* If the destination is in the superpage, the page perms can't change.  */
-if (in_superpage(ctx, dest)) {
-return true;
-}
 /* Check for the dest on the same page as the start of the TB.  */
 return ((ctx->base.tb->pc ^ dest) & TARGET_PAGE_MASK) == 0;
 #else
@@ -2916,7 +2901,7 @@ static void alpha_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cpu)
 {
 DisasContext *ctx = container_of(dcbase, DisasContext, base);
 CPUAlphaState *env = cpu->env_ptr;
-int64_t bound, mask;
+int64_t bound;
 
 ctx->tbflags = ctx->base.tb->flags;
 ctx->mem_idx = cpu_mmu_index(env, false);
@@ -2945,12 +2930,7 @@ static void alpha_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cpu)
 ctx->lit = NULL;
 
 /* Bound the number of insns to execute to those left on the page.  */
-if (in_superpage(ctx, ctx->base.pc_first)) {
-mask = -1ULL << 41;
-} else {
-mask = TARGET_PAGE_MASK;
-}
-bound = -(ctx->base.pc_first | mask) / 4;
+bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4;
 ctx->base.max_insns = MIN(ctx->base.max_insns, bound);
 }
 
-- 
2.25.1




[PATCH 12/26] target/microblaze: Use translator_use_goto_tb

2021-06-20 Thread Richard Henderson
Just use translator_use_goto_tb directly at the one call site,
rather than maintaining a local wrapper.

Cc: Edgar E. Iglesias 
Signed-off-by: Richard Henderson 
---
 target/microblaze/translate.c | 11 +--
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index c1b13f4c7d..b753f080e7 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -125,15 +125,6 @@ static void gen_raise_hw_excp(DisasContext *dc, uint32_t 
esr_ec)
 gen_raise_exception_sync(dc, EXCP_HW_EXCP);
 }
 
-static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
-{
-#ifndef CONFIG_USER_ONLY
-return (dc->base.pc_first & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-return true;
-#endif
-}
-
 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
 {
 if (dc->base.singlestep_enabled) {
@@ -141,7 +132,7 @@ static void gen_goto_tb(DisasContext *dc, int n, 
target_ulong dest)
 tcg_gen_movi_i32(cpu_pc, dest);
 gen_helper_raise_exception(cpu_env, tmp);
 tcg_temp_free_i32(tmp);
-} else if (use_goto_tb(dc, dest)) {
+} else if (translator_use_goto_tb(>base, dest)) {
 tcg_gen_goto_tb(n);
 tcg_gen_movi_i32(cpu_pc, dest);
 tcg_gen_exit_tb(dc->base.tb, n);
-- 
2.25.1




[PATCH 10/26] target/i386: Use translator_use_goto_tb

2021-06-20 Thread Richard Henderson
Just use translator_use_goto_tb directly at the one call site,
rather than maintaining a local wrapper.

Cc: Paolo Bonzini 
Cc: Eduardo Habkost 
Signed-off-by: Richard Henderson 
---
 target/i386/tcg/translate.c | 14 ++
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index a7f5c0c8f2..e47b220ce7 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -2314,21 +2314,11 @@ static inline int insn_const_size(MemOp ot)
 }
 }
 
-static inline bool use_goto_tb(DisasContext *s, target_ulong pc)
-{
-#ifndef CONFIG_USER_ONLY
-return (pc & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK) ||
-   (pc & TARGET_PAGE_MASK) == (s->pc_start & TARGET_PAGE_MASK);
-#else
-return true;
-#endif
-}
-
-static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
+static void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
 {
 target_ulong pc = s->cs_base + eip;
 
-if (use_goto_tb(s, pc))  {
+if (translator_use_goto_tb(>base, pc))  {
 /* jump to same page: we can use a direct jump */
 tcg_gen_goto_tb(tb_num);
 gen_jmp_im(s, eip);
-- 
2.25.1




[PATCH 04/26] target/alpha: Use translator_use_goto_tb

2021-06-20 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/alpha/translate.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index 6ea19a1d4c..1aa6d24d83 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -441,12 +441,7 @@ static DisasJumpType gen_store_conditional(DisasContext 
*ctx, int ra, int rb,
 
 static bool use_goto_tb(DisasContext *ctx, uint64_t dest)
 {
-#ifndef CONFIG_USER_ONLY
-/* Check for the dest on the same page as the start of the TB.  */
-return ((ctx->base.tb->pc ^ dest) & TARGET_PAGE_MASK) == 0;
-#else
-return true;
-#endif
+return translator_use_goto_tb(>base, dest);
 }
 
 static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
-- 
2.25.1




[PATCH 02/26] target/alpha: Remove use_exit_tb

2021-06-20 Thread Richard Henderson
We have not needed to end a TB for I/O since ba3e7926691
("icount: clean up cpu_can_io at the entry to the block").
We do not need to use exit_tb for singlestep, which only
means generate one insn per TB.

Which leaves only singlestep_enabled, which means raise a
debug trap after every TB, which does not use exit_tb,
which would leave the function mis-named.

Signed-off-by: Richard Henderson 
---
 target/alpha/translate.c | 15 ++-
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index f454adea5e..70ba4a67c7 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -450,19 +450,8 @@ static bool in_superpage(DisasContext *ctx, int64_t addr)
 #endif
 }
 
-static bool use_exit_tb(DisasContext *ctx)
-{
-return ((tb_cflags(ctx->base.tb) & CF_LAST_IO)
-|| ctx->base.singlestep_enabled
-|| singlestep);
-}
-
 static bool use_goto_tb(DisasContext *ctx, uint64_t dest)
 {
-/* Suppress goto_tb in the case of single-steping and IO.  */
-if (unlikely(use_exit_tb(ctx))) {
-return false;
-}
 #ifndef CONFIG_USER_ONLY
 /* If the destination is in the superpage, the page perms can't change.  */
 if (in_superpage(ctx, dest)) {
@@ -1271,7 +1260,7 @@ static DisasJumpType gen_call_pal(DisasContext *ctx, int 
palcode)
need the page permissions check.  We'll see the existence of
the page when we create the TB, and we'll flush all TBs if
we change the PAL base register.  */
-if (!use_exit_tb(ctx)) {
+if (!ctx->base.singlestep_enabled) {
 tcg_gen_goto_tb(0);
 tcg_gen_movi_i64(cpu_pc, entry);
 tcg_gen_exit_tb(ctx->base.tb, 0);
@@ -3020,7 +3009,7 @@ static void alpha_tr_tb_stop(DisasContextBase *dcbase, 
CPUState *cpu)
 tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
 /* FALLTHRU */
 case DISAS_PC_UPDATED:
-if (!use_exit_tb(ctx)) {
+if (!ctx->base.singlestep_enabled) {
 tcg_gen_lookup_and_goto_ptr();
 break;
 }
-- 
2.25.1




[PATCH 06/26] target/avr: Use translator_use_goto_tb

2021-06-20 Thread Richard Henderson
Single stepping is not the only reason not to use goto_tb.
If goto_tb is disallowed, and single-stepping is not enabled,
then use tcg_gen_lookup_and_goto_tb to indirectly chain.

Cc: Michael Rolnik 
Signed-off-by: Richard Henderson 
---
 target/avr/translate.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/target/avr/translate.c b/target/avr/translate.c
index c06ce45bc7..8237a03c23 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -1083,14 +1083,17 @@ static void gen_goto_tb(DisasContext *ctx, int n, 
target_ulong dest)
 {
 const TranslationBlock *tb = ctx->base.tb;
 
-if (!ctx->base.singlestep_enabled) {
+if (translator_use_goto_tb(>base, dest)) {
 tcg_gen_goto_tb(n);
 tcg_gen_movi_i32(cpu_pc, dest);
 tcg_gen_exit_tb(tb, n);
 } else {
 tcg_gen_movi_i32(cpu_pc, dest);
-gen_helper_debug(cpu_env);
-tcg_gen_exit_tb(NULL, 0);
+if (ctx->base.singlestep_enabled) {
+gen_helper_debug(cpu_env);
+} else {
+tcg_gen_lookup_and_goto_ptr();
+}
 }
 ctx->base.is_jmp = DISAS_NORETURN;
 }
-- 
2.25.1




[PATCH 01/26] accel/tcg: Introduce translator_use_goto_tb

2021-06-20 Thread Richard Henderson
Add a generic version of the common use_goto_tb test.

Signed-off-by: Richard Henderson 
---
 include/exec/translator.h | 10 ++
 accel/tcg/translator.c| 11 +++
 2 files changed, 21 insertions(+)

diff --git a/include/exec/translator.h b/include/exec/translator.h
index 24232ead41..dd9c06d40d 100644
--- a/include/exec/translator.h
+++ b/include/exec/translator.h
@@ -145,6 +145,16 @@ void translator_loop(const TranslatorOps *ops, 
DisasContextBase *db,
 
 void translator_loop_temp_check(DisasContextBase *db);
 
+/**
+ * translator_use_goto_tb
+ * @db: Disassembly context
+ * @dest: target pc of the goto
+ *
+ * Return true if goto_tb is allowed between the current TB
+ * and the destination PC.
+ */
+bool translator_use_goto_tb(DisasContextBase *db, target_ulong dest);
+
 /*
  * Translator Load Functions
  *
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
index 1d32732198..59804af37b 100644
--- a/accel/tcg/translator.c
+++ b/accel/tcg/translator.c
@@ -31,6 +31,17 @@ void translator_loop_temp_check(DisasContextBase *db)
 }
 }
 
+bool translator_use_goto_tb(DisasContextBase *db, target_ulong dest)
+{
+/* Suppress goto_tb in the case of single-steping.  */
+if (db->singlestep_enabled || singlestep) {
+return false;
+}
+
+/* Check for the dest on the same page as the start of the TB.  */
+return ((db->pc_first ^ dest) & TARGET_PAGE_MASK) == 0;
+}
+
 void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
  CPUState *cpu, TranslationBlock *tb, int max_insns)
 {
-- 
2.25.1




[PATCH 09/26] target/hppa: Use translator_use_goto_tb

2021-06-20 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 64af1e0d5c..952cfe09a6 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -817,10 +817,7 @@ static bool gen_illegal(DisasContext *ctx)
 
 static bool use_goto_tb(DisasContext *ctx, target_ureg dest)
 {
-/* Suppress goto_tb for page crossing, IO, or single-steping.  */
-return !(((ctx->base.pc_first ^ dest) & TARGET_PAGE_MASK)
- || (tb_cflags(ctx->base.tb) & CF_LAST_IO)
- || ctx->base.singlestep_enabled);
+return translator_use_goto_tb(>base, dest);
 }
 
 /* If the next insn is to be nullified, and it's on the same page,
-- 
2.25.1




[PATCH 00/26] accel/tcg: Introduce translator_use_goto_tb

2021-06-20 Thread Richard Henderson
There are a number of inconsistencies with goto_tb usage, and I
plan to make changes in order to better support breakpoints.

(1) Testing CF_LAST_IO is a hold-over from since before ba3e7926691
("icount: clean up cpu_can_io at the entry to the block").
Several targets still have this test.

(2) Testing singlestep is superfluous, as it doesn't mean anything
besides limiting max_insns to 1.

(3) Not testing page crossing for CONFIG_USER_ONLY is wrong, because
mmap and mprotect can change page permissions.  It's a very
uncommon case wrt executables, but it's still wrong.

(4) Not testing page crossing for non-mmu targets (where page
permissions literally cannot change) is not currently wrong,
but will be after the breakpoint changes.

(5) When the TB does cross two pages, considering non-page crossing
from the second page is not currently wrong, but will be after
the breakpoint changes.

Based on my recent avr, cris and nios2 patch sets.  The full tree is

https://gitlab.com/rth7680/qemu/-/tree/tcg-goto-tb


r~


Richard Henderson (26):
  accel/tcg: Introduce translator_use_goto_tb
  target/alpha: Remove use_exit_tb
  target/alpha: Remove in_superpage
  target/alpha: Use translator_use_goto_tb
  target/arm: Use translator_use_goto_tb
  target/avr: Use translator_use_goto_tb
  target/avr: Mark some helpers noreturn
  target/cris: Use translator_use_goto_tb
  target/hppa: Use translator_use_goto_tb
  target/i386: Use translator_use_goto_tb
  target/m68k: Use translator_use_goto_tb
  target/microblaze: Use translator_use_goto_tb
  target/mips: Use translator_use_goto_tb
  target/mips: Fix missing else in gen_goto_tb
  target/nios2: Use translator_use_goto_tb
  target/openrisc: Use translator_use_goto_tb
  target/ppc: Use translator_use_goto_tb
  target/riscv: Use translator_use_goto_tb
  target/rx: Use translator_use_goto_tb
  target/s390x: Use translator_use_goto_tb
  target/s390x: Remove use_exit_tb
  target/sh4: Use translator_use_goto_tb
  target/sparc: Use translator_use_goto_tb
  target/tricore: Use translator_use_goto_tb
  target/tricore: Use tcg_gen_lookup_and_goto_ptr
  target/xtensa: Use translator_use_goto_tb

 include/exec/translator.h | 10 
 target/arm/translate.h| 13 ++
 target/avr/helper.h   |  8 +++---
 accel/tcg/translator.c| 11 +
 target/alpha/translate.c  | 46 ---
 target/arm/translate-a64.c| 22 +
 target/arm/translate.c| 10 
 target/avr/translate.c|  9 ---
 target/cris/translate.c   |  5 ++--
 target/hppa/translate.c   |  5 +---
 target/i386/tcg/translate.c   | 14 ++-
 target/m68k/translate.c   | 12 +
 target/microblaze/translate.c | 11 +
 target/mips/tcg/translate.c   | 20 +++
 target/nios2/translate.c  | 15 +---
 target/openrisc/translate.c   | 15 ++--
 target/ppc/translate.c| 10 +---
 target/riscv/translate.c  | 20 +--
 target/rx/translate.c | 11 +
 target/s390x/translate.c  | 18 +++---
 target/sh4/translate.c| 11 +++--
 target/sparc/translate.c  | 19 ---
 target/tricore/translate.c| 20 +++
 target/xtensa/translate.c |  6 +
 24 files changed, 89 insertions(+), 252 deletions(-)

-- 
2.25.1




Re: [PATCH v2 02/11] linux-user: Fix the execfd case of /proc/self/exe open

2021-06-20 Thread Takashi Yamamoto
On Sun, Jun 20, 2021 at 11:16 PM Laurent Vivier  wrote:
>
> Le 31/05/2021 à 07:50, YAMAMOTO Takashi a écrit :
> > It's problematic to return AT_EXECFD as it is because the user app
> > would close it.
> > This patch opens it via /proc/self/fd instead.
> >
> > Signed-off-by: YAMAMOTO Takashi 
> > ---
> >  linux-user/syscall.c | 12 +++-
> >  1 file changed, 11 insertions(+), 1 deletion(-)
> >
> > diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> > index a2b03ecb8b..14a63518e2 100644
> > --- a/linux-user/syscall.c
> > +++ b/linux-user/syscall.c
> > @@ -8118,7 +8118,17 @@ static int do_openat(void *cpu_env, int dirfd, const 
> > char *pathname, int flags,
> >
> >  if (is_proc_myself(pathname, "exe")) {
> >  int execfd = qemu_getauxval(AT_EXECFD);
> > -return execfd ? execfd : safe_openat(dirfd, exec_path, flags, 
> > mode);
> > +if (execfd) {
> > +char filename[PATH_MAX];
> > +int ret;
> > +
> > +snprintf(filename, sizeof(filename), "/proc/self/fd/%d", 
> > execfd);
> > +ret = safe_openat(dirfd, filename, flags, mode);
> > +if (ret != -1) {
> > +return ret;
> > +}
> > +}
> > +return safe_openat(dirfd, exec_path, flags, mode);
> >  }
> >
> >  for (fake_open = fakes; fake_open->filename; fake_open++) {
> >
>
> I think a dup() would be more appropriate, or explain why not.

i did this way because dup() doesn't deal with open flags.

>
> Thanks,
> Laurent



[PATCH v2 5/7] target/nios2: Convert to TranslatorOps

2021-06-20 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/nios2/translate.c | 130 ---
 1 file changed, 67 insertions(+), 63 deletions(-)

diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 31653b7912..06705c894d 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -803,75 +803,72 @@ static void gen_exception(DisasContext *dc, uint32_t excp)
 }
 
 /* generate intermediate code for basic block 'tb'.  */
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
+static void nios2_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
 {
+DisasContext *dc = container_of(dcbase, DisasContext, base);
 CPUNios2State *env = cs->env_ptr;
-DisasContext dc1, *dc = 
-int num_insns;
-
-/* Initialize DC */
-
-dc->base.tb = tb;
-dc->base.singlestep_enabled = cs->singlestep_enabled;
-dc->base.is_jmp = DISAS_NEXT;
-dc->base.pc_first = tb->pc;
-dc->base.pc_next = tb->pc;
+target_ulong pc = dc->base.pc_first;
+int page_insns;
 
 dc->zero= NULL;
-dc->pc  = tb->pc;
+dc->pc  = pc;
 dc->mem_idx = cpu_mmu_index(env, false);
 
-/* Set up instruction counts */
-num_insns = 0;
-if (max_insns > 1) {
-int page_insns = (TARGET_PAGE_SIZE - (tb->pc & ~TARGET_PAGE_MASK)) / 4;
-if (max_insns > page_insns) {
-max_insns = page_insns;
-}
-}
+/* Bound the number of insns to execute to those left on the page.  */
+page_insns = -(pc | TARGET_PAGE_MASK) / 4;
+dc->base.max_insns = MIN(page_insns, dc->base.max_insns);
+}
 
-gen_tb_start(tb);
-do {
-tcg_gen_insn_start(dc->pc);
-num_insns++;
+static void nios2_tr_tb_start(DisasContextBase *db, CPUState *cs)
+{
+}
 
-if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
-gen_exception(dc, EXCP_DEBUG);
-/* The address covered by the breakpoint must be included in
-   [tb->pc, tb->pc + tb->size) in order to for it to be
-   properly cleared -- thus we increment the PC here so that
-   the logic setting tb->size below does the right thing.  */
-dc->pc += 4;
-break;
-}
+static void nios2_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
+{
+tcg_gen_insn_start(dcbase->pc_next);
+}
 
-if (num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
-gen_io_start();
-}
+static bool nios2_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
+  const CPUBreakpoint *bp)
+{
+DisasContext *dc = container_of(dcbase, DisasContext, base);
 
-/* Decode an instruction */
-handle_instruction(dc, env);
+gen_exception(dc, EXCP_DEBUG);
+/*
+ * The address covered by the breakpoint must be included in
+ * [tb->pc, tb->pc + tb->size) in order to for it to be
+ * properly cleared -- thus we increment the PC here so that
+ * the logic setting tb->size below does the right thing.
+ */
+dc->pc += 4;
+return true;
+}
 
-dc->pc += 4;
+static void nios2_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
+{
+DisasContext *dc = container_of(dcbase, DisasContext, base);
+CPUNios2State *env = cs->env_ptr;
 
-/* Translation stops when a conditional branch is encountered.
- * Otherwise the subsequent code could get translated several times.
- * Also stop translation when a page boundary is reached.  This
- * ensures prefetch aborts occur at the right place.  */
-} while (!dc->base.is_jmp &&
- !tcg_op_buf_full() &&
- num_insns < max_insns);
+/* Decode an instruction */
+handle_instruction(dc, env);
+
+dc->base.pc_next += 4;
+dc->pc += 4;
+}
+
+static void nios2_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
+{
+DisasContext *dc = container_of(dcbase, DisasContext, base);
 
 /* Indicate where the next block should start */
 switch (dc->base.is_jmp) {
-case DISAS_NEXT:
+case DISAS_TOO_MANY:
 case DISAS_UPDATE:
 /* Save the current PC back into the CPU register */
 tcg_gen_movi_tl(cpu_R[R_PC], dc->pc);
 tcg_gen_exit_tb(NULL, 0);
 break;
 
-default:
 case DISAS_JUMP:
 /* The jump will already have updated the PC register */
 tcg_gen_exit_tb(NULL, 0);
@@ -880,25 +877,32 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock 
*tb, int max_insns)
 case DISAS_NORETURN:
 /* nothing more to generate */
 break;
+
+default:
+g_assert_not_reached();
 }
+}
 
-/* End off the block */
-gen_tb_end(tb, num_insns);
+static void nios2_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
+{
+qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
+log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size);
+}
 
-/* Mark instruction 

[PATCH v2 2/7] target/nios2: Use global cpu_env

2021-06-20 Thread Richard Henderson
We do not need to copy this into DisasContext.

Signed-off-by: Richard Henderson 
---
 target/nios2/translate.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 388fae93a2..39538e1870 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -97,7 +97,6 @@
 }
 
 typedef struct DisasContext {
-TCGv_ptr  cpu_env;
 TCGv *cpu_R;
 TCGv_i32  zero;
 int   is_jmp;
@@ -147,7 +146,7 @@ static void t_gen_helper_raise_exception(DisasContext *dc,
 TCGv_i32 tmp = tcg_const_i32(index);
 
 tcg_gen_movi_tl(dc->cpu_R[R_PC], dc->pc);
-gen_helper_raise_exception(dc->cpu_env, tmp);
+gen_helper_raise_exception(cpu_env, tmp);
 tcg_temp_free_i32(tmp);
 dc->is_jmp = DISAS_NORETURN;
 }
@@ -474,7 +473,7 @@ static void rdctl(DisasContext *dc, uint32_t code, uint32_t 
flags)
 tcg_gen_mov_tl(dc->cpu_R[instr.c], dc->cpu_R[instr.imm5 + 
CR_BASE]);
 #ifdef DEBUG_MMU
 TCGv_i32 tmp = tcg_const_i32(instr.imm5 + CR_BASE);
-gen_helper_mmu_read_debug(dc->cpu_R[instr.c], dc->cpu_env, tmp);
+gen_helper_mmu_read_debug(dc->cpu_R[instr.c], cpu_env, tmp);
 tcg_temp_free_i32(tmp);
 #endif
 }
@@ -504,7 +503,7 @@ static void wrctl(DisasContext *dc, uint32_t code, uint32_t 
flags)
 {
 #if !defined(CONFIG_USER_ONLY)
 TCGv_i32 tmp = tcg_const_i32(instr.imm5 + CR_BASE);
-gen_helper_mmu_write(dc->cpu_env, tmp, load_gpr(dc, instr.a));
+gen_helper_mmu_write(cpu_env, tmp, load_gpr(dc, instr.a));
 tcg_temp_free_i32(tmp);
 #endif
 break;
@@ -521,7 +520,7 @@ static void wrctl(DisasContext *dc, uint32_t code, uint32_t 
flags)
 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
 gen_io_start();
 }
-gen_helper_check_interrupts(dc->cpu_env);
+gen_helper_check_interrupts(cpu_env);
 dc->is_jmp = DISAS_UPDATE;
 }
 #endif
@@ -817,7 +816,6 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock 
*tb, int max_insns)
 int num_insns;
 
 /* Initialize DC */
-dc->cpu_env = cpu_env;
 dc->cpu_R   = cpu_R;
 dc->is_jmp  = DISAS_NEXT;
 dc->pc  = tb->pc;
-- 
2.25.1




[PATCH v2 6/7] target/nios2: Remove assignment to env in handle_instruction

2021-06-20 Thread Richard Henderson
Direct assignments to env during translation do not work.

As it happens, the only way we can get here is if env->pc
is already set to dc->pc.  We will trap on the first insn
we execute anywhere on the page.

Signed-off-by: Richard Henderson 
---
 target/nios2/translate.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 06705c894d..31f63d9faa 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -740,14 +740,15 @@ static void handle_instruction(DisasContext *dc, 
CPUNios2State *env)
 uint32_t code;
 uint8_t op;
 const Nios2Instruction *instr;
+
 #if defined(CONFIG_USER_ONLY)
 /* FIXME: Is this needed ? */
 if (dc->pc >= 0x1000 && dc->pc < 0x2000) {
-env->regs[R_PC] = dc->pc;
 t_gen_helper_raise_exception(dc, 0xaa);
 return;
 }
 #endif
+
 code = cpu_ldl_code(env, dc->pc);
 op = get_opcode(code);
 
-- 
2.25.1




[PATCH v2 1/7] target/nios2: Replace DISAS_TB_JUMP with DISAS_NORETURN

2021-06-20 Thread Richard Henderson
The only semantic of DISAS_TB_JUMP is that we've done goto_tb,
which is the same as DISAS_NORETURN -- we've exited the tb.

Signed-off-by: Richard Henderson 
---
 target/nios2/translate.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 399f22d938..388fae93a2 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -37,7 +37,6 @@
 /* is_jmp field values */
 #define DISAS_JUMPDISAS_TARGET_0 /* only pc was modified dynamically */
 #define DISAS_UPDATE  DISAS_TARGET_1 /* cpu state was modified dynamically */
-#define DISAS_TB_JUMP DISAS_TARGET_2 /* only pc was modified statically */
 
 #define INSTRUCTION_FLG(func, flags) { (func), (flags) }
 #define INSTRUCTION(func)  \
@@ -209,7 +208,7 @@ static void jmpi(DisasContext *dc, uint32_t code, uint32_t 
flags)
 {
 J_TYPE(instr, code);
 gen_goto_tb(dc, 0, (dc->pc & 0xF000) | (instr.imm26 << 2));
-dc->is_jmp = DISAS_TB_JUMP;
+dc->is_jmp = DISAS_NORETURN;
 }
 
 static void call(DisasContext *dc, uint32_t code, uint32_t flags)
@@ -269,7 +268,7 @@ static void br(DisasContext *dc, uint32_t code, uint32_t 
flags)
 I_TYPE(instr, code);
 
 gen_goto_tb(dc, 0, dc->pc + 4 + (instr.imm16.s & -4));
-dc->is_jmp = DISAS_TB_JUMP;
+dc->is_jmp = DISAS_NORETURN;
 }
 
 static void gen_bxx(DisasContext *dc, uint32_t code, uint32_t flags)
@@ -281,7 +280,7 @@ static void gen_bxx(DisasContext *dc, uint32_t code, 
uint32_t flags)
 gen_goto_tb(dc, 0, dc->pc + 4);
 gen_set_label(l1);
 gen_goto_tb(dc, 1, dc->pc + 4 + (instr.imm16.s & -4));
-dc->is_jmp = DISAS_TB_JUMP;
+dc->is_jmp = DISAS_NORETURN;
 }
 
 /* Comparison instructions */
@@ -883,7 +882,6 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock 
*tb, int max_insns)
 break;
 
 case DISAS_NORETURN:
-case DISAS_TB_JUMP:
 /* nothing more to generate */
 break;
 }
-- 
2.25.1




[PATCH v2 3/7] target/nios2: Use global cpu_R

2021-06-20 Thread Richard Henderson
We do not need to copy this into DisasContext.

Signed-off-by: Richard Henderson 
---
 target/nios2/translate.c | 73 +++-
 1 file changed, 34 insertions(+), 39 deletions(-)

diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 39538e1870..6bdd388bd8 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -97,7 +97,6 @@
 }
 
 typedef struct DisasContext {
-TCGv *cpu_R;
 TCGv_i32  zero;
 int   is_jmp;
 target_ulong  pc;
@@ -106,6 +105,8 @@ typedef struct DisasContext {
 bool  singlestep_enabled;
 } DisasContext;
 
+static TCGv cpu_R[NUM_CORE_REGS];
+
 typedef struct Nios2Instruction {
 void (*handler)(DisasContext *dc, uint32_t code, uint32_t flags);
 uint32_t  flags;
@@ -134,7 +135,7 @@ static TCGv load_zero(DisasContext *dc)
 static TCGv load_gpr(DisasContext *dc, uint8_t reg)
 {
 if (likely(reg != R_ZERO)) {
-return dc->cpu_R[reg];
+return cpu_R[reg];
 } else {
 return load_zero(dc);
 }
@@ -145,7 +146,7 @@ static void t_gen_helper_raise_exception(DisasContext *dc,
 {
 TCGv_i32 tmp = tcg_const_i32(index);
 
-tcg_gen_movi_tl(dc->cpu_R[R_PC], dc->pc);
+tcg_gen_movi_tl(cpu_R[R_PC], dc->pc);
 gen_helper_raise_exception(cpu_env, tmp);
 tcg_temp_free_i32(tmp);
 dc->is_jmp = DISAS_NORETURN;
@@ -170,10 +171,10 @@ static void gen_goto_tb(DisasContext *dc, int n, uint32_t 
dest)
 
 if (use_goto_tb(dc, dest)) {
 tcg_gen_goto_tb(n);
-tcg_gen_movi_tl(dc->cpu_R[R_PC], dest);
+tcg_gen_movi_tl(cpu_R[R_PC], dest);
 tcg_gen_exit_tb(tb, n);
 } else {
-tcg_gen_movi_tl(dc->cpu_R[R_PC], dest);
+tcg_gen_movi_tl(cpu_R[R_PC], dest);
 tcg_gen_exit_tb(NULL, 0);
 }
 }
@@ -212,7 +213,7 @@ static void jmpi(DisasContext *dc, uint32_t code, uint32_t 
flags)
 
 static void call(DisasContext *dc, uint32_t code, uint32_t flags)
 {
-tcg_gen_movi_tl(dc->cpu_R[R_RA], dc->pc + 4);
+tcg_gen_movi_tl(cpu_R[R_RA], dc->pc + 4);
 jmpi(dc, code, flags);
 }
 
@@ -234,7 +235,7 @@ static void gen_ldx(DisasContext *dc, uint32_t code, 
uint32_t flags)
  *  the Nios2 CPU.
  */
 if (likely(instr.b != R_ZERO)) {
-data = dc->cpu_R[instr.b];
+data = cpu_R[instr.b];
 } else {
 data = tcg_temp_new();
 }
@@ -275,7 +276,7 @@ static void gen_bxx(DisasContext *dc, uint32_t code, 
uint32_t flags)
 I_TYPE(instr, code);
 
 TCGLabel *l1 = gen_new_label();
-tcg_gen_brcond_tl(flags, dc->cpu_R[instr.a], dc->cpu_R[instr.b], l1);
+tcg_gen_brcond_tl(flags, cpu_R[instr.a], cpu_R[instr.b], l1);
 gen_goto_tb(dc, 0, dc->pc + 4);
 gen_set_label(l1);
 gen_goto_tb(dc, 1, dc->pc + 4 + (instr.imm16.s & -4));
@@ -287,8 +288,7 @@ static void gen_bxx(DisasContext *dc, uint32_t code, 
uint32_t flags)
 static void (fname)(DisasContext *dc, uint32_t code, uint32_t flags) \
 {\
 I_TYPE(instr, (code));   \
-tcg_gen_setcondi_tl(flags, (dc)->cpu_R[instr.b], (dc)->cpu_R[instr.a],   \
-(op3));  \
+tcg_gen_setcondi_tl(flags, cpu_R[instr.b], cpu_R[instr.a], (op3));   \
 }
 
 gen_i_cmpxx(gen_cmpxxsi, instr.imm16.s)
@@ -302,10 +302,9 @@ static void (fname)(DisasContext *dc, uint32_t code, 
uint32_t flags)\
 if (unlikely(instr.b == R_ZERO)) { /* Store to R_ZERO is ignored */ \
 return; \
 } else if (instr.a == R_ZERO) { /* MOVxI optimizations */   \
-tcg_gen_movi_tl(dc->cpu_R[instr.b], (resimm) ? (op3) : 0);  \
+tcg_gen_movi_tl(cpu_R[instr.b], (resimm) ? (op3) : 0);  \
 } else {\
-tcg_gen_##insn##_tl((dc)->cpu_R[instr.b], (dc)->cpu_R[instr.a], \
-(op3)); \
+tcg_gen_##insn##_tl(cpu_R[instr.b], cpu_R[instr.a], (op3)); \
 }   \
 }
 
@@ -400,8 +399,8 @@ static const Nios2Instruction i_type_instructions[] = {
  */
 static void eret(DisasContext *dc, uint32_t code, uint32_t flags)
 {
-tcg_gen_mov_tl(dc->cpu_R[CR_STATUS], dc->cpu_R[CR_ESTATUS]);
-tcg_gen_mov_tl(dc->cpu_R[R_PC], dc->cpu_R[R_EA]);
+tcg_gen_mov_tl(cpu_R[CR_STATUS], cpu_R[CR_ESTATUS]);
+tcg_gen_mov_tl(cpu_R[R_PC], cpu_R[R_EA]);
 
 dc->is_jmp = DISAS_JUMP;
 }
@@ -409,7 +408,7 @@ static void eret(DisasContext *dc, uint32_t code, uint32_t 
flags)
 /* PC <- ra */
 static void ret(DisasContext *dc, uint32_t code, uint32_t flags)
 {
-tcg_gen_mov_tl(dc->cpu_R[R_PC], dc->cpu_R[R_RA]);
+ 

[PATCH v2 7/7] target/nios2: Clean up goto in handle_instruction

2021-06-20 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/nios2/translate.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 31f63d9faa..276643cee0 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -753,7 +753,8 @@ static void handle_instruction(DisasContext *dc, 
CPUNios2State *env)
 op = get_opcode(code);
 
 if (unlikely(op >= ARRAY_SIZE(i_type_instructions))) {
-goto illegal_op;
+t_gen_helper_raise_exception(dc, EXCP_ILLEGAL);
+return;
 }
 
 dc->zero = NULL;
@@ -764,11 +765,6 @@ static void handle_instruction(DisasContext *dc, 
CPUNios2State *env)
 if (dc->zero) {
 tcg_temp_free(dc->zero);
 }
-
-return;
-
-illegal_op:
-t_gen_helper_raise_exception(dc, EXCP_ILLEGAL);
 }
 
 static const char * const regnames[] = {
-- 
2.25.1




[PATCH v2 4/7] target/nios2: Add DisasContextBase to DisasContext

2021-06-20 Thread Richard Henderson
Migrate the is_jmp, tb and singlestep_enabled fields
from DisasContext into the base.

Signed-off-by: Richard Henderson 
---
 target/nios2/translate.c | 51 +---
 1 file changed, 27 insertions(+), 24 deletions(-)

diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 6bdd388bd8..31653b7912 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -97,12 +97,10 @@
 }
 
 typedef struct DisasContext {
+DisasContextBase  base;
 TCGv_i32  zero;
-int   is_jmp;
 target_ulong  pc;
-TranslationBlock *tb;
 int   mem_idx;
-bool  singlestep_enabled;
 } DisasContext;
 
 static TCGv cpu_R[NUM_CORE_REGS];
@@ -149,17 +147,17 @@ static void t_gen_helper_raise_exception(DisasContext *dc,
 tcg_gen_movi_tl(cpu_R[R_PC], dc->pc);
 gen_helper_raise_exception(cpu_env, tmp);
 tcg_temp_free_i32(tmp);
-dc->is_jmp = DISAS_NORETURN;
+dc->base.is_jmp = DISAS_NORETURN;
 }
 
 static bool use_goto_tb(DisasContext *dc, uint32_t dest)
 {
-if (unlikely(dc->singlestep_enabled)) {
+if (unlikely(dc->base.singlestep_enabled)) {
 return false;
 }
 
 #ifndef CONFIG_USER_ONLY
-return (dc->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
+return (dc->base.pc_first & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
 #else
 return true;
 #endif
@@ -167,7 +165,7 @@ static bool use_goto_tb(DisasContext *dc, uint32_t dest)
 
 static void gen_goto_tb(DisasContext *dc, int n, uint32_t dest)
 {
-TranslationBlock *tb = dc->tb;
+const TranslationBlock *tb = dc->base.tb;
 
 if (use_goto_tb(dc, dest)) {
 tcg_gen_goto_tb(n);
@@ -186,7 +184,7 @@ static void gen_excp(DisasContext *dc, uint32_t code, 
uint32_t flags)
 
 static void gen_check_supervisor(DisasContext *dc)
 {
-if (dc->tb->flags & CR_STATUS_U) {
+if (dc->base.tb->flags & CR_STATUS_U) {
 /* CPU in user mode, privileged instruction called, stop. */
 t_gen_helper_raise_exception(dc, EXCP_SUPERI);
 }
@@ -208,7 +206,7 @@ static void jmpi(DisasContext *dc, uint32_t code, uint32_t 
flags)
 {
 J_TYPE(instr, code);
 gen_goto_tb(dc, 0, (dc->pc & 0xF000) | (instr.imm26 << 2));
-dc->is_jmp = DISAS_NORETURN;
+dc->base.is_jmp = DISAS_NORETURN;
 }
 
 static void call(DisasContext *dc, uint32_t code, uint32_t flags)
@@ -268,7 +266,7 @@ static void br(DisasContext *dc, uint32_t code, uint32_t 
flags)
 I_TYPE(instr, code);
 
 gen_goto_tb(dc, 0, dc->pc + 4 + (instr.imm16.s & -4));
-dc->is_jmp = DISAS_NORETURN;
+dc->base.is_jmp = DISAS_NORETURN;
 }
 
 static void gen_bxx(DisasContext *dc, uint32_t code, uint32_t flags)
@@ -280,7 +278,7 @@ static void gen_bxx(DisasContext *dc, uint32_t code, 
uint32_t flags)
 gen_goto_tb(dc, 0, dc->pc + 4);
 gen_set_label(l1);
 gen_goto_tb(dc, 1, dc->pc + 4 + (instr.imm16.s & -4));
-dc->is_jmp = DISAS_NORETURN;
+dc->base.is_jmp = DISAS_NORETURN;
 }
 
 /* Comparison instructions */
@@ -402,7 +400,7 @@ static void eret(DisasContext *dc, uint32_t code, uint32_t 
flags)
 tcg_gen_mov_tl(cpu_R[CR_STATUS], cpu_R[CR_ESTATUS]);
 tcg_gen_mov_tl(cpu_R[R_PC], cpu_R[R_EA]);
 
-dc->is_jmp = DISAS_JUMP;
+dc->base.is_jmp = DISAS_JUMP;
 }
 
 /* PC <- ra */
@@ -410,7 +408,7 @@ static void ret(DisasContext *dc, uint32_t code, uint32_t 
flags)
 {
 tcg_gen_mov_tl(cpu_R[R_PC], cpu_R[R_RA]);
 
-dc->is_jmp = DISAS_JUMP;
+dc->base.is_jmp = DISAS_JUMP;
 }
 
 /* PC <- ba */
@@ -418,7 +416,7 @@ static void bret(DisasContext *dc, uint32_t code, uint32_t 
flags)
 {
 tcg_gen_mov_tl(cpu_R[R_PC], cpu_R[R_BA]);
 
-dc->is_jmp = DISAS_JUMP;
+dc->base.is_jmp = DISAS_JUMP;
 }
 
 /* PC <- rA */
@@ -428,7 +426,7 @@ static void jmp(DisasContext *dc, uint32_t code, uint32_t 
flags)
 
 tcg_gen_mov_tl(cpu_R[R_PC], load_gpr(dc, instr.a));
 
-dc->is_jmp = DISAS_JUMP;
+dc->base.is_jmp = DISAS_JUMP;
 }
 
 /* rC <- PC + 4 */
@@ -452,7 +450,7 @@ static void callr(DisasContext *dc, uint32_t code, uint32_t 
flags)
 tcg_gen_mov_tl(cpu_R[R_PC], load_gpr(dc, instr.a));
 tcg_gen_movi_tl(cpu_R[R_RA], dc->pc + 4);
 
-dc->is_jmp = DISAS_JUMP;
+dc->base.is_jmp = DISAS_JUMP;
 }
 
 /* rC <- ctlN */
@@ -516,11 +514,11 @@ static void wrctl(DisasContext *dc, uint32_t code, 
uint32_t flags)
 /* If interrupts were enabled using WRCTL, trigger them. */
 #if !defined(CONFIG_USER_ONLY)
 if ((instr.imm5 + CR_BASE) == CR_STATUS) {
-if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
+if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
 gen_io_start();
 }
 gen_helper_check_interrupts(cpu_env);
-dc->is_jmp = DISAS_UPDATE;
+dc->base.is_jmp = DISAS_UPDATE;
 }
 #endif
 }
@@ -801,7 +799,7 @@ static void gen_exception(DisasContext *dc, uint32_t excp)
 tcg_gen_movi_tl(cpu_R[R_PC], dc->pc);
 gen_helper_raise_exception(cpu_env, tmp);

[PATCH v2 0/7] target/nios2: Convert to TranslatorOps

2021-06-20 Thread Richard Henderson
I've reached a point where *all* targets must use the translator loop.  
Do that, plus some other obvious cleanups.

Changes for v2:
  * Fix (drop) singlestep check for max_insns.
We already do that generically.


r~


Richard Henderson (7):
  target/nios2: Replace DISAS_TB_JUMP with DISAS_NORETURN
  target/nios2: Use global cpu_env
  target/nios2: Use global cpu_R
  target/nios2: Add DisasContextBase to DisasContext
  target/nios2: Convert to TranslatorOps
  target/nios2: Remove assignment to env in handle_instruction
  target/nios2: Clean up goto in handle_instruction

 target/nios2/translate.c | 259 +++
 1 file changed, 127 insertions(+), 132 deletions(-)

-- 
2.25.1




[PATCH v2 3/3] target/avr: Convert to TranslatorOps

2021-06-20 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/avr/translate.c | 234 ++---
 1 file changed, 128 insertions(+), 106 deletions(-)

diff --git a/target/avr/translate.c b/target/avr/translate.c
index 66e9882422..c06ce45bc7 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -2897,113 +2897,131 @@ static bool canonicalize_skip(DisasContext *ctx)
 return true;
 }
 
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
+static void gen_breakpoint(DisasContext *ctx)
 {
+canonicalize_skip(ctx);
+tcg_gen_movi_tl(cpu_pc, ctx->npc);
+gen_helper_debug(cpu_env);
+ctx->base.is_jmp = DISAS_NORETURN;
+}
+
+static void avr_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
+{
+DisasContext *ctx = container_of(dcbase, DisasContext, base);
 CPUAVRState *env = cs->env_ptr;
-DisasContext ctx1 = {
-.base.tb = tb,
-.base.is_jmp = DISAS_NEXT,
-.base.pc_first = tb->pc,
-.base.pc_next = tb->pc,
-.base.singlestep_enabled = cs->singlestep_enabled,
-.cs = cs,
-.env = env,
-.memidx = 0,
-.skip_cond = TCG_COND_NEVER,
-};
-DisasContext *ctx = 
-target_ulong pc_start = tb->pc / 2;
-int num_insns = 0;
+uint32_t tb_flags = ctx->base.tb->flags;
 
-if (tb->flags & TB_FLAGS_FULL_ACCESS) {
-/*
- * This flag is set by ST/LD instruction we will regenerate it ONLY
- * with mem/cpu memory access instead of mem access
- */
-max_insns = 1;
-}
-if (ctx->base.singlestep_enabled) {
-max_insns = 1;
-}
+ctx->cs = cs;
+ctx->env = env;
+ctx->npc = ctx->base.pc_first / 2;
 
-gen_tb_start(tb);
-
-ctx->npc = pc_start;
-if (tb->flags & TB_FLAGS_SKIP) {
+ctx->skip_cond = TCG_COND_NEVER;
+if (tb_flags & TB_FLAGS_SKIP) {
 ctx->skip_cond = TCG_COND_ALWAYS;
 ctx->skip_var0 = cpu_skip;
 }
 
-do {
-TCGLabel *skip_label = NULL;
-
-/* translate current instruction */
-tcg_gen_insn_start(ctx->npc);
-num_insns++;
-
+if (tb_flags & TB_FLAGS_FULL_ACCESS) {
 /*
- * this is due to some strange GDB behavior
- * let's assume main has address 0x100
- * b main   - sets breakpoint at address 0x0100 (code)
- * b *0x100 - sets breakpoint at address 0x00800100 (data)
+ * This flag is set by ST/LD instruction we will regenerate it ONLY
+ * with mem/cpu memory access instead of mem access
  */
-if (unlikely(!ctx->base.singlestep_enabled &&
-(cpu_breakpoint_test(cs, OFFSET_CODE + ctx->npc * 2, BP_ANY) ||
- cpu_breakpoint_test(cs, OFFSET_DATA + ctx->npc * 2, BP_ANY {
-canonicalize_skip(ctx);
-tcg_gen_movi_tl(cpu_pc, ctx->npc);
-gen_helper_debug(cpu_env);
-goto done_generating;
-}
+ctx->base.max_insns = 1;
+}
+}
 
-/* Conditionally skip the next instruction, if indicated.  */
-if (ctx->skip_cond != TCG_COND_NEVER) {
-skip_label = gen_new_label();
-if (ctx->skip_var0 == cpu_skip) {
-/*
- * Copy cpu_skip so that we may zero it before the branch.
- * This ensures that cpu_skip is non-zero after the label
- * if and only if the skipped insn itself sets a skip.
- */
-ctx->free_skip_var0 = true;
-ctx->skip_var0 = tcg_temp_new();
-tcg_gen_mov_tl(ctx->skip_var0, cpu_skip);
-tcg_gen_movi_tl(cpu_skip, 0);
-}
-if (ctx->skip_var1 == NULL) {
-tcg_gen_brcondi_tl(ctx->skip_cond, ctx->skip_var0,
-   0, skip_label);
-} else {
-tcg_gen_brcond_tl(ctx->skip_cond, ctx->skip_var0,
-  ctx->skip_var1, skip_label);
-ctx->skip_var1 = NULL;
-}
-if (ctx->free_skip_var0) {
-tcg_temp_free(ctx->skip_var0);
-ctx->free_skip_var0 = false;
-}
-ctx->skip_cond = TCG_COND_NEVER;
-ctx->skip_var0 = NULL;
-}
+static void avr_tr_tb_start(DisasContextBase *db, CPUState *cs)
+{
+}
 
-translate(ctx);
+static void avr_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
+{
+DisasContext *ctx = container_of(dcbase, DisasContext, base);
 
-if (skip_label) {
-canonicalize_skip(ctx);
-gen_set_label(skip_label);
-if (ctx->base.is_jmp == DISAS_NORETURN) {
-ctx->base.is_jmp = DISAS_CHAIN;
-}
-}
-} while (ctx->base.is_jmp == DISAS_NEXT
- && num_insns < max_insns
- && (ctx->npc - pc_start) * 2 < TARGET_PAGE_SIZE - 4
- && !tcg_op_buf_full());
+

[PATCH v2 2/3] target/avr: Change ctx to DisasContext* in gen_intermediate_code

2021-06-20 Thread Richard Henderson
Prepare for receiving it as a pointer input.

Signed-off-by: Richard Henderson 
---
 target/avr/translate.c | 84 +-
 1 file changed, 43 insertions(+), 41 deletions(-)

diff --git a/target/avr/translate.c b/target/avr/translate.c
index 20c5062730..66e9882422 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -104,7 +104,7 @@ struct DisasContext {
  * used in the following manner (sketch)
  *
  * TCGLabel *skip_label = NULL;
- * if (ctx.skip_cond != TCG_COND_NEVER) {
+ * if (ctx->skip_cond != TCG_COND_NEVER) {
  * skip_label = gen_new_label();
  * tcg_gen_brcond_tl(skip_cond, skip_var0, skip_var1, skip_label);
  * }
@@ -114,7 +114,7 @@ struct DisasContext {
  * free_skip_var0 = false;
  * }
  *
- * translate();
+ * translate(ctx);
  *
  * if (skip_label) {
  * gen_set_label(skip_label);
@@ -2900,7 +2900,7 @@ static bool canonicalize_skip(DisasContext *ctx)
 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
 {
 CPUAVRState *env = cs->env_ptr;
-DisasContext ctx = {
+DisasContext ctx1 = {
 .base.tb = tb,
 .base.is_jmp = DISAS_NEXT,
 .base.pc_first = tb->pc,
@@ -2911,6 +2911,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock 
*tb, int max_insns)
 .memidx = 0,
 .skip_cond = TCG_COND_NEVER,
 };
+DisasContext *ctx = 
 target_ulong pc_start = tb->pc / 2;
 int num_insns = 0;
 
@@ -2921,23 +2922,23 @@ void gen_intermediate_code(CPUState *cs, 
TranslationBlock *tb, int max_insns)
  */
 max_insns = 1;
 }
-if (ctx.base.singlestep_enabled) {
+if (ctx->base.singlestep_enabled) {
 max_insns = 1;
 }
 
 gen_tb_start(tb);
 
-ctx.npc = pc_start;
+ctx->npc = pc_start;
 if (tb->flags & TB_FLAGS_SKIP) {
-ctx.skip_cond = TCG_COND_ALWAYS;
-ctx.skip_var0 = cpu_skip;
+ctx->skip_cond = TCG_COND_ALWAYS;
+ctx->skip_var0 = cpu_skip;
 }
 
 do {
 TCGLabel *skip_label = NULL;
 
 /* translate current instruction */
-tcg_gen_insn_start(ctx.npc);
+tcg_gen_insn_start(ctx->npc);
 num_insns++;
 
 /*
@@ -2946,65 +2947,66 @@ void gen_intermediate_code(CPUState *cs, 
TranslationBlock *tb, int max_insns)
  * b main   - sets breakpoint at address 0x0100 (code)
  * b *0x100 - sets breakpoint at address 0x00800100 (data)
  */
-if (unlikely(!ctx.base.singlestep_enabled &&
-(cpu_breakpoint_test(cs, OFFSET_CODE + ctx.npc * 2, BP_ANY) ||
- cpu_breakpoint_test(cs, OFFSET_DATA + ctx.npc * 2, BP_ANY 
{
-canonicalize_skip();
-tcg_gen_movi_tl(cpu_pc, ctx.npc);
+if (unlikely(!ctx->base.singlestep_enabled &&
+(cpu_breakpoint_test(cs, OFFSET_CODE + ctx->npc * 2, BP_ANY) ||
+ cpu_breakpoint_test(cs, OFFSET_DATA + ctx->npc * 2, BP_ANY {
+canonicalize_skip(ctx);
+tcg_gen_movi_tl(cpu_pc, ctx->npc);
 gen_helper_debug(cpu_env);
 goto done_generating;
 }
 
 /* Conditionally skip the next instruction, if indicated.  */
-if (ctx.skip_cond != TCG_COND_NEVER) {
+if (ctx->skip_cond != TCG_COND_NEVER) {
 skip_label = gen_new_label();
-if (ctx.skip_var0 == cpu_skip) {
+if (ctx->skip_var0 == cpu_skip) {
 /*
  * Copy cpu_skip so that we may zero it before the branch.
  * This ensures that cpu_skip is non-zero after the label
  * if and only if the skipped insn itself sets a skip.
  */
-ctx.free_skip_var0 = true;
-ctx.skip_var0 = tcg_temp_new();
-tcg_gen_mov_tl(ctx.skip_var0, cpu_skip);
+ctx->free_skip_var0 = true;
+ctx->skip_var0 = tcg_temp_new();
+tcg_gen_mov_tl(ctx->skip_var0, cpu_skip);
 tcg_gen_movi_tl(cpu_skip, 0);
 }
-if (ctx.skip_var1 == NULL) {
-tcg_gen_brcondi_tl(ctx.skip_cond, ctx.skip_var0, 0, 
skip_label);
+if (ctx->skip_var1 == NULL) {
+tcg_gen_brcondi_tl(ctx->skip_cond, ctx->skip_var0,
+   0, skip_label);
 } else {
-tcg_gen_brcond_tl(ctx.skip_cond, ctx.skip_var0,
-  ctx.skip_var1, skip_label);
-ctx.skip_var1 = NULL;
+tcg_gen_brcond_tl(ctx->skip_cond, ctx->skip_var0,
+  ctx->skip_var1, skip_label);
+ctx->skip_var1 = NULL;
 }
-if (ctx.free_skip_var0) {
-tcg_temp_free(ctx.skip_var0);
-ctx.free_skip_var0 = false;
+if (ctx->free_skip_var0) {
+   

[PATCH v2 1/3] target/avr: Add DisasContextBase to DisasContext

2021-06-20 Thread Richard Henderson
Migrate the bstate, tb and singlestep_enabled fields
from DisasContext into the base.

Signed-off-by: Richard Henderson 
---
 target/avr/translate.c | 58 +-
 1 file changed, 29 insertions(+), 29 deletions(-)

diff --git a/target/avr/translate.c b/target/avr/translate.c
index 850c5941d9..20c5062730 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -80,7 +80,7 @@ typedef struct DisasContext DisasContext;
 
 /* This is the state at translation time. */
 struct DisasContext {
-TranslationBlock *tb;
+DisasContextBase base;
 
 CPUAVRState *env;
 CPUState *cs;
@@ -90,8 +90,6 @@ struct DisasContext {
 
 /* Routine used to access memory */
 int memidx;
-int bstate;
-int singlestep;
 
 /*
  * some AVR instructions can make the following instruction to be skipped
@@ -191,7 +189,7 @@ static bool avr_have_feature(DisasContext *ctx, int feature)
 {
 if (!avr_feature(ctx->env, feature)) {
 gen_helper_unsupported(cpu_env);
-ctx->bstate = DISAS_NORETURN;
+ctx->base.is_jmp = DISAS_NORETURN;
 return false;
 }
 return true;
@@ -1011,13 +1009,13 @@ static void gen_jmp_ez(DisasContext *ctx)
 {
 tcg_gen_deposit_tl(cpu_pc, cpu_r[30], cpu_r[31], 8, 8);
 tcg_gen_or_tl(cpu_pc, cpu_pc, cpu_eind);
-ctx->bstate = DISAS_LOOKUP;
+ctx->base.is_jmp = DISAS_LOOKUP;
 }
 
 static void gen_jmp_z(DisasContext *ctx)
 {
 tcg_gen_deposit_tl(cpu_pc, cpu_r[30], cpu_r[31], 8, 8);
-ctx->bstate = DISAS_LOOKUP;
+ctx->base.is_jmp = DISAS_LOOKUP;
 }
 
 static void gen_push_ret(DisasContext *ctx, int ret)
@@ -1083,9 +1081,9 @@ static void gen_pop_ret(DisasContext *ctx, TCGv ret)
 
 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
 {
-TranslationBlock *tb = ctx->tb;
+const TranslationBlock *tb = ctx->base.tb;
 
-if (ctx->singlestep == 0) {
+if (!ctx->base.singlestep_enabled) {
 tcg_gen_goto_tb(n);
 tcg_gen_movi_i32(cpu_pc, dest);
 tcg_gen_exit_tb(tb, n);
@@ -1094,7 +1092,7 @@ static void gen_goto_tb(DisasContext *ctx, int n, 
target_ulong dest)
 gen_helper_debug(cpu_env);
 tcg_gen_exit_tb(NULL, 0);
 }
-ctx->bstate = DISAS_NORETURN;
+ctx->base.is_jmp = DISAS_NORETURN;
 }
 
 /*
@@ -1254,7 +1252,7 @@ static bool trans_RET(DisasContext *ctx, arg_RET *a)
 {
 gen_pop_ret(ctx, cpu_pc);
 
-ctx->bstate = DISAS_LOOKUP;
+ctx->base.is_jmp = DISAS_LOOKUP;
 return true;
 }
 
@@ -1272,7 +1270,7 @@ static bool trans_RETI(DisasContext *ctx, arg_RETI *a)
 tcg_gen_movi_tl(cpu_If, 1);
 
 /* Need to return to main loop to re-evaluate interrupts.  */
-ctx->bstate = DISAS_EXIT;
+ctx->base.is_jmp = DISAS_EXIT;
 return true;
 }
 
@@ -1484,7 +1482,7 @@ static bool trans_BRBC(DisasContext *ctx, arg_BRBC *a)
 gen_goto_tb(ctx, 0, ctx->npc + a->imm);
 gen_set_label(not_taken);
 
-ctx->bstate = DISAS_CHAIN;
+ctx->base.is_jmp = DISAS_CHAIN;
 return true;
 }
 
@@ -1533,7 +1531,7 @@ static bool trans_BRBS(DisasContext *ctx, arg_BRBS *a)
 gen_goto_tb(ctx, 0, ctx->npc + a->imm);
 gen_set_label(not_taken);
 
-ctx->bstate = DISAS_CHAIN;
+ctx->base.is_jmp = DISAS_CHAIN;
 return true;
 }
 
@@ -1610,7 +1608,7 @@ static TCGv gen_get_zaddr(void)
  */
 static void gen_data_store(DisasContext *ctx, TCGv data, TCGv addr)
 {
-if (ctx->tb->flags & TB_FLAGS_FULL_ACCESS) {
+if (ctx->base.tb->flags & TB_FLAGS_FULL_ACCESS) {
 gen_helper_fullwr(cpu_env, data, addr);
 } else {
 tcg_gen_qemu_st8(data, addr, MMU_DATA_IDX); /* mem[addr] = data */
@@ -1619,7 +1617,7 @@ static void gen_data_store(DisasContext *ctx, TCGv data, 
TCGv addr)
 
 static void gen_data_load(DisasContext *ctx, TCGv data, TCGv addr)
 {
-if (ctx->tb->flags & TB_FLAGS_FULL_ACCESS) {
+if (ctx->base.tb->flags & TB_FLAGS_FULL_ACCESS) {
 gen_helper_fullrd(data, cpu_env, addr);
 } else {
 tcg_gen_qemu_ld8u(data, addr, MMU_DATA_IDX); /* data = mem[addr] */
@@ -2793,7 +2791,7 @@ static bool trans_BREAK(DisasContext *ctx, arg_BREAK *a)
 #ifdef BREAKPOINT_ON_BREAK
 tcg_gen_movi_tl(cpu_pc, ctx->npc - 1);
 gen_helper_debug(cpu_env);
-ctx->bstate = DISAS_EXIT;
+ctx->base.is_jmp = DISAS_EXIT;
 #else
 /* NOP */
 #endif
@@ -2819,7 +2817,7 @@ static bool trans_NOP(DisasContext *ctx, arg_NOP *a)
 static bool trans_SLEEP(DisasContext *ctx, arg_SLEEP *a)
 {
 gen_helper_sleep(cpu_env);
-ctx->bstate = DISAS_NORETURN;
+ctx->base.is_jmp = DISAS_NORETURN;
 return true;
 }
 
@@ -2850,7 +2848,7 @@ static void translate(DisasContext *ctx)
 
 if (!decode_insn(ctx, opcode)) {
 gen_helper_unsupported(cpu_env);
-ctx->bstate = DISAS_NORETURN;
+ctx->base.is_jmp = DISAS_NORETURN;
 }
 }
 
@@ -2903,13 +2901,15 @@ void gen_intermediate_code(CPUState *cs, 
TranslationBlock *tb, int max_insns)
 {
 CPUAVRState *env = 

[PATCH v2 0/3] target/avr: Convert to TranslatorOps

2021-06-20 Thread Richard Henderson
I've reached a point where *all* targets must use the translator loop.  

Changes for v2:
  * Fix (drop) singlestep check for max_insns.
We already do that generically.
  * Fully initialize DisasContext.

It was that last that caused the check-acceptance regression for v1.
I simply got lucky the first time (with optimization) and the
uninitialized struct members happened to have some zeros.


r~


Richard Henderson (3):
  target/avr: Add DisasContextBase to DisasContext
  target/avr: Change ctx to DisasContext* in gen_intermediate_code
  target/avr: Convert to TranslatorOps

 target/avr/translate.c | 284 ++---
 1 file changed, 154 insertions(+), 130 deletions(-)

-- 
2.25.1




[PATCH v2 08/11] target/cris: Mark static arrays const

2021-06-20 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/cris/translate.c | 19 ++-
 target/cris/translate_v10.c.inc |  6 +++---
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index f6d1fa914f..83b20162f1 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -137,14 +137,15 @@ static void gen_BUG(DisasContext *dc, const char *file, 
int line)
 cpu_abort(CPU(dc->cpu), "%s:%d pc=%x\n", file, line, dc->pc);
 }
 
-static const char *regnames_v32[] =
+static const char * const regnames_v32[] =
 {
 "$r0", "$r1", "$r2", "$r3",
 "$r4", "$r5", "$r6", "$r7",
 "$r8", "$r9", "$r10", "$r11",
 "$r12", "$r13", "$sp", "$acr",
 };
-static const char *pregnames_v32[] =
+
+static const char * const pregnames_v32[] =
 {
 "$bz", "$vr", "$pid", "$srs",
 "$wz", "$exs", "$eda", "$mof",
@@ -153,7 +154,7 @@ static const char *pregnames_v32[] =
 };
 
 /* We need this table to handle preg-moves with implicit width.  */
-static int preg_sizes[] = {
+static const int preg_sizes[] = {
 1, /* bz.  */
 1, /* vr.  */
 4, /* pid.  */
@@ -475,9 +476,9 @@ static inline void t_gen_swapw(TCGv d, TCGv s)
((T0 >> 5) & 0x02020202) |
((T0 >> 7) & 0x01010101));
  */
-static inline void t_gen_swapr(TCGv d, TCGv s)
+static void t_gen_swapr(TCGv d, TCGv s)
 {
-struct {
+static const struct {
 int shift; /* LSL when positive, LSR when negative.  */
 uint32_t mask;
 } bitrev[] = {
@@ -1279,7 +1280,7 @@ static int dec_prep_alu_m(CPUCRISState *env, DisasContext 
*dc,
 #if DISAS_CRIS
 static const char *cc_name(int cc)
 {
-static const char *cc_names[16] = {
+static const char * const cc_names[16] = {
 "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
 "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
 };
@@ -2926,7 +2927,7 @@ static int dec_null(CPUCRISState *env, DisasContext *dc)
 return 2;
 }
 
-static struct decoder_info {
+static const struct decoder_info {
 struct {
 uint32_t bits;
 uint32_t mask;
@@ -3359,8 +3360,8 @@ void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags)
 {
 CRISCPU *cpu = CRIS_CPU(cs);
 CPUCRISState *env = >env;
-const char **regnames;
-const char **pregnames;
+const char * const *regnames;
+const char * const *pregnames;
 int i;
 
 if (!env) {
diff --git a/target/cris/translate_v10.c.inc b/target/cris/translate_v10.c.inc
index 0ba2aca96f..4ab43dc404 100644
--- a/target/cris/translate_v10.c.inc
+++ b/target/cris/translate_v10.c.inc
@@ -21,7 +21,7 @@
 #include "qemu/osdep.h"
 #include "crisv10-decode.h"
 
-static const char *regnames_v10[] =
+static const char * const regnames_v10[] =
 {
 "$r0", "$r1", "$r2", "$r3",
 "$r4", "$r5", "$r6", "$r7",
@@ -29,7 +29,7 @@ static const char *regnames_v10[] =
 "$r12", "$r13", "$sp", "$pc",
 };
 
-static const char *pregnames_v10[] =
+static const char * const pregnames_v10[] =
 {
 "$bz", "$vr", "$p2", "$p3",
 "$wz", "$ccr", "$p6-prefix", "$mof",
@@ -38,7 +38,7 @@ static const char *pregnames_v10[] =
 };
 
 /* We need this table to handle preg-moves with implicit width.  */
-static int preg_sizes_v10[] = {
+static const int preg_sizes_v10[] = {
 1, /* bz.  */
 1, /* vr.  */
 1, /* pid. */
-- 
2.25.1




[PATCH v2 05/11] target/cris: Fix use_goto_tb

2021-06-20 Thread Richard Henderson
Do not skip the page check for user-only -- mmap/mprotect can
still change page mappings.  Only check dc->base.pc_first, not
dc->ppc -- the start page is the only one that's relevant.

Signed-off-by: Richard Henderson 
---
 target/cris/translate.c | 9 ++---
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index 24dbae6d58..9e1f2f9239 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -524,14 +524,9 @@ static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false)
 gen_set_label(l1);
 }
 
-static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
+static bool use_goto_tb(DisasContext *dc, target_ulong dest)
 {
-#ifndef CONFIG_USER_ONLY
-return (dc->base.pc_first & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) 
||
-   (dc->ppc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-return true;
-#endif
+return ((dest ^ dc->base.pc_first) & TARGET_PAGE_MASK) == 0;
 }
 
 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
-- 
2.25.1




[PATCH v2 09/11] target/cris: Move delayed branch handling to tb_stop

2021-06-20 Thread Richard Henderson
By moving the code here, we can re-use other end-of-tb code,
e.g. the evaluation of flags.  Honor single stepping.

Signed-off-by: Richard Henderson 
---
 target/cris/translate.c | 82 ++---
 1 file changed, 45 insertions(+), 37 deletions(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index 83b20162f1..0e925320b3 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -55,6 +55,7 @@
 /* is_jmp field values */
 #define DISAS_JUMPDISAS_TARGET_0 /* only pc was modified dynamically */
 #define DISAS_UPDATE  DISAS_TARGET_1 /* cpu state was modified dynamically */
+#define DISAS_DBRANCH DISAS_TARGET_2 /* pc update for delayed branch */
 
 /* Used by the decoder.  */
 #define EXTRACT_FIELD(src, start, end) \
@@ -3219,43 +3220,8 @@ static void cris_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cs)
  * loop doing nothing for on this program location.
  */
 if (dc->delayed_branch && --dc->delayed_branch == 0) {
-if (dc->base.tb->flags & 7) {
-t_gen_movi_env_TN(dslot, 0);
-}
-
-if (dc->cpustate_changed
-|| !dc->flagx_known
-|| (dc->flags_x != (dc->base.tb->flags & X_FLAG))) {
-cris_store_direct_jmp(dc);
-}
-
-if (dc->clear_locked_irq) {
-dc->clear_locked_irq = 0;
-t_gen_movi_env_TN(locked_irq, 0);
-}
-
-if (dc->jmp == JMP_DIRECT_CC) {
-TCGLabel *l1 = gen_new_label();
-cris_evaluate_flags(dc);
-
-/* Conditional jmp.  */
-tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
-gen_goto_tb(dc, 1, dc->jmp_pc);
-gen_set_label(l1);
-gen_goto_tb(dc, 0, dc->pc);
-dc->base.is_jmp = DISAS_NORETURN;
-dc->jmp = JMP_NOJMP;
-} else if (dc->jmp == JMP_DIRECT) {
-cris_evaluate_flags(dc);
-gen_goto_tb(dc, 0, dc->jmp_pc);
-dc->base.is_jmp = DISAS_NORETURN;
-dc->jmp = JMP_NOJMP;
-} else {
-TCGv c = tcg_const_tl(dc->pc);
-t_gen_cc_jmp(env_btarget, c);
-tcg_temp_free(c);
-dc->base.is_jmp = DISAS_JUMP;
-}
+dc->base.is_jmp = DISAS_DBRANCH;
+return;
 }
 
 /* Force an update if the per-tb cpu state has changed.  */
@@ -3303,6 +3269,48 @@ static void cris_tr_tb_stop(DisasContextBase *dcbase, 
CPUState *cpu)
 
 cris_evaluate_flags(dc);
 
+/* Evaluate delayed branch destination and fold to another is_jmp case. */
+if (is_jmp == DISAS_DBRANCH) {
+if (dc->base.tb->flags & 7) {
+t_gen_movi_env_TN(dslot, 0);
+}
+
+switch (dc->jmp) {
+case JMP_DIRECT:
+npc = dc->jmp_pc;
+is_jmp = DISAS_TOO_MANY;
+break;
+
+case JMP_DIRECT_CC:
+/*
+ * Use a conditional branch if either taken or not-taken path
+ * can use goto_tb.  If neither can, then treat it as indirect.
+ */
+if (likely(!dc->base.singlestep_enabled)
+&& (use_goto_tb(dc, dc->jmp_pc) || use_goto_tb(dc, npc))) {
+TCGLabel *not_taken = gen_new_label();
+
+tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, not_taken);
+gen_goto_tb(dc, 1, dc->jmp_pc);
+gen_set_label(not_taken);
+
+/* not-taken case handled below. */
+is_jmp = DISAS_TOO_MANY;
+break;
+}
+tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
+/* fall through */
+
+case JMP_INDIRECT:
+t_gen_cc_jmp(env_btarget, tcg_constant_tl(npc));
+is_jmp = DISAS_JUMP;
+break;
+
+default:
+g_assert_not_reached();
+}
+}
+
 if (unlikely(dc->base.singlestep_enabled)) {
 switch (is_jmp) {
 case DISAS_TOO_MANY:
-- 
2.25.1




[PATCH v2 02/11] target/cris: Replace DISAS_TB_JUMP with DISAS_NORETURN

2021-06-20 Thread Richard Henderson
The only semantic of DISAS_TB_JUMP is that we've done goto_tb,
which is the same as DISAS_NORETURN -- we've exited the tb.

Signed-off-by: Richard Henderson 
---
 target/cris/translate.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index bed7a7ed10..2ff4319dd1 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -55,7 +55,6 @@
 /* is_jmp field values */
 #define DISAS_JUMPDISAS_TARGET_0 /* only pc was modified dynamically */
 #define DISAS_UPDATE  DISAS_TARGET_1 /* cpu state was modified dynamically */
-#define DISAS_TB_JUMP DISAS_TARGET_2 /* only pc was modified statically */
 #define DISAS_SWI DISAS_TARGET_3
 
 /* Used by the decoder.  */
@@ -3243,12 +3242,12 @@ void gen_intermediate_code(CPUState *cs, 
TranslationBlock *tb, int max_insns)
 gen_goto_tb(dc, 1, dc->jmp_pc);
 gen_set_label(l1);
 gen_goto_tb(dc, 0, dc->pc);
-dc->base.is_jmp = DISAS_TB_JUMP;
+dc->base.is_jmp = DISAS_NORETURN;
 dc->jmp = JMP_NOJMP;
 } else if (dc->jmp == JMP_DIRECT) {
 cris_evaluate_flags(dc);
 gen_goto_tb(dc, 0, dc->jmp_pc);
-dc->base.is_jmp = DISAS_TB_JUMP;
+dc->base.is_jmp = DISAS_NORETURN;
 dc->jmp = JMP_NOJMP;
 } else {
 TCGv c = tcg_const_tl(dc->pc);
@@ -3311,7 +3310,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock 
*tb, int max_insns)
 tcg_gen_exit_tb(NULL, 0);
 break;
 case DISAS_SWI:
-case DISAS_TB_JUMP:
+case DISAS_NORETURN:
 /* nothing more to generate */
 break;
 }
-- 
2.25.1




[PATCH v2 11/11] target/cris: Improve JMP_INDIRECT

2021-06-20 Thread Richard Henderson
Use movcond instead of brcond to set env_pc.
Discard the btarget and btaken variables to improve
register allocation and avoid unnecessary writeback.

Signed-off-by: Richard Henderson 
---
 target/cris/translate.c | 22 ++
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index c33324b988..3200819f32 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -515,17 +515,6 @@ static void t_gen_swapr(TCGv d, TCGv s)
 tcg_temp_free(org_s);
 }
 
-static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false)
-{
-TCGLabel *l1 = gen_new_label();
-
-/* Conditional jmp.  */
-tcg_gen_mov_tl(env_pc, pc_false);
-tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
-tcg_gen_mov_tl(env_pc, pc_true);
-gen_set_label(l1);
-}
-
 static bool use_goto_tb(DisasContext *dc, target_ulong dest)
 {
 return ((dest ^ dc->base.pc_first) & TARGET_PAGE_MASK) == 0;
@@ -3302,8 +3291,17 @@ static void cris_tr_tb_stop(DisasContextBase *dcbase, 
CPUState *cpu)
 /* fall through */
 
 case JMP_INDIRECT:
-t_gen_cc_jmp(env_btarget, tcg_constant_tl(npc));
+tcg_gen_movcond_tl(TCG_COND_NE, env_pc,
+   env_btaken, tcg_constant_tl(0),
+   env_btarget, tcg_constant_tl(npc));
 is_jmp = DISAS_JUMP;
+
+/*
+ * We have consumed btaken and btarget.  Hint to the
+ * tcg compiler that the writeback to env may be dropped.
+ */
+tcg_gen_discard_tl(env_btaken);
+tcg_gen_discard_tl(env_btarget);
 break;
 
 default:
-- 
2.25.1




[PATCH v2 10/11] target/cris: Use tcg_gen_lookup_and_goto_ptr

2021-06-20 Thread Richard Henderson
We can use this in gen_goto_tb and for DISAS_JUMP
to indirectly chain to the next TB.

Signed-off-by: Richard Henderson 
---
 target/cris/translate.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index 0e925320b3..c33324b988 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -539,7 +539,7 @@ static void gen_goto_tb(DisasContext *dc, int n, 
target_ulong dest)
 tcg_gen_exit_tb(dc->base.tb, n);
 } else {
 tcg_gen_movi_tl(env_pc, dest);
-tcg_gen_exit_tb(NULL, 0);
+tcg_gen_lookup_and_goto_ptr();
 }
 }
 
@@ -3331,6 +3331,8 @@ static void cris_tr_tb_stop(DisasContextBase *dcbase, 
CPUState *cpu)
 gen_goto_tb(dc, 0, npc);
 break;
 case DISAS_JUMP:
+tcg_gen_lookup_and_goto_ptr();
+break;
 case DISAS_UPDATE:
 /* Indicate that interupts must be re-evaluated before the next TB. */
 tcg_gen_exit_tb(NULL, 0);
-- 
2.25.1




[PATCH v2 04/11] target/cris: Remove DISAS_SWI

2021-06-20 Thread Richard Henderson
This value is unused.

Signed-off-by: Richard Henderson 
---
 target/cris/translate.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index f8b574b0b6..24dbae6d58 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -55,7 +55,6 @@
 /* is_jmp field values */
 #define DISAS_JUMPDISAS_TARGET_0 /* only pc was modified dynamically */
 #define DISAS_UPDATE  DISAS_TARGET_1 /* cpu state was modified dynamically */
-#define DISAS_SWI DISAS_TARGET_3
 
 /* Used by the decoder.  */
 #define EXTRACT_FIELD(src, start, end) \
@@ -3310,7 +3309,6 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock 
*tb, int max_insns)
to find the next TB */
 tcg_gen_exit_tb(NULL, 0);
 break;
-case DISAS_SWI:
 case DISAS_NORETURN:
 /* nothing more to generate */
 break;
-- 
2.25.1




[PATCH v2 03/11] target/cris: Mark exceptions as DISAS_NORETURN

2021-06-20 Thread Richard Henderson
After we've raised the exception, we have left the TB.

Signed-off-by: Richard Henderson 
---
 target/cris/translate.c | 5 +++--
 target/cris/translate_v10.c.inc | 3 ++-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index 2ff4319dd1..f8b574b0b6 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -2874,6 +2874,7 @@ static int dec_rfe_etc(CPUCRISState *env, DisasContext 
*dc)
-offsetof(CRISCPU, env) + offsetof(CPUState, halted));
 tcg_gen_movi_tl(env_pc, dc->pc + 2);
 t_gen_raise_exception(EXCP_HLT);
+dc->base.is_jmp = DISAS_NORETURN;
 return 2;
 }
 
@@ -2901,7 +2902,7 @@ static int dec_rfe_etc(CPUCRISState *env, DisasContext 
*dc)
 /* Breaks start at 16 in the exception vector.  */
 t_gen_movi_env_TN(trap_vector, dc->op1 + 16);
 t_gen_raise_exception(EXCP_BREAK);
-dc->base.is_jmp = DISAS_UPDATE;
+dc->base.is_jmp = DISAS_NORETURN;
 break;
 default:
 printf("op2=%x\n", dc->op2);
@@ -3189,7 +3190,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock 
*tb, int max_insns)
 cris_evaluate_flags(dc);
 tcg_gen_movi_tl(env_pc, dc->pc);
 t_gen_raise_exception(EXCP_DEBUG);
-dc->base.is_jmp = DISAS_UPDATE;
+dc->base.is_jmp = DISAS_NORETURN;
 /* The address covered by the breakpoint must be included in
[tb->pc, tb->pc + tb->size) in order to for it to be
properly cleared -- thus we increment the PC here so that
diff --git a/target/cris/translate_v10.c.inc b/target/cris/translate_v10.c.inc
index dd44a7eb97..0ba2aca96f 100644
--- a/target/cris/translate_v10.c.inc
+++ b/target/cris/translate_v10.c.inc
@@ -61,6 +61,7 @@ static inline void cris_illegal_insn(DisasContext *dc)
 {
 qemu_log_mask(LOG_GUEST_ERROR, "illegal insn at pc=%x\n", dc->pc);
 t_gen_raise_exception(EXCP_BREAK);
+dc->base.is_jmp = DISAS_NORETURN;
 }
 
 static void gen_store_v10_conditional(DisasContext *dc, TCGv addr, TCGv val,
@@ -1169,7 +1170,7 @@ static unsigned int dec10_ind(CPUCRISState *env, 
DisasContext *dc)
 t_gen_mov_env_TN(trap_vector, c);
 tcg_temp_free(c);
 t_gen_raise_exception(EXCP_BREAK);
-dc->base.is_jmp = DISAS_UPDATE;
+dc->base.is_jmp = DISAS_NORETURN;
 return insn_len;
 }
 LOG_DIS("%d: jump.%d %d r%d r%d\n", __LINE__, size,
-- 
2.25.1




[PATCH v2 06/11] target/cris: Convert to TranslatorOps

2021-06-20 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/cris/translate.c | 313 ++--
 1 file changed, 170 insertions(+), 143 deletions(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index 9e1f2f9239..f6d1fa914f 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -3114,17 +3114,12 @@ static unsigned int crisv32_decoder(CPUCRISState *env, 
DisasContext *dc)
  *
  */
 
-/* generate intermediate code for basic block 'tb'.  */
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
+static void cris_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
 {
+DisasContext *dc = container_of(dcbase, DisasContext, base);
 CPUCRISState *env = cs->env_ptr;
+uint32_t tb_flags = dc->base.tb->flags;
 uint32_t pc_start;
-unsigned int insn_len;
-struct DisasContext ctx;
-struct DisasContext *dc = 
-uint32_t page_start;
-target_ulong npc;
-int num_insns;
 
 if (env->pregs[PR_VR] == 32) {
 dc->decoder = crisv32_decoder;
@@ -3134,150 +3129,170 @@ void gen_intermediate_code(CPUState *cs, 
TranslationBlock *tb, int max_insns)
 dc->clear_locked_irq = 1;
 }
 
-/* Odd PC indicates that branch is rexecuting due to exception in the
+/*
+ * Odd PC indicates that branch is rexecuting due to exception in the
  * delayslot, like in real hw.
  */
-pc_start = tb->pc & ~1;
-
-dc->base.tb = tb;
+pc_start = dc->base.pc_first & ~1;
 dc->base.pc_first = pc_start;
 dc->base.pc_next = pc_start;
-dc->base.is_jmp = DISAS_NEXT;
-dc->base.singlestep_enabled = cs->singlestep_enabled;
 
 dc->cpu = env_archcpu(env);
 dc->ppc = pc_start;
 dc->pc = pc_start;
 dc->flags_uptodate = 1;
 dc->flagx_known = 1;
-dc->flags_x = tb->flags & X_FLAG;
+dc->flags_x = tb_flags & X_FLAG;
 dc->cc_x_uptodate = 0;
 dc->cc_mask = 0;
 dc->update_cc = 0;
 dc->clear_prefix = 0;
+dc->cpustate_changed = 0;
 
 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
 dc->cc_size_uptodate = -1;
 
 /* Decode TB flags.  */
-dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \
-| X_FLAG | PFIX_FLAG);
-dc->delayed_branch = !!(tb->flags & 7);
+dc->tb_flags = tb_flags & (S_FLAG | P_FLAG | U_FLAG | X_FLAG | PFIX_FLAG);
+dc->delayed_branch = !!(tb_flags & 7);
 if (dc->delayed_branch) {
 dc->jmp = JMP_INDIRECT;
 } else {
 dc->jmp = JMP_NOJMP;
 }
+}
 
-dc->cpustate_changed = 0;
+static void cris_tr_tb_start(DisasContextBase *db, CPUState *cpu)
+{
+}
 
-page_start = pc_start & TARGET_PAGE_MASK;
-num_insns = 0;
+static void cris_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
+{
+DisasContext *dc = container_of(dcbase, DisasContext, base);
 
-gen_tb_start(tb);
-do {
-tcg_gen_insn_start(dc->delayed_branch == 1
-   ? dc->ppc | 1 : dc->pc);
-num_insns++;
+tcg_gen_insn_start(dc->delayed_branch == 1 ? dc->ppc | 1 : dc->pc);
+}
 
-if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
+static bool cris_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
+ const CPUBreakpoint *bp)
+{
+DisasContext *dc = container_of(dcbase, DisasContext, base);
+
+cris_evaluate_flags(dc);
+tcg_gen_movi_tl(env_pc, dc->pc);
+t_gen_raise_exception(EXCP_DEBUG);
+dc->base.is_jmp = DISAS_NORETURN;
+/*
+ * The address covered by the breakpoint must be included in
+ * [tb->pc, tb->pc + tb->size) in order to for it to be
+ * properly cleared -- thus we increment the PC here so that
+ * the logic setting tb->size below does the right thing.
+ */
+dc->pc += 2;
+return true;
+}
+
+static void cris_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
+{
+DisasContext *dc = container_of(dcbase, DisasContext, base);
+CPUCRISState *env = cs->env_ptr;
+unsigned int insn_len;
+
+/* Pretty disas.  */
+LOG_DIS("%8.8x:\t", dc->pc);
+
+dc->clear_x = 1;
+
+insn_len = dc->decoder(env, dc);
+dc->ppc = dc->pc;
+dc->pc += insn_len;
+dc->base.pc_next += insn_len;
+
+if (dc->clear_x) {
+cris_clear_x_flag(dc);
+}
+
+/*
+ * Check for delayed branches here.  If we do it before
+ * actually generating any host code, the simulator will just
+ * loop doing nothing for on this program location.
+ */
+if (dc->delayed_branch && --dc->delayed_branch == 0) {
+if (dc->base.tb->flags & 7) {
+t_gen_movi_env_TN(dslot, 0);
+}
+
+if (dc->cpustate_changed
+|| !dc->flagx_known
+|| (dc->flags_x != (dc->base.tb->flags & X_FLAG))) {
+cris_store_direct_jmp(dc);
+}
+
+if (dc->clear_locked_irq) {
+dc->clear_locked_irq = 0;
+t_gen_movi_env_TN(locked_irq, 0);
+}
+
+if (dc->jmp == 

[PATCH v2 07/11] target/cris: Mark helper_raise_exception noreturn

2021-06-20 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/cris/helper.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/cris/helper.h b/target/cris/helper.h
index 20d21c4358..3abf608682 100644
--- a/target/cris/helper.h
+++ b/target/cris/helper.h
@@ -1,4 +1,4 @@
-DEF_HELPER_2(raise_exception, void, env, i32)
+DEF_HELPER_2(raise_exception, noreturn, env, i32)
 DEF_HELPER_2(tlb_flush_pid, void, env, i32)
 DEF_HELPER_2(spc_write, void, env, i32)
 DEF_HELPER_1(rfe, void, env)
-- 
2.25.1




[PATCH v2 01/11] target/cris: Add DisasContextBase to DisasContext

2021-06-20 Thread Richard Henderson
Migrate the is_jmp, tb and singlestep_enabled fields
from DisasContext into the base.

Signed-off-by: Richard Henderson 
---
 target/cris/translate.c | 49 +
 target/cris/translate_v10.c.inc |  4 +--
 2 files changed, 27 insertions(+), 26 deletions(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index 6dd5a267a6..bed7a7ed10 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -85,6 +85,8 @@ static TCGv env_pc;
 
 /* This is the state at translation time.  */
 typedef struct DisasContext {
+DisasContextBase base;
+
 CRISCPU *cpu;
 target_ulong pc, ppc;
 
@@ -121,7 +123,6 @@ typedef struct DisasContext {
 int clear_locked_irq; /* Clear the irq lockout.  */
 int cpustate_changed;
 unsigned int tb_flags; /* tb dependent flags.  */
-int is_jmp;
 
 #define JMP_NOJMP 0
 #define JMP_DIRECT1
@@ -131,9 +132,6 @@ typedef struct DisasContext {
 uint32_t jmp_pc;
 
 int delayed_branch;
-
-TranslationBlock *tb;
-int singlestep_enabled;
 } DisasContext;
 
 static void gen_BUG(DisasContext *dc, const char *file, int line)
@@ -531,7 +529,7 @@ static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false)
 static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
 {
 #ifndef CONFIG_USER_ONLY
-return (dc->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
+return (dc->base.pc_first & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) 
||
(dc->ppc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
 #else
 return true;
@@ -543,7 +541,7 @@ static void gen_goto_tb(DisasContext *dc, int n, 
target_ulong dest)
 if (use_goto_tb(dc, dest)) {
 tcg_gen_goto_tb(n);
 tcg_gen_movi_tl(env_pc, dest);
-tcg_gen_exit_tb(dc->tb, n);
+tcg_gen_exit_tb(dc->base.tb, n);
 } else {
 tcg_gen_movi_tl(env_pc, dest);
 tcg_gen_exit_tb(NULL, 0);
@@ -2037,14 +2035,14 @@ static int dec_setclrf(CPUCRISState *env, DisasContext 
*dc)
 /* Break the TB if any of the SPI flag changes.  */
 if (flags & (P_FLAG | S_FLAG)) {
 tcg_gen_movi_tl(env_pc, dc->pc + 2);
-dc->is_jmp = DISAS_UPDATE;
+dc->base.is_jmp = DISAS_UPDATE;
 dc->cpustate_changed = 1;
 }
 
 /* For the I flag, only act on posedge.  */
 if ((flags & I_FLAG)) {
 tcg_gen_movi_tl(env_pc, dc->pc + 2);
-dc->is_jmp = DISAS_UPDATE;
+dc->base.is_jmp = DISAS_UPDATE;
 dc->cpustate_changed = 1;
 }
 
@@ -2886,14 +2884,14 @@ static int dec_rfe_etc(CPUCRISState *env, DisasContext 
*dc)
 LOG_DIS("rfe\n");
 cris_evaluate_flags(dc);
 gen_helper_rfe(cpu_env);
-dc->is_jmp = DISAS_UPDATE;
+dc->base.is_jmp = DISAS_UPDATE;
 break;
 case 5:
 /* rfn.  */
 LOG_DIS("rfn\n");
 cris_evaluate_flags(dc);
 gen_helper_rfn(cpu_env);
-dc->is_jmp = DISAS_UPDATE;
+dc->base.is_jmp = DISAS_UPDATE;
 break;
 case 6:
 LOG_DIS("break %d\n", dc->op1);
@@ -2904,7 +2902,7 @@ static int dec_rfe_etc(CPUCRISState *env, DisasContext 
*dc)
 /* Breaks start at 16 in the exception vector.  */
 t_gen_movi_env_TN(trap_vector, dc->op1 + 16);
 t_gen_raise_exception(EXCP_BREAK);
-dc->is_jmp = DISAS_UPDATE;
+dc->base.is_jmp = DISAS_UPDATE;
 break;
 default:
 printf("op2=%x\n", dc->op2);
@@ -3146,13 +3144,16 @@ void gen_intermediate_code(CPUState *cs, 
TranslationBlock *tb, int max_insns)
  * delayslot, like in real hw.
  */
 pc_start = tb->pc & ~1;
-dc->cpu = env_archcpu(env);
-dc->tb = tb;
 
-dc->is_jmp = DISAS_NEXT;
+dc->base.tb = tb;
+dc->base.pc_first = pc_start;
+dc->base.pc_next = pc_start;
+dc->base.is_jmp = DISAS_NEXT;
+dc->base.singlestep_enabled = cs->singlestep_enabled;
+
+dc->cpu = env_archcpu(env);
 dc->ppc = pc_start;
 dc->pc = pc_start;
-dc->singlestep_enabled = cs->singlestep_enabled;
 dc->flags_uptodate = 1;
 dc->flagx_known = 1;
 dc->flags_x = tb->flags & X_FLAG;
@@ -3189,7 +3190,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock 
*tb, int max_insns)
 cris_evaluate_flags(dc);
 tcg_gen_movi_tl(env_pc, dc->pc);
 t_gen_raise_exception(EXCP_DEBUG);
-dc->is_jmp = DISAS_UPDATE;
+dc->base.is_jmp = DISAS_UPDATE;
 /* The address covered by the breakpoint must be included in
[tb->pc, tb->pc + tb->size) in order to for it to be
properly cleared -- thus we increment the PC here so that
@@ -3242,18 +3243,18 @@ void gen_intermediate_code(CPUState *cs, 
TranslationBlock *tb, int max_insns)
 gen_goto_tb(dc, 1, dc->jmp_pc);
 gen_set_label(l1);
 gen_goto_tb(dc, 0, dc->pc);
-dc->is_jmp = DISAS_TB_JUMP;
+

[PATCH v2 00/11] target/cris: Convert to TranslatorOps

2021-06-20 Thread Richard Henderson
I've reached a point where *all* targets must use the translator loop.  
Do that, plus some other obvious cleanups.

Changes for v2:
  * Fix (drop) singlestep check for max_insns.
We already do that generically.
  * Move delay branch handling to tb_stop.
  * Improve tcg_gen_lookup_and_goto_ptr patch.
  * Patch 8, Use movcond for t_gen_cc_jmp, now
folded into single caller, for JMP_INDIRECT.

I'll note, while glancing through the emitted opcodes,
that the comment at the top of the translator still stands:
The cc handling is the thing most in need of attention.


r~


Richard Henderson (11):
  target/cris: Add DisasContextBase to DisasContext
  target/cris: Replace DISAS_TB_JUMP with DISAS_NORETURN
  target/cris: Mark exceptions as DISAS_NORETURN
  target/cris: Remove DISAS_SWI
  target/cris: Fix use_goto_tb
  target/cris: Convert to TranslatorOps
  target/cris: Mark helper_raise_exception noreturn
  target/cris: Mark static arrays const
  target/cris: Move delayed branch handling to tb_stop
  target/cris: Use tcg_gen_lookup_and_goto_ptr
  target/cris: Improve JMP_INDIRECT

 target/cris/helper.h|   2 +-
 target/cris/translate.c | 392 +---
 target/cris/translate_v10.c.inc |  11 +-
 3 files changed, 218 insertions(+), 187 deletions(-)

-- 
2.25.1




Re: qemu-binfmt-conf.sh: enforce style consistency

2021-06-20 Thread Unai Martinez Corral
Hi Laurent,

Well, I'm not sure there is a real consistency with this in the other
> scripts...
>

Changes look good, but can someone confirm this is the style we want to use
> everywhere?
>
> Peter?
>

Please, see
https://lists.gnu.org/archive/html/qemu-devel/2020-03/msg02267.html


> Please use your real name, not a nickname.
>

Sorry about that. It's 'Unai Martinez-Corral'.
Shall I resend the patch?

Cheers

Unai


Re: qemu-binfmt-conf.sh: enforce style consistency

2021-06-20 Thread Laurent Vivier
Le 20/06/2021 à 22:15, umarcor a écrit :
> Spaces are removed before '; then', for consistency with other scripts
> in the project.

Well, I'm not sure there is a real consistency with this in the other scripts...

> Signed-off-by: umarcor 

Please use your real name, not a nickname.

Changes look good, but can someone confirm this is the style we want to use 
everywhere?

Peter?

Thanks,
Laurent

> ---
>  scripts/qemu-binfmt-conf.sh | 36 ++--
>  1 file changed, 18 insertions(+), 18 deletions(-)
> 
> diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
> index 7de996d536..13bff41b47 100755
> --- a/scripts/qemu-binfmt-conf.sh
> +++ b/scripts/qemu-binfmt-conf.sh
> @@ -221,7 +221,7 @@ EOF
>  }
> 
>  qemu_check_access() {
> -if [ ! -w "$1" ] ; then
> +if [ ! -w "$1" ]; then
>  echo "ERROR: cannot write to $1" 1>&2
>  exit 1
>  fi
> @@ -230,12 +230,12 @@ qemu_check_access() {
>  qemu_check_bintfmt_misc() {
>  # load the binfmt_misc module
>  if [ ! -d /proc/sys/fs/binfmt_misc ]; then
> -  if ! /sbin/modprobe binfmt_misc ; then
> +  if ! /sbin/modprobe binfmt_misc; then
>exit 1
>fi
>  fi
>  if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
> -  if ! mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc ; then
> +  if ! mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc; then
>exit 1
>fi
>  fi
> @@ -248,16 +248,16 @@ installed_dpkg() {
>  }
> 
>  qemu_check_debian() {
> -if [ ! -e /etc/debian_version ] ; then
> +if [ ! -e /etc/debian_version ]; then
>  echo "WARNING: your system is not a Debian based distro" 1>&2
> -elif ! installed_dpkg binfmt-support ; then
> +elif ! installed_dpkg binfmt-support; then
>  echo "WARNING: package binfmt-support is needed" 1>&2
>  fi
>  qemu_check_access "$EXPORTDIR"
>  }
> 
>  qemu_check_systemd() {
> -if ! systemctl -q is-enabled systemd-binfmt.service ; then
> +if ! systemctl -q is-enabled systemd-binfmt.service; then
>  echo "WARNING: systemd-binfmt.service is missing or disabled" 1>&2
>  fi
>  qemu_check_access "$EXPORTDIR"
> @@ -265,13 +265,13 @@ qemu_check_systemd() {
> 
>  qemu_generate_register() {
>  flags=""
> -if [ "$CREDENTIAL" = "yes" ] ; then
> +if [ "$CREDENTIAL" = "yes" ]; then
>  flags="OC"
>  fi
> -if [ "$PERSISTENT" = "yes" ] ; then
> +if [ "$PERSISTENT" = "yes" ]; then
>  flags="${flags}F"
>  fi
> -if [ "$PRESERVE_ARG0" = "yes" ] ; then
> +if [ "$PRESERVE_ARG0" = "yes" ]; then
>  flags="${flags}P"
>  fi
> 
> @@ -306,23 +306,23 @@ qemu_set_binfmts() {
> 
>  # register the interpreter for each cpu except for the native one
> 
> -for cpu in ${qemu_target_list} ; do
> +for cpu in ${qemu_target_list}; do
>  magic=$(eval echo \$${cpu}_magic)
>  mask=$(eval echo \$${cpu}_mask)
>  family=$(eval echo \$${cpu}_family)
> 
> -if [ "$magic" = "" ] || [ "$mask" = "" ] || [ "$family" = "" ] ; then
> +if [ "$magic" = "" ] || [ "$mask" = "" ] || [ "$family" = "" ]; then
>  echo "INTERNAL ERROR: unknown cpu $cpu" 1>&2
>  continue
>  fi
> 
>  qemu="$QEMU_PATH/qemu-$cpu"
> -if [ "$cpu" = "i486" ] ; then
> +if [ "$cpu" = "i486" ]; then
>  qemu="$QEMU_PATH/qemu-i386"
>  fi
> 
>  qemu="$qemu$QEMU_SUFFIX"
> -if [ "$host_family" != "$family" ] ; then
> +if [ "$host_family" != "$family" ]; then
>  $BINFMT_SET
>  fi
>  done
> @@ -343,7 +343,7 @@ QEMU_SUFFIX=""
>  options=$(getopt -o ds:Q:S:e:hc:p:g: -l 
> debian,systemd:,qemu-path:,qemu-suffix:,exportdir:,help,credential:,persistent:,preserve-argv0:
>  -- "$@")
>  eval set -- "$options"
> 
> -while true ; do
> +while true; do
>  case "$1" in
>  -d|--debian)
>  CHECK=qemu_check_debian
> @@ -356,14 +356,14 @@ while true ; do
>  EXPORTDIR=${EXPORTDIR:-$SYSTEMDDIR}
>  shift
>  # check given cpu is in the supported CPU list
> -if [ "$1" != "ALL" ] ; then
> -for cpu in ${qemu_target_list} ; do
> -if [ "$cpu" = "$1" ] ; then
> +if [ "$1" != "ALL" ]; then
> +for cpu in ${qemu_target_list}; do
> +if [ "$cpu" = "$1" ]; then
>  break
>  fi
>  done
> 
> -if [ "$cpu" = "$1" ] ; then
> +if [ "$cpu" = "$1" ]; then
>  qemu_target_list="$1"
>  else
>  echo "ERROR: unknown CPU \"$1\"" 1>&2
> --
> 2.32.0
> 




Re: [PULL 0/3] VFIO update 2021-06-18

2021-06-20 Thread Peter Maydell
On Fri, 18 Jun 2021 at 16:36, Alex Williamson
 wrote:
>
> The following changes since commit 3ccf6cd0e3e1dfd663814640b3b18b55715d7a75:
>
>   Merge remote-tracking branch 
> 'remotes/kraxel/tags/audio-20210617-pull-request' into staging (2021-06-18 
> 09:54:42 +0100)
>
> are available in the Git repository at:
>
>   git://github.com/awilliam/qemu-vfio.git tags/vfio-update-20210618.0
>
> for you to fetch changes up to d742d064c1f541ac8ad6541e248a97f2dc502721:
>
>   vfio/migration: Correct device state from vmstate change for savevm case 
> (2021-06-18 09:10:35 -0600)
>
> 
> VFIO update 2021-06-18
>
>  * VFIO migration documentation (Tarun Gupta)
>
>  * Fix SaveVMHandler de-registration (Kunkun Jiang)
>
>  * Fix vmstate change transition (Kirti Wankhede)
>
> 



Applied, thanks.

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

-- PMM



qemu-binfmt-conf.sh: enforce style consistency

2021-06-20 Thread umarcor
Spaces are removed before '; then', for consistency with other scripts
in the project.

Signed-off-by: umarcor 
---
 scripts/qemu-binfmt-conf.sh | 36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
index 7de996d536..13bff41b47 100755
--- a/scripts/qemu-binfmt-conf.sh
+++ b/scripts/qemu-binfmt-conf.sh
@@ -221,7 +221,7 @@ EOF
 }

 qemu_check_access() {
-if [ ! -w "$1" ] ; then
+if [ ! -w "$1" ]; then
 echo "ERROR: cannot write to $1" 1>&2
 exit 1
 fi
@@ -230,12 +230,12 @@ qemu_check_access() {
 qemu_check_bintfmt_misc() {
 # load the binfmt_misc module
 if [ ! -d /proc/sys/fs/binfmt_misc ]; then
-  if ! /sbin/modprobe binfmt_misc ; then
+  if ! /sbin/modprobe binfmt_misc; then
   exit 1
   fi
 fi
 if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
-  if ! mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc ; then
+  if ! mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc; then
   exit 1
   fi
 fi
@@ -248,16 +248,16 @@ installed_dpkg() {
 }

 qemu_check_debian() {
-if [ ! -e /etc/debian_version ] ; then
+if [ ! -e /etc/debian_version ]; then
 echo "WARNING: your system is not a Debian based distro" 1>&2
-elif ! installed_dpkg binfmt-support ; then
+elif ! installed_dpkg binfmt-support; then
 echo "WARNING: package binfmt-support is needed" 1>&2
 fi
 qemu_check_access "$EXPORTDIR"
 }

 qemu_check_systemd() {
-if ! systemctl -q is-enabled systemd-binfmt.service ; then
+if ! systemctl -q is-enabled systemd-binfmt.service; then
 echo "WARNING: systemd-binfmt.service is missing or disabled" 1>&2
 fi
 qemu_check_access "$EXPORTDIR"
@@ -265,13 +265,13 @@ qemu_check_systemd() {

 qemu_generate_register() {
 flags=""
-if [ "$CREDENTIAL" = "yes" ] ; then
+if [ "$CREDENTIAL" = "yes" ]; then
 flags="OC"
 fi
-if [ "$PERSISTENT" = "yes" ] ; then
+if [ "$PERSISTENT" = "yes" ]; then
 flags="${flags}F"
 fi
-if [ "$PRESERVE_ARG0" = "yes" ] ; then
+if [ "$PRESERVE_ARG0" = "yes" ]; then
 flags="${flags}P"
 fi

@@ -306,23 +306,23 @@ qemu_set_binfmts() {

 # register the interpreter for each cpu except for the native one

-for cpu in ${qemu_target_list} ; do
+for cpu in ${qemu_target_list}; do
 magic=$(eval echo \$${cpu}_magic)
 mask=$(eval echo \$${cpu}_mask)
 family=$(eval echo \$${cpu}_family)

-if [ "$magic" = "" ] || [ "$mask" = "" ] || [ "$family" = "" ] ; then
+if [ "$magic" = "" ] || [ "$mask" = "" ] || [ "$family" = "" ]; then
 echo "INTERNAL ERROR: unknown cpu $cpu" 1>&2
 continue
 fi

 qemu="$QEMU_PATH/qemu-$cpu"
-if [ "$cpu" = "i486" ] ; then
+if [ "$cpu" = "i486" ]; then
 qemu="$QEMU_PATH/qemu-i386"
 fi

 qemu="$qemu$QEMU_SUFFIX"
-if [ "$host_family" != "$family" ] ; then
+if [ "$host_family" != "$family" ]; then
 $BINFMT_SET
 fi
 done
@@ -343,7 +343,7 @@ QEMU_SUFFIX=""
 options=$(getopt -o ds:Q:S:e:hc:p:g: -l 
debian,systemd:,qemu-path:,qemu-suffix:,exportdir:,help,credential:,persistent:,preserve-argv0:
 -- "$@")
 eval set -- "$options"

-while true ; do
+while true; do
 case "$1" in
 -d|--debian)
 CHECK=qemu_check_debian
@@ -356,14 +356,14 @@ while true ; do
 EXPORTDIR=${EXPORTDIR:-$SYSTEMDDIR}
 shift
 # check given cpu is in the supported CPU list
-if [ "$1" != "ALL" ] ; then
-for cpu in ${qemu_target_list} ; do
-if [ "$cpu" = "$1" ] ; then
+if [ "$1" != "ALL" ]; then
+for cpu in ${qemu_target_list}; do
+if [ "$cpu" = "$1" ]; then
 break
 fi
 done

-if [ "$cpu" = "$1" ] ; then
+if [ "$cpu" = "$1" ]; then
 qemu_target_list="$1"
 else
 echo "ERROR: unknown CPU \"$1\"" 1>&2
--
2.32.0




Re: [PATCH] ppc: Replace TAB indentations with spaces

2021-06-20 Thread Richard Henderson

On 6/20/21 11:04 AM, Ahmed Abouzied wrote:

+#define IH_CPU_INVALID0/* Invalid CPU*/
+#define IH_CPU_ALPHA1/* Alpha*/
+#define IH_CPU_ARM2/* ARM*/
+#define IH_CPU_I3863/* Intel x86*/
+#define IH_CPU_IA644/* IA64*/
+#define IH_CPU_MIPS5/* MIPS*/
+#define IH_CPU_MIPS646/* MIPS 64 Bit */


You're doing it wrong. These should still line up after tabs are replaced.

There are tools for this sort of thing, sometimes built into your editor, often called 
"untabify".



r~



  1   2   >