RE: [PATCH] xhci: Fix memory leak in xhci_kick_epctx when poweroff GuestOS

2020-01-10 Thread Chenqun (kuhn)


>-Original Message-
>From: Philippe Mathieu-Daudé [mailto:phi...@redhat.com]
>Sent: Friday, January 10, 2020 9:14 PM
>To: Chenqun (kuhn) ; qemu-
>de...@nongnu.org; kra...@redhat.com
>Cc: qemu-triv...@nongnu.org; Pannengyuan ;
>Zhanghailiang 
>Subject: Re: [PATCH] xhci: Fix memory leak in xhci_kick_epctx when poweroff
>GuestOS
>
>On 1/10/20 11:58 AM, kuhn.chen...@huawei.com wrote:
>> From: Chen Qun 
>>
>> start vm with libvirt, when GuestOS running, enter poweroff command
>> using the xhci keyboard, then ASAN shows memory leak stack:
>>
>> Direct leak of 80 byte(s) in 5 object(s) allocated from:
>>  #0 0xfffd1e6431cb in __interceptor_malloc (/lib64/libasan.so.4+0xd31cb)
>>  #1 0xfffd1e107163 in g_malloc (/lib64/libglib-2.0.so.0+0x57163)
>>  #2 0xaaad39051367 in qemu_sglist_init /qemu/dma-helpers.c:43
>>  #3 0xaaad3947c407 in pci_dma_sglist_init
>/qemu/include/hw/pci/pci.h:842
>>  #4 0xaaad3947c407 in xhci_xfer_create_sgl /qemu/hw/usb/hcd-
>xhci.c:1446
>>  #5 0xaaad3947c407 in xhci_setup_packet /qemu/hw/usb/hcd-xhci.c:1618
>>  #6 0xaaad3948625f in xhci_submit /qemu/hw/usb/hcd-xhci.c:1827
>>  #7 0xaaad3948625f in xhci_fire_transfer /qemu/hw/usb/hcd-xhci.c:1839
>>  #8 0xaaad3948625f in xhci_kick_epctx /qemu/hw/usb/hcd-xhci.c:1991
>>  #9 0xaaad3948f537 in xhci_doorbell_write /qemu/hw/usb/hcd-
>xhci.c:3158
>>  #10 0xaaad38bcbfc7 in memory_region_write_accessor
>/qemu/memory.c:483
>>  #11 0xaaad38bc654f in access_with_adjusted_size /qemu/memory.c:544
>>  #12 0xaaad38bd1877 in memory_region_dispatch_write
>/qemu/memory.c:1482
>>  #13 0xaaad38b1c77f in flatview_write_continue /qemu/exec.c:3167
>>  #14 0xaaad38b1ca83 in flatview_write /qemu/exec.c:3207
>>  #15 0xaaad38b268db in address_space_write /qemu/exec.c:3297
>>  #16 0xaaad38bf909b in kvm_cpu_exec /qemu/accel/kvm/kvm-all.c:2383
>>  #17 0xaaad38bb063f in qemu_kvm_cpu_thread_fn /qemu/cpus.c:1246
>>  #18 0xaaad39821c93 in qemu_thread_start /qemu/util/qemu-thread-
>posix.c:519
>>  #19 0xfffd1c8378bb  (/lib64/libpthread.so.0+0x78bb)
>>  #20 0xfffd1c77616b  (/lib64/libc.so.6+0xd616b)
>>
>> Reported-by: Euler Robot 
>> Signed-off-by: Chen Qun 
>> ---
>>   hw/usb/hcd-xhci.c | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index
>> 80988bb305..0d3d96d05a 100644
>> --- a/hw/usb/hcd-xhci.c
>> +++ b/hw/usb/hcd-xhci.c
>> @@ -2000,6 +2000,7 @@ static void xhci_kick_epctx(XHCIEPContext *epctx,
>unsigned int streamid)
>>   if (xfer != NULL && xfer->running_retry) {
>>   DPRINTF("xhci: xfer nacked, stopping schedule\n");
>>   epctx->retry = xfer;
>> +xhci_xfer_unmap(xfer);
>
>Shouldn't we use xhci_ep_free_xfer() instead?
>Also, it would be cleaner if you set it to NULL.
>
Hi  Philippe,
Thanks for your reply!  
But,  It  is just a sglist leak.  xhci_xfer_unmap() can free and set  it to 
NULL.
The  xhci_ep_free_xfer() did't free a sglist.  

By the way, xfer should be use for epctx->retry, we can't free it.

Thanks.
>>   break;
>>   }
>>   if (count++ > TRANSFER_LIMIT) {
>>



Re: [PATCH v2] Implement the Screamer sound chip for the mac99 machine type

2020-01-10 Thread Programmingkid


> On Jan 10, 2020, at 7:32 PM, Zoltán Kővágó  wrote:
> 
> On 2020-01-05 02:58, Programmingkid wrote:
>> I found the patch that breaks Screamer sound support for qemu-system-ppc. It 
>> is this:
>> commit 2ceb8240fa4e4e30fb853565eb2bed3032d74f62
>> Author: Kővágó, Zoltán 
>> Date:   Thu Sep 19 23:24:11 2019 +0200
>> coreaudio: port to the new audio backend api
>>  Signed-off-by: Kővágó, Zoltán 
>> Message-id: 
>> 586a1e66de5cbc6c5234f9ae556d24befb6afada.1568927990.git.dirty.ice...@gmail.com
>> Signed-off-by: Gerd Hoffmann 
>> Reversing this patch should make the Screamer patch work with the current 
>> git version of QEMU.
> 
> Hi,
> 
> Unfortunately it's not that simple to simply revert the patch since the old 
> backend api no longer exists.  Also I don't have a Mac so it's almost 
> impossible for me to test the results.  I looked at the specified commit and 
> I think I found a problem, could you please apply the attached patch on the 
> current git master and check whether it solves the problem?  If yes I'll turn 
> it into a proper patch.
> 
> Regards,
> Zoltan
> 
> 

Sorry it did not fix the problem. I only hear pops occasionally. Most of the 
time only silence can be heard.

Thank you for the patch. 


[Bug 1859254] [NEW] host window size does not change when guest video screen size changes while moving host window

2020-01-10 Thread Benjamin David Lunt
Public bug reported:

When QEMU is emulating a legacy text mode, then switches to a VESA mode,
if you happen to be moving the host window while the switch is made, the
host window never changes size.  The emulated size does, but the host
window doesn't.

For example, at Legacy boot up, the screen mode is mode 03 at 80x25.
Then when the GUEST OS changes the screen to a VESA mode, say
1024x768x16, normally the host window will change to that size to
accommodate the new emulated screen size.

However, if you happen to be moving the host window at the time of the
screen mode change, the host window doesn't change in size to
accommodate the new screen size.

I am using:
  QEMU for Windows, version 4.1.0-11789
  Host: Windows 10 (latest updates)
  Emulating: Intel x64, Legacy BIOS
Command line:
"c:\program files\qemu\qemu-system-x86_64.exe" -m 256 -drive 
file=C:\fysos64.img,format=raw,if=ide,media=disk,index=0 -parallel 
file:para.txt -boot c -d guest_errors -vga std -smp cpus=4 -rtc 
base=localtime,clock=host,driftfix=slew -net none -monitor stdio

I tried different -vga settings:
   -vga std
   -vga cirrus
   -vga vmware
Each did the same thing.

[ Side note (possible error in documentation):
[  at: https://qemu.weilnetz.de/doc/qemu-doc.html#SVGA-graphic-modes-support
[  end of 2.16.2.1
[  (option -std-vga)
[possibly should be
[  (option -vga std)

If you need an image to test with, I have been using
www.fysnet.net/temp/fysos64.zip (2meg zipped/10meg raw).  It starts in
Legacy BIOS/Hardware mode 3, then switches to VESA 1024x768x16 within a
few seconds, so be ready to move the HOST window when the mode changes.

I do not have a Linux box to test with, so unknown if this is only an
issue with the Windows version or not.

** Affects: qemu
 Importance: Undecided
 Status: New

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

Title:
  host window size does not change when guest video screen size changes
  while moving host window

Status in QEMU:
  New

Bug description:
  When QEMU is emulating a legacy text mode, then switches to a VESA
  mode, if you happen to be moving the host window while the switch is
  made, the host window never changes size.  The emulated size does, but
  the host window doesn't.

  For example, at Legacy boot up, the screen mode is mode 03 at 80x25.
  Then when the GUEST OS changes the screen to a VESA mode, say
  1024x768x16, normally the host window will change to that size to
  accommodate the new emulated screen size.

  However, if you happen to be moving the host window at the time of the
  screen mode change, the host window doesn't change in size to
  accommodate the new screen size.

  I am using:
QEMU for Windows, version 4.1.0-11789
Host: Windows 10 (latest updates)
Emulating: Intel x64, Legacy BIOS
  Command line:
  "c:\program files\qemu\qemu-system-x86_64.exe" -m 256 -drive 
file=C:\fysos64.img,format=raw,if=ide,media=disk,index=0 -parallel 
file:para.txt -boot c -d guest_errors -vga std -smp cpus=4 -rtc 
base=localtime,clock=host,driftfix=slew -net none -monitor stdio

  I tried different -vga settings:
 -vga std
 -vga cirrus
 -vga vmware
  Each did the same thing.

  [ Side note (possible error in documentation):
  [  at: https://qemu.weilnetz.de/doc/qemu-doc.html#SVGA-graphic-modes-support
  [  end of 2.16.2.1
  [  (option -std-vga)
  [possibly should be
  [  (option -vga std)

  If you need an image to test with, I have been using
  www.fysnet.net/temp/fysos64.zip (2meg zipped/10meg raw).  It starts in
  Legacy BIOS/Hardware mode 3, then switches to VESA 1024x768x16 within
  a few seconds, so be ready to move the HOST window when the mode
  changes.

  I do not have a Linux box to test with, so unknown if this is only an
  issue with the Windows version or not.

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



Re: [PATCH v2] Implement the Screamer sound chip for the mac99 machine type

2020-01-10 Thread Zoltán Kővágó

On 2020-01-05 02:58, Programmingkid wrote:

I found the patch that breaks Screamer sound support for qemu-system-ppc. It is 
this:

commit 2ceb8240fa4e4e30fb853565eb2bed3032d74f62
Author: Kővágó, Zoltán 
Date:   Thu Sep 19 23:24:11 2019 +0200

 coreaudio: port to the new audio backend api
 
 Signed-off-by: Kővágó, Zoltán 

 Message-id: 
586a1e66de5cbc6c5234f9ae556d24befb6afada.1568927990.git.dirty.ice...@gmail.com
 Signed-off-by: Gerd Hoffmann 


Reversing this patch should make the Screamer patch work with the current git 
version of QEMU.



Hi,

Unfortunately it's not that simple to simply revert the patch since the 
old backend api no longer exists.  Also I don't have a Mac so it's 
almost impossible for me to test the results.  I looked at the specified 
commit and I think I found a problem, could you please apply the 
attached patch on the current git master and check whether it solves the 
problem?  If yes I'll turn it into a proper patch.


Regards,
Zoltan

diff --git a/audio/audio_template.h b/audio/audio_template.h
index 3287d7075e..a7b46b8363 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -153,6 +153,13 @@ static int glue (audio_pcm_sw_init_, TYPE) (
 sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;
 #endif
 
+#ifdef FLOAT_MIXENG
+#ifdef DAC
+sw->conv = mixeng_conv_float;
+#else
+sw->clip = mixeng_clip_float;
+#endif
+#else
 #ifdef DAC
 sw->conv = mixeng_conv
 #else
@@ -162,6 +169,7 @@ static int glue (audio_pcm_sw_init_, TYPE) (
 [sw->info.sign]
 [sw->info.swap_endianness]
 [audio_bits_to_index (sw->info.bits)];
+#endif
 
 sw->name = g_strdup (name);
 err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw);
diff --git a/audio/mixeng.h b/audio/mixeng.h
index 18e62c7c49..343f5fb810 100644
--- a/audio/mixeng.h
+++ b/audio/mixeng.h
@@ -41,6 +41,11 @@ typedef void (f_sample) (void *dst, const struct st_sample *src, int samples);
 extern t_sample *mixeng_conv[2][2][2][3];
 extern f_sample *mixeng_clip[2][2][2][3];
 
+#ifdef FLOAT_MIXENG
+void mixeng_conv_float(struct st_sample *dst, const void *src, int samples);
+void mixeng_clip_float(void *dst, const struct st_sample *src, int samples);
+#endif
+
 void *st_rate_start (int inrate, int outrate);
 void st_rate_flow(void *opaque, st_sample *ibuf, st_sample *obuf,
   size_t *isamp, size_t *osamp);
diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index 66f0f459cf..4e7e509ad0 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -471,20 +471,6 @@ static OSStatus audioDeviceIOProc(
 return 0;
 }
 
-static UInt32 coreaudio_get_flags(struct audio_pcm_info *info,
-  struct audsettings *as)
-{
-UInt32 flags = info->sign ? kAudioFormatFlagIsSignedInteger : 0;
-if (as->endianness) { /* 0 = little, 1 = big */
-flags |= kAudioFormatFlagIsBigEndian;
-}
-
-if (flags == 0) { /* must not be 0 */
-flags = kAudioFormatFlagsAreAllClear;
-}
-return flags;
-}
-
 static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
   void *drv_opaque)
 {
@@ -572,15 +558,6 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
 
 /* set Samplerate */
 core->outputStreamBasicDescription.mSampleRate = (Float64) as->freq;
-core->outputStreamBasicDescription.mFormatID = kAudioFormatLinearPCM;
-core->outputStreamBasicDescription.mFormatFlags =
-coreaudio_get_flags(>info, as);
-core->outputStreamBasicDescription.mBytesPerPacket =
-core->outputStreamBasicDescription.mBytesPerFrame =
-hw->info.nchannels * hw->info.bits / 8;
-core->outputStreamBasicDescription.mFramesPerPacket = 1;
-core->outputStreamBasicDescription.mChannelsPerFrame = hw->info.nchannels;
-core->outputStreamBasicDescription.mBitsPerChannel = hw->info.bits;
 
 status = coreaudio_set_streamformat(core->outputDeviceID,
 >outputStreamBasicDescription);
diff --git a/audio/mixeng.c b/audio/mixeng.c
index 2f5ba71381..424ffe30d7 100644
--- a/audio/mixeng.c
+++ b/audio/mixeng.c
@@ -267,6 +267,27 @@ f_sample *mixeng_clip[2][2][2][3] = {
 }
 };
 
+#ifdef FLOAT_MIXENG
+void mixeng_conv_float(struct st_sample *dst, const void *src, int samples)
+{
+float *in = (float *) src;
+while (samples--) {
+dst->l = *in++;
+dst->r = *in++;
+dst++;
+}
+}
+
+void mixeng_clip_float(void *dst, const struct st_sample *src, int samples)
+{
+float *out = (float *) dst;
+while (samples--) {
+*out++ = src->l;
+*out++ = src->r;
+src++;
+}
+}
+#endif
 
 void audio_sample_to_uint64(void *samples, int pos,
 uint64_t *left, uint64_t *right)


Re: [PATCH v1 20/36] target/riscv: Add support for virtual interrupt setting

2020-01-10 Thread Palmer Dabbelt

On Wed, 08 Jan 2020 18:33:40 PST (-0800), richard.hender...@linaro.org wrote:

On 1/9/20 11:49 AM, Palmer Dabbelt wrote:

+    irqs = (pending & ~env->mideleg & -mie) | (pending &  env->mideleg & -sie);


Isn't "-unsigned" implementation defined?  I can't get GCC to throw a warning
and it was already there, so maybe I'm just wrong?


(1) You're confusing implementation defined with undefined, and unsigned
arithmetic is the former not the latter.

(2) There is no such thing as ones-compliment or sign-magnitude integer
hardware anymore, so for this case "implementation defined" is in fact 
universal.

(3) We build with -fwrapv, so we're explicitly asking for sane behaviour from
our signed types as well.


Ah, thanks -- I didn't know we had -fwrapv.  In that case we're safe!




r~




[Bug 1856834] Re: Virtio broken in qemu ppc in 4.2.0 and other versions

2020-01-10 Thread ecsdn
Sorry for the delay, I have sent you a private message/email with the
actual kernel image. thx!

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

Title:
  Virtio broken in qemu ppc in 4.2.0 and other versions

Status in QEMU:
  New

Bug description:
  The same qemu -M mpc... command that works on qemu-system-ppc version
  2.8.0 freezes guest on bootup and shows error for qemu-system-ppc
  version 4.2.0release and 4.19dirtygit:

  qemu-system-ppc: virtio-blk failed to set guest notifier (-24), ensure -accel 
kvm is set.
  qemu-system-ppc: virtio_bus_start_ioeventfd: failed. Fallback to userspace 
(slower).

  ends/freezes at:
  nbd: registered device at major 43
   vda:

  I'm using -drive file=/home/me/rawimage.dd,if=virtio and works fine in
  version 2.8.0 installed with apt-get install (Ubuntu 17.04) and also
  with 2.8.0 official release from git/github that I compiled/built
  myself. But both of the newer releases fail on the same exact machine
  same config.

  I also noticed that qemu-2.8.0 was fine with mtd but the newer ones I tried 
weren't, ie gave
  qemu-system-ppc: -drive if=mtd: machine type does not support 
if=mtd,bus=0,unit=0
  (but I removed -drive if=mtd since wasn't using it anyway)

  I also tried on windows but I think virtio doesn't work on windows
  hosts at all? On windows host it fails the same way, even version 2.12
  as well as 4.1.10...

  used:
  ./configure --prefix=/opt/... --enable-fdt --enable-kvm --enable-debug

  (basically all steps the same on same exact system same config, yet
  2.8.0 works fine whether apt-get installed or built from source while
  the others I built, 4.19/4.2.0 or 2.12/4.1.10(win) don't.)

  In case newer qemu versions act weird on various kernels, I did try with both 
vmlinuz-4.10.0-19-generic and vmlinuz-4.13.12-041312-generic (I didn't compile 
them but I can provide config-..files. This is on Ubuntu 17.04 x86_64 host 
emulating e500v2 cpm guest, ie -M mpc... GUEST kernel 2.6.32.44 which is why I 
can't use -M ppce500 instead..)
  tx
   ecs

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



[PATCH] target/openrisc: Fix FPCSR mask to allow setting DZF

2020-01-10 Thread Stafford Horne
The mask used when setting FPCSR allows setting bits 10 to 1.  However,
OpenRISC has flags and config bits in 11 to 1, 11 being Divide by Zero
Flag (DZF).  This seems like an off-by-one bug.

This was found when testing the GLIBC test suite which has test cases to
set and clear all bits.

Signed-off-by: Stafford Horne 
---
 target/openrisc/fpu_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/openrisc/fpu_helper.c b/target/openrisc/fpu_helper.c
index 59e1413279..6f75ea0505 100644
--- a/target/openrisc/fpu_helper.c
+++ b/target/openrisc/fpu_helper.c
@@ -70,7 +70,7 @@ void cpu_set_fpcsr(CPUOpenRISCState *env, uint32_t val)
 float_round_down
 };
 
-env->fpcsr = val & 0x7ff;
+env->fpcsr = val & 0xfff;
 set_float_rounding_mode(rm_to_sf[extract32(val, 1, 2)], >fp_status);
 }
 
-- 
2.21.0




Re: [PATCH v3 02/17] hw/arm: add Xunlong Orange Pi PC machine

2020-01-10 Thread Niek Linnenbank
On Wed, Jan 8, 2020 at 11:44 PM Philippe Mathieu-Daudé 
wrote:

> On 1/8/20 9:00 PM, Niek Linnenbank wrote:
> > The Xunlong Orange Pi PC is an Allwinner H3 System on Chip
> > based embedded computer with mainline support in both U-Boot
> > and Linux. The board comes with a Quad Core Cortex A7 @ 1.3GHz,
> > 512MB RAM, 100Mbit ethernet, USB, SD/MMC, USB, HDMI and
> > various other I/O. This commit add support for the Xunlong
> > Orange Pi PC machine.
> >
> > Signed-off-by: Niek Linnenbank 
> > Tested-by: KONRAD Frederic 
> > ---
> >   hw/arm/orangepi.c| 93 
> >   MAINTAINERS  |  1 +
> >   hw/arm/Makefile.objs |  2 +-
> >   3 files changed, 95 insertions(+), 1 deletion(-)
> >   create mode 100644 hw/arm/orangepi.c
> >
> > diff --git a/hw/arm/orangepi.c b/hw/arm/orangepi.c
> > new file mode 100644
> > index 00..051184f14f
> > --- /dev/null
> > +++ b/hw/arm/orangepi.c
> > @@ -0,0 +1,93 @@
> > +/*
> > + * Orange Pi emulation
> > + *
> > + * Copyright (C) 2019 Niek Linnenbank 
> > + *
> > + * This program is free software: you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation, either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program.  If not, see  >.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "exec/address-spaces.h"
> > +#include "qapi/error.h"
> > +#include "cpu.h"
> > +#include "hw/sysbus.h"
> > +#include "hw/boards.h"
> > +#include "hw/qdev-properties.h"
> > +#include "hw/arm/allwinner-h3.h"
> > +#include "sysemu/sysemu.h"
> > +
> > +static struct arm_boot_info orangepi_binfo = {
> > +.board_id = -1,
>
> Since you use a dtb, I suppose Linux ignores this board_id.
>
> Nitpick, you can set this here:
>
> .nb_cpus = AW_H3_NUM_CPUS,
>
> > +};
> > +
> > +typedef struct OrangePiState {
> > +AwH3State *h3;
> > +MemoryRegion sdram;
> > +} OrangePiState;
> > +
> > +static void orangepi_init(MachineState *machine)
> > +{
> > +OrangePiState *s = g_new(OrangePiState, 1);
> > +
>
> I'd do the bios check first, as it is cheap and avoid allocating RAM + H3:
>
> /* Load target kernel or start using BootROM */
> if (bios_name) {
> error_report("BIOS not supported for this machine");
> exit(1);
> }
>
> > +/* Only allow Cortex-A7 for this board */
> > +if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a7")) != 0)
> {
> > +error_report("This board can only be used with cortex-a7 CPU");
> > +exit(1);
> > +}
> > +
> > +s->h3 = AW_H3(object_new(TYPE_AW_H3));
> > +
> > +/* Setup timer properties */
> > +object_property_set_int(OBJECT(s->h3), 32768, "clk0-freq",
> > +_abort);
> > +object_property_set_int(OBJECT(s->h3), 2400, "clk1-freq",
>
> I find 24 * 1000 * 1000 easier to review.
>
> > +_abort);
> > +
> > +/* Mark H3 object realized */
> > +object_property_set_bool(OBJECT(s->h3), true, "realized",
> _abort);
> > +
> > +/* SDRAM */
> > +if (machine->ram_size != 1 * GiB) {
> > +error_report("Requested ram size is not supported for this
> machine: "
> > + "restricted to 1GiB");
>
> Maybe easier as "This machine can only be used with 1GiB of RAM"
>
> > +exit(1);
> > +}
> > +memory_region_allocate_system_memory(>sdram, NULL, "sdram",
> > + machine->ram_size);
> > +memory_region_add_subregion(get_system_memory(),
> s->h3->memmap[AW_H3_SDRAM],
> > +>sdram);
> > +
> > +/* Load target kernel or start using BootROM */
> > +if (bios_name) {
> > +error_report("BIOS not supported for this machine");
> > +exit(1);
> > +}
> > +orangepi_binfo.loader_start = s->h3->memmap[AW_H3_SDRAM];
> > +orangepi_binfo.ram_size = machine->ram_size;
> > +orangepi_binfo.nb_cpus  = AW_H3_NUM_CPUS;
> > +arm_load_kernel(ARM_CPU(first_cpu), machine, _binfo);
> > +}
> > +
> > +static void orangepi_machine_init(MachineClass *mc)
> > +{
> > +mc->desc = "Orange Pi PC";
> > +mc->init = orangepi_init;
> > +mc->min_cpus = AW_H3_NUM_CPUS;
> > +mc->max_cpus = AW_H3_NUM_CPUS;
> > +mc->default_cpus = AW_H3_NUM_CPUS;
> > +mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a7");
> > +mc->default_ram_size = 1 * GiB;
> > +}
> > +
> > +DEFINE_MACHINE("orangepi-pc", orangepi_machine_init)
> > 

[PATCH 5/6] hw/char/exynos4210_uart: Add receive DMA support

2020-01-10 Thread Guenter Roeck
To support receive DMA, we need to inform the DMA controller if receive data
is available. Otherwise the DMA controller keeps requesting data, causing
receive errors.

Implement this using an interrupt line. The instantiating code then needs
to connect the interrupt with the matching DMA controller GPIO pin.

Signed-off-by: Guenter Roeck 
---
 hw/char/exynos4210_uart.c | 24 
 hw/char/trace-events  |  2 ++
 2 files changed, 26 insertions(+)

diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
index 61134a7bdc..e23799f93b 100644
--- a/hw/char/exynos4210_uart.c
+++ b/hw/char/exynos4210_uart.c
@@ -154,6 +154,7 @@ typedef struct Exynos4210UartState {
 
 CharBackend   chr;
 qemu_irq  irq;
+qemu_irq  dmairq;
 
 uint32_t channel;
 
@@ -261,6 +262,24 @@ exynos4210_uart_Rx_FIFO_trigger_level(const 
Exynos4210UartState *s)
 return exynos4210_uart_FIFO_trigger_level(s->channel, reg);
 }
 
+/*
+ * Update Rx DMA busy signal if Rx DMA is enabled. For simplicity,
+ * mark DMA as busy if DMA is enabled and the receive buffer is empty.
+ */
+static void exynos4210_uart_update_dmabusy(Exynos4210UartState *s)
+{
+bool rx_dma_enabled = (s->reg[I_(UCON)] & 0x03) == 0x02;
+uint32_t count = fifo_elements_number(>rx);
+
+if (rx_dma_enabled && !count) {
+qemu_irq_raise(s->dmairq);
+trace_exynos_uart_dmabusy(s->channel);
+} else {
+qemu_irq_lower(s->dmairq);
+trace_exynos_uart_dmaready(s->channel);
+}
+}
+
 static void exynos4210_uart_update_irq(Exynos4210UartState *s)
 {
 /*
@@ -282,10 +301,12 @@ static void 
exynos4210_uart_update_irq(Exynos4210UartState *s)
 count = fifo_elements_number(>rx);
 if ((count && !(s->reg[I_(UCON)] & 0x80)) ||
 count >= exynos4210_uart_Rx_FIFO_trigger_level(s)) {
+exynos4210_uart_update_dmabusy(s);
 s->reg[I_(UINTSP)] |= UINTSP_RXD;
 timer_del(s->fifo_timeout_timer);
 }
 } else if (s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY) {
+exynos4210_uart_update_dmabusy(s);
 s->reg[I_(UINTSP)] |= UINTSP_RXD;
 }
 
@@ -311,6 +332,7 @@ static void exynos4210_uart_timeout_int(void *opaque)
 (s->reg[I_(UCON)] & (1 << 11))) {
 s->reg[I_(UINTSP)] |= UINTSP_RXD;
 s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_TIMEOUT;
+exynos4210_uart_update_dmabusy(s);
 exynos4210_uart_update_irq(s);
 }
 }
@@ -499,6 +521,7 @@ static uint64_t exynos4210_uart_read(void *opaque, hwaddr 
offset,
 s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_BUFFER_DATA_READY;
 res = s->reg[I_(URXH)];
 }
+exynos4210_uart_update_dmabusy(s);
 trace_exynos_uart_read(s->channel, offset,
exynos4210_uart_regname(offset), res);
 return res;
@@ -654,6 +677,7 @@ static void exynos4210_uart_init(Object *obj)
 sysbus_init_mmio(dev, >iomem);
 
 sysbus_init_irq(dev, >irq);
+sysbus_init_irq(dev, >dmairq);
 }
 
 static void exynos4210_uart_realize(DeviceState *dev, Error **errp)
diff --git a/hw/char/trace-events b/hw/char/trace-events
index cb73fee6a9..6f938301d9 100644
--- a/hw/char/trace-events
+++ b/hw/char/trace-events
@@ -79,6 +79,8 @@ nrf51_uart_read(uint64_t addr, uint64_t r, unsigned int size) 
"addr 0x%" PRIx64
 nrf51_uart_write(uint64_t addr, uint64_t value, unsigned int size) "addr 0x%" 
PRIx64 " value 0x%" PRIx64 " size %u"
 
 # exynos4210_uart.c
+exynos_uart_dmabusy(uint32_t channel) "UART%d: DMA busy (Rx buffer empty)"
+exynos_uart_dmaready(uint32_t channel) "UART%d: DMA ready"
 exynos_uart_irq_raised(uint32_t channel, uint32_t reg) "UART%d: IRQ raised: 
0x%08"PRIx32
 exynos_uart_irq_lowered(uint32_t channel) "UART%d: IRQ lowered"
 exynos_uart_update_params(uint32_t channel, int speed, uint8_t parity, int 
data, int stop, uint64_t wordtime) "UART%d: speed: %d, parity: %c, data bits: 
%d, stop bits: %d wordtime: %"PRId64"ns"
-- 
2.17.1




[PATCH 6/6] hw/arm/exynos4210: Connect serial port DMA busy signals with pl330

2020-01-10 Thread Guenter Roeck
The Exynos4210 serial driver uses an interrupt line to signal if receive
data is available. Connect that interrupt with the DMA controller's
'peripheral busy' gpio pin.

Signed-off-by: Guenter Roeck 
---
 hw/arm/exynos4210.c | 39 ++-
 1 file changed, 26 insertions(+), 13 deletions(-)

diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
index c7b5c587b1..498d79ebb2 100644
--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -166,8 +166,8 @@ static uint64_t exynos4210_calc_affinity(int cpu)
 return (0x9 << ARM_AFF1_SHIFT) | cpu;
 }
 
-static void pl330_create(uint32_t base, qemu_irq irq, int nreq, int nevents,
- int width)
+static DeviceState *pl330_create(uint32_t base, qemu_irq irq, int nreq,
+ int nevents, int width)
 {
 SysBusDevice *busdev;
 DeviceState *dev;
@@ -191,6 +191,7 @@ static void pl330_create(uint32_t base, qemu_irq irq, int 
nreq, int nevents,
 for (i = 0; i < nevents; i++) {
 sysbus_connect_irq(busdev, i + 1, irq); /* event irq lines */
 }
+return dev;
 }
 
 static void exynos4210_realize(DeviceState *socdev, Error **errp)
@@ -199,7 +200,7 @@ static void exynos4210_realize(DeviceState *socdev, Error 
**errp)
 MemoryRegion *system_mem = get_system_memory();
 qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
 SysBusDevice *busdev;
-DeviceState *dev;
+DeviceState *dev, *uart[4], *pl330[3];
 int i, n;
 
 for (n = 0; n < EXYNOS4210_NCPUS; n++) {
@@ -385,19 +386,19 @@ static void exynos4210_realize(DeviceState *socdev, Error 
**errp)
 
 
 /*** UARTs ***/
-exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
+uart[0] = exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
EXYNOS4210_UART0_FIFO_SIZE, 0, serial_hd(0),
   s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 
0)]);
 
-exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
+uart[1] = exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
EXYNOS4210_UART1_FIFO_SIZE, 1, serial_hd(1),
   s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 
1)]);
 
-exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
+uart[2] = exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
EXYNOS4210_UART2_FIFO_SIZE, 2, serial_hd(2),
   s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 
2)]);
 
-exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
+uart[3] = exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
EXYNOS4210_UART3_FIFO_SIZE, 3, serial_hd(3),
   s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 
3)]);
 
@@ -445,12 +446,24 @@ static void exynos4210_realize(DeviceState *socdev, Error 
**errp)
 s->irq_table[exynos4210_get_irq(28, 3)]);
 
 /*** DMA controllers ***/
-pl330_create(EXYNOS4210_PL330_BASE0_ADDR,
- s->irq_table[exynos4210_get_irq(21, 0)], 32, 32, 32);
-pl330_create(EXYNOS4210_PL330_BASE1_ADDR,
- s->irq_table[exynos4210_get_irq(21, 1)], 32, 32, 32);
-pl330_create(EXYNOS4210_PL330_BASE2_ADDR,
- s->irq_table[exynos4210_get_irq(20, 1)], 1, 31, 64);
+pl330[0] = pl330_create(EXYNOS4210_PL330_BASE0_ADDR,
+s->irq_table[exynos4210_get_irq(21, 0)],
+32, 32, 32);
+pl330[1] = pl330_create(EXYNOS4210_PL330_BASE1_ADDR,
+s->irq_table[exynos4210_get_irq(21, 1)],
+32, 32, 32);
+pl330[2] = pl330_create(EXYNOS4210_PL330_BASE2_ADDR,
+s->irq_table[exynos4210_get_irq(20, 1)],
+1, 31, 64);
+
+sysbus_connect_irq(SYS_BUS_DEVICE(uart[0]), 1,
+   qdev_get_gpio_in(pl330[0], 15));
+sysbus_connect_irq(SYS_BUS_DEVICE(uart[1]), 1,
+   qdev_get_gpio_in(pl330[1], 15));
+sysbus_connect_irq(SYS_BUS_DEVICE(uart[2]), 1,
+   qdev_get_gpio_in(pl330[0], 17));
+sysbus_connect_irq(SYS_BUS_DEVICE(uart[3]), 1,
+   qdev_get_gpio_in(pl330[1], 17));
 }
 
 static void exynos4210_class_init(ObjectClass *klass, void *data)
-- 
2.17.1




[PATCH 3/6] hw/char/exynos4210_uart: Convert to support tracing

2020-01-10 Thread Guenter Roeck
Replace debug code with tracing to aid debugging.

Signed-off-by: Guenter Roeck 
---
 hw/char/exynos4210_uart.c | 96 ---
 hw/char/trace-events  | 17 +++
 2 files changed, 47 insertions(+), 66 deletions(-)

diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
index d6b6b62366..fb7a3ebd09 100644
--- a/hw/char/exynos4210_uart.c
+++ b/hw/char/exynos4210_uart.c
@@ -31,45 +31,7 @@
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
 
-#undef DEBUG_UART
-#undef DEBUG_UART_EXTEND
-#undef DEBUG_IRQ
-#undef DEBUG_Rx_DATA
-#undef DEBUG_Tx_DATA
-
-#define DEBUG_UART0
-#define DEBUG_UART_EXTEND 0
-#define DEBUG_IRQ 0
-#define DEBUG_Rx_DATA 0
-#define DEBUG_Tx_DATA 0
-
-#if DEBUG_UART
-#define  PRINT_DEBUG(fmt, args...)  \
-do { \
-fprintf(stderr, "  [%s:%d]   "fmt, __func__, __LINE__, ##args); \
-} while (0)
-
-#if DEBUG_UART_EXTEND
-#define  PRINT_DEBUG_EXTEND(fmt, args...) \
-do { \
-fprintf(stderr, "  [%s:%d]   "fmt, __func__, __LINE__, ##args); \
-} while (0)
-#else
-#define  PRINT_DEBUG_EXTEND(fmt, args...) \
-do {} while (0)
-#endif /* EXTEND */
-
-#else
-#define  PRINT_DEBUG(fmt, args...)  \
-do {} while (0)
-#define  PRINT_DEBUG_EXTEND(fmt, args...) \
-do {} while (0)
-#endif
-
-#define  PRINT_ERROR(fmt, args...) \
-do { \
-fprintf(stderr, "  [%s:%d]   "fmt, __func__, __LINE__, ##args); \
-} while (0)
+#include "trace.h"
 
 /*
  *  Offsets for UART registers relative to SFR base address
@@ -193,8 +155,7 @@ typedef struct Exynos4210UartState {
 } Exynos4210UartState;
 
 
-#if DEBUG_UART
-/* Used only for debugging inside PRINT_DEBUG_... macros */
+/* Used only for tracing */
 static const char *exynos4210_uart_regname(hwaddr  offset)
 {
 
@@ -208,7 +169,6 @@ static const char *exynos4210_uart_regname(hwaddr  offset)
 
 return NULL;
 }
-#endif
 
 
 static void fifo_store(Exynos4210UartFIFO *q, uint8_t ch)
@@ -271,7 +231,7 @@ static uint32_t exynos4210_uart_Tx_FIFO_trigger_level(const 
Exynos4210UartState
 break;
 default:
 level = 0;
-PRINT_ERROR("Wrong UART channel number: %d\n", s->channel);
+trace_exynos_uart_channel_error(s->channel);
 }
 
 return level;
@@ -297,14 +257,10 @@ static void 
exynos4210_uart_update_irq(Exynos4210UartState *s)
 
 if (s->reg[I_(UINTP)]) {
 qemu_irq_raise(s->irq);
-
-#if DEBUG_IRQ
-fprintf(stderr, "UART%d: IRQ has been raised: %08x\n",
-s->channel, s->reg[I_(UINTP)]);
-#endif
-
+trace_exynos_uart_irq_raised(s->channel, s->reg[I_(UINTP)]);
 } else {
 qemu_irq_lower(s->irq);
+trace_exynos_uart_irq_lowered(s->channel);
 }
 }
 
@@ -348,7 +304,7 @@ static void 
exynos4210_uart_update_parameters(Exynos4210UartState *s)
 
 qemu_chr_fe_ioctl(>chr, CHR_IOCTL_SERIAL_SET_PARAMS, );
 
-PRINT_DEBUG("UART%d: speed: %d, parity: %c, data: %d, stop: %d\n",
+trace_exynos_uart_update_params(
 s->channel, speed, parity, data_bits, stop_bits);
 }
 
@@ -358,8 +314,8 @@ static void exynos4210_uart_write(void *opaque, hwaddr 
offset,
 Exynos4210UartState *s = (Exynos4210UartState *)opaque;
 uint8_t ch;
 
-PRINT_DEBUG_EXTEND("UART%d: <0x%04x> %s <- 0x%08llx\n", s->channel,
-offset, exynos4210_uart_regname(offset), (long long unsigned int)val);
+trace_exynos_uart_write(s->channel, offset,
+exynos4210_uart_regname(offset), val);
 
 switch (offset) {
 case ULCON:
@@ -373,12 +329,12 @@ static void exynos4210_uart_write(void *opaque, hwaddr 
offset,
 if (val & UFCON_Rx_FIFO_RESET) {
 fifo_reset(>rx);
 s->reg[I_(UFCON)] &= ~UFCON_Rx_FIFO_RESET;
-PRINT_DEBUG("UART%d: Rx FIFO Reset\n", s->channel);
+trace_exynos_uart_rx_fifo_reset(s->channel);
 }
 if (val & UFCON_Tx_FIFO_RESET) {
 fifo_reset(>tx);
 s->reg[I_(UFCON)] &= ~UFCON_Tx_FIFO_RESET;
-PRINT_DEBUG("UART%d: Tx FIFO Reset\n", s->channel);
+trace_exynos_uart_tx_fifo_reset(s->channel);
 }
 break;
 
@@ -390,9 +346,7 @@ static void exynos4210_uart_write(void *opaque, hwaddr 
offset,
 /* XXX this blocks entire thread. Rewrite to use
  * qemu_chr_fe_write and background I/O callbacks */
 qemu_chr_fe_write_all(>chr, , 1);
-#if DEBUG_Tx_DATA
-fprintf(stderr, "%c", ch);
-#endif
+trace_exynos_uart_tx(s->channel, ch);
 s->reg[I_(UTRSTAT)] |= UTRSTAT_TRANSMITTER_EMPTY |
 UTRSTAT_Tx_BUFFER_EMPTY;
 s->reg[I_(UINTSP)]  |= UINTSP_TXD;
@@ -403,8 +357,7 @@ static void exynos4210_uart_write(void *opaque, hwaddr 
offset,
 case UINTP:
 s->reg[I_(UINTP)] &= ~val;
 s->reg[I_(UINTSP)] &= ~val;
-

[PATCH 1/6] dma/pl330: Convert to support tracing

2020-01-10 Thread Guenter Roeck
Replace debug logging code with tracing.

Signed-off-by: Guenter Roeck 
---
 hw/dma/pl330.c  | 88 +++--
 hw/dma/trace-events | 24 +
 2 files changed, 70 insertions(+), 42 deletions(-)

diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c
index f2bb2d9ac1..c64cc4e67a 100644
--- a/hw/dma/pl330.c
+++ b/hw/dma/pl330.c
@@ -25,19 +25,12 @@
 #include "sysemu/dma.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
+#include "trace.h"
 
 #ifndef PL330_ERR_DEBUG
 #define PL330_ERR_DEBUG 0
 #endif
 
-#define DB_PRINT_L(lvl, fmt, args...) do {\
-if (PL330_ERR_DEBUG >= lvl) {\
-fprintf(stderr, "PL330: %s:" fmt, __func__, ## args);\
-} \
-} while (0)
-
-#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
-
 #define PL330_PERIPH_NUM32
 #define PL330_MAX_BURST_LEN 128
 #define PL330_INSN_MAXSIZE  6
@@ -319,6 +312,26 @@ typedef struct PL330InsnDesc {
 void (*exec)(PL330Chan *, uint8_t opcode, uint8_t *args, int len);
 } PL330InsnDesc;
 
+static void pl330_hexdump(uint8_t *buf, size_t size)
+{
+unsigned int b, i, len;
+char tmpbuf[80];
+
+for (b = 0; b < size; b += 16) {
+len = size - b;
+if (len > 16) {
+len = 16;
+}
+tmpbuf[0] = '\0';
+for (i = 0; i < len; i++) {
+if ((i % 4) == 0) {
+strcat(tmpbuf, " ");
+}
+sprintf(tmpbuf + strlen(tmpbuf), " %02x", buf[b + i]);
+}
+trace_pl330_hexdump(b, tmpbuf);
+}
+}
 
 /* MFIFO Implementation
  *
@@ -582,7 +595,7 @@ static inline void pl330_queue_remove_tagged(PL330Queue *s, 
uint8_t tag)
 
 static inline void pl330_fault(PL330Chan *ch, uint32_t flags)
 {
-DB_PRINT("ch: %p, flags: %" PRIx32 "\n", ch, flags);
+trace_pl330_fault(ch, flags);
 ch->fault_type |= flags;
 if (ch->state == pl330_chan_fault) {
 return;
@@ -590,7 +603,7 @@ static inline void pl330_fault(PL330Chan *ch, uint32_t 
flags)
 ch->state = pl330_chan_fault;
 ch->parent->num_faulting++;
 if (ch->parent->num_faulting == 1) {
-DB_PRINT("abort interrupt raised\n");
+trace_pl330_fault_abort();
 qemu_irq_raise(ch->parent->irq_abort);
 }
 }
@@ -648,7 +661,7 @@ static void pl330_dmaend(PL330Chan *ch, uint8_t opcode,
 return;
 }
 }
-DB_PRINT("DMA ending!\n");
+trace_pl330_dmaend();
 pl330_fifo_tagged_remove(>fifo, ch->tag);
 pl330_queue_remove_tagged(>read_queue, ch->tag);
 pl330_queue_remove_tagged(>write_queue, ch->tag);
@@ -683,7 +696,7 @@ static void pl330_dmago(PL330Chan *ch, uint8_t opcode, 
uint8_t *args, int len)
 uint32_t pc;
 PL330Chan *s;
 
-DB_PRINT("\n");
+trace_pl330_dmago();
 
 if (!ch->is_manager) {
 pl330_fault(ch, PL330_FAULT_UNDEF_INSTR);
@@ -740,9 +753,7 @@ static void pl330_dmald(PL330Chan *ch, uint8_t opcode, 
uint8_t *args, int len)
 ch->stall = pl330_queue_put_insn(>parent->read_queue, ch->src,
 size, num, inc, 0, ch->tag);
 if (!ch->stall) {
-DB_PRINT("channel:%" PRId8 " address:%08" PRIx32 " size:%" PRIx32
- " num:%" PRId32 " %c\n",
- ch->tag, ch->src, size, num, inc ? 'Y' : 'N');
+trace_pl330_dmald(ch->tag, ch->src, size, num, inc ? 'Y' : 'N');
 ch->src += inc ? size * num - (ch->src & (size - 1)) : 0;
 }
 }
@@ -782,7 +793,7 @@ static void pl330_dmakill(PL330Chan *ch, uint8_t opcode, 
uint8_t *args, int len)
 ch->fault_type = 0;
 ch->parent->num_faulting--;
 if (ch->parent->num_faulting == 0) {
-DB_PRINT("abort interrupt lowered\n");
+trace_pl330_dmakill();
 qemu_irq_lower(ch->parent->irq_abort);
 }
 }
@@ -800,6 +811,8 @@ static void pl330_dmalpend(PL330Chan *ch, uint8_t opcode,
 uint8_t bs = opcode & 3;
 uint8_t lc = (opcode & 4) >> 2;
 
+trace_pl330_dmalpend(nf, bs, lc, ch->lc[lc], ch->request_flag);
+
 if (bs == 2) {
 pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
 return;
@@ -813,12 +826,12 @@ static void pl330_dmalpend(PL330Chan *ch, uint8_t opcode,
 if (nf) {
 ch->lc[lc]--;
 }
-DB_PRINT("loop reiteration\n");
+trace_pl330_dmalpiter();
 ch->pc -= args[0];
 ch->pc -= len + 1;
 /* "ch->pc -= args[0] + len + 1" is incorrect when args[0] == 256 */
 } else {
-DB_PRINT("loop fallthrough\n");
+trace_pl330_dmalpfallthrough();
 }
 }
 
@@ -886,10 +899,10 @@ static void pl330_dmasev(PL330Chan *ch, uint8_t opcode, 
uint8_t *args, int len)
 }
 if (ch->parent->inten & (1 << ev_id)) {
 ch->parent->int_status |= (1 << ev_id);
-DB_PRINT("event interrupt raised %" PRId8 "\n", ev_id);
+trace_pl330_dmasev_evirq(ev_id);
 qemu_irq_raise(ch->parent->irq[ev_id]);
 }
-DB_PRINT("event raised %" PRId8 "\n", 

[PATCH 2/6] hw/arm/exynos4210: Fix DMA initialization

2020-01-10 Thread Guenter Roeck
First parameter to exynos4210_get_irq() is not the SPI port number,
but the interrupt group number. Interrupt groups are 20 for mdma
and 21 for pdma. Interrupts are not inverted. Controllers support 32
events (pdma) or 31 events (mdma). Events must all be routed to a single
interrupt line. Set other parameters as documented in Exynos4210 datasheet,
section 8 (DMA controller).

Fixes: 59520dc65e ("hw/arm/exynos4210: Add DMA support for the Exynos4210")
Signed-off-by: Guenter Roeck 
---
 hw/arm/exynos4210.c | 24 +++-
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
index 77fbe1baab..c7b5c587b1 100644
--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -166,17 +166,31 @@ static uint64_t exynos4210_calc_affinity(int cpu)
 return (0x9 << ARM_AFF1_SHIFT) | cpu;
 }
 
-static void pl330_create(uint32_t base, qemu_irq irq, int nreq)
+static void pl330_create(uint32_t base, qemu_irq irq, int nreq, int nevents,
+ int width)
 {
 SysBusDevice *busdev;
 DeviceState *dev;
+int i;
 
 dev = qdev_create(NULL, "pl330");
+qdev_prop_set_uint8(dev, "num_events", nevents);
+qdev_prop_set_uint8(dev, "num_chnls",  8);
 qdev_prop_set_uint8(dev, "num_periph_req",  nreq);
+
+qdev_prop_set_uint8(dev, "wr_cap", 4);
+qdev_prop_set_uint8(dev, "wr_q_dep", 8);
+qdev_prop_set_uint8(dev, "rd_cap", 4);
+qdev_prop_set_uint8(dev, "rd_q_dep", 8);
+qdev_prop_set_uint8(dev, "data_width", width);
+qdev_prop_set_uint16(dev, "data_buffer_dep", width);
 qdev_init_nofail(dev);
 busdev = SYS_BUS_DEVICE(dev);
 sysbus_mmio_map(busdev, 0, base);
-sysbus_connect_irq(busdev, 0, irq);
+sysbus_connect_irq(busdev, 0, irq); /* abort irq line */
+for (i = 0; i < nevents; i++) {
+sysbus_connect_irq(busdev, i + 1, irq); /* event irq lines */
+}
 }
 
 static void exynos4210_realize(DeviceState *socdev, Error **errp)
@@ -432,11 +446,11 @@ static void exynos4210_realize(DeviceState *socdev, Error 
**errp)
 
 /*** DMA controllers ***/
 pl330_create(EXYNOS4210_PL330_BASE0_ADDR,
- qemu_irq_invert(s->irq_table[exynos4210_get_irq(35, 1)]), 32);
+ s->irq_table[exynos4210_get_irq(21, 0)], 32, 32, 32);
 pl330_create(EXYNOS4210_PL330_BASE1_ADDR,
- qemu_irq_invert(s->irq_table[exynos4210_get_irq(36, 1)]), 32);
+ s->irq_table[exynos4210_get_irq(21, 1)], 32, 32, 32);
 pl330_create(EXYNOS4210_PL330_BASE2_ADDR,
- qemu_irq_invert(s->irq_table[exynos4210_get_irq(34, 1)]), 1);
+ s->irq_table[exynos4210_get_irq(20, 1)], 1, 31, 64);
 }
 
 static void exynos4210_class_init(ObjectClass *klass, void *data)
-- 
2.17.1




[PATCH 4/6] hw/char/exynos4210_uart: Implement receive FIFO

2020-01-10 Thread Guenter Roeck
Signed-off-by: Guenter Roeck 
---
 hw/char/exynos4210_uart.c | 120 ++
 hw/char/trace-events  |   3 +-
 2 files changed, 97 insertions(+), 26 deletions(-)

diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
index fb7a3ebd09..61134a7bdc 100644
--- a/hw/char/exynos4210_uart.c
+++ b/hw/char/exynos4210_uart.c
@@ -24,6 +24,7 @@
 #include "migration/vmstate.h"
 #include "qemu/error-report.h"
 #include "qemu/module.h"
+#include "qemu/timer.h"
 #include "chardev/char-fe.h"
 #include "chardev/char-serial.h"
 
@@ -118,6 +119,7 @@ static const Exynos4210UartReg exynos4210_uart_regs[] = {
 #define ULCON_STOP_BIT_SHIFT  1
 
 /* UART Tx/Rx Status */
+#define UTRSTAT_Rx_TIMEOUT  0x8
 #define UTRSTAT_TRANSMITTER_EMPTY   0x4
 #define UTRSTAT_Tx_BUFFER_EMPTY 0x2
 #define UTRSTAT_Rx_BUFFER_DATA_READY0x1
@@ -147,6 +149,9 @@ typedef struct Exynos4210UartState {
 Exynos4210UartFIFO   rx;
 Exynos4210UartFIFO   tx;
 
+QEMUTimer *fifo_timeout_timer;
+uint64_t wordtime;/* word time in ns */
+
 CharBackend   chr;
 qemu_irq  irq;
 
@@ -209,15 +214,12 @@ static void fifo_reset(Exynos4210UartFIFO *q)
 q->rp = 0;
 }
 
-static uint32_t exynos4210_uart_Tx_FIFO_trigger_level(const 
Exynos4210UartState *s)
+static uint32_t exynos4210_uart_FIFO_trigger_level(uint32_t channel,
+   uint32_t reg)
 {
-uint32_t level = 0;
-uint32_t reg;
+uint32_t level;
 
-reg = (s->reg[I_(UFCON)] & UFCON_Tx_FIFO_TRIGGER_LEVEL) >>
-UFCON_Tx_FIFO_TRIGGER_LEVEL_SHIFT;
-
-switch (s->channel) {
+switch (channel) {
 case 0:
 level = reg * 32;
 break;
@@ -231,12 +233,34 @@ static uint32_t 
exynos4210_uart_Tx_FIFO_trigger_level(const Exynos4210UartState
 break;
 default:
 level = 0;
-trace_exynos_uart_channel_error(s->channel);
+trace_exynos_uart_channel_error(channel);
+break;
 }
-
 return level;
 }
 
+static uint32_t
+exynos4210_uart_Tx_FIFO_trigger_level(const Exynos4210UartState *s)
+{
+uint32_t reg;
+
+reg = (s->reg[I_(UFCON)] & UFCON_Tx_FIFO_TRIGGER_LEVEL) >>
+UFCON_Tx_FIFO_TRIGGER_LEVEL_SHIFT;
+
+return exynos4210_uart_FIFO_trigger_level(s->channel, reg);
+}
+
+static uint32_t
+exynos4210_uart_Rx_FIFO_trigger_level(const Exynos4210UartState *s)
+{
+uint32_t reg;
+
+reg = ((s->reg[I_(UFCON)] & UFCON_Rx_FIFO_TRIGGER_LEVEL) >>
+UFCON_Rx_FIFO_TRIGGER_LEVEL_SHIFT) + 1;
+
+return exynos4210_uart_FIFO_trigger_level(s->channel, reg);
+}
+
 static void exynos4210_uart_update_irq(Exynos4210UartState *s)
 {
 /*
@@ -244,13 +268,25 @@ static void 
exynos4210_uart_update_irq(Exynos4210UartState *s)
  * transmit FIFO is smaller than the trigger level.
  */
 if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) {
-
 uint32_t count = (s->reg[I_(UFSTAT)] & UFSTAT_Tx_FIFO_COUNT) >>
 UFSTAT_Tx_FIFO_COUNT_SHIFT;
 
 if (count <= exynos4210_uart_Tx_FIFO_trigger_level(s)) {
 s->reg[I_(UINTSP)] |= UINTSP_TXD;
 }
+
+/*
+ * Rx interrupt if trigger level is reached or if rx timeout
+ * interrupt is disabled and there is data in the receive buffer
+ */
+count = fifo_elements_number(>rx);
+if ((count && !(s->reg[I_(UCON)] & 0x80)) ||
+count >= exynos4210_uart_Rx_FIFO_trigger_level(s)) {
+s->reg[I_(UINTSP)] |= UINTSP_RXD;
+timer_del(s->fifo_timeout_timer);
+}
+} else if (s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY) {
+s->reg[I_(UINTSP)] |= UINTSP_RXD;
 }
 
 s->reg[I_(UINTP)] = s->reg[I_(UINTSP)] & ~s->reg[I_(UINTM)];
@@ -264,6 +300,21 @@ static void exynos4210_uart_update_irq(Exynos4210UartState 
*s)
 }
 }
 
+static void exynos4210_uart_timeout_int(void *opaque)
+{
+Exynos4210UartState *s = opaque;
+
+trace_exynos_uart_rx_timeout(s->channel, s->reg[I_(UTRSTAT)],
+ s->reg[I_(UINTSP)]);
+
+if ((s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY) ||
+(s->reg[I_(UCON)] & (1 << 11))) {
+s->reg[I_(UINTSP)] |= UINTSP_RXD;
+s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_TIMEOUT;
+exynos4210_uart_update_irq(s);
+}
+}
+
 static void exynos4210_uart_update_parameters(Exynos4210UartState *s)
 {
 int speed, parity, data_bits, stop_bits;
@@ -302,10 +353,24 @@ static void 
exynos4210_uart_update_parameters(Exynos4210UartState *s)
 ssp.data_bits = data_bits;
 ssp.stop_bits = stop_bits;
 
+s->wordtime = NANOSECONDS_PER_SECOND * (data_bits + stop_bits + 1) / speed;
+
 qemu_chr_fe_ioctl(>chr, CHR_IOCTL_SERIAL_SET_PARAMS, );
 
 trace_exynos_uart_update_params(
-s->channel, speed, parity, data_bits, stop_bits);
+s->channel, speed, parity, data_bits, stop_bits, s->wordtime);
+}
+
+static 

[PATCH 0/6] Fix Exynos4210 DMA support

2020-01-10 Thread Guenter Roeck
Commit 59520dc65e ("hw/arm/exynos4210: Add DMA support for the Exynos4210")
introduced DMA support for Exynos4210. Unfortunately, it never really
worked. DMA interrupt line and polarity was wrong, and the serial port
needs extra code to support DMA. This patch series fixes the problem.



Re: [PATCH v1 00/59] trivial unneeded labels cleanup

2020-01-10 Thread Daniel Henrique Barboza




On 1/10/20 4:05 PM, Eric Blake wrote:

On 1/6/20 12:23 PM, Daniel Henrique Barboza wrote:

Hello,

This is the type of cleanup I've contributed to Libvirt
during the last year. Figured QEMU also deserves the same
care.

The idea here is remove unneeded labels. By 'unneeded' I
mean labels that does nothing but a 'return' call. One
common case is something like this:

if ()
 goto cleanup;
[...]
  cleanup:
 return 0;

This code can be simplified to:

if ()
 return 0;




How much of this work is done manually, and how much via Coccinelle?



I'm still getting along with Coccinelle. I'm able to do simple matches but
couldn't make it work to match this scenario. I didn't invest too much
time on it though.






  qga/commands-win32.c  | 17 ---
  target/mips/mips-semi.c   | 15 +++---
  target/unicore32/softmmu.c    | 23 +++---
  util/aio-posix.c  |  3 +-
  util/module.c | 11 ++---


Hmm, no change to scripts/coccinelle, so presumably all manual :(


I used pcregrep:

$ pcregrep --exclude-dir=build --exclude-dir=docs --exclude-dir=scripts -r -n -M 
':\n*\s*return' . > clean_labels

(note: there was a lot more of --exclude-dir in the original command, 
unfortunately I
didn't record it)

Then I filtered in the output file the cases where the regexp matched "switch"
labels and any other false positives like strings in comments. It's not manual
inspection, but it was crude indeed.





If we have a Coccinelle script that performs this transformation, we are more 
likely to be able to catch all places in the tree that would benefit (rather 
than relying on grep calls or other manual inspection), and more importantly, 
we can repeat the effort periodically to fix future additions that don't comply 
with the preferred style as well as backport the patch by rerunning the 
Coccinelle script with less worry of changed context.  Automated cleanups are 
always going to be easier to swallow (even if the diffstat is larger) than 
manual ad hoc cleanups.


I am not aware of how QEMU handles Coccinelle, if it is imposed via
./scripts/checkpatch.pl or something that it is ran from time to time to
suggest changes. But if it's desirable, I can see if I can cook a Coccinelle
script (or anything a bit more sophisticated than what I did)  to flag these
cases I attempted to handle with this series.


Thanks,


DHB








Re: [Xen-devel] [PATCH v6 00/11] error: auto propagated local_err part I

2020-01-10 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20200110194158.14190-1-vsement...@virtuozzo.com/



Hi,

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

Subject: [Xen-devel] [PATCH v6 00/11] error: auto propagated local_err part I
Type: series
Message-id: 20200110194158.14190-1-vsement...@virtuozzo.com

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

Switched to a new branch 'test'
fee0dd2 xen: introduce ERRP_AUTO_PROPAGATE
9074b45 nbd: introduce ERRP_AUTO_PROPAGATE
05632cb TPM: introduce ERRP_AUTO_PROPAGATE
2a019cd virtio-9p: introduce ERRP_AUTO_PROPAGATE
b4e0525 fw_cfg: introduce ERRP_AUTO_PROPAGATE
3a69800 pflash: introduce ERRP_AUTO_PROPAGATE
f4ac870 SD (Secure Card): introduce ERRP_AUTO_PROPAGATE
29fbc1d hw/sd/ssi-sd: fix error handling in ssi_sd_realize
6ebc57a scripts: add coccinelle script to use auto propagated errp
477b9ec error: auto propagated local_err
0c38914 qapi/error: add (Error **errp) cleaning APIs

=== OUTPUT BEGIN ===
1/11 Checking commit 0c389147591a (qapi/error: add (Error **errp) cleaning APIs)
2/11 Checking commit 477b9ec03898 (error: auto propagated local_err)
ERROR: Macros with multiple statements should be enclosed in a do - while loop
#138: FILE: include/qapi/error.h:428:
+#define ERRP_AUTO_PROPAGATE()  \
+g_auto(ErrorPropagator) _auto_errp_prop = {.errp = errp};  \
+errp = ((errp == NULL || *errp == error_fatal) \
+? &_auto_errp_prop.local_err : errp)

total: 1 errors, 0 warnings, 102 lines checked

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

3/11 Checking commit 6ebc57a94cf0 (scripts: add coccinelle script to use auto 
propagated errp)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#25: 
new file mode 100644

total: 0 errors, 1 warnings, 148 lines checked

Patch 3/11 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
4/11 Checking commit 29fbc1d61eb1 (hw/sd/ssi-sd: fix error handling in 
ssi_sd_realize)
5/11 Checking commit f4ac87065f2c (SD (Secure Card): introduce 
ERRP_AUTO_PROPAGATE)
6/11 Checking commit 3a69800331a4 (pflash: introduce ERRP_AUTO_PROPAGATE)
7/11 Checking commit b4e0525d3dcf (fw_cfg: introduce ERRP_AUTO_PROPAGATE)
8/11 Checking commit 2a019cd1f992 (virtio-9p: introduce ERRP_AUTO_PROPAGATE)
9/11 Checking commit 05632cbe2d39 (TPM: introduce ERRP_AUTO_PROPAGATE)
10/11 Checking commit 9074b450cb34 (nbd: introduce ERRP_AUTO_PROPAGATE)
11/11 Checking commit fee0dd26ea0b (xen: introduce ERRP_AUTO_PROPAGATE)
=== OUTPUT END ===

Test command exited with code: 1


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

Re: [PATCH 10/21] hw/core: Fix latent fit_load_fdt() error handling bug

2020-01-10 Thread Vladimir Sementsov-Ogievskiy
06.12.2019 13:53, Vladimir Sementsov-Ogievskiy wrote:
> 06.12.2019 10:46, Markus Armbruster wrote:
>> Vladimir Sementsov-Ogievskiy  writes:
>>
>>> 30.11.2019 22:42, Markus Armbruster wrote:
 fit_load_fdt() recovers from fit_image_addr() failing with ENOENT.
 Except it doesn't when its @errp argument is _fatal or
 _abort, because it blindly passes @errp to fit_image_addr().
 Messed up in commit 3eb99edb48 "loader-fit: Wean off error_printf()".

 The bug can't bite as no caller actually passes _fatal or
 _abort.  Fix it anyway.

 Signed-off-by: Markus Armbruster 
>>>
>>> Reviewed-by: Vladimir Sementsov-Ogievskiy 
>>>
>>> Hmm, actually it makes my
>>> "[PATCH v7 01/21] hw/core/loader-fit: fix freeing errp in fit_load_fdt"
>>> unnecessary. If you want you may drop my 01 (as it covers less problems),
>>
>> Yes.
>>
>>> and in this case you may note in your cover letter, that
>>> errp = NULL is broken here too (may be nobady pass it?),
>>
>> You're right, null @errp is wrong, too.
>>
>>> and normal errp is handled wrong, as *errp doesn't set to NULL after
>>> error_free(*errp)
>>
>> Yes, that's wrong, too.  fit_load_fdt() itself doesn't use *errp after
>> freeing it, but it sets a trap for its callers.
>>
>>>    (still, the only caller rely on return value more than on
>>> err, so the problem can't be triggered with current code)
>>
>> True.
>>
>> New commit message (based on v2's):
>>
>>  hw/core: Fix fit_load_fdt() error API violations
>>
>>  fit_load_fdt() passes @errp to fit_image_addr(), then recovers from
>>  ENOENT failures.  Passing @errp is wrong, because it works only as
>>  long as @errp is neither @error_fatal nor @error_abort.  Error
>>  recovery dereferences @errp.  That's also wrong; see the big comment
>>  in error.h.  Error recovery can leave *errp pointing to a freed
>>  Error object.  Wrong, it must be null on success.  Messed up in
>>  commit 3eb99edb48 "loader-fit: Wean off error_printf()".
>>
>>  No caller actually passes such values, or uses *errp on success.
>>
>>  Fix anyway: splice in a local Error *err, and error_propagate().
>>
>>  Signed-off-by: Markus Armbruster 
>>
>> Okay?
> 
> Yes) also add
> Reviewed-by: Vladimir Sementsov-Ogievskiy 
> 
> 
>>
>>>
 ---
    hw/core/loader-fit.c | 15 ---
    1 file changed, 8 insertions(+), 7 deletions(-)

 diff --git a/hw/core/loader-fit.c b/hw/core/loader-fit.c
 index 953b16bc82..c465921b8f 100644
 --- a/hw/core/loader-fit.c
 +++ b/hw/core/loader-fit.c
 @@ -178,11 +178,12 @@ static int fit_load_fdt(const struct fit_loader 
 *ldr, const void *itb,
    int cfg, void *opaque, const void *match_data,
    hwaddr kernel_end, Error **errp)
    {
 +    Error *err = NULL;
    const char *name;
    const void *data;
    const void *load_data;
    hwaddr load_addr;
 -    int img_off, err;
 +    int img_off;
    size_t sz;
    int ret;
 @@ -197,13 +198,13 @@ static int fit_load_fdt(const struct fit_loader 
 *ldr, const void *itb,
    return -EINVAL;
    }
 -    err = fit_image_addr(itb, img_off, "load", _addr, errp);
 -    if (err == -ENOENT) {
 +    ret = fit_image_addr(itb, img_off, "load", _addr, );
 +    if (ret == -ENOENT) {
    load_addr = ROUND_UP(kernel_end, 64 * KiB) + (10 * MiB);
 -    error_free(*errp);
 -    } else if (err) {
 -    error_prepend(errp, "unable to read FDT load address from FIT: ");
 -    ret = err;
 +    error_free(err);
 +    } else if (ret) {
 +    error_propagate_prepend(errp, err,
 +    "unable to read FDT load address from 
 FIT: ");
    goto out;
    }

>>>
>>> So much attention to that function :)
>>>
>>> I'd also propose the following:
>>>
>>> diff --git a/hw/core/loader-fit.c b/hw/core/loader-fit.c
>>> index c465921b8f..2c9efeef7a 100644
>>> --- a/hw/core/loader-fit.c
>>> +++ b/hw/core/loader-fit.c
>>> @@ -180,8 +180,8 @@ static int fit_load_fdt(const struct fit_loader *ldr, 
>>> const void *itb,
>>>    {
>>>    Error *err = NULL;
>>>    const char *name;
>>> -    const void *data;
>>> -    const void *load_data;
>>> +    void *data;
>>> +    void *load_data;
>>>    hwaddr load_addr;
>>>    int img_off;
>>>    size_t sz;
>>> @@ -218,9 +218,9 @@ static int fit_load_fdt(const struct fit_loader *ldr, 
>>> const void *itb,
>>>
>>>    ret = 0;
>>>    out:
>>> -    g_free((void *) data);
>>> +    g_free(data);
>>>    if (data != load_data) {
>>> -    g_free((void *) load_data);
>>> +    g_free(load_data);
>>>    }
>>>    return ret;
>>>    }
>>>
>>>
>>> Or, even better:
>>>
>>> --- a/hw/core/loader-fit.c
>>> +++ b/hw/core/loader-fit.c
>>> @@ -180,7 +180,8 @@ 

Re: [PATCH v2 1/3] tests/acceptance: avocado_qemu: Introduce the 'accel' test parameter

2020-01-10 Thread Wainer dos Santos Moschetta

Hi Thomas,

On 12/18/19 4:48 PM, Thomas Huth wrote:

On 18/12/2019 18.00, Wainer dos Santos Moschetta wrote:

The test case may need to boot the VM with an accelerator that
isn't actually enabled on the QEMU binary and/or present in the host. In
this case the test behavior is undefined, and the best course of
action is to skip its execution.

This change introduced the 'accel' parameter (and the handler of
tag with same name) used to indicate the test case requires a
given accelerator available. It was implemented a mechanism to
skip the test case if the accelerator is not available. Moreover,
  the QEMU --accel argument is set automatically to any VM
launched if the parameter is present.

Signed-off-by: Wainer dos Santos Moschetta 
---
  docs/devel/testing.rst| 16 
  tests/acceptance/avocado_qemu/__init__.py | 23 +++
  2 files changed, 39 insertions(+)

diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst
index 27f286858a..6c2e0718e1 100644
--- a/docs/devel/testing.rst
+++ b/docs/devel/testing.rst
@@ -757,6 +757,17 @@ name.  If one is not given explicitly, it will either be 
set to
  ``None``, or, if the test is tagged with one (and only one)
  ``:avocado: tags=machine:VALUE`` tag, it will be set to ``VALUE``.
  
+accel

+~
+The accelerator that will be set to all QEMUMachine instances created
+by the test.
+
+The ``accel`` attribute will be set to the test parameter of the same
+name.  If one is not given explicitly, it will either be set to
+``None``, or, if the test is tagged with one (and only one)
+``:avocado: tags=accel:VALUE`` tag, it will be set to ``VALUE``. Currently
+``VALUE`` should be either ``kvm`` or ``tcg``.
+
  qemu_bin
  
  
@@ -798,6 +809,11 @@ machine

  The machine type that will be set to all QEMUMachine instances created
  by the test.
  
+accel

+~
+The accelerator that will be set to all QEMUMachine instances created
+by the test. In case the accelerator is not available (both QEMU
+binary and the host system are checked) then the test is canceled.
  
  qemu_bin

  
diff --git a/tests/acceptance/avocado_qemu/__init__.py 
b/tests/acceptance/avocado_qemu/__init__.py
index 6618ea67c1..aff32668d9 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -20,6 +20,7 @@ SRC_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..', 
'..', '..')
  sys.path.append(os.path.join(SRC_ROOT_DIR, 'python'))
  
  from qemu.machine import QEMUMachine

+from qemu.accel import kvm_available, tcg_available
  
  def is_readable_executable_file(path):

  return os.path.isfile(path) and os.access(path, os.R_OK | os.X_OK)
@@ -111,6 +112,8 @@ class Test(avocado.Test):
  
  def setUp(self):

  self._vms = {}
+# VM argumments that are mapped from parameters
+self._param_to_vm_args = []
  
  self.arch = self.params.get('arch',

  default=self._get_unique_tag_val('arch'))
@@ -124,10 +127,30 @@ class Test(avocado.Test):
  if self.qemu_bin is None:
  self.cancel("No QEMU binary defined or found in the source tree")
  
+self.accel = self.params.get('accel',

+ default=self._get_unique_tag_val('accel'))
+if self.accel:
+avail = False
+if self.accel == 'kvm':
+if kvm_available(self.arch, self.qemu_bin):
+self._param_to_vm_args.append('-enable-kvm')

Could you please use "-accel kvm" instead? "-accel" is now our official
way to configure an accelerator ... so we should not use the old
wrappers in new code anymore if possible.

Sure, I am going to adjust that on v3.


  Thanks,
   Thomas


PS: Travis supports KVM now, too (with some tweaking of the permissions)
... maybe we should now try to get some QEMU tests running with KVM
there, too...


I heard that but I failed miserably to enable nested virt on Travis. 
Actually I was expecting it enabled by default but not the case. I did 
not find documentation so I tried some tweaks like setting 
'sudo:required' and using bionic but none of that worked out.


Do you know what needs to be done?

Thanks!

- Wainer




Re: [Qemu-devel] What should a virtual board emulate?

2020-01-10 Thread Aleksandar Markovic
8:42 PM Pet, 10.01.2020. Aleksandar Markovic 
је написао/ла:
>
> 7:45 AM Pon, 06.01.2020. Gerd Hoffmann  је написао/ла:
> >
> >   Hi,
> >
> > > 78c37d88f1b8b0b3ebcc632c458f0c3779fe2951 is the first bad commit
> > > commit 78c37d88f1b8b0b3ebcc632c458f0c3779fe2951
> > > Author: Paolo Bonzini 
> > > Date:   Tue Mar 19 15:37:19 2019 +0100
> > >
> > > mips-fulong2e: obey -vga none
> > >
> > > Do not create an ATI VGA if "-vga none" was passed on the command
line.
> >
> > > 1/ the Radeon chip is soldered on the motherboard,
> > >
> > > 2/ the default BIOS expects the Radeon chip to be
> > >unconditionally present,
> > >
> > > I insist this patch is incorrect for the particular case of the
Fuloong2e
> > > board. I plan to revert it when I post the test.
> >
> > Yep.  IMHO devices which you can't unplug on the physical board should
> > be present even with "qemu -nodefaults".
> >
>
> I have to agree with Philippe's approach. That is not to say that
Zoltan's efforts are not appreciated.

I meant to say also Paolo's. But, I didn't mean to fingerpoint. It is quite
normal that from time to time, a well-intended change may actually produce
unexpected breaking. All is well, no bad feelings at all.

Yours,
Aleksandar

Just that the patch in question that broke Foolong scenario didn't fit
quite well, however some other its reincarnation may have better destiny.
>
> Sincerely,
> Aleksandar
>
> > cheers,
> >   Gerd
> >
> >


[PATCH v6 03/11] scripts: add coccinelle script to use auto propagated errp

2020-01-10 Thread Vladimir Sementsov-Ogievskiy
Signed-off-by: Vladimir Sementsov-Ogievskiy 
---

CC: Cornelia Huck 
CC: Eric Blake 
CC: Kevin Wolf 
CC: Max Reitz 
CC: Greg Kurz 
CC: Stefan Hajnoczi 
CC: Stefano Stabellini 
CC: Anthony Perard 
CC: Paul Durrant 
CC: "Philippe Mathieu-Daudé" 
CC: Laszlo Ersek 
CC: Gerd Hoffmann 
CC: Stefan Berger 
CC: Markus Armbruster 
CC: Michael Roth 
CC: qemu-bl...@nongnu.org
CC: xen-de...@lists.xenproject.org

 include/qapi/error.h  |   3 +
 scripts/coccinelle/auto-propagated-errp.cocci | 139 ++
 2 files changed, 142 insertions(+)
 create mode 100644 scripts/coccinelle/auto-propagated-errp.cocci

diff --git a/include/qapi/error.h b/include/qapi/error.h
index 532b9afb9e..dcfb77e107 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h
@@ -141,6 +141,9 @@
  * ...
  * }
  *
+ * For mass conversion use script
+ *   scripts/coccinelle/auto-propagated-errp.cocci
+ *
  *
  * Receive and accumulate multiple errors (first one wins):
  * Error *err = NULL, *local_err = NULL;
diff --git a/scripts/coccinelle/auto-propagated-errp.cocci 
b/scripts/coccinelle/auto-propagated-errp.cocci
new file mode 100644
index 00..6c72a5049f
--- /dev/null
+++ b/scripts/coccinelle/auto-propagated-errp.cocci
@@ -0,0 +1,139 @@
+// Use ERRP_AUTO_PROPAGATE (see include/qapi/error.h)
+//
+// Copyright (c) 2020 Virtuozzo International GmbH.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see .
+//
+// Usage example:
+// spatch --sp-file scripts/coccinelle/auto-propagated-errp.cocci \
+//  --macro-file scripts/cocci-macro-file.h --in-place --no-show-diff \
+//  blockdev-nbd.c qemu-nbd.c {block/nbd*,nbd/*,include/block/nbd*}.[hc]
+
+@@
+// Add invocation to errp-functions where necessary
+// We should skip functions with "Error *const *errp"
+// parameter, but how to do it with coccinelle?
+// I don't know, so, I skip them by function name regex.
+// It's safe: if we not skip some functions with
+// "Error *const *errp", ERRP_AUTO_PROPAGATE invocation
+// will fail to compile, because of const violation.
+identifier fn !~ "error_append_.*_hint";
+identifier local_err, errp;
+@@
+
+ fn(..., Error **errp, ...)
+ {
++   ERRP_AUTO_PROPAGATE();
+<+...
+when != ERRP_AUTO_PROPAGATE();
+(
+error_append_hint(errp, ...);
+|
+error_prepend(errp, ...);
+|
+Error *local_err = NULL;
+)
+...+>
+ }
+
+@rule1@
+// We do not inherit from previous rule, as we want to match
+// also functions, which already had ERRP_AUTO_PROPAGATE
+// invocation.
+identifier fn !~ "error_append_.*_hint";
+identifier local_err, errp;
+@@
+
+ fn(..., Error **errp, ...)
+ {
+ <...
+-Error *local_err = NULL;
+ ...>
+ }
+
+@@
+// Handle pattern with goto, otherwise we'll finish up
+// with labels at function end which will not compile.
+identifier rule1.fn, rule1.local_err, rule1.errp;
+identifier OUT;
+@@
+
+ fn(...)
+ {
+ <...
+-goto OUT;
++return;
+ ...>
+- OUT:
+-error_propagate(errp, local_err);
+ }
+
+@@
+identifier rule1.fn, rule1.local_err, rule1.errp;
+expression list args; // to reindent error_propagate_prepend
+@@
+
+ fn(...)
+ {
+ <...
+(
+-error_free(local_err);
+-local_err = NULL;
++error_free_errp(errp);
+|
+-error_free(local_err);
++error_free_errp(errp);
+|
+-error_report_err(local_err);
++error_report_errp(errp);
+|
+-warn_report_err(local_err);
++warn_report_errp(errp);
+|
+-error_propagate_prepend(errp, local_err, args);
++error_prepend(errp, args);
+|
+-error_propagate(errp, local_err);
+)
+ ...>
+ }
+
+@@
+identifier rule1.fn, rule1.local_err, rule1.errp;
+@@
+
+ fn(...)
+ {
+ <...
+(
+-_err
++errp
+|
+-local_err
++*errp
+)
+ ...>
+ }
+
+@@
+identifier rule1.fn, rule1.errp;
+@@
+
+ fn(...)
+ {
+ <...
+- *errp != NULL
++ *errp
+ ...>
+ }
-- 
2.21.0




[PATCH v6 00/11] error: auto propagated local_err part I

2020-01-10 Thread Vladimir Sementsov-Ogievskiy
Hi all!

Now, when preparations from
 [RFC v5 000/126] error: auto propagated local_err
 https://lists.gnu.org/archive/html/qemu-devel/2019-10/msg02771.html
 https://src.openvz.org/scm/~vsementsov/qemu.git #tag up-auto-local-err-v5 
, after some iterations, are finally merged, let's proceed with the
rest. Sorry for a big delay on my part.

As a first step, I decided to take subsystems, each of them covered by
one patch, which get r-b/a-b marks by maintainer of the subsystem in v5.

v6 is available at
 https://src.openvz.org/scm/~vsementsov/qemu.git #tag 
up-auto-local-err-partI-v6 

Changes v5->v6:
01: use errp name for the parameter, add assertion
02: add a lot of text information, drop Eric's r-b.
no semantic changes.
03: add more comments
skip functions with pattern error_append_.*_hint in name
make errp identifier, to match any name of Error ** paramter
some other improvements
04: only commit message changed,
keep Philippe's r-b
05: new, manual update for hw/sd/ssi-sd
06: only commit message changed,
keep Philippe's r-b
07: only commit message changed,
keep Philippe's r-b
08: local_parse_opts() changed, so patch changed in this
function, drop a-b mark
also, indentation fixed, by improvement in coccinelle script
09: only commit message changed,
keep Stefan's r-b
10: commit message and a bit of context changed, still seems
valid to keep Eric's r-b
11: add new hunk: hw/pci-host/xen_igd_pt.c, so, drop r-b
also, indentation fixed, by improvement in coccinelle script

In these series, there is no commit-per-subsystem script, each generated
commit is generated in separate.

Still, generating commands are very similar, and looks like

sed -n '/^$/,/^$/{s/^F: //p}' MAINTAINERS | \
xargs git ls-files | grep '\.[hc]$' | \
xargs spatch \
--sp-file scripts/coccinelle/auto-propagated-errp.cocci \
--macro-file scripts/cocci-macro-file.h \
--in-place --no-show-diff --max-width 80

Note, that in each generated commit, generation command is the only
text, indented by 8 spaces in 'git log -1' output, so, to regenerate all
commits (for example, after rebase, or change in coccinelle script), you
may use the following command:

git rebase -x "sh -c \"git show --pretty= --name-only | xargs git checkout 
HEAD^ -- ; git reset; git log -1 | grep '^' | sh\"" HEAD~7

Which will start automated interactive rebase for generated patches,
which will stop if generated patch changed
(you may do git commit --amend to apply updated generated changes).

Note:
  git show --pretty= --name-only   - lists files, changed in HEAD
  git log -1 | grep '^' | sh   - rerun generation command of HEAD


Check for compilation of changed .c files
git rebase -x "sh -c \"git show --pretty= --name-only | sed -n 's/\.c$/.o/p' | 
xargs make -j9\"" HEAD~7
  

Vladimir Sementsov-Ogievskiy (11):
  qapi/error: add (Error **errp) cleaning APIs
  error: auto propagated local_err
  scripts: add coccinelle script to use auto propagated errp
  hw/sd/ssi-sd: fix error handling in ssi_sd_realize
  SD (Secure Card): introduce ERRP_AUTO_PROPAGATE
  pflash: introduce ERRP_AUTO_PROPAGATE
  fw_cfg: introduce ERRP_AUTO_PROPAGATE
  virtio-9p: introduce ERRP_AUTO_PROPAGATE
  TPM: introduce ERRP_AUTO_PROPAGATE
  nbd: introduce ERRP_AUTO_PROPAGATE
  xen: introduce ERRP_AUTO_PROPAGATE

 include/block/nbd.h   |   1 +
 include/qapi/error.h  | 113 +-
 block/nbd.c   |  49 +++---
 hw/9pfs/9p-local.c|  12 +-
 hw/9pfs/9p.c  |   1 +
 hw/block/dataplane/xen-block.c|  17 +--
 hw/block/pflash_cfi01.c   |   7 +-
 hw/block/pflash_cfi02.c   |   7 +-
 hw/block/xen-block.c  | 125 +++-
 hw/nvram/fw_cfg.c |  14 +-
 hw/pci-host/xen_igd_pt.c  |   7 +-
 hw/sd/sdhci-pci.c |   7 +-
 hw/sd/sdhci.c |  21 ++-
 hw/sd/ssi-sd.c|  26 +++-
 hw/tpm/tpm_util.c |   7 +-
 hw/xen/xen-backend.c  |   7 +-
 hw/xen/xen-bus.c  | 100 ++---
 hw/xen/xen-host-pci-device.c  |  27 ++--
 hw/xen/xen_pt.c   |  25 ++--
 hw/xen/xen_pt_config_init.c   |  20 +--
 nbd/client.c  |   5 +
 nbd/server.c  |   5 +
 tpm.c |   7 +-
 scripts/coccinelle/auto-propagated-errp.cocci | 139 ++
 24 files changed, 482 insertions(+), 267 deletions(-)
 create mode 100644 scripts/coccinelle/auto-propagated-errp.cocci

CC: Cornelia Huck 
CC: Eric Blake 
CC: Kevin Wolf 
CC: Max Reitz 
CC: Greg Kurz 
CC: Stefan 

Re: [Qemu-devel] What should a virtual board emulate?

2020-01-10 Thread Aleksandar Markovic
7:45 AM Pon, 06.01.2020. Gerd Hoffmann  је написао/ла:
>
>   Hi,
>
> > 78c37d88f1b8b0b3ebcc632c458f0c3779fe2951 is the first bad commit
> > commit 78c37d88f1b8b0b3ebcc632c458f0c3779fe2951
> > Author: Paolo Bonzini 
> > Date:   Tue Mar 19 15:37:19 2019 +0100
> >
> > mips-fulong2e: obey -vga none
> >
> > Do not create an ATI VGA if "-vga none" was passed on the command
line.
>
> > 1/ the Radeon chip is soldered on the motherboard,
> >
> > 2/ the default BIOS expects the Radeon chip to be
> >unconditionally present,
> >
> > I insist this patch is incorrect for the particular case of the
Fuloong2e
> > board. I plan to revert it when I post the test.
>
> Yep.  IMHO devices which you can't unplug on the physical board should
> be present even with "qemu -nodefaults".
>

I have to agree with Philippe's approach. That is not to say that Zoltan's
efforts are not appreciated. Just that the patch in question that broke
Foolong scenario didn't fit quite well, however some other its
reincarnation may have better destiny.

Sincerely,
Aleksandar

> cheers,
>   Gerd
>
>


[PATCH v6 09/11] TPM: introduce ERRP_AUTO_PROPAGATE

2020-01-10 Thread Vladimir Sementsov-Ogievskiy
If we want to add some info to errp (by error_prepend() or
error_append_hint()), we must use the ERRP_AUTO_PROPAGATE macro.
Otherwise, this info will not be added when errp == _fatal
(the program will exit prior to the error_append_hint() or
error_prepend() call).  Fix such cases.

If we want to check error after errp-function call, we need to
introduce local_err and then propagate it to errp. Instead, use
ERRP_AUTO_PROPAGATE macro, benefits are:
1. No need of explicit error_propagate call
2. No need of explicit local_err variable: use errp directly
3. ERRP_AUTO_PROPAGATE leaves errp as is if it's not NULL or
   _fatal, this means that we don't break error_abort
   (we'll abort on error_set, not on error_propagate)

This commit is generated by command

sed -n '/^TPM$/,/^$/{s/^F: //p}' MAINTAINERS | \
xargs git ls-files | grep '\.[hc]$' | \
xargs spatch \
--sp-file scripts/coccinelle/auto-propagated-errp.cocci \
--macro-file scripts/cocci-macro-file.h \
--in-place --no-show-diff --max-width 80

Reported-by: Kevin Wolf 
Reported-by: Greg Kurz 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Stefan Berger 
---
 hw/tpm/tpm_util.c | 7 +++
 tpm.c | 7 +++
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/hw/tpm/tpm_util.c b/hw/tpm/tpm_util.c
index 62b091f0c0..b0657bbbf2 100644
--- a/hw/tpm/tpm_util.c
+++ b/hw/tpm/tpm_util.c
@@ -47,8 +47,8 @@ static void get_tpm(Object *obj, Visitor *v, const char 
*name, void *opaque,
 static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
 Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 DeviceState *dev = DEVICE(obj);
-Error *local_err = NULL;
 Property *prop = opaque;
 TPMBackend *s, **be = qdev_get_prop_ptr(dev, prop);
 char *str;
@@ -58,9 +58,8 @@ static void set_tpm(Object *obj, Visitor *v, const char 
*name, void *opaque,
 return;
 }
 
-visit_type_str(v, name, , _err);
-if (local_err) {
-error_propagate(errp, local_err);
+visit_type_str(v, name, , errp);
+if (*errp) {
 return;
 }
 
diff --git a/tpm.c b/tpm.c
index 9c9e20bbb7..359ebb7f68 100644
--- a/tpm.c
+++ b/tpm.c
@@ -81,11 +81,11 @@ TPMBackend *qemu_find_tpm_be(const char *id)
 
 static int tpm_init_tpmdev(void *dummy, QemuOpts *opts, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 const char *value;
 const char *id;
 const TPMBackendClass *be;
 TPMBackend *drv;
-Error *local_err = NULL;
 int i;
 
 if (!QLIST_EMPTY(_backends)) {
@@ -116,9 +116,8 @@ static int tpm_init_tpmdev(void *dummy, QemuOpts *opts, 
Error **errp)
 }
 
 /* validate backend specific opts */
-qemu_opts_validate(opts, be->opts, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+qemu_opts_validate(opts, be->opts, errp);
+if (*errp) {
 return 1;
 }
 
-- 
2.21.0




[PATCH v6 11/11] xen: introduce ERRP_AUTO_PROPAGATE

2020-01-10 Thread Vladimir Sementsov-Ogievskiy
If we want to add some info to errp (by error_prepend() or
error_append_hint()), we must use the ERRP_AUTO_PROPAGATE macro.
Otherwise, this info will not be added when errp == _fatal
(the program will exit prior to the error_append_hint() or
error_prepend() call).  Fix such cases.

If we want to check error after errp-function call, we need to
introduce local_err and then propagate it to errp. Instead, use
ERRP_AUTO_PROPAGATE macro, benefits are:
1. No need of explicit error_propagate call
2. No need of explicit local_err variable: use errp directly
3. ERRP_AUTO_PROPAGATE leaves errp as is if it's not NULL or
   _fatal, this means that we don't break error_abort
   (we'll abort on error_set, not on error_propagate)

This commit is generated by command

sed -n '/^X86 Xen CPUs$/,/^$/{s/^F: //p}' MAINTAINERS | \
xargs git ls-files | grep '\.[hc]$' | \
xargs spatch \
--sp-file scripts/coccinelle/auto-propagated-errp.cocci \
--macro-file scripts/cocci-macro-file.h \
--in-place --no-show-diff --max-width 80

Reported-by: Kevin Wolf 
Reported-by: Greg Kurz 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 hw/block/dataplane/xen-block.c |  17 ++---
 hw/block/xen-block.c   | 125 ++---
 hw/pci-host/xen_igd_pt.c   |   7 +-
 hw/xen/xen-backend.c   |   7 +-
 hw/xen/xen-bus.c   | 100 --
 hw/xen/xen-host-pci-device.c   |  27 ---
 hw/xen/xen_pt.c|  25 +++
 hw/xen/xen_pt_config_init.c|  20 +++---
 8 files changed, 142 insertions(+), 186 deletions(-)

diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c
index 3b9caeb2fa..c38e3c3d85 100644
--- a/hw/block/dataplane/xen-block.c
+++ b/hw/block/dataplane/xen-block.c
@@ -727,8 +727,8 @@ void xen_block_dataplane_start(XenBlockDataPlane *dataplane,
unsigned int protocol,
Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 XenDevice *xendev = dataplane->xendev;
-Error *local_err = NULL;
 unsigned int ring_size;
 unsigned int i;
 
@@ -764,9 +764,8 @@ void xen_block_dataplane_start(XenBlockDataPlane *dataplane,
 }
 
 xen_device_set_max_grant_refs(xendev, dataplane->nr_ring_ref,
-  _err);
-if (local_err) {
-error_propagate(errp, local_err);
+  errp);
+if (*errp) {
 goto stop;
 }
 
@@ -774,9 +773,8 @@ void xen_block_dataplane_start(XenBlockDataPlane *dataplane,
   dataplane->ring_ref,
   dataplane->nr_ring_ref,
   PROT_READ | PROT_WRITE,
-  _err);
-if (local_err) {
-error_propagate(errp, local_err);
+  errp);
+if (*errp) {
 goto stop;
 }
 
@@ -809,9 +807,8 @@ void xen_block_dataplane_start(XenBlockDataPlane *dataplane,
 dataplane->event_channel =
 xen_device_bind_event_channel(xendev, dataplane->ctx, event_channel,
   xen_block_dataplane_event, dataplane,
-  _err);
-if (local_err) {
-error_propagate(errp, local_err);
+  errp);
+if (*errp) {
 goto stop;
 }
 
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index 879fc310a4..70428f5a79 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -194,6 +194,7 @@ static const BlockDevOps xen_block_dev_ops = {
 
 static void xen_block_realize(XenDevice *xendev, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 XenBlockDevice *blockdev = XEN_BLOCK_DEVICE(xendev);
 XenBlockDeviceClass *blockdev_class =
 XEN_BLOCK_DEVICE_GET_CLASS(xendev);
@@ -201,7 +202,6 @@ static void xen_block_realize(XenDevice *xendev, Error 
**errp)
 XenBlockVdev *vdev = >props.vdev;
 BlockConf *conf = >props.conf;
 BlockBackend *blk = conf->blk;
-Error *local_err = NULL;
 
 if (vdev->type == XEN_BLOCK_VDEV_TYPE_INVALID) {
 error_setg(errp, "vdev property not set");
@@ -211,9 +211,8 @@ static void xen_block_realize(XenDevice *xendev, Error 
**errp)
 trace_xen_block_realize(type, vdev->disk, vdev->partition);
 
 if (blockdev_class->realize) {
-blockdev_class->realize(blockdev, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+blockdev_class->realize(blockdev, errp);
+if (*errp) {
 return;
 }
 }
@@ -283,8 +282,8 @@ static void xen_block_frontend_changed(XenDevice *xendev,
enum xenbus_state frontend_state,
Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 enum xenbus_state backend_state = xen_device_backend_get_state(xendev);
-

[PATCH v6 07/11] fw_cfg: introduce ERRP_AUTO_PROPAGATE

2020-01-10 Thread Vladimir Sementsov-Ogievskiy
If we want to add some info to errp (by error_prepend() or
error_append_hint()), we must use the ERRP_AUTO_PROPAGATE macro.
Otherwise, this info will not be added when errp == _fatal
(the program will exit prior to the error_append_hint() or
error_prepend() call).  Fix such cases.

If we want to check error after errp-function call, we need to
introduce local_err and then propagate it to errp. Instead, use
ERRP_AUTO_PROPAGATE macro, benefits are:
1. No need of explicit error_propagate call
2. No need of explicit local_err variable: use errp directly
3. ERRP_AUTO_PROPAGATE leaves errp as is if it's not NULL or
   _fatal, this means that we don't break error_abort
   (we'll abort on error_set, not on error_propagate)

This commit is generated by command

sed -n '/^Firmware configuration (fw_cfg)$/,/^$/{s/^F: //p}' \
MAINTAINERS | \
xargs git ls-files | grep '\.[hc]$' | \
xargs spatch \
--sp-file scripts/coccinelle/auto-propagated-errp.cocci \
--macro-file scripts/cocci-macro-file.h \
--in-place --no-show-diff --max-width 80

Reported-by: Kevin Wolf 
Reported-by: Greg Kurz 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/nvram/fw_cfg.c | 14 ++
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 5d879c471e..4f019efcc4 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -1142,12 +1142,11 @@ static Property fw_cfg_io_properties[] = {
 
 static void fw_cfg_io_realize(DeviceState *dev, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 FWCfgIoState *s = FW_CFG_IO(dev);
-Error *local_err = NULL;
 
-fw_cfg_file_slots_allocate(FW_CFG(s), _err);
-if (local_err) {
-error_propagate(errp, local_err);
+fw_cfg_file_slots_allocate(FW_CFG(s), errp);
+if (*errp) {
 return;
 }
 
@@ -1193,14 +1192,13 @@ static Property fw_cfg_mem_properties[] = {
 
 static void fw_cfg_mem_realize(DeviceState *dev, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 FWCfgMemState *s = FW_CFG_MEM(dev);
 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 const MemoryRegionOps *data_ops = _cfg_data_mem_ops;
-Error *local_err = NULL;
 
-fw_cfg_file_slots_allocate(FW_CFG(s), _err);
-if (local_err) {
-error_propagate(errp, local_err);
+fw_cfg_file_slots_allocate(FW_CFG(s), errp);
+if (*errp) {
 return;
 }
 
-- 
2.21.0




[PATCH v6 08/11] virtio-9p: introduce ERRP_AUTO_PROPAGATE

2020-01-10 Thread Vladimir Sementsov-Ogievskiy
If we want to add some info to errp (by error_prepend() or
error_append_hint()), we must use the ERRP_AUTO_PROPAGATE macro.
Otherwise, this info will not be added when errp == _fatal
(the program will exit prior to the error_append_hint() or
error_prepend() call).  Fix such cases.

If we want to check error after errp-function call, we need to
introduce local_err and then propagate it to errp. Instead, use
ERRP_AUTO_PROPAGATE macro, benefits are:
1. No need of explicit error_propagate call
2. No need of explicit local_err variable: use errp directly
3. ERRP_AUTO_PROPAGATE leaves errp as is if it's not NULL or
   _fatal, this means that we don't break error_abort
   (we'll abort on error_set, not on error_propagate)

This commit is generated by command

sed -n '/^virtio-9p$/,/^$/{s/^F: //p}' MAINTAINERS | \
xargs git ls-files | grep '\.[hc]$' | \
xargs spatch \
--sp-file scripts/coccinelle/auto-propagated-errp.cocci \
--macro-file scripts/cocci-macro-file.h \
--in-place --no-show-diff --max-width 80

Reported-by: Kevin Wolf 
Reported-by: Greg Kurz 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 hw/9pfs/9p-local.c | 12 +---
 hw/9pfs/9p.c   |  1 +
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index ca641390fb..253814ef2c 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -1481,10 +1481,10 @@ static void error_append_security_model_hint(Error 
*const *errp)
 
 static int local_parse_opts(QemuOpts *opts, FsDriverEntry *fse, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 const char *sec_model = qemu_opt_get(opts, "security_model");
 const char *path = qemu_opt_get(opts, "path");
 const char *multidevs = qemu_opt_get(opts, "multidevs");
-Error *local_err = NULL;
 
 if (!sec_model) {
 error_setg(errp, "security_model property not set");
@@ -1518,11 +1518,10 @@ static int local_parse_opts(QemuOpts *opts, 
FsDriverEntry *fse, Error **errp)
 fse->export_flags &= ~V9FS_FORBID_MULTIDEVS;
 fse->export_flags &= ~V9FS_REMAP_INODES;
 } else {
-error_setg(_err, "invalid multidevs property '%s'",
+error_setg(errp, "invalid multidevs property '%s'",
multidevs);
-error_append_hint(_err, "Valid options are: multidevs="
+error_append_hint(errp, "Valid options are: multidevs="
   "[remap|forbid|warn]\n");
-error_propagate(errp, local_err);
 return -1;
 }
 }
@@ -1532,9 +1531,8 @@ static int local_parse_opts(QemuOpts *opts, FsDriverEntry 
*fse, Error **errp)
 return -1;
 }
 
-if (fsdev_throttle_parse_opts(opts, >fst, _err)) {
-error_propagate_prepend(errp, local_err,
-"invalid throttle configuration: ");
+if (fsdev_throttle_parse_opts(opts, >fst, errp)) {
+error_prepend(errp, "invalid throttle configuration: ");
 return -1;
 }
 
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index 520177f40c..4200c3416b 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -3994,6 +3994,7 @@ void pdu_submit(V9fsPDU *pdu, P9MsgHeader *hdr)
 int v9fs_device_realize_common(V9fsState *s, const V9fsTransport *t,
Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 int i, len;
 struct stat stat;
 FsDriverEntry *fse;
-- 
2.21.0




[PATCH v6 10/11] nbd: introduce ERRP_AUTO_PROPAGATE

2020-01-10 Thread Vladimir Sementsov-Ogievskiy
If we want to add some info to errp (by error_prepend() or
error_append_hint()), we must use the ERRP_AUTO_PROPAGATE macro.
Otherwise, this info will not be added when errp == _fatal
(the program will exit prior to the error_append_hint() or
error_prepend() call).  Fix such cases.

If we want to check error after errp-function call, we need to
introduce local_err and then propagate it to errp. Instead, use
ERRP_AUTO_PROPAGATE macro, benefits are:
1. No need of explicit error_propagate call
2. No need of explicit local_err variable: use errp directly
3. ERRP_AUTO_PROPAGATE leaves errp as is if it's not NULL or
   _fatal, this means that we don't break error_abort
   (we'll abort on error_set, not on error_propagate)

This commit is generated by command

sed -n '/^Network Block Device (NBD)$/,/^$/{s/^F: //p}' \
MAINTAINERS | \
xargs git ls-files | grep '\.[hc]$' | \
xargs spatch \
--sp-file scripts/coccinelle/auto-propagated-errp.cocci \
--macro-file scripts/cocci-macro-file.h \
--in-place --no-show-diff --max-width 80

Reported-by: Kevin Wolf 
Reported-by: Greg Kurz 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Eric Blake 
---
 include/block/nbd.h |  1 +
 block/nbd.c | 49 +
 nbd/client.c|  5 +
 nbd/server.c|  5 +
 4 files changed, 34 insertions(+), 26 deletions(-)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index 7f46932d80..4ab8d917ed 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -360,6 +360,7 @@ void nbd_server_start(SocketAddress *addr, const char 
*tls_creds,
 static inline int nbd_read(QIOChannel *ioc, void *buffer, size_t size,
const char *desc, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 int ret = qio_channel_read_all(ioc, buffer, size, errp) < 0 ? -EIO : 0;
 
 if (ret < 0) {
diff --git a/block/nbd.c b/block/nbd.c
index d085554f21..9701ccf887 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -990,10 +990,10 @@ static int nbd_co_receive_cmdread_reply(BDRVNBDState *s, 
uint64_t handle,
 uint64_t offset, QEMUIOVector *qiov,
 int *request_ret, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 NBDReplyChunkIter iter;
 NBDReply reply;
 void *payload = NULL;
-Error *local_err = NULL;
 
 NBD_FOREACH_REPLY_CHUNK(s, iter, handle, s->info.structured_reply,
 qiov, , )
@@ -1012,20 +1012,20 @@ static int nbd_co_receive_cmdread_reply(BDRVNBDState 
*s, uint64_t handle,
 break;
 case NBD_REPLY_TYPE_OFFSET_HOLE:
 ret = nbd_parse_offset_hole_payload(s, , payload,
-offset, qiov, _err);
+offset, qiov, errp);
 if (ret < 0) {
 nbd_channel_error(s, ret);
-nbd_iter_channel_error(, ret, _err);
+nbd_iter_channel_error(, ret, errp);
 }
 break;
 default:
 if (!nbd_reply_type_is_error(chunk->type)) {
 /* not allowed reply type */
 nbd_channel_error(s, -EINVAL);
-error_setg(_err,
+error_setg(errp,
"Unexpected reply type: %d (%s) for CMD_READ",
chunk->type, nbd_reply_type_lookup(chunk->type));
-nbd_iter_channel_error(, -EINVAL, _err);
+nbd_iter_channel_error(, -EINVAL, errp);
 }
 }
 
@@ -1043,10 +1043,10 @@ static int 
nbd_co_receive_blockstatus_reply(BDRVNBDState *s,
 NBDExtent *extent,
 int *request_ret, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 NBDReplyChunkIter iter;
 NBDReply reply;
 void *payload = NULL;
-Error *local_err = NULL;
 bool received = false;
 
 assert(!extent->length);
@@ -1060,27 +1060,27 @@ static int 
nbd_co_receive_blockstatus_reply(BDRVNBDState *s,
 case NBD_REPLY_TYPE_BLOCK_STATUS:
 if (received) {
 nbd_channel_error(s, -EINVAL);
-error_setg(_err, "Several BLOCK_STATUS chunks in reply");
-nbd_iter_channel_error(, -EINVAL, _err);
+error_setg(errp, "Several BLOCK_STATUS chunks in reply");
+nbd_iter_channel_error(, -EINVAL, errp);
 }
 received = true;
 
 ret = nbd_parse_blockstatus_payload(s, ,
 payload, length, extent,
-_err);
+errp);
 if (ret < 0) {
 nbd_channel_error(s, ret);
-nbd_iter_channel_error(, ret, _err);
+nbd_iter_channel_error(, ret, errp);
 

[PATCH v6 02/11] error: auto propagated local_err

2020-01-10 Thread Vladimir Sementsov-Ogievskiy
Here is introduced ERRP_AUTO_PROPAGATE macro, to be used at start of
functions with errp OUT parameter.

It has three goals:

1. Fix issue with error_fatal & error_prepend/error_append_hint: user
can't see this additional information, because exit() happens in
error_setg earlier than information is added. [Reported by Greg Kurz]

2. Fix issue with error_abort & error_propagate: when we wrap
error_abort by local_err+error_propagate, resulting coredump will
refer to error_propagate and not to the place where error happened.
(the macro itself doesn't fix the issue, but it allows to [3.] drop all
local_err+error_propagate pattern, which will definitely fix the issue)
[Reported by Kevin Wolf]

3. Drop local_err+error_propagate pattern, which is used to workaround
void functions with errp parameter, when caller wants to know resulting
status. (Note: actually these functions could be merely updated to
return int error code).

To achieve these goals, we need to add invocation of the macro at start
of functions, which needs error_prepend/error_append_hint (1.); add
invocation of the macro at start of functions which do
local_err+error_propagate scenario the check errors, drop local errors
from them and just use *errp instead (2., 3.).

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---

CC: Cornelia Huck 
CC: Eric Blake 
CC: Kevin Wolf 
CC: Max Reitz 
CC: Greg Kurz 
CC: Stefan Hajnoczi 
CC: Stefano Stabellini 
CC: Anthony Perard 
CC: Paul Durrant 
CC: "Philippe Mathieu-Daudé" 
CC: Laszlo Ersek 
CC: Gerd Hoffmann 
CC: Stefan Berger 
CC: Markus Armbruster 
CC: Michael Roth 
CC: qemu-bl...@nongnu.org
CC: xen-de...@lists.xenproject.org

 include/qapi/error.h | 84 +++-
 1 file changed, 83 insertions(+), 1 deletion(-)

diff --git a/include/qapi/error.h b/include/qapi/error.h
index fa8d51fd6d..532b9afb9e 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h
@@ -78,7 +78,7 @@
  * Call a function treating errors as fatal:
  * foo(arg, _fatal);
  *
- * Receive an error and pass it on to the caller:
+ * Receive an error and pass it on to the caller (DEPRECATED*):
  * Error *err = NULL;
  * foo(arg, );
  * if (err) {
@@ -98,6 +98,50 @@
  * foo(arg, errp);
  * for readability.
  *
+ * DEPRECATED* This pattern is deprecated now, use ERRP_AUTO_PROPAGATE macro
+ * instead (defined below).
+ * It's deprecated because of two things:
+ *
+ * 1. Issue with error_abort & error_propagate: when we wrap error_abort by
+ * local_err+error_propagate, resulting coredump will refer to error_propagate
+ * and not to the place where error happened.
+ *
+ * 2. A lot of extra code of the same pattern
+ *
+ * How to update old code to use ERRP_AUTO_PROPAGATE?
+ *
+ * All you need is to add ERRP_AUTO_PROPAGATE() invocation at function start,
+ * than you may safely dereference errp to check errors and do not need any
+ * additional local Error variables or calls to error_propagate().
+ *
+ * Example:
+ *
+ * old code
+ *
+ * void fn(..., Error **errp) {
+ * Error *err = NULL;
+ * foo(arg, );
+ * if (err) {
+ * handle the error...
+ * error_propagate(errp, err);
+ * return;
+ * }
+ * ...
+ * }
+ *
+ * updated code
+ *
+ * void fn(..., Error **errp) {
+ * ERRP_AUTO_PROPAGATE();
+ * foo(arg, errp);
+ * if (*errp) {
+ * handle the error...
+ * return;
+ * }
+ * ...
+ * }
+ *
+ *
  * Receive and accumulate multiple errors (first one wins):
  * Error *err = NULL, *local_err = NULL;
  * foo(arg, );
@@ -348,6 +392,44 @@ void error_set_internal(Error **errp,
 ErrorClass err_class, const char *fmt, ...)
 GCC_FMT_ATTR(6, 7);
 
+typedef struct ErrorPropagator {
+Error *local_err;
+Error **errp;
+} ErrorPropagator;
+
+static inline void error_propagator_cleanup(ErrorPropagator *prop)
+{
+error_propagate(prop->errp, prop->local_err);
+}
+
+G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(ErrorPropagator, error_propagator_cleanup);
+
+/*
+ * ERRP_AUTO_PROPAGATE
+ *
+ * This macro is created to be the first line of a function which use
+ * Error **errp parameter to report error. It's needed only in cases where we
+ * want to use error_prepend, error_append_hint or dereference *errp. It's
+ * still safe (but useless) in other cases.
+ *
+ * If errp is NULL or points to error_fatal, it is rewritten to point to a
+ * local Error object, which will be automatically propagated to the original
+ * errp on function exit (see error_propagator_cleanup).
+ *
+ * After invocation of this macro it is always safe to dereference errp
+ * (as it's not NULL anymore) and to add information (by error_prepend or
+ * error_append_hint)
+ * (as, if it was error_fatal, we swapped it with a local_error to be
+ * propagated on cleanup).
+ *
+ * Note: we don't wrap the error_abort case, as we want resulting coredump
+ * to point to the 

[PATCH v6 05/11] SD (Secure Card): introduce ERRP_AUTO_PROPAGATE

2020-01-10 Thread Vladimir Sementsov-Ogievskiy
If we want to add some info to errp (by error_prepend() or
error_append_hint()), we must use the ERRP_AUTO_PROPAGATE macro.
Otherwise, this info will not be added when errp == _fatal
(the program will exit prior to the error_append_hint() or
error_prepend() call).  Fix such cases.

If we want to check error after errp-function call, we need to
introduce local_err and then propagate it to errp. Instead, use
ERRP_AUTO_PROPAGATE macro, benefits are:
1. No need of explicit error_propagate call
2. No need of explicit local_err variable: use errp directly
3. ERRP_AUTO_PROPAGATE leaves errp as is if it's not NULL or
   _fatal, this means that we don't break error_abort
   (we'll abort on error_set, not on error_propagate)

This commit is generated by command

sed -n '/^SD (Secure Card)$/,/^$/{s/^F: //p}' \
MAINTAINERS | \
xargs git ls-files | grep '\.[hc]$' | \
xargs spatch \
--sp-file scripts/coccinelle/auto-propagated-errp.cocci \
--macro-file scripts/cocci-macro-file.h \
--in-place --no-show-diff --max-width 80

Reported-by: Kevin Wolf 
Reported-by: Greg Kurz 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/sd/sdhci-pci.c |  7 +++
 hw/sd/sdhci.c | 21 +
 2 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/hw/sd/sdhci-pci.c b/hw/sd/sdhci-pci.c
index 2c8d8f59b5..b1448cf22e 100644
--- a/hw/sd/sdhci-pci.c
+++ b/hw/sd/sdhci-pci.c
@@ -29,13 +29,12 @@ static Property sdhci_pci_properties[] = {
 
 static void sdhci_pci_realize(PCIDevice *dev, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 SDHCIState *s = PCI_SDHCI(dev);
-Error *local_err = NULL;
 
 sdhci_initfn(s);
-sdhci_common_realize(s, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+sdhci_common_realize(s, errp);
+if (*errp) {
 return;
 }
 
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 18c0c052ce..ca258572b3 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1293,7 +1293,7 @@ static const MemoryRegionOps sdhci_mmio_ops = {
 
 static void sdhci_init_readonly_registers(SDHCIState *s, Error **errp)
 {
-Error *local_err = NULL;
+ERRP_AUTO_PROPAGATE();
 
 switch (s->sd_spec_version) {
 case 2 ... 3:
@@ -1304,9 +1304,8 @@ static void sdhci_init_readonly_registers(SDHCIState *s, 
Error **errp)
 }
 s->version = (SDHC_HCVER_VENDOR << 8) | (s->sd_spec_version - 1);
 
-sdhci_check_capareg(s, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+sdhci_check_capareg(s, errp);
+if (*errp) {
 return;
 }
 }
@@ -1337,11 +1336,10 @@ void sdhci_uninitfn(SDHCIState *s)
 
 void sdhci_common_realize(SDHCIState *s, Error **errp)
 {
-Error *local_err = NULL;
+ERRP_AUTO_PROPAGATE();
 
-sdhci_init_readonly_registers(s, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+sdhci_init_readonly_registers(s, errp);
+if (*errp) {
 return;
 }
 s->buf_maxsz = sdhci_get_fifolen(s);
@@ -1461,13 +1459,12 @@ static void sdhci_sysbus_finalize(Object *obj)
 
 static void sdhci_sysbus_realize(DeviceState *dev, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 SDHCIState *s = SYSBUS_SDHCI(dev);
 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
-Error *local_err = NULL;
 
-sdhci_common_realize(s, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+sdhci_common_realize(s, errp);
+if (*errp) {
 return;
 }
 
-- 
2.21.0




[PATCH v6 01/11] qapi/error: add (Error **errp) cleaning APIs

2020-01-10 Thread Vladimir Sementsov-Ogievskiy
Signed-off-by: Vladimir Sementsov-Ogievskiy 
---

CC: Cornelia Huck 
CC: Eric Blake 
CC: Kevin Wolf 
CC: Max Reitz 
CC: Greg Kurz 
CC: Stefan Hajnoczi 
CC: Stefano Stabellini 
CC: Anthony Perard 
CC: Paul Durrant 
CC: "Philippe Mathieu-Daudé" 
CC: Laszlo Ersek 
CC: Gerd Hoffmann 
CC: Stefan Berger 
CC: Markus Armbruster 
CC: Michael Roth 
CC: qemu-bl...@nongnu.org
CC: xen-de...@lists.xenproject.org

 include/qapi/error.h | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/include/qapi/error.h b/include/qapi/error.h
index ad5b6e896d..fa8d51fd6d 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h
@@ -309,6 +309,32 @@ void warn_reportf_err(Error *err, const char *fmt, ...)
 void error_reportf_err(Error *err, const char *fmt, ...)
 GCC_FMT_ATTR(2, 3);
 
+/*
+ * Functions to clean Error **errp: call corresponding Error *err cleaning
+ * function an set pointer to NULL
+ */
+static inline void error_free_errp(Error **errp)
+{
+assert(errp && *errp);
+error_free(*errp);
+*errp = NULL;
+}
+
+static inline void error_report_errp(Error **errp)
+{
+assert(errp && *errp);
+error_report_err(*errp);
+*errp = NULL;
+}
+
+static inline void warn_report_errp(Error **errp)
+{
+assert(errp && *errp);
+warn_report_err(*errp);
+*errp = NULL;
+}
+
+
 /*
  * Just like error_setg(), except you get to specify the error class.
  * Note: use of error classes other than ERROR_CLASS_GENERIC_ERROR is
-- 
2.21.0




[PATCH v6 04/11] hw/sd/ssi-sd: fix error handling in ssi_sd_realize

2020-01-10 Thread Vladimir Sementsov-Ogievskiy
It's wrong to use same err object as errp parameter for several
function calls without intermediate checking for error: we'll crash if
try to set err object twice.

Fix that, using new ERRP_AUTO_PROPAGATE macro.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 hw/sd/ssi-sd.c | 26 +++---
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 91db069212..bc44e1a0f5 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -241,10 +241,10 @@ static const VMStateDescription vmstate_ssi_sd = {
 
 static void ssi_sd_realize(SSISlave *d, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, d);
 DeviceState *carddev;
 DriveInfo *dinfo;
-Error *err = NULL;
 
 qbus_create_inplace(>sdbus, sizeof(s->sdbus), TYPE_SD_BUS,
 DEVICE(d), "sd-bus");
@@ -254,14 +254,26 @@ static void ssi_sd_realize(SSISlave *d, Error **errp)
 dinfo = drive_get_next(IF_SD);
 carddev = qdev_create(BUS(>sdbus), TYPE_SD_CARD);
 if (dinfo) {
-qdev_prop_set_drive(carddev, "drive", blk_by_legacy_dinfo(dinfo), 
);
+qdev_prop_set_drive(carddev, "drive", blk_by_legacy_dinfo(dinfo), 
errp);
+if (*errp) {
+goto fail;
+}
+}
+
+object_property_set_bool(OBJECT(carddev), true, "spi", errp);
+if (*errp) {
+goto fail;
 }
-object_property_set_bool(OBJECT(carddev), true, "spi", );
-object_property_set_bool(OBJECT(carddev), true, "realized", );
-if (err) {
-error_setg(errp, "failed to init SD card: %s", error_get_pretty(err));
-return;
+
+object_property_set_bool(OBJECT(carddev), true, "realized", errp);
+if (*errp) {
+goto fail;
 }
+
+return;
+
+fail:
+error_prepend(errp, "failed to init SD card: ");
 }
 
 static void ssi_sd_reset(DeviceState *dev)
-- 
2.21.0




[PATCH v6 06/11] pflash: introduce ERRP_AUTO_PROPAGATE

2020-01-10 Thread Vladimir Sementsov-Ogievskiy
If we want to add some info to errp (by error_prepend() or
error_append_hint()), we must use the ERRP_AUTO_PROPAGATE macro.
Otherwise, this info will not be added when errp == _fatal
(the program will exit prior to the error_append_hint() or
error_prepend() call).  Fix such cases.

If we want to check error after errp-function call, we need to
introduce local_err and then propagate it to errp. Instead, use
ERRP_AUTO_PROPAGATE macro, benefits are:
1. No need of explicit error_propagate call
2. No need of explicit local_err variable: use errp directly
3. ERRP_AUTO_PROPAGATE leaves errp as is if it's not NULL or
   _fatal, this means that we don't break error_abort
   (we'll abort on error_set, not on error_propagate)

This commit is generated by command

sed -n '/^Parallel NOR Flash devices$/,/^$/{s/^F: //p}' \
MAINTAINERS | \
xargs git ls-files | grep '\.[hc]$' | \
xargs spatch \
--sp-file scripts/coccinelle/auto-propagated-errp.cocci \
--macro-file scripts/cocci-macro-file.h \
--in-place --no-show-diff --max-width 80

Reported-by: Kevin Wolf 
Reported-by: Greg Kurz 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/block/pflash_cfi01.c | 7 +++
 hw/block/pflash_cfi02.c | 7 +++
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 54e6ebd385..9b12b04b65 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -700,12 +700,12 @@ static const MemoryRegionOps pflash_cfi01_ops = {
 
 static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 PFlashCFI01 *pfl = PFLASH_CFI01(dev);
 uint64_t total_len;
 int ret;
 uint64_t blocks_per_device, sector_len_per_device, device_len;
 int num_devices;
-Error *local_err = NULL;
 
 if (pfl->sector_len == 0) {
 error_setg(errp, "attribute \"sector-length\" not specified or zero.");
@@ -739,9 +739,8 @@ static void pflash_cfi01_realize(DeviceState *dev, Error 
**errp)
 >mem, OBJECT(dev),
 _cfi01_ops,
 pfl,
-pfl->name, total_len, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+pfl->name, total_len, errp);
+if (*errp) {
 return;
 }
 
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index c7d92c3e79..7b33008fd5 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -719,9 +719,9 @@ static const MemoryRegionOps pflash_cfi02_ops = {
 
 static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 PFlashCFI02 *pfl = PFLASH_CFI02(dev);
 int ret;
-Error *local_err = NULL;
 
 if (pfl->uniform_sector_len == 0 && pfl->sector_len[0] == 0) {
 error_setg(errp, "attribute \"sector-length\" not specified or zero.");
@@ -787,9 +787,8 @@ static void pflash_cfi02_realize(DeviceState *dev, Error 
**errp)
 
 memory_region_init_rom_device(>orig_mem, OBJECT(pfl),
   _cfi02_ops, pfl, pfl->name,
-  pfl->chip_len, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+  pfl->chip_len, errp);
+if (*errp) {
 return;
 }
 
-- 
2.21.0




Re: [PATCH] block: Use a GString in bdrv_perm_names()

2020-01-10 Thread Eric Blake

On 1/10/20 11:15 AM, Alberto Garcia wrote:

This is a bit more efficient than having to allocate and free memory
for each new permission.

The default size (30) is enough for "consistent read, write, resize".

Signed-off-by: Alberto Garcia 
---
  block.c | 11 ++-
  1 file changed, 6 insertions(+), 5 deletions(-)



Reviewed-by: Eric Blake 

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PATCH 18/26] object: return self in object_ref()

2020-01-10 Thread Philippe Mathieu-Daudé

On 1/10/20 4:30 PM, Marc-André Lureau wrote:

This allow for simpler assignment with ref: foo = object_ref(bar)

Signed-off-by: Marc-André Lureau 


Reviewed-by: Philippe Mathieu-Daudé 


---
  include/qom/object.h | 3 ++-
  qom/object.c | 5 +++--
  2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index ead9129ac8..933e5c6cb9 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1013,8 +1013,9 @@ GSList *object_class_get_list_sorted(const char 
*implements_type,
   *
   * Increase the reference count of a object.  A object cannot be freed as long
   * as its reference count is greater than zero.
+ * Returns: @obj
   */
-void object_ref(Object *obj);
+Object *object_ref(Object *obj);
  
  /**

   * object_unref:
diff --git a/qom/object.c b/qom/object.c
index 3924678ec3..9f76a330ff 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1098,12 +1098,13 @@ GSList *object_class_get_list_sorted(const char 
*implements_type,
  object_class_cmp);
  }
  
-void object_ref(Object *obj)

+Object *object_ref(Object *obj)
  {
  if (!obj) {
-return;
+return NULL;
  }
  atomic_inc(>ref);
+return obj;
  }
  
  void object_unref(Object *obj)







Re: [PATCH] target/arm: adjust program counter for wfi exception in AArch32

2020-01-10 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20200110180211.29025-1-jeff.kubas...@dornerworks.com/



Hi,

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

Subject: [PATCH] target/arm: adjust program counter for wfi exception in AArch32
Type: series
Message-id: 20200110180211.29025-1-jeff.kubas...@dornerworks.com

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

Switched to a new branch 'test'
800339c target/arm: adjust program counter for wfi exception in AArch32

=== OUTPUT BEGIN ===
ERROR: braces {} are necessary for all arms of this statement
#30: FILE: target/arm/op_helper.c:298:
+if (env->aarch64)
[...]
+else
[...]

total: 1 errors, 0 warnings, 12 lines checked

Commit 800339c7aaeb (target/arm: adjust program counter for wfi exception in 
AArch32) 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/20200110180211.29025-1-jeff.kubas...@dornerworks.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [PATCH 04/15] hw/ppc/spapr_rtas: Restrict variables scope to single switch case

2020-01-10 Thread Eric Blake

On 1/10/20 3:50 AM, Greg Kurz wrote:


I guess a decent compiler can be smart enough detect that the initialization
isn't needed outside of the RTAS_SYSPARM_SPLPAR_CHARACTERISTICS branch...
Anyway, reducing scope isn't bad. The only hitch I could see is that some
people do prefer to have all variables declared upfront, but there's a nested
param_val variable already so I guess it's okay.


I don't want to outsmart compilers :)


Or conversely play the game of which compilers will warn about an 
atypical construct.




The MACHINE() macro is not a simple cast, it does object introspection
with OBJECT_CHECK(), thus is not free. Since


Sure, I understand the motivation in avoiding an unneeded call
to calling object_dynamic_cast_assert().


object_dynamic_cast_assert() argument is not const, I'm not sure the
compiler can remove the call.



Not remove the call, but delay it to the branch that uses it,
ie. parameter == RTAS_SYSPARM_SPLPAR_CHARACTERISTICS.


Richard, Eric, do you know?


Signed-off-by: Philippe Mathieu-Daudé 
---
   hw/ppc/spapr_rtas.c | 4 ++--
   1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 6f06e9d7fe..7237e5ebf2 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -267,8 +267,6 @@ static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu,
 uint32_t nret, target_ulong rets)
   {
   PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
-MachineState *ms = MACHINE(spapr);
-unsigned int max_cpus = ms->smp.max_cpus;
   target_ulong parameter = rtas_ld(args, 0);
   target_ulong buffer = rtas_ld(args, 1);
   target_ulong length = rtas_ld(args, 2);
@@ -276,6 +274,8 @@ static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu,
   
   switch (parameter) {

   case RTAS_SYSPARM_SPLPAR_CHARACTERISTICS: {
+MachineState *ms = MACHINE(spapr);
+unsigned int max_cpus = ms->smp.max_cpus;


Declaring an initializer inside a switch statement can trigger warnings 
under some compilation scenarios (particularly if the variable is 
referenced outside of the scope where it was introduced).  But here, you 
are using 'case label: { ...' to create a scope, which presumably ends 
before the next case label, and is thus not going to trigger compiler 
warnings.


An alternative is indeed leaving the declaration up front but deferring 
the (possibly expensive) initializer to the case label that needs it:


MachineState *ms;
switch (parameter) {
case ...:
  ms = MACHINE(spapr);

and done that way, you might not even need the extra {} behind the case 
label (I didn't read the file to see if there is already some other 
reason for having introduced that sub-scope).


As for whether compilers are smart enough to defer non-trivial 
initialization to the one case label that uses the variable, I wouldn't 
count on it.  If the non-trivial initialization includes a function call 
(which the MACHINE() macro does), it's much harder to prove whether that 
function call has side effects that may be needed prior to the switch 
statement.  So limiting the scope of the initialization (whether by 
dropping the declaration, or just deferring the call) DOES make sense.



--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PATCH 04/26] qdev: move helper function to monitor/misc

2020-01-10 Thread Philippe Mathieu-Daudé

On 1/10/20 4:30 PM, Marc-André Lureau wrote:

Move the one-user function to the place it is being used.

Signed-off-by: Marc-André Lureau 


Reviewed-by: Philippe Mathieu-Daudé 


---
  include/hw/qdev-core.h |  2 --
  hw/core/qdev.c | 26 --
  monitor/misc.c | 26 ++
  3 files changed, 26 insertions(+), 28 deletions(-)

diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 1518495b1e..6b0e7b265d 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -457,8 +457,6 @@ extern bool qdev_hot_removed;
  
  char *qdev_get_dev_path(DeviceState *dev);
  
-GSList *qdev_build_hotpluggable_device_list(Object *peripheral);

-
  void qbus_set_hotplug_handler(BusState *bus, Object *handler, Error **errp);
  
  void qbus_set_bus_hotplug_handler(BusState *bus, Error **errp);

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index c2aa7f91a6..a520d7fa89 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -760,32 +760,6 @@ void qdev_alias_all_properties(DeviceState *target, Object 
*source)
  } while (class != object_class_by_name(TYPE_DEVICE));
  }
  
-static int qdev_add_hotpluggable_device(Object *obj, void *opaque)

-{
-GSList **list = opaque;
-DeviceState *dev = (DeviceState *)object_dynamic_cast(OBJECT(obj),
-  TYPE_DEVICE);
-
-if (dev == NULL) {
-return 0;
-}
-
-if (dev->realized && object_property_get_bool(obj, "hotpluggable", NULL)) {
-*list = g_slist_append(*list, dev);
-}
-
-return 0;
-}
-
-GSList *qdev_build_hotpluggable_device_list(Object *peripheral)
-{
-GSList *list = NULL;
-
-object_child_foreach(peripheral, qdev_add_hotpluggable_device, );
-
-return list;
-}
-
  static bool device_get_realized(Object *obj, Error **errp)
  {
  DeviceState *dev = DEVICE(obj);
diff --git a/monitor/misc.c b/monitor/misc.c
index a04d7edde0..be3c700511 100644
--- a/monitor/misc.c
+++ b/monitor/misc.c
@@ -1954,6 +1954,32 @@ void object_add_completion(ReadLineState *rs, int 
nb_args, const char *str)
  g_slist_free(list);
  }
  
+static int qdev_add_hotpluggable_device(Object *obj, void *opaque)

+{
+GSList **list = opaque;
+DeviceState *dev = (DeviceState *)object_dynamic_cast(OBJECT(obj),
+  TYPE_DEVICE);
+
+if (dev == NULL) {
+return 0;
+}
+
+if (dev->realized && object_property_get_bool(obj, "hotpluggable", NULL)) {
+*list = g_slist_append(*list, dev);
+}
+
+return 0;
+}
+
+static GSList *qdev_build_hotpluggable_device_list(Object *peripheral)
+{
+GSList *list = NULL;
+
+object_child_foreach(peripheral, qdev_add_hotpluggable_device, );
+
+return list;
+}
+
  static void peripheral_device_del_completion(ReadLineState *rs,
   const char *str, size_t len)
  {






Re: [PATCH 01/26] object: add extra sanity checks

2020-01-10 Thread Philippe Mathieu-Daudé

On 1/10/20 4:30 PM, Marc-André Lureau wrote:

Type system checked that children class_size >= parent class_size, but
not instances. Fix that.

Signed-off-by: Marc-André Lureau 
---
  qom/object.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/qom/object.c b/qom/object.c
index 0d971ca897..8453e4ac91 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -303,6 +303,7 @@ static void type_initialize(TypeImpl *ti)
  int i;
  
  g_assert(parent->class_size <= ti->class_size);

+g_assert(parent->instance_size <= ti->instance_size);
  memcpy(ti->class, parent->class, parent->class_size);
  ti->class->interfaces = NULL;
  ti->class->properties = g_hash_table_new_full(



Reviewed-by: Philippe Mathieu-Daudé 




[PATCH 0/1] travis.yml: Missing genisoimage package

2020-01-10 Thread Wainer dos Santos Moschetta
Let's install genisoimage package on Travis build environments so that
the cdrom-test tests run (currently they skip due the missing dependency).

As an example, on
https://travis-ci.org/qemu/qemu/jobs/635375718:

```
MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))}
QTEST_QEMU_BINARY=aarch64-softmmu/qemu-system-aarch64
QTEST_QEMU_IMG=qemu-img tests/cdrom-test -m=quick -k --tap < /dev/null |
./scripts/tap-driver.pl --test-name="cdrom-test" 

SKIP
```

Now with this change on
https://travis-ci.org/wainersm/qemu/jobs/635358843:

```
MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))}  
QTEST_QEMU_BINARY=aarch64-softmmu/qemu-system-aarch64 QTEST_QEMU_IMG=qemu-img 
tests/cdrom-test -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl 
--test-name="cdrom-test" 

PASS 1 cdrom-test /aarch64/cdrom/param/realview-eb

PASS 2 cdrom-test /aarch64/cdrom/param/realview-eb-mpcore

PASS 3 cdrom-test /aarch64/cdrom/param/realview-pb-a8

PASS 4 cdrom-test /aarch64/cdrom/param/realview-pbx-a9

PASS 5 cdrom-test /aarch64/cdrom/param/versatileab

PASS 6 cdrom-test /aarch64/cdrom/param/versatilepb

PASS 7 cdrom-test /aarch64/cdrom/param/vexpress-a15

PASS 8 cdrom-test /aarch64/cdrom/param/vexpress-a9

PASS 9 cdrom-test /aarch64/cdrom/param/virt
```

Wainer dos Santos Moschetta (1):
  travis.yml: Install genisoimage package

 .travis.yml | 8 
 1 file changed, 8 insertions(+)

-- 
2.23.0




[PATCH 1/1] travis.yml: Install genisoimage package

2020-01-10 Thread Wainer dos Santos Moschetta
The genisoimage program is required for tests/cdrom-test
tests, otherwise they are skipped. The current Travis
environments do not provide it by default, so let's
explicitly require the genisoimage package.

Signed-off-by: Wainer dos Santos Moschetta 
---
 .travis.yml | 8 
 1 file changed, 8 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index 6c1038a0f1..131c920255 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -51,6 +51,8 @@ addons:
   - sparse
   - uuid-dev
   - gcovr
+  # Tests dependencies
+  - genisoimage
 
 
 # The channel name "irc.oftc.net#qemu" is encrypted against qemu/qemu
@@ -383,6 +385,8 @@ matrix:
   - libusb-1.0-0-dev
   - libvdeplug-dev
   - libvte-2.91-dev
+  # Tests dependencies
+  - genisoimage
   env:
 - TEST_CMD="make check check-tcg V=1"
 - CONFIG="--disable-containers --target-list=${MAIN_SOFTMMU_TARGETS}"
@@ -412,6 +416,8 @@ matrix:
   - libusb-1.0-0-dev
   - libvdeplug-dev
   - libvte-2.91-dev
+  # Tests dependencies
+  - genisoimage
   env:
 - TEST_CMD="make check check-tcg V=1"
 - CONFIG="--disable-containers 
--target-list=${MAIN_SOFTMMU_TARGETS},ppc64le-linux-user"
@@ -441,6 +447,8 @@ matrix:
   - libusb-1.0-0-dev
   - libvdeplug-dev
   - libvte-2.91-dev
+  # Tests dependencies
+  - genisoimage
   env:
 - TEST_CMD="make check check-tcg V=1"
 - CONFIG="--disable-containers 
--target-list=${MAIN_SOFTMMU_TARGETS},s390x-linux-user"
-- 
2.23.0




Re: [PATCH v1 00/59] trivial unneeded labels cleanup

2020-01-10 Thread Eric Blake

On 1/6/20 12:23 PM, Daniel Henrique Barboza wrote:

Hello,

This is the type of cleanup I've contributed to Libvirt
during the last year. Figured QEMU also deserves the same
care.

The idea here is remove unneeded labels. By 'unneeded' I
mean labels that does nothing but a 'return' call. One
common case is something like this:

if ()
 goto cleanup;
[...]
  cleanup:
 return 0;

This code can be simplified to:

if ()
 return 0;




How much of this work is done manually, and how much via Coccinelle?



  qga/commands-win32.c  | 17 ---
  target/mips/mips-semi.c   | 15 +++---
  target/unicore32/softmmu.c| 23 +++---
  util/aio-posix.c  |  3 +-
  util/module.c | 11 ++---


Hmm, no change to scripts/coccinelle, so presumably all manual :(

If we have a Coccinelle script that performs this transformation, we are 
more likely to be able to catch all places in the tree that would 
benefit (rather than relying on grep calls or other manual inspection), 
and more importantly, we can repeat the effort periodically to fix 
future additions that don't comply with the preferred style as well as 
backport the patch by rerunning the Coccinelle script with less worry of 
changed context.  Automated cleanups are always going to be easier to 
swallow (even if the diffstat is larger) than manual ad hoc cleanups.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PATCH 1/4] qapi: Add a 'coroutine' flag for commands

2020-01-10 Thread Eric Blake

On 1/9/20 12:35 PM, Kevin Wolf wrote:

This patch adds a new 'coroutine' flag to QMP command definitions that
tells the QMP dispatcher than the command handler is safe to be run in a


s/than/that/


coroutine.

Signed-off-by: Kevin Wolf 
---
  tests/qapi-schema/qapi-schema-test.json |  1 +
  docs/devel/qapi-code-gen.txt|  4 
  include/qapi/qmp/dispatch.h |  1 +
  tests/test-qmp-cmds.c   |  4 
  scripts/qapi/commands.py| 17 +++--
  scripts/qapi/doc.py |  2 +-
  scripts/qapi/expr.py|  4 ++--
  scripts/qapi/introspect.py  |  2 +-
  scripts/qapi/schema.py  |  9 ++---
  tests/qapi-schema/qapi-schema-test.out  |  2 ++
  tests/qapi-schema/test-qapi.py  |  7 ---
  11 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/tests/qapi-schema/qapi-schema-test.json 
b/tests/qapi-schema/qapi-schema-test.json
index 9abf175fe0..55f596dbaa 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -147,6 +147,7 @@
'returns': 'UserDefTwo' }
  
  { 'command': 'cmd-success-response', 'data': {}, 'success-response': false }

+{ 'command': 'coroutine_cmd', 'data': {}, 'coroutine': true }


Not user-visible (it's the testsuite), but why not follow our naming 
convention of 'coroutine-cmd'?




+++ b/docs/devel/qapi-code-gen.txt
@@ -457,6 +457,7 @@ Syntax:
  '*gen': false,
  '*allow-oob': true,
  '*allow-preconfig': true,
+'*coroutine': true,
  '*if': COND,
  '*features': FEATURES }
  
@@ -581,6 +582,9 @@ before the machine is built.  It defaults to false.  For example:

  QMP is available before the machine is built only when QEMU was
  started with --preconfig.
  
+Member 'coroutine' tells the QMP dispatcher whether the command handler

+is safe to be run in a coroutine. It defaults to false.
+
  The optional 'if' member specifies a conditional.  See "Configuring


Maybe "The optional 'coroutine' member tells..." for symmetry with the 
next paragraph.



+++ b/scripts/qapi/commands.py
@@ -15,6 +15,7 @@ See the COPYING file in the top-level directory.
  
  from qapi.common import *

  from qapi.gen import QAPIGenCCode, QAPISchemaModularCVisitor, ifcontext
+from typing import List
  
  
  def gen_command_decl(name, arg_type, boxed, ret_type):

@@ -194,8 +195,9 @@ out:
  return ret
  
  
-def gen_register_command(name, success_response, allow_oob, allow_preconfig):

-options = []
+def gen_register_command(name: str, success_response: bool, allow_oob: bool,
+ allow_preconfig: bool, coroutine: bool) -> str:
+options = [] # type: List[str]


Aha - now that we require python 3, you're going to exploit it ;)



+++ b/scripts/qapi/introspect.py
@@ -212,7 +212,7 @@ const QLitObject %(c_name)s = %(c_string)s;
  
  def visit_command(self, name, info, ifcond, arg_type, ret_type, gen,

success_response, boxed, allow_oob, allow_preconfig,
-  features):
+  coroutine, features):
  arg_type = arg_type or self._schema.the_empty_object_type
  ret_type = ret_type or self._schema.the_empty_object_type
  obj = {'arg-type': self._use_type(arg_type),


I'm assuming the new flag is internal only, and doesn't affect behavior 
seen by the user, and thus nothing to change in the introspection output.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: How to tell DMA controller in qemu to terminate transfer ?

2020-01-10 Thread Guenter Roeck
On Fri, Jan 10, 2020 at 10:36:20AM +, Peter Maydell wrote:
> On Wed, 8 Jan 2020 at 18:36, Guenter Roeck  wrote:
> >
> > Hi,
> >
> > I am trying to fix DMA support with Exynos4210. The original commit
> > 59520dc65e ("hw/arm/exynos4210: Add DMA support for the Exynos4210") doesn't
> > really work, primarily because it assigns wrong interrupt lines (no idea
> > how I thought I tested that).
> >
> > Problem I have right now is that the pl330 peripheral DMA in Exynos4210
> > depends on a signal from the peripheral device (here: serial ports)
> > to end a DMA transfer. To make this work, I need a signal from
> > exynos4210_uart.c to pl330.c to terminate the DMA after the receive
> > buffer is empty.
> >
> > How can I implement this in qemu ?
> 
> That depends. How does the UART signal the DMA controller
> in real hardware? If there's a signal line of some kind,
> then you can model that with a qemu_irq line which the UART
> exposes and raises/lowers at the right time, that's then
> plumbed through by the SoC to the DMA controller.
> 
Never mind my previous e-mail; the above was enough to get it working.

Thanks!
Guenter



[PATCH] target/arm: adjust program counter for wfi exception in AArch32

2020-01-10 Thread Jeff Kubascik
The wfi instruction can be configured to be trapped by a higher exception
level, such as the EL2 hypervisor. When the instruction is trapped, the
program counter should contain the address of the wfi instruction that
caused the exception. The program counter is adjusted for this in the wfi op
helper function.

However, this correction is done to env->pc, which only applies to AArch64
mode. For AArch32, the program counter is stored in env->regs[15]. This
adds an if-else statement to modify the correct program counter location
based on the the current CPU mode.

Signed-off-by: Jeff Kubascik 
---
Hello,

I am using the ARMv8 version of QEMU to run the Xen hypervisor with a guest
virtual machine compiled for AArch32/Thumb code. I have noticed that when
the AArch32 guest VM executes the wfi instruction, the hypervisor trap of
the wfi instruction sees the program counter contain the address of the
instruction following the wfi. This does not occur for an AARch64 guest VM;
in this case, the program counter contains the address of the wfi
instruction. I am confident the correct behavior in both cases is for the
program counter to contain the address of the wfi instruction, as this works
on actual hardware (Xilinx Zynq UltraScale+ MPSoC).

I have tested the above patch and it works for Xen with both an AArch64
guest (Linux) and an AArch32 guest (RTEMS). I'm still getting accustomed to
the QEMU code base, so it may not be correct. Any feedback would be greatly
appreciated.

Sincerely,
Jeff Kubascik
---
 target/arm/op_helper.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index e5a346cb87..7295645854 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -295,7 +295,11 @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
 }
 
 if (target_el) {
-env->pc -= insn_len;
+if (env->aarch64)
+env->pc -= insn_len;
+else
+env->regs[15] -= insn_len;
+
 raise_exception(env, EXCP_UDEF, syn_wfx(1, 0xe, 0, insn_len == 2),
 target_el);
 }
-- 
2.17.1




[PULL 28/28] apic: Use 32bit APIC ID for migration instance ID

2020-01-10 Thread Juan Quintela
From: Peter Xu 

Migration is silently broken now with x2apic config like this:

 -smp 200,maxcpus=288,sockets=2,cores=72,threads=2 \
 -device intel-iommu,intremap=on,eim=on

After migration, the guest kernel could hang at anything, due to
x2apic bit not migrated correctly in IA32_APIC_BASE on some vcpus, so
any operations related to x2apic could be broken then (e.g., RDMSR on
x2apic MSRs could fail because KVM would think that the vcpu hasn't
enabled x2apic at all).

The issue is that the x2apic bit was never applied correctly for vcpus
whose ID > 255 when migrate completes, and that's because when we
migrate APIC we use the APICCommonState.id as instance ID of the
migration stream, while that's too short for x2apic.

Let's use the newly introduced initial_apic_id for that.

Signed-off-by: Peter Xu 
Reviewed-by: Juan Quintela 
Reviewed-by: Eduardo Habkost 
Signed-off-by: Juan Quintela 
---
 hw/intc/apic_common.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index 54b8731fca..b5dbeb6206 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -268,7 +268,10 @@ static void apic_common_realize(DeviceState *dev, Error 
**errp)
 APICCommonState *s = APIC_COMMON(dev);
 APICCommonClass *info;
 static DeviceState *vapic;
-uint32_t instance_id = s->id;
+uint32_t instance_id = s->initial_apic_id;
+
+/* Normally initial APIC ID should be no more than hundreds */
+assert(instance_id != VMSTATE_INSTANCE_ID_ANY);
 
 info = APIC_COMMON_GET_CLASS(s);
 info->realize(dev, errp);
-- 
2.24.1




[PULL 24/28] migration/multifd: fix destroyed mutex access in terminating multifd threads

2020-01-10 Thread Juan Quintela
From: Jiahui Cen 

One multifd will lock all the other multifds' IOChannel mutex to inform them
to quit by setting p->quit or shutting down p->c. In this senario, if some
multifds had already been terminated and 
multifd_load_cleanup/multifd_save_cleanup
had destroyed their mutex, it could cause destroyed mutex access when trying
lock their mutex.

Here is the coredump stack:
#0  0x7f81a2794437 in raise () from /usr/lib64/libc.so.6
#1  0x7f81a2795b28 in abort () from /usr/lib64/libc.so.6
#2  0x7f81a278d1b6 in __assert_fail_base () from /usr/lib64/libc.so.6
#3  0x7f81a278d262 in __assert_fail () from /usr/lib64/libc.so.6
#4  0x55eb1bfadbd3 in qemu_mutex_lock_impl (mutex=0x55eb1e2d1988, 
file=, line=) at util/qemu-thread-posix.c:64
#5  0x55eb1bb4564a in multifd_send_terminate_threads (err=) at migration/ram.c:1015
#6  0x55eb1bb4bb7f in multifd_send_thread (opaque=0x55eb1e2d19f8) at 
migration/ram.c:1171
#7  0x55eb1bfad628 in qemu_thread_start (args=0x55eb1e170450) at 
util/qemu-thread-posix.c:502
#8  0x7f81a2b36df5 in start_thread () from /usr/lib64/libpthread.so.0
#9  0x7f81a286048d in clone () from /usr/lib64/libc.so.6

To fix it up, let's destroy the mutex after all the other multifd threads had
been terminated.

Signed-off-by: Jiahui Cen 
Signed-off-by: Ying Fang 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 migration/ram.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/migration/ram.c b/migration/ram.c
index 5da3a47ffc..67a24bf217 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1053,6 +1053,10 @@ void multifd_save_cleanup(void)
 if (p->running) {
 qemu_thread_join(>thread);
 }
+}
+for (i = 0; i < migrate_multifd_channels(); i++) {
+MultiFDSendParams *p = _send_state->params[i];
+
 socket_send_channel_destroy(p->c);
 p->c = NULL;
 qemu_mutex_destroy(>mutex);
@@ -1336,6 +1340,10 @@ int multifd_load_cleanup(Error **errp)
 qemu_sem_post(>sem_sync);
 qemu_thread_join(>thread);
 }
+}
+for (i = 0; i < migrate_multifd_channels(); i++) {
+MultiFDRecvParams *p = _recv_state->params[i];
+
 object_unref(OBJECT(p->c));
 p->c = NULL;
 qemu_mutex_destroy(>mutex);
-- 
2.24.1




[PULL 22/28] migration/multifd: not use multifd during postcopy

2020-01-10 Thread Juan Quintela
From: Wei Yang 

We don't support multifd during postcopy, but user still could enable
both multifd and postcopy. This leads to migration failure.

Skip multifd during postcopy.

Signed-off-by: Wei Yang 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 migration/ram.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index 57e22cac4c..4ba9037e78 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -2587,10 +2587,13 @@ static int ram_save_target_page(RAMState *rs, 
PageSearchStatus *pss,
 }
 
 /*
- * do not use multifd for compression as the first page in the new
- * block should be posted out before sending the compressed page
+ * Do not use multifd for:
+ * 1. Compression as the first page in the new block should be posted out
+ *before sending the compressed page
+ * 2. In postcopy as one whole host page should be placed
  */
-if (!save_page_use_compression(rs) && migrate_use_multifd()) {
+if (!save_page_use_compression(rs) && migrate_use_multifd()
+&& !migration_in_postcopy()) {
 return ram_save_multifd_page(rs, block, offset);
 }
 
-- 
2.24.1




[PULL 27/28] migration: Change SaveStateEntry.instance_id into uint32_t

2020-01-10 Thread Juan Quintela
From: Peter Xu 

It was always used as 32bit, so define it as used to be clear.
Instead of using -1 as the auto-gen magic value, we switch to
UINT32_MAX.  We also make sure that we don't auto-gen this value to
avoid overflowed instance IDs without being noticed.

Suggested-by: Juan Quintela 
Signed-off-by: Peter Xu 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 hw/intc/apic_common.c|  2 +-
 include/migration/register.h |  2 +-
 include/migration/vmstate.h  |  2 +-
 migration/savevm.c   | 18 ++
 stubs/vmstate.c  |  2 +-
 5 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index f2c3a7f309..54b8731fca 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -268,7 +268,7 @@ static void apic_common_realize(DeviceState *dev, Error 
**errp)
 APICCommonState *s = APIC_COMMON(dev);
 APICCommonClass *info;
 static DeviceState *vapic;
-int instance_id = s->id;
+uint32_t instance_id = s->id;
 
 info = APIC_COMMON_GET_CLASS(s);
 info->realize(dev, errp);
diff --git a/include/migration/register.h b/include/migration/register.h
index 00c38ebe9f..c1dcff0f90 100644
--- a/include/migration/register.h
+++ b/include/migration/register.h
@@ -71,7 +71,7 @@ typedef struct SaveVMHandlers {
 } SaveVMHandlers;
 
 int register_savevm_live(const char *idstr,
- int instance_id,
+ uint32_t instance_id,
  int version_id,
  const SaveVMHandlers *ops,
  void *opaque);
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index a33861e1d4..30667631bc 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -1181,7 +1181,7 @@ bool vmstate_save_needed(const VMStateDescription *vmsd, 
void *opaque);
 #define  VMSTATE_INSTANCE_ID_ANY  -1
 
 /* Returns: 0 on success, -1 on failure */
-int vmstate_register_with_alias_id(VMStateIf *obj, int instance_id,
+int vmstate_register_with_alias_id(VMStateIf *obj, uint32_t instance_id,
const VMStateDescription *vmsd,
void *base, int alias_id,
int required_for_version,
diff --git a/migration/savevm.c b/migration/savevm.c
index 8dab99efc4..adfdca26ac 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -233,7 +233,7 @@ typedef struct CompatEntry {
 typedef struct SaveStateEntry {
 QTAILQ_ENTRY(SaveStateEntry) entry;
 char idstr[256];
-int instance_id;
+uint32_t instance_id;
 int alias_id;
 int version_id;
 /* version id read from the stream */
@@ -667,10 +667,10 @@ void dump_vmstate_json_to_file(FILE *out_file)
 fclose(out_file);
 }
 
-static int calculate_new_instance_id(const char *idstr)
+static uint32_t calculate_new_instance_id(const char *idstr)
 {
 SaveStateEntry *se;
-int instance_id = 0;
+uint32_t instance_id = 0;
 
 QTAILQ_FOREACH(se, _state.handlers, entry) {
 if (strcmp(idstr, se->idstr) == 0
@@ -678,6 +678,8 @@ static int calculate_new_instance_id(const char *idstr)
 instance_id = se->instance_id + 1;
 }
 }
+/* Make sure we never loop over without being noticed */
+assert(instance_id != VMSTATE_INSTANCE_ID_ANY);
 return instance_id;
 }
 
@@ -755,7 +757,7 @@ static void savevm_state_handler_remove(SaveStateEntry *se)
Meanwhile pass -1 as instance_id if you do not already have a clearly
distinguishing id for all instances of your device class. */
 int register_savevm_live(const char *idstr,
- int instance_id,
+ uint32_t instance_id,
  int version_id,
  const SaveVMHandlers *ops,
  void *opaque)
@@ -809,7 +811,7 @@ void unregister_savevm(VMStateIf *obj, const char *idstr, 
void *opaque)
 }
 }
 
-int vmstate_register_with_alias_id(VMStateIf *obj, int instance_id,
+int vmstate_register_with_alias_id(VMStateIf *obj, uint32_t instance_id,
const VMStateDescription *vmsd,
void *opaque, int alias_id,
int required_for_version,
@@ -1625,7 +1627,7 @@ int qemu_save_device_state(QEMUFile *f)
 return qemu_file_get_error(f);
 }
 
-static SaveStateEntry *find_se(const char *idstr, int instance_id)
+static SaveStateEntry *find_se(const char *idstr, uint32_t instance_id)
 {
 SaveStateEntry *se;
 
@@ -2292,7 +2294,7 @@ qemu_loadvm_section_start_full(QEMUFile *f, 
MigrationIncomingState *mis)
 /* Find savevm section */
 se = find_se(idstr, instance_id);
 if (se == NULL) {
-error_report("Unknown savevm section or instance '%s' %d. "
+error_report("Unknown savevm section or instance '%s' %"PRIu32". "
  "Make sure 

[PULL 18/28] migration/postcopy: set all_zero to true on the first target page

2020-01-10 Thread Juan Quintela
From: Wei Yang 

For the first target page, all_zero is set to true for this round check.

After target_pages introduced, we could leverage this variable instead
of checking the address offset.

Signed-off-by: Wei Yang 
Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 migration/ram.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/migration/ram.c b/migration/ram.c
index f20dfc3b68..f3889904b2 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -4102,7 +4102,7 @@ static int ram_load_postcopy(QEMUFile *f)
 page_buffer = postcopy_host_page +
   ((uintptr_t)host & (block->page_size - 1));
 /* If all TP are zero then we can optimise the place */
-if (!((uintptr_t)host & (block->page_size - 1))) {
+if (target_pages == 1) {
 all_zero = true;
 } else {
 /* not the 1st TP within the HP */
-- 
2.24.1




[PULL 26/28] migration: Define VMSTATE_INSTANCE_ID_ANY

2020-01-10 Thread Juan Quintela
From: Peter Xu 

Define the new macro VMSTATE_INSTANCE_ID_ANY for callers who wants to
auto-generate the vmstate instance ID.  Previously it was hard coded
as -1 instead of this macro.  It helps to change this default value in
the follow up patches.  No functional change.

Signed-off-by: Peter Xu 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 backends/dbus-vmstate.c | 3 ++-
 hw/arm/stellaris.c  | 2 +-
 hw/core/qdev.c  | 3 ++-
 hw/display/ads7846.c| 2 +-
 hw/i2c/core.c   | 2 +-
 hw/input/stellaris_input.c  | 3 ++-
 hw/intc/apic_common.c   | 2 +-
 hw/misc/max111x.c   | 3 ++-
 hw/net/eepro100.c   | 3 ++-
 hw/pci/pci.c| 2 +-
 hw/ppc/spapr.c  | 2 +-
 hw/timer/arm_timer.c| 2 +-
 hw/tpm/tpm_emulator.c   | 3 ++-
 include/migration/vmstate.h | 2 ++
 migration/savevm.c  | 8 
 15 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/backends/dbus-vmstate.c b/backends/dbus-vmstate.c
index 56b482a7d6..cc594a722e 100644
--- a/backends/dbus-vmstate.c
+++ b/backends/dbus-vmstate.c
@@ -412,7 +412,8 @@ dbus_vmstate_complete(UserCreatable *uc, Error **errp)
 return;
 }
 
-if (vmstate_register(VMSTATE_IF(self), -1, _vmstate, self) < 0) {
+if (vmstate_register(VMSTATE_IF(self), VMSTATE_INSTANCE_ID_ANY,
+ _vmstate, self) < 0) {
 error_setg(errp, "Failed to register vmstate");
 }
 }
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index b198066b54..bb025e0bd0 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -708,7 +708,7 @@ static int stellaris_sys_init(uint32_t base, qemu_irq irq,
 memory_region_init_io(>iomem, NULL, _ops, s, "ssys", 0x1000);
 memory_region_add_subregion(get_system_memory(), base, >iomem);
 ssys_reset(s);
-vmstate_register(NULL, -1, _stellaris_sys, s);
+vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, _stellaris_sys, s);
 return 0;
 }
 
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 9f1753f5cf..58e87d336d 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -879,7 +879,8 @@ static void device_set_realized(Object *obj, bool value, 
Error **errp)
 
 if (qdev_get_vmsd(dev)) {
 if (vmstate_register_with_alias_id(VMSTATE_IF(dev),
-   -1, qdev_get_vmsd(dev), dev,
+   VMSTATE_INSTANCE_ID_ANY,
+   qdev_get_vmsd(dev), dev,
dev->instance_id_alias,
dev->alias_required_for_version,
_err) < 0) {
diff --git a/hw/display/ads7846.c b/hw/display/ads7846.c
index c12272ae72..9228b40b1a 100644
--- a/hw/display/ads7846.c
+++ b/hw/display/ads7846.c
@@ -154,7 +154,7 @@ static void ads7846_realize(SSISlave *d, Error **errp)
 
 ads7846_int_update(s);
 
-vmstate_register(NULL, -1, _ads7846, s);
+vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, _ads7846, s);
 }
 
 static void ads7846_class_init(ObjectClass *klass, void *data)
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
index 92cd489069..d770035ba0 100644
--- a/hw/i2c/core.c
+++ b/hw/i2c/core.c
@@ -61,7 +61,7 @@ I2CBus *i2c_init_bus(DeviceState *parent, const char *name)
 
 bus = I2C_BUS(qbus_create(TYPE_I2C_BUS, parent, name));
 QLIST_INIT(>current_devs);
-vmstate_register(NULL, -1, _i2c_bus, bus);
+vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, _i2c_bus, bus);
 return bus;
 }
 
diff --git a/hw/input/stellaris_input.c b/hw/input/stellaris_input.c
index 59892b07fc..e6ee5e11f1 100644
--- a/hw/input/stellaris_input.c
+++ b/hw/input/stellaris_input.c
@@ -88,5 +88,6 @@ void stellaris_gamepad_init(int n, qemu_irq *irq, const int 
*keycode)
 }
 s->num_buttons = n;
 qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
-vmstate_register(NULL, -1, _stellaris_gamepad, s);
+vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY,
+ _stellaris_gamepad, s);
 }
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index 375cb6abe9..f2c3a7f309 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -284,7 +284,7 @@ static void apic_common_realize(DeviceState *dev, Error 
**errp)
 }
 
 if (s->legacy_instance_id) {
-instance_id = -1;
+instance_id = VMSTATE_INSTANCE_ID_ANY;
 }
 vmstate_register_with_alias_id(NULL, instance_id, _apic_common,
s, -1, 0, NULL);
diff --git a/hw/misc/max111x.c b/hw/misc/max111x.c
index 211008ce02..2b87bdee5b 100644
--- a/hw/misc/max111x.c
+++ b/hw/misc/max111x.c
@@ -146,7 +146,8 @@ static int max111x_init(SSISlave *d, int inputs)
 s->input[7] = 0x80;
 s->com = 0;
 
-vmstate_register(VMSTATE_IF(dev), -1, _max111x, s);
+vmstate_register(VMSTATE_IF(dev), VMSTATE_INSTANCE_ID_ANY,
+  

[PULL 15/28] migration/postcopy: reduce memset when it is zero page and matches_target_page_size

2020-01-10 Thread Juan Quintela
From: Wei Yang 

In this case, page_buffer content would not be used.

Skip this to save some time.

Signed-off-by: Wei Yang 
Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 migration/ram.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/migration/ram.c b/migration/ram.c
index 31d21b7f6b..6702a3203e 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -4126,7 +4126,13 @@ static int ram_load_postcopy(QEMUFile *f)
 switch (flags & ~RAM_SAVE_FLAG_CONTINUE) {
 case RAM_SAVE_FLAG_ZERO:
 ch = qemu_get_byte(f);
-memset(page_buffer, ch, TARGET_PAGE_SIZE);
+/*
+ * Can skip to set page_buffer when
+ * this is a zero page and (block->page_size == TARGET_PAGE_SIZE).
+ */
+if (ch || !matches_target_page_size) {
+memset(page_buffer, ch, TARGET_PAGE_SIZE);
+}
 if (ch) {
 all_zero = false;
 }
-- 
2.24.1




[PULL 25/28] Bug #1829242 correction.

2020-01-10 Thread Juan Quintela
From: Alexey Romko 

Added type conversions to ram_addr_t before all left shifts of page
indexes to TARGET_PAGE_BITS, to correct overflows when the page
address was 4Gb and more.

Signed-off-by: Alexey Romko 
Reviewed-by: Juan Quintela 
Reviewed-by: Dr. David Alan Gilbert 
Signed-off-by: Juan Quintela 
---
 migration/ram.c | 29 ++---
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index 67a24bf217..e711f9003b 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1768,7 +1768,7 @@ static inline bool migration_bitmap_clear_dirty(RAMState 
*rs,
 if (rb->clear_bmap && clear_bmap_test_and_clear(rb, page)) {
 uint8_t shift = rb->clear_bmap_shift;
 hwaddr size = 1ULL << (TARGET_PAGE_BITS + shift);
-hwaddr start = (page << TARGET_PAGE_BITS) & (-size);
+hwaddr start = (((ram_addr_t)page) << TARGET_PAGE_BITS) & (-size);
 
 /*
  * CLEAR_BITMAP_SHIFT_MIN should always guarantee this... this
@@ -2005,7 +2005,7 @@ static void ram_release_pages(const char *rbname, 
uint64_t offset, int pages)
 return;
 }
 
-ram_discard_range(rbname, offset, pages << TARGET_PAGE_BITS);
+ram_discard_range(rbname, offset, ((ram_addr_t)pages) << TARGET_PAGE_BITS);
 }
 
 /*
@@ -2093,7 +2093,7 @@ static int ram_save_page(RAMState *rs, PageSearchStatus 
*pss, bool last_stage)
 uint8_t *p;
 bool send_async = true;
 RAMBlock *block = pss->block;
-ram_addr_t offset = pss->page << TARGET_PAGE_BITS;
+ram_addr_t offset = ((ram_addr_t)pss->page) << TARGET_PAGE_BITS;
 ram_addr_t current_addr = block->offset + offset;
 
 p = block->host + offset;
@@ -2280,7 +2280,8 @@ static bool find_dirty_block(RAMState *rs, 
PageSearchStatus *pss, bool *again)
 *again = false;
 return false;
 }
-if ((pss->page << TARGET_PAGE_BITS) >= pss->block->used_length) {
+if ram_addr_t)pss->page) << TARGET_PAGE_BITS)
+>= pss->block->used_length) {
 /* Didn't find anything in this RAM Block */
 pss->page = 0;
 pss->block = QLIST_NEXT_RCU(pss->block, next);
@@ -2571,7 +2572,7 @@ static int ram_save_target_page(RAMState *rs, 
PageSearchStatus *pss,
 bool last_stage)
 {
 RAMBlock *block = pss->block;
-ram_addr_t offset = pss->page << TARGET_PAGE_BITS;
+ram_addr_t offset = ((ram_addr_t)pss->page) << TARGET_PAGE_BITS;
 int res;
 
 if (control_save_page(rs, block, offset, )) {
@@ -2657,7 +2658,8 @@ static int ram_save_host_page(RAMState *rs, 
PageSearchStatus *pss,
 /* Allow rate limiting to happen in the middle of huge pages */
 migration_rate_limit();
 } while ((pss->page & (pagesize_bits - 1)) &&
- offset_in_ramblock(pss->block, pss->page << TARGET_PAGE_BITS));
+ offset_in_ramblock(pss->block,
+((ram_addr_t)pss->page) << TARGET_PAGE_BITS));
 
 /* The offset we leave with is the last one we looked at */
 pss->page--;
@@ -2874,8 +2876,10 @@ void ram_postcopy_migrated_memory_release(MigrationState 
*ms)
 
 while (run_start < range) {
 unsigned long run_end = find_next_bit(bitmap, range, run_start + 
1);
-ram_discard_range(block->idstr, run_start << TARGET_PAGE_BITS,
-  (run_end - run_start) << TARGET_PAGE_BITS);
+ram_discard_range(block->idstr,
+  ((ram_addr_t)run_start) << TARGET_PAGE_BITS,
+  ((ram_addr_t)(run_end - run_start))
+<< TARGET_PAGE_BITS);
 run_start = find_next_zero_bit(bitmap, range, run_end + 1);
 }
 }
@@ -4273,13 +4277,16 @@ static void colo_flush_ram_cache(void)
 while (block) {
 offset = migration_bitmap_find_dirty(ram_state, block, offset);
 
-if (offset << TARGET_PAGE_BITS >= block->used_length) {
+if (((ram_addr_t)offset) << TARGET_PAGE_BITS
+>= block->used_length) {
 offset = 0;
 block = QLIST_NEXT_RCU(block, next);
 } else {
 migration_bitmap_clear_dirty(ram_state, block, offset);
-dst_host = block->host + (offset << TARGET_PAGE_BITS);
-src_host = block->colo_cache + (offset << TARGET_PAGE_BITS);
+dst_host = block->host
+ + (((ram_addr_t)offset) << TARGET_PAGE_BITS);
+src_host = block->colo_cache
+ + (((ram_addr_t)offset) << TARGET_PAGE_BITS);
 memcpy(dst_host, src_host, TARGET_PAGE_SIZE);
 }
 }
-- 
2.24.1




[PULL 23/28] migration/multifd: fix nullptr access in terminating multifd threads

2020-01-10 Thread Juan Quintela
From: Jiahui Cen 

One multifd channel will shutdown all the other multifd's IOChannel when it
fails to receive an IOChannel. In this senario, if some multifds had not
received its IOChannel yet, it would try to shutdown its IOChannel which could
cause nullptr access at qio_channel_shutdown.

Here is the coredump stack:
#0  object_get_class (obj=obj@entry=0x0) at qom/object.c:908
#1  0x5563fdbb8f4a in qio_channel_shutdown (ioc=0x0, 
how=QIO_CHANNEL_SHUTDOWN_BOTH, errp=0x0) at io/channel.c:355
#2  0x5563fd7b4c5f in multifd_recv_terminate_threads (err=) at migration/ram.c:1280
#3  0x5563fd7bc019 in multifd_recv_new_channel 
(ioc=ioc@entry=0x556400255610, errp=errp@entry=0x7ffec07dce00) at 
migration/ram.c:1478
#4  0x5563fda82177 in migration_ioc_process_incoming 
(ioc=ioc@entry=0x556400255610, errp=errp@entry=0x7ffec07dce30) at 
migration/migration.c:605
#5  0x5563fda8567d in migration_channel_process_incoming 
(ioc=0x556400255610) at migration/channel.c:44
#6  0x5563fda83ee0 in socket_accept_incoming_migration 
(listener=0x5563fff6b920, cioc=0x556400255610, opaque=) at 
migration/socket.c:166
#7  0x5563fdbc25cd in qio_net_listener_channel_func (ioc=, condition=, opaque=) at io/net-listener.c:54
#8  0x7f895b6fe9a9 in g_main_context_dispatch () from 
/usr/lib64/libglib-2.0.so.0
#9  0x5563fdc18136 in glib_pollfds_poll () at util/main-loop.c:218
#10 0x5563fdc181b5 in os_host_main_loop_wait (timeout=10) at 
util/main-loop.c:241
#11 0x5563fdc183a2 in main_loop_wait (nonblocking=nonblocking@entry=0) 
at util/main-loop.c:517
#12 0x5563fd8edb37 in main_loop () at vl.c:1791
#13 0x5563fd74fd45 in main (argc=, argv=, 
envp=) at vl.c:4473

To fix it up, let's check p->c before calling qio_channel_shutdown.

Signed-off-by: Jiahui Cen 
Signed-off-by: Ying Fang 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 migration/ram.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/migration/ram.c b/migration/ram.c
index 4ba9037e78..5da3a47ffc 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1308,7 +1308,9 @@ static void multifd_recv_terminate_threads(Error *err)
- normal quit, i.e. everything went fine, just finished
- error quit: We close the channels so the channel threads
  finish the qio_channel_read_all_eof() */
-qio_channel_shutdown(p->c, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
+if (p->c) {
+qio_channel_shutdown(p->c, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
+}
 qemu_mutex_unlock(>mutex);
 }
 }
-- 
2.24.1




[PULL 19/28] migration/postcopy: enable random order target page arrival

2020-01-10 Thread Juan Quintela
From: Wei Yang 

After using number of target page received to track one host page, we
could have the capability to handle random order target page arrival in
one host page.

This is a preparation for enabling compress during postcopy.

Signed-off-by: Wei Yang 
Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 migration/ram.c | 18 ++
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index f3889904b2..b5546940f9 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -4050,7 +4050,7 @@ static int ram_load_postcopy(QEMUFile *f)
 MigrationIncomingState *mis = migration_incoming_get_current();
 /* Temporary page that is later 'placed' */
 void *postcopy_host_page = mis->postcopy_tmp_page;
-void *last_host = NULL;
+void *this_host = NULL;
 bool all_zero = false;
 int target_pages = 0;
 
@@ -4097,24 +4097,26 @@ static int ram_load_postcopy(QEMUFile *f)
  * that's moved into place later.
  * The migration protocol uses,  possibly smaller, target-pages
  * however the source ensures it always sends all the components
- * of a host page in order.
+ * of a host page in one chunk.
  */
 page_buffer = postcopy_host_page +
   ((uintptr_t)host & (block->page_size - 1));
 /* If all TP are zero then we can optimise the place */
 if (target_pages == 1) {
 all_zero = true;
+this_host = (void *)QEMU_ALIGN_DOWN((uintptr_t)host,
+block->page_size);
 } else {
 /* not the 1st TP within the HP */
-if (host != (last_host + TARGET_PAGE_SIZE)) {
-error_report("Non-sequential target page %p/%p",
-  host, last_host);
+if (QEMU_ALIGN_DOWN((uintptr_t)host, block->page_size) !=
+(uintptr_t)this_host) {
+error_report("Non-same host page %p/%p",
+  host, this_host);
 ret = -EINVAL;
 break;
 }
 }
 
-
 /*
  * If it's the last part of a host page then we place the host
  * page
@@ -4125,7 +4127,6 @@ static int ram_load_postcopy(QEMUFile *f)
 }
 place_source = postcopy_host_page;
 }
-last_host = host;
 
 switch (flags & ~RAM_SAVE_FLAG_CONTINUE) {
 case RAM_SAVE_FLAG_ZERO:
@@ -4178,7 +4179,8 @@ static int ram_load_postcopy(QEMUFile *f)
 
 if (!ret && place_needed) {
 /* This gets called at the last target page in the host page */
-void *place_dest = host + TARGET_PAGE_SIZE - block->page_size;
+void *place_dest = (void *)QEMU_ALIGN_DOWN((uintptr_t)host,
+   block->page_size);
 
 if (all_zero) {
 ret = postcopy_place_page_zero(mis, place_dest,
-- 
2.24.1




[PULL 21/28] migration/multifd: clean pages after filling packet

2020-01-10 Thread Juan Quintela
From: Wei Yang 

This is a preparation for the next patch:

not use multifd during postcopy.

Without enabling postcopy, everything looks good. While after enabling
postcopy, migration may fail even not use multifd during postcopy. The
reason is the pages is not properly cleared and *old* target page will
continue to be transferred.

After clean pages, migration succeeds.

Signed-off-by: Wei Yang 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 migration/ram.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index b9eb08f549..57e22cac4c 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -955,10 +955,10 @@ static int multifd_send_pages(RAMState *rs)
 }
 qemu_mutex_unlock(>mutex);
 }
-p->pages->used = 0;
+assert(!p->pages->used);
+assert(!p->pages->block);
 
 p->packet_num = multifd_send_state->packet_num++;
-p->pages->block = NULL;
 multifd_send_state->pages = p->pages;
 p->pages = pages;
 transferred = ((uint64_t) pages->used) * TARGET_PAGE_SIZE + p->packet_len;
@@ -1154,6 +1154,8 @@ static void *multifd_send_thread(void *opaque)
 p->flags = 0;
 p->num_packets++;
 p->num_pages += used;
+p->pages->used = 0;
+p->pages->block = NULL;
 qemu_mutex_unlock(>mutex);
 
 trace_multifd_send(p->id, packet_num, used, flags,
-- 
2.24.1




[PULL 20/28] migration/postcopy: enable compress during postcopy

2020-01-10 Thread Juan Quintela
From: Wei Yang 

postcopy requires to place a whole host page, while migration thread
migrate memory in target page size. This makes postcopy need to collect
all target pages in one host page before placing via userfaultfd.

To enable compress during postcopy, there are two problems to solve:

1. Random order for target page arrival
2. Target pages in one host page arrives without interrupt by target
   page from other host page

The first one is handled by previous cleanup patch.

This patch handles the second one by:

1. Flush compress thread for each host page
2. Wait for decompress thread for before placing host page

Signed-off-by: Wei Yang 
Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 migration/migration.c | 11 ---
 migration/ram.c   | 28 +++-
 2 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index e55edee606..990bff00c0 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1005,17 +1005,6 @@ static bool migrate_caps_check(bool *cap_list,
 #endif
 
 if (cap_list[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
-if (cap_list[MIGRATION_CAPABILITY_COMPRESS]) {
-/* The decompression threads asynchronously write into RAM
- * rather than use the atomic copies needed to avoid
- * userfaulting.  It should be possible to fix the decompression
- * threads for compatibility in future.
- */
-error_setg(errp, "Postcopy is not currently compatible "
-   "with compression");
-return false;
-}
-
 /* This check is reasonably expensive, so only when it's being
  * set the first time, also it's only the destination that needs
  * special support.
diff --git a/migration/ram.c b/migration/ram.c
index b5546940f9..b9eb08f549 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -3469,6 +3469,14 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
 
 rs->target_page_count += pages;
 
+/*
+ * During postcopy, it is necessary to make sure one whole host
+ * page is sent in one chunk.
+ */
+if (migrate_postcopy_ram()) {
+flush_compressed_data(rs);
+}
+
 /*
  * we want to check in the 1st loop, just in case it was the 1st
  * time and we had to sync the dirty bitmap.
@@ -4061,6 +4069,7 @@ static int ram_load_postcopy(QEMUFile *f)
 void *place_source = NULL;
 RAMBlock *block = NULL;
 uint8_t ch;
+int len;
 
 addr = qemu_get_be64(f);
 
@@ -4078,7 +4087,8 @@ static int ram_load_postcopy(QEMUFile *f)
 
 trace_ram_load_postcopy_loop((uint64_t)addr, flags);
 place_needed = false;
-if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE)) {
+if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE |
+ RAM_SAVE_FLAG_COMPRESS_PAGE)) {
 block = ram_block_from_stream(f, flags);
 
 host = host_from_ram_block_offset(block, addr);
@@ -4161,6 +4171,17 @@ static int ram_load_postcopy(QEMUFile *f)
  TARGET_PAGE_SIZE);
 }
 break;
+case RAM_SAVE_FLAG_COMPRESS_PAGE:
+all_zero = false;
+len = qemu_get_be32(f);
+if (len < 0 || len > compressBound(TARGET_PAGE_SIZE)) {
+error_report("Invalid compressed data length: %d", len);
+ret = -EINVAL;
+break;
+}
+decompress_data_with_multi_threads(f, page_buffer, len);
+break;
+
 case RAM_SAVE_FLAG_EOS:
 /* normal exit */
 multifd_recv_sync_main();
@@ -4172,6 +4193,11 @@ static int ram_load_postcopy(QEMUFile *f)
 break;
 }
 
+/* Got the whole host page, wait for decompress before placing. */
+if (place_needed) {
+ret |= wait_for_decompress_done();
+}
+
 /* Detect for any possible file errors */
 if (!ret && qemu_file_get_error(f)) {
 ret = qemu_file_get_error(f);
-- 
2.24.1




[PULL 09/28] migration: Fix incorrect integer->float conversion caught by clang

2020-01-10 Thread Juan Quintela
From: Fangrui Song 

Clang does not like qmp_migrate_set_downtime()'s code to clamp double
@value to 0..INT64_MAX:

qemu/migration/migration.c:2038:24: error: implicit conversion from 'long' 
to 'double' changes value from 9223372036854775807 to 9223372036854775808 
[-Werror,-Wimplicit-int-float-conversion]

The warning will be enabled by default in clang 10. It is not
available for clang <= 9.

The clamp is actually useless; @value is checked to be within
0..MAX_MIGRATE_DOWNTIME_SECONDS immediately before.  Delete it.

While there, make the conversion from double to int64_t explicit.

Signed-off-by: Fangrui Song 
Reviewed-by: Markus Armbruster 
Reviewed-by: Juan Quintela 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
[Patch split, commit message improved]
Signed-off-by: Markus Armbruster 
Signed-off-by: Juan Quintela 
---
 migration/migration.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index 27500d09a9..f79d0bf89a 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2035,11 +2035,10 @@ void qmp_migrate_set_downtime(double value, Error 
**errp)
 }
 
 value *= 1000; /* Convert to milliseconds */
-value = MAX(0, MIN(INT64_MAX, value));
 
 MigrateSetParameters p = {
 .has_downtime_limit = true,
-.downtime_limit = value,
+.downtime_limit = (int64_t)value,
 };
 
 qmp_migrate_set_parameters(, errp);
-- 
2.24.1




[PULL 17/28] migration/postcopy: count target page number to decide the place_needed

2020-01-10 Thread Juan Quintela
From: Wei Yang 

In postcopy, it requires to place whole host page instead of target
page.

Currently, it relies on the page offset to decide whether this is the
last target page. We also can count the target page number during the
iteration. When the number of target page equals
(host page size / target page size), this means it is the last target
page in the host page.

This is a preparation for non-ordered target page transmission.

Signed-off-by: Wei Yang 
Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 migration/ram.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index f9e6f20024..f20dfc3b68 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -4052,6 +4052,7 @@ static int ram_load_postcopy(QEMUFile *f)
 void *postcopy_host_page = mis->postcopy_tmp_page;
 void *last_host = NULL;
 bool all_zero = false;
+int target_pages = 0;
 
 while (!ret && !(flags & RAM_SAVE_FLAG_EOS)) {
 ram_addr_t addr;
@@ -4086,6 +4087,7 @@ static int ram_load_postcopy(QEMUFile *f)
 ret = -EINVAL;
 break;
 }
+target_pages++;
 matches_target_page_size = block->page_size == TARGET_PAGE_SIZE;
 /*
  * Postcopy requires that we place whole host pages atomically;
@@ -4117,8 +4119,10 @@ static int ram_load_postcopy(QEMUFile *f)
  * If it's the last part of a host page then we place the host
  * page
  */
-place_needed = (((uintptr_t)host + TARGET_PAGE_SIZE) &
- (block->page_size - 1)) == 0;
+if (target_pages == (block->page_size / TARGET_PAGE_SIZE)) {
+place_needed = true;
+target_pages = 0;
+}
 place_source = postcopy_host_page;
 }
 last_host = host;
-- 
2.24.1




[PULL 16/28] migration/postcopy: wait for decompress thread in precopy

2020-01-10 Thread Juan Quintela
From: Wei Yang 

Compress is not supported with postcopy, it is safe to wait for
decompress thread just in precopy.

This is a preparation for later patch.

Signed-off-by: Wei Yang 
Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 migration/ram.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index 6702a3203e..f9e6f20024 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -4421,6 +4421,7 @@ static int ram_load_precopy(QEMUFile *f)
 }
 }
 
+ret |= wait_for_decompress_done();
 return ret;
 }
 
@@ -4452,8 +4453,6 @@ static int ram_load(QEMUFile *f, void *opaque, int 
version_id)
 } else {
 ret = ram_load_precopy(f);
 }
-
-ret |= wait_for_decompress_done();
 }
 trace_ram_load_complete(ret, seq_iter);
 
-- 
2.24.1




[PULL 10/28] migration: Fix the re-run check of the migrate-incoming command

2020-01-10 Thread Juan Quintela
From: Yury Kotov 

The current check sets an error but doesn't fail the command.
This may cause a problem if new connection attempt by the same URI
affects the first connection.

Signed-off-by: Yury Kotov 
Reviewed-by: Juan Quintela 
Reviewed-by: Darren Kenny 
Signed-off-by: Juan Quintela 
---
 migration/migration.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/migration/migration.c b/migration/migration.c
index f79d0bf89a..e55edee606 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1784,6 +1784,7 @@ void qmp_migrate_incoming(const char *uri, Error **errp)
 }
 if (!once) {
 error_setg(errp, "The incoming migration has already been started");
+return;
 }
 
 qemu_start_incoming_migration(uri, _err);
-- 
2.24.1




[PULL 08/28] migration: Support QLIST migration

2020-01-10 Thread Juan Quintela
From: Eric Auger 

Support QLIST migration using the same principle as QTAILQ:
94869d5c52 ("migration: migrate QTAILQ").

The VMSTATE_QLIST_V macro has the same proto as VMSTATE_QTAILQ_V.
The change mainly resides in QLIST RAW macros: QLIST_RAW_INSERT_HEAD
and QLIST_RAW_REVERSE.

Tests also are provided.

Signed-off-by: Eric Auger 
Reviewed-by: Peter Xu 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 include/migration/vmstate.h |  21 +
 include/qemu/queue.h|  39 +
 migration/trace-events  |   5 ++
 migration/vmstate-types.c   |  70 +++
 tests/test-vmstate.c| 170 
 5 files changed, 305 insertions(+)

diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index 4aef72c426..0dc04fc48e 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -229,6 +229,7 @@ extern const VMStateInfo vmstate_info_tmp;
 extern const VMStateInfo vmstate_info_bitmap;
 extern const VMStateInfo vmstate_info_qtailq;
 extern const VMStateInfo vmstate_info_gtree;
+extern const VMStateInfo vmstate_info_qlist;
 
 #define type_check_2darray(t1,t2,n,m) ((t1(*)[n][m])0 - (t2*)0)
 /*
@@ -798,6 +799,26 @@ extern const VMStateInfo vmstate_info_gtree;
 .offset   = offsetof(_state, _field),  
\
 }
 
+/*
+ * For migrating a QLIST
+ * Target QLIST needs be properly initialized.
+ * _type: type of QLIST element
+ * _next: name of QLIST_ENTRY entry field in QLIST element
+ * _vmsd: VMSD for QLIST element
+ * size: size of QLIST element
+ * start: offset of QLIST_ENTRY in QTAILQ element
+ */
+#define VMSTATE_QLIST_V(_field, _state, _version, _vmsd, _type, _next)  \
+{\
+.name = (stringify(_field)), \
+.version_id   = (_version),  \
+.vmsd = &(_vmsd),\
+.size = sizeof(_type),   \
+.info = _info_qlist, \
+.offset   = offsetof(_state, _field),\
+.start= offsetof(_type, _next),  \
+}
+
 /* _f : field name
_f_n : num of elements field_name
_n : num of elements
diff --git a/include/qemu/queue.h b/include/qemu/queue.h
index 4764d93ea3..4d4554a7ce 100644
--- a/include/qemu/queue.h
+++ b/include/qemu/queue.h
@@ -501,4 +501,43 @@ union {
 \
 QTAILQ_RAW_TQH_CIRC(head)->tql_prev = QTAILQ_RAW_TQE_CIRC(elm, entry); 
 \
 } while (/*CONSTCOND*/0)
 
+#define QLIST_RAW_FIRST(head)  
\
+field_at_offset(head, 0, void *)
+
+#define QLIST_RAW_NEXT(elm, entry) 
\
+field_at_offset(elm, entry, void *)
+
+#define QLIST_RAW_PREVIOUS(elm, entry) 
\
+field_at_offset(elm, entry + sizeof(void *), void *)
+
+#define QLIST_RAW_FOREACH(elm, head, entry)
\
+for ((elm) = *QLIST_RAW_FIRST(head);   
\
+ (elm);
\
+ (elm) = *QLIST_RAW_NEXT(elm, entry))
+
+#define QLIST_RAW_INSERT_HEAD(head, elm, entry) do {   
\
+void *first = *QLIST_RAW_FIRST(head);  
\
+*QLIST_RAW_FIRST(head) = elm;  
\
+*QLIST_RAW_PREVIOUS(elm, entry) = QLIST_RAW_FIRST(head);   
\
+if (first) {   
\
+*QLIST_RAW_NEXT(elm, entry) = first;   
\
+*QLIST_RAW_PREVIOUS(first, entry) = QLIST_RAW_NEXT(elm, entry);
\
+} else {   
\
+*QLIST_RAW_NEXT(elm, entry) = NULL;
\
+}  
\
+} while (0)
+
+#define QLIST_RAW_REVERSE(head, elm, entry) do {   
\
+void *iter = *QLIST_RAW_FIRST(head), *prev = NULL, *next;  
\
+while (iter) { 
\
+next = *QLIST_RAW_NEXT(iter, entry);   
\
+*QLIST_RAW_PREVIOUS(iter, entry) = QLIST_RAW_NEXT(next, entry);
\
+*QLIST_RAW_NEXT(iter, entry) = prev;   
\
+prev = iter;   
\
+iter = next;   
\
+}   

[PULL 14/28] migration/ram: Yield periodically to the main loop

2020-01-10 Thread Juan Quintela
From: Yury Kotov 

Usually, incoming migration coroutine yields to the main loop
while its IO-channel is waiting for data to receive. But there is a case
when RAM migration and data receive have the same speed: VM with huge
zeroed RAM. In this case, IO-channel won't read and thus the main loop
is stuck and for instance, it doesn't respond to QMP commands.

For this case, yield periodically, but not too often, so as not to
affect the speed of migration.

Signed-off-by: Yury Kotov 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 migration/ram.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/migration/ram.c b/migration/ram.c
index 718a02a974..31d21b7f6b 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -4246,7 +4246,7 @@ static void colo_flush_ram_cache(void)
  */
 static int ram_load_precopy(QEMUFile *f)
 {
-int flags = 0, ret = 0, invalid_flags = 0, len = 0;
+int flags = 0, ret = 0, invalid_flags = 0, len = 0, i = 0;
 /* ADVISE is earlier, it shows the source has the postcopy capability on */
 bool postcopy_advised = postcopy_is_advised();
 if (!migrate_use_compression()) {
@@ -4258,6 +4258,17 @@ static int ram_load_precopy(QEMUFile *f)
 void *host = NULL;
 uint8_t ch;
 
+/*
+ * Yield periodically to let main loop run, but an iteration of
+ * the main loop is expensive, so do it each some iterations
+ */
+if ((i & 32767) == 0 && qemu_in_coroutine()) {
+aio_co_schedule(qemu_get_current_aio_context(),
+qemu_coroutine_self());
+qemu_coroutine_yield();
+}
+i++;
+
 addr = qemu_get_be64(f);
 flags = addr & ~TARGET_PAGE_MASK;
 addr &= TARGET_PAGE_MASK;
-- 
2.24.1




[PULL 11/28] misc: use QEMU_IS_ALIGNED

2020-01-10 Thread Juan Quintela
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Reviewed-by: Juan Quintela 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Stefan Berger 
Reviewed-by: Paolo Bonzini 
Signed-off-by: Juan Quintela 
---
 exec.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/exec.c b/exec.c
index d4b769d0d4..1feda49ca1 100644
--- a/exec.c
+++ b/exec.c
@@ -3895,7 +3895,7 @@ int ram_block_discard_range(RAMBlock *rb, uint64_t start, 
size_t length)
 
 uint8_t *host_startaddr = rb->host + start;
 
-if ((uintptr_t)host_startaddr & (rb->page_size - 1)) {
+if (!QEMU_PTR_IS_ALIGNED(host_startaddr, rb->page_size)) {
 error_report("ram_block_discard_range: Unaligned start address: %p",
  host_startaddr);
 goto err;
@@ -3903,7 +3903,7 @@ int ram_block_discard_range(RAMBlock *rb, uint64_t start, 
size_t length)
 
 if ((start + length) <= rb->used_length) {
 bool need_madvise, need_fallocate;
-if (length & (rb->page_size - 1)) {
+if (!QEMU_IS_ALIGNED(length, rb->page_size)) {
 error_report("ram_block_discard_range: Unaligned length: %zx",
  length);
 goto err;
-- 
2.24.1




[PULL 12/28] migration: add savevm_state_handler_remove()

2020-01-10 Thread Juan Quintela
From: Scott Cheloha 

Create a function to abstract common logic needed when removing a
SaveStateEntry element from the savevm_state.handlers queue.

For now we just remove the element.  Soon it will involve additional
cleanup.

Signed-off-by: Scott Cheloha 
Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 migration/savevm.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/migration/savevm.c b/migration/savevm.c
index 59efc1981d..30d980caa2 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -725,6 +725,11 @@ static void savevm_state_handler_insert(SaveStateEntry 
*nse)
 }
 }
 
+static void savevm_state_handler_remove(SaveStateEntry *se)
+{
+QTAILQ_REMOVE(_state.handlers, se, entry);
+}
+
 /* TODO: Individual devices generally have very little idea about the rest
of the system, so instance_id should be removed/replaced.
Meanwhile pass -1 as instance_id if you do not already have a clearly
@@ -777,7 +782,7 @@ void unregister_savevm(VMStateIf *obj, const char *idstr, 
void *opaque)
 
 QTAILQ_FOREACH_SAFE(se, _state.handlers, entry, new_se) {
 if (strcmp(se->idstr, id) == 0 && se->opaque == opaque) {
-QTAILQ_REMOVE(_state.handlers, se, entry);
+savevm_state_handler_remove(se);
 g_free(se->compat);
 g_free(se);
 }
@@ -841,7 +846,7 @@ void vmstate_unregister(VMStateIf *obj, const 
VMStateDescription *vmsd,
 
 QTAILQ_FOREACH_SAFE(se, _state.handlers, entry, new_se) {
 if (se->vmsd == vmsd && se->opaque == opaque) {
-QTAILQ_REMOVE(_state.handlers, se, entry);
+savevm_state_handler_remove(se);
 g_free(se->compat);
 g_free(se);
 }
-- 
2.24.1




[PULL 06/28] ram.c: remove unneeded labels

2020-01-10 Thread Juan Quintela
From: Daniel Henrique Barboza 

ram_save_queue_pages() has an 'err' label that can be replaced by
'return -1' instead.

Same thing with ram_discard_range(), and in this case we can also
get rid of the 'ret' variable and return either '-1' on error
or the result of ram_block_discard_range().

CC: Juan Quintela 
CC: Dr. David Alan Gilbert 
Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 migration/ram.c | 18 +-
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index 6e678dbd2e..733aee61e3 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -2459,7 +2459,7 @@ int ram_save_queue_pages(const char *rbname, ram_addr_t 
start, ram_addr_t len)
  * it's the 1st request.
  */
 error_report("ram_save_queue_pages no previous block");
-goto err;
+return -1;
 }
 } else {
 ramblock = qemu_ram_block_by_name(rbname);
@@ -2467,7 +2467,7 @@ int ram_save_queue_pages(const char *rbname, ram_addr_t 
start, ram_addr_t len)
 if (!ramblock) {
 /* We shouldn't be asked for a non-existent RAMBlock */
 error_report("ram_save_queue_pages no block '%s'", rbname);
-goto err;
+return -1;
 }
 rs->last_req_rb = ramblock;
 }
@@ -2476,7 +2476,7 @@ int ram_save_queue_pages(const char *rbname, ram_addr_t 
start, ram_addr_t len)
 error_report("%s request overrun start=" RAM_ADDR_FMT " len="
  RAM_ADDR_FMT " blocklen=" RAM_ADDR_FMT,
  __func__, start, len, ramblock->used_length);
-goto err;
+return -1;
 }
 
 struct RAMSrcPageRequest *new_entry =
@@ -2492,9 +2492,6 @@ int ram_save_queue_pages(const char *rbname, ram_addr_t 
start, ram_addr_t len)
 qemu_mutex_unlock(>src_page_req_mutex);
 
 return 0;
-
-err:
-return -1;
 }
 
 static bool save_page_use_compression(RAMState *rs)
@@ -3097,8 +3094,6 @@ int ram_postcopy_send_discard_bitmap(MigrationState *ms)
  */
 int ram_discard_range(const char *rbname, uint64_t start, size_t length)
 {
-int ret = -1;
-
 trace_ram_discard_range(rbname, start, length);
 
 RCU_READ_LOCK_GUARD();
@@ -3106,7 +3101,7 @@ int ram_discard_range(const char *rbname, uint64_t start, 
size_t length)
 
 if (!rb) {
 error_report("ram_discard_range: Failed to find block '%s'", rbname);
-goto err;
+return -1;
 }
 
 /*
@@ -3118,10 +3113,7 @@ int ram_discard_range(const char *rbname, uint64_t 
start, size_t length)
  length >> qemu_target_page_bits());
 }
 
-ret = ram_block_discard_range(rb, start, length);
-
-err:
-return ret;
+return ram_block_discard_range(rb, start, length);
 }
 
 /*
-- 
2.24.1




[PULL 13/28] migration: savevm_state_handler_insert: constant-time element insertion

2020-01-10 Thread Juan Quintela
From: Scott Cheloha 

savevm_state's SaveStateEntry TAILQ is a priority queue.  Priority
sorting is maintained by searching from head to tail for a suitable
insertion spot.  Insertion is thus an O(n) operation.

If we instead keep track of the head of each priority's subqueue
within that larger queue we can reduce this operation to O(1) time.

savevm_state_handler_remove() becomes slightly more complex to
accomodate these gains: we need to replace the head of a priority's
subqueue when removing it.

With O(1) insertion, booting VMs with many SaveStateEntry objects is
more plausible.  For example, a ppc64 VM with maxmem=8T has 4 such
objects to insert.

Signed-off-by: Scott Cheloha 
Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 migration/savevm.c | 26 +++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/migration/savevm.c b/migration/savevm.c
index 30d980caa2..e57686bca7 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -250,6 +250,7 @@ typedef struct SaveStateEntry {
 
 typedef struct SaveState {
 QTAILQ_HEAD(, SaveStateEntry) handlers;
+SaveStateEntry *handler_pri_head[MIG_PRI_MAX + 1];
 int global_section_id;
 uint32_t len;
 const char *name;
@@ -261,6 +262,7 @@ typedef struct SaveState {
 
 static SaveState savevm_state = {
 .handlers = QTAILQ_HEAD_INITIALIZER(savevm_state.handlers),
+.handler_pri_head = { [MIG_PRI_DEFAULT ... MIG_PRI_MAX] = NULL },
 .global_section_id = 0,
 };
 
@@ -709,24 +711,42 @@ static void savevm_state_handler_insert(SaveStateEntry 
*nse)
 {
 MigrationPriority priority = save_state_priority(nse);
 SaveStateEntry *se;
+int i;
 
 assert(priority <= MIG_PRI_MAX);
 
-QTAILQ_FOREACH(se, _state.handlers, entry) {
-if (save_state_priority(se) < priority) {
+for (i = priority - 1; i >= 0; i--) {
+se = savevm_state.handler_pri_head[i];
+if (se != NULL) {
+assert(save_state_priority(se) < priority);
 break;
 }
 }
 
-if (se) {
+if (i >= 0) {
 QTAILQ_INSERT_BEFORE(se, nse, entry);
 } else {
 QTAILQ_INSERT_TAIL(_state.handlers, nse, entry);
 }
+
+if (savevm_state.handler_pri_head[priority] == NULL) {
+savevm_state.handler_pri_head[priority] = nse;
+}
 }
 
 static void savevm_state_handler_remove(SaveStateEntry *se)
 {
+SaveStateEntry *next;
+MigrationPriority priority = save_state_priority(se);
+
+if (se == savevm_state.handler_pri_head[priority]) {
+next = QTAILQ_NEXT(se, entry);
+if (next != NULL && save_state_priority(next) == priority) {
+savevm_state.handler_pri_head[priority] = next;
+} else {
+savevm_state.handler_pri_head[priority] = NULL;
+}
+}
 QTAILQ_REMOVE(_state.handlers, se, entry);
 }
 
-- 
2.24.1




[PULL 07/28] migration: Rate limit inside host pages

2020-01-10 Thread Juan Quintela
From: "Dr. David Alan Gilbert" 

When using hugepages, rate limiting is necessary within each huge
page, since a 1G huge page can take a significant time to send, so
you end up with bursty behaviour.

Fixes: 4c011c37ecb3 ("postcopy: Send whole huge pages")
Reported-by: Lin Ma 
Signed-off-by: Dr. David Alan Gilbert 
Reviewed-by: Juan Quintela 
Reviewed-by: Peter Xu 
Signed-off-by: Juan Quintela 
---
 migration/migration.c  | 57 --
 migration/migration.h  |  1 +
 migration/ram.c|  2 ++
 migration/trace-events |  4 +--
 4 files changed, 37 insertions(+), 27 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index 354ad072fa..27500d09a9 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -3224,6 +3224,37 @@ void migration_consume_urgent_request(void)
 qemu_sem_wait(_get_current()->rate_limit_sem);
 }
 
+/* Returns true if the rate limiting was broken by an urgent request */
+bool migration_rate_limit(void)
+{
+int64_t now = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+MigrationState *s = migrate_get_current();
+
+bool urgent = false;
+migration_update_counters(s, now);
+if (qemu_file_rate_limit(s->to_dst_file)) {
+/*
+ * Wait for a delay to do rate limiting OR
+ * something urgent to post the semaphore.
+ */
+int ms = s->iteration_start_time + BUFFER_DELAY - now;
+trace_migration_rate_limit_pre(ms);
+if (qemu_sem_timedwait(>rate_limit_sem, ms) == 0) {
+/*
+ * We were woken by one or more urgent things but
+ * the timedwait will have consumed one of them.
+ * The service routine for the urgent wake will dec
+ * the semaphore itself for each item it consumes,
+ * so add this one we just eat back.
+ */
+qemu_sem_post(>rate_limit_sem);
+urgent = true;
+}
+trace_migration_rate_limit_post(urgent);
+}
+return urgent;
+}
+
 /*
  * Master migration thread on the source VM.
  * It drives the migration and pumps the data down the outgoing channel.
@@ -3290,8 +3321,6 @@ static void *migration_thread(void *opaque)
 trace_migration_thread_setup_complete();
 
 while (migration_is_active(s)) {
-int64_t current_time;
-
 if (urgent || !qemu_file_rate_limit(s->to_dst_file)) {
 MigIterateState iter_state = migration_iteration_run(s);
 if (iter_state == MIG_ITERATE_SKIP) {
@@ -3318,29 +3347,7 @@ static void *migration_thread(void *opaque)
 update_iteration_initial_status(s);
 }
 
-current_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
-
-migration_update_counters(s, current_time);
-
-urgent = false;
-if (qemu_file_rate_limit(s->to_dst_file)) {
-/* Wait for a delay to do rate limiting OR
- * something urgent to post the semaphore.
- */
-int ms = s->iteration_start_time + BUFFER_DELAY - current_time;
-trace_migration_thread_ratelimit_pre(ms);
-if (qemu_sem_timedwait(>rate_limit_sem, ms) == 0) {
-/* We were worken by one or more urgent things but
- * the timedwait will have consumed one of them.
- * The service routine for the urgent wake will dec
- * the semaphore itself for each item it consumes,
- * so add this one we just eat back.
- */
-qemu_sem_post(>rate_limit_sem);
-urgent = true;
-}
-trace_migration_thread_ratelimit_post(urgent);
-}
+urgent = migration_rate_limit();
 }
 
 trace_migration_thread_after_loop();
diff --git a/migration/migration.h b/migration/migration.h
index 79b3dda146..aa9ff6f27b 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -341,5 +341,6 @@ int foreach_not_ignored_block(RAMBlockIterFunc func, void 
*opaque);
 
 void migration_make_urgent_request(void);
 void migration_consume_urgent_request(void);
+bool migration_rate_limit(void);
 
 #endif
diff --git a/migration/ram.c b/migration/ram.c
index 733aee61e3..718a02a974 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -2639,6 +2639,8 @@ static int ram_save_host_page(RAMState *rs, 
PageSearchStatus *pss,
 
 pages += tmppages;
 pss->page++;
+/* Allow rate limiting to happen in the middle of huge pages */
+migration_rate_limit();
 } while ((pss->page & (pagesize_bits - 1)) &&
  offset_in_ramblock(pss->block, pss->page << TARGET_PAGE_BITS));
 
diff --git a/migration/trace-events b/migration/trace-events
index 6dee7b5389..2f9129e213 100644
--- a/migration/trace-events
+++ b/migration/trace-events
@@ -138,12 +138,12 @@ migrate_send_rp_recv_bitmap(char *name, int64_t size) 
"block '%s' size 0x%"PRIi6
 migration_completion_file_err(void) ""
 

[PULL 02/28] migration: Make sure that we don't call write() in case of error

2020-01-10 Thread Juan Quintela
If we are exiting due to an error/finish/ Just don't try to even
touch the channel with one IO operation.

Signed-off-by: Juan Quintela 
Reviewed-by: Dr. David Alan Gilbert 
---
 migration/ram.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/migration/ram.c b/migration/ram.c
index 96feb4062c..6e678dbd2e 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -900,6 +900,12 @@ struct {
 uint64_t packet_num;
 /* send channels ready */
 QemuSemaphore channels_ready;
+/*
+ * Have we already run terminate threads.  There is a race when it
+ * happens that we got one error while we are exiting.
+ * We will use atomic operations.  Only valid values are 0 and 1.
+ */
+int exiting;
 } *multifd_send_state;
 
 /*
@@ -928,6 +934,10 @@ static int multifd_send_pages(RAMState *rs)
 MultiFDPages_t *pages = multifd_send_state->pages;
 uint64_t transferred;
 
+if (atomic_read(_send_state->exiting)) {
+return -1;
+}
+
 qemu_sem_wait(_send_state->channels_ready);
 for (i = next_channel;; i = (i + 1) % migrate_multifd_channels()) {
 p = _send_state->params[i];
@@ -1009,6 +1019,16 @@ static void multifd_send_terminate_threads(Error *err)
 }
 }
 
+/*
+ * We don't want to exit each threads twice.  Depending on where
+ * we get the error, or if there are two independent errors in two
+ * threads at the same time, we can end calling this function
+ * twice.
+ */
+if (atomic_xchg(_send_state->exiting, 1)) {
+return;
+}
+
 for (i = 0; i < migrate_multifd_channels(); i++) {
 MultiFDSendParams *p = _send_state->params[i];
 
@@ -1118,6 +1138,10 @@ static void *multifd_send_thread(void *opaque)
 
 while (true) {
 qemu_sem_wait(>sem);
+
+if (atomic_read(_send_state->exiting)) {
+break;
+}
 qemu_mutex_lock(>mutex);
 
 if (p->pending_job) {
@@ -1224,6 +1248,7 @@ int multifd_save_setup(void)
 multifd_send_state->params = g_new0(MultiFDSendParams, thread_count);
 multifd_send_state->pages = multifd_pages_init(page_count);
 qemu_sem_init(_send_state->channels_ready, 0);
+atomic_set(_send_state->exiting, 0);
 
 for (i = 0; i < thread_count; i++) {
 MultiFDSendParams *p = _send_state->params[i];
-- 
2.24.1




[PULL 03/28] migration-test: introduce functions to handle string parameters

2020-01-10 Thread Juan Quintela
Signed-off-by: Juan Quintela 
Reviewed-by: Dr. David Alan Gilbert 
---
 tests/migration-test.c | 37 +
 1 file changed, 37 insertions(+)

diff --git a/tests/migration-test.c b/tests/migration-test.c
index fb70214f44..b0580dd541 100644
--- a/tests/migration-test.c
+++ b/tests/migration-test.c
@@ -356,6 +356,43 @@ static void migrate_set_parameter_int(QTestState *who, 
const char *parameter,
 migrate_check_parameter_int(who, parameter, value);
 }
 
+static char *migrate_get_parameter_str(QTestState *who,
+   const char *parameter)
+{
+QDict *rsp;
+char *result;
+
+rsp = wait_command(who, "{ 'execute': 'query-migrate-parameters' }");
+result = g_strdup(qdict_get_str(rsp, parameter));
+qobject_unref(rsp);
+return result;
+}
+
+static void migrate_check_parameter_str(QTestState *who, const char *parameter,
+const char *value)
+{
+char *result;
+
+result = migrate_get_parameter_str(who, parameter);
+g_assert_cmpstr(result, ==, value);
+g_free(result);
+}
+
+__attribute__((unused))
+static void migrate_set_parameter_str(QTestState *who, const char *parameter,
+  const char *value)
+{
+QDict *rsp;
+
+rsp = qtest_qmp(who,
+"{ 'execute': 'migrate-set-parameters',"
+"'arguments': { %s: %s } }",
+parameter, value);
+g_assert(qdict_haskey(rsp, "return"));
+qobject_unref(rsp);
+migrate_check_parameter_str(who, parameter, value);
+}
+
 static void migrate_pause(QTestState *who)
 {
 QDict *rsp;
-- 
2.24.1




[PULL 05/28] runstate: ignore finishmigrate -> prelaunch transition

2020-01-10 Thread Juan Quintela
From: Laurent Vivier 

Commit 1bd71dce4bf2 tries to prevent a finishmigrate -> prelaunch
transition by exiting at the beginning of the main_loop_should_exit()
function if the state is already finishmigrate.

As the finishmigrate state is set in the migration thread it can
happen concurrently to the function. The migration thread and the
function are normally protected by the iothread mutex and thus the
state should no evolve between the start of the function and its end.

Unfortunately during the function life the lock is released by
pause_all_vcpus() just before the point we need to be sure we are
not in finishmigrate state and if the migration thread is waiting
for the lock it will take the opportunity to change the state
to finishmigrate.

The only way to be sure we are not in the finishmigrate state when
we need is to check the state after the pause_all_vcpus() function.

Fixes: 1bd71dce4bf2 ("runstate: ignore exit request in finish migrate state")
Signed-off-by: Laurent Vivier 
Signed-off-by: Juan Quintela 
---
 vl.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/vl.c b/vl.c
index b211921258..5401d6e440 100644
--- a/vl.c
+++ b/vl.c
@@ -1604,9 +1604,6 @@ static bool main_loop_should_exit(void)
 RunState r;
 ShutdownCause request;
 
-if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
-return false;
-}
 if (preconfig_exit_requested) {
 if (runstate_check(RUN_STATE_PRECONFIG)) {
 runstate_set(RUN_STATE_PRELAUNCH);
@@ -1635,8 +1632,13 @@ static bool main_loop_should_exit(void)
 pause_all_vcpus();
 qemu_system_reset(request);
 resume_all_vcpus();
+/*
+ * runstate can change in pause_all_vcpus()
+ * as iothread mutex is unlocked
+ */
 if (!runstate_check(RUN_STATE_RUNNING) &&
-!runstate_check(RUN_STATE_INMIGRATE)) {
+!runstate_check(RUN_STATE_INMIGRATE) &&
+!runstate_check(RUN_STATE_FINISH_MIGRATE)) {
 runstate_set(RUN_STATE_PRELAUNCH);
 }
 }
-- 
2.24.1




[PULL 04/28] migration-test: ppc64: fix FORTH test program

2020-01-10 Thread Juan Quintela
From: Laurent Vivier 

Commit e51e711b1bef has moved the initialization of start_address and
end_address after the definition of the command line argument,
where the nvramrc is initialized, and thus the loop is between 0 and 0
rather than 1 MiB and 100 MiB.

It doesn't affect the result of the test if all the tests are run in
sequence because the two first tests don't run the loop, so the
values are correctly initialized when we actually need them.

But it hangs when we ask to run only one test, for instance:

QTEST_QEMU_BINARY=ppc64-softmmu/qemu-system-ppc64 \
tests/migration-test -m=quick -p /ppc64/migration/validate_uuid_error

Fixes: e51e711b1bef ("tests/migration: Add migration-test header file")
Cc: w...@redhat.com
Signed-off-by: Laurent Vivier 
Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Juan Quintela 
Reviewed-by: David Gibson 
Signed-off-by: Juan Quintela 
---
 tests/migration-test.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/migration-test.c b/tests/migration-test.c
index b0580dd541..26e2e77289 100644
--- a/tests/migration-test.c
+++ b/tests/migration-test.c
@@ -517,14 +517,14 @@ static int test_migrate_start(QTestState **from, 
QTestState **to,
 } else if (strcmp(arch, "ppc64") == 0) {
 machine_opts = "vsmt=8";
 memory_size = "256M";
+start_address = PPC_TEST_MEM_START;
+end_address = PPC_TEST_MEM_END;
 arch_source = g_strdup_printf("-nodefaults "
   "-prom-env 'use-nvramrc?=true' -prom-env 
"
   "'nvramrc=hex .\" _\" begin %x %x "
   "do i c@ 1 + i c! 1000 +loop .\" B\" 0 "
   "until'", end_address, start_address);
 arch_target = g_strdup("");
-start_address = PPC_TEST_MEM_START;
-end_address = PPC_TEST_MEM_END;
 } else if (strcmp(arch, "aarch64") == 0) {
 init_bootfile(bootpath, aarch64_kernel, sizeof(aarch64_kernel));
 machine_opts = "virt,gic-version=max";
-- 
2.24.1




[PULL 01/28] migration-test: Add migration multifd test

2020-01-10 Thread Juan Quintela
We set multifd-channels.

Signed-off-by: Juan Quintela 
Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Thomas Huth 
Tested-by: Wei Yang 
---
 tests/migration-test.c | 56 ++
 1 file changed, 56 insertions(+)

diff --git a/tests/migration-test.c b/tests/migration-test.c
index 53afec4395..fb70214f44 100644
--- a/tests/migration-test.c
+++ b/tests/migration-test.c
@@ -1202,6 +1202,61 @@ static void test_migrate_auto_converge(void)
 test_migrate_end(from, to, true);
 }
 
+static void test_multifd_tcp(void)
+{
+MigrateStart *args = migrate_start_new();
+QTestState *from, *to;
+QDict *rsp;
+char *uri;
+
+if (test_migrate_start(, , "defer", args)) {
+return;
+}
+
+/*
+ * We want to pick a speed slow enough that the test completes
+ * quickly, but that it doesn't complete precopy even on a slow
+ * machine, so also set the downtime.
+ */
+/* 1 ms should make it not converge*/
+migrate_set_parameter_int(from, "downtime-limit", 1);
+/* 1GB/s */
+migrate_set_parameter_int(from, "max-bandwidth", 10);
+
+migrate_set_parameter_int(from, "multifd-channels", 16);
+migrate_set_parameter_int(to, "multifd-channels", 16);
+
+migrate_set_capability(from, "multifd", "true");
+migrate_set_capability(to, "multifd", "true");
+
+/* Start incoming migration from the 1st socket */
+rsp = wait_command(to, "{ 'execute': 'migrate-incoming',"
+   "  'arguments': { 'uri': 'tcp:127.0.0.1:0' }}");
+qobject_unref(rsp);
+
+/* Wait for the first serial output from the source */
+wait_for_serial("src_serial");
+
+uri = migrate_get_socket_address(to, "socket-address");
+
+migrate_qmp(from, uri, "{}");
+
+wait_for_migration_pass(from);
+
+/* 300ms it should converge */
+migrate_set_parameter_int(from, "downtime-limit", 300);
+
+if (!got_stop) {
+qtest_qmp_eventwait(from, "STOP");
+}
+qtest_qmp_eventwait(to, "RESUME");
+
+wait_for_serial("dest_serial");
+wait_for_migration_complete(from);
+test_migrate_end(from, to, true);
+free(uri);
+}
+
 int main(int argc, char **argv)
 {
 char template[] = "/tmp/migration-test-XX";
@@ -1266,6 +1321,7 @@ int main(int argc, char **argv)
test_validate_uuid_dst_not_set);
 
 qtest_add_func("/migration/auto_converge", test_migrate_auto_converge);
+qtest_add_func("/migration/multifd/tcp", test_multifd_tcp);
 
 ret = g_test_run();
 
-- 
2.24.1




[PULL 00/28] Migration pull patches

2020-01-10 Thread Juan Quintela
The following changes since commit f38a71b01f839c7b65ea73ddd507903cb9489ed6:

  Merge remote-tracking branch 
'remotes/stsquad/tags/pull-testing-and-semihosting-090120-2' into staging 
(2020-01-10 13:19:34 +)

are available in the Git repository at:

  https://github.com/juanquintela/qemu.git tags/migration-pull-pull-request

for you to fetch changes up to cc708d2411d3ed2ab4a428c996b778c7c7a47a04:

  apic: Use 32bit APIC ID for migration instance ID (2020-01-10 18:19:18 +0100)


Migration pull request

- several multifd mixes (jiahui, me)
- rate limit host pages (david)
- remove unneeded labels (daniel)
- several multifd fixes (wei)
- improve handler insert (scott)
- qlist migration (eric)
- power fixes (laurent)
- migration improvemests (yury)
- lots of fixes (wei)



Alexey Romko (1):
  Bug #1829242 correction.

Daniel Henrique Barboza (1):
  ram.c: remove unneeded labels

Dr. David Alan Gilbert (1):
  migration: Rate limit inside host pages

Eric Auger (1):
  migration: Support QLIST migration

Fangrui Song (1):
  migration: Fix incorrect integer->float conversion caught by clang

Jiahui Cen (2):
  migration/multifd: fix nullptr access in terminating multifd threads
  migration/multifd: fix destroyed mutex access in terminating multifd
threads

Juan Quintela (3):
  migration-test: Add migration multifd test
  migration: Make sure that we don't call write() in case of error
  migration-test: introduce functions to handle string parameters

Laurent Vivier (2):
  migration-test: ppc64: fix FORTH test program
  runstate: ignore finishmigrate -> prelaunch transition

Marc-André Lureau (1):
  misc: use QEMU_IS_ALIGNED

Peter Xu (3):
  migration: Define VMSTATE_INSTANCE_ID_ANY
  migration: Change SaveStateEntry.instance_id into uint32_t
  apic: Use 32bit APIC ID for migration instance ID

Scott Cheloha (2):
  migration: add savevm_state_handler_remove()
  migration: savevm_state_handler_insert: constant-time element
insertion

Wei Yang (8):
  migration/postcopy: reduce memset when it is zero page and
matches_target_page_size
  migration/postcopy: wait for decompress thread in precopy
  migration/postcopy: count target page number to decide the
place_needed
  migration/postcopy: set all_zero to true on the first target page
  migration/postcopy: enable random order target page arrival
  migration/postcopy: enable compress during postcopy
  migration/multifd: clean pages after filling packet
  migration/multifd: not use multifd during postcopy

Yury Kotov (2):
  migration: Fix the re-run check of the migrate-incoming command
  migration/ram: Yield periodically to the main loop

 backends/dbus-vmstate.c  |   3 +-
 exec.c   |   4 +-
 hw/arm/stellaris.c   |   2 +-
 hw/core/qdev.c   |   3 +-
 hw/display/ads7846.c |   2 +-
 hw/i2c/core.c|   2 +-
 hw/input/stellaris_input.c   |   3 +-
 hw/intc/apic_common.c|   7 +-
 hw/misc/max111x.c|   3 +-
 hw/net/eepro100.c|   3 +-
 hw/pci/pci.c |   2 +-
 hw/ppc/spapr.c   |   2 +-
 hw/timer/arm_timer.c |   2 +-
 hw/tpm/tpm_emulator.c|   3 +-
 include/migration/register.h |   2 +-
 include/migration/vmstate.h  |  25 -
 include/qemu/queue.h |  39 
 migration/migration.c|  72 +++---
 migration/migration.h|   1 +
 migration/ram.c  | 181 ++-
 migration/savevm.c   |  61 
 migration/trace-events   |   9 +-
 migration/vmstate-types.c|  70 ++
 stubs/vmstate.c  |   2 +-
 tests/migration-test.c   |  97 ++-
 tests/test-vmstate.c | 170 
 vl.c |  10 +-
 27 files changed, 652 insertions(+), 128 deletions(-)

-- 
2.24.1




Re: [PULL 00/26] ppc-for-5.0 queue 20200108

2020-01-10 Thread Peter Maydell
On Wed, 8 Jan 2020 at 05:23, David Gibson  wrote:
>
> The following changes since commit 035eed4c0d257c905a556fa0f4865a0c077b4e7f:
>
>   Merge remote-tracking branch 
> 'remotes/vivier/tags/q800-for-5.0-pull-request' into staging (2020-01-07 
> 17:08:21 +)
>
> are available in the Git repository at:
>
>   git://github.com/dgibson/qemu.git tags/ppc-for-5.0-20200108
>
> for you to fetch changes up to fc2527fb024abf92719952c939d751739455bd6b:
>
>   ppc/pnv: fix check on return value of blk_getlength() (2020-01-08 12:01:14 
> +1100)
>
> 
> ppc patch queue 2020-01-08
>
> Here's another pull request for qemu-5.0 of ppc related changes.
> Highlights are:
>  * First parts of support for POWER Secure VMs
>  * Rework to clean up how we pass context information to the various
>components of the pnv machine (reduces usage of qdev_get_machine())
>  * Assorted cleanups and bugfixes
>


Applied, thanks.

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

-- PMM



[PATCH] block: Use a GString in bdrv_perm_names()

2020-01-10 Thread Alberto Garcia
This is a bit more efficient than having to allocate and free memory
for each new permission.

The default size (30) is enough for "consistent read, write, resize".

Signed-off-by: Alberto Garcia 
---
 block.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/block.c b/block.c
index 1b6f7c86e8..2bc9e58392 100644
--- a/block.c
+++ b/block.c
@@ -1976,18 +1976,19 @@ char *bdrv_perm_names(uint64_t perm)
 { 0, NULL }
 };
 
-char *result = g_strdup("");
+GString *result = g_string_sized_new(30);
 struct perm_name *p;
 
 for (p = permissions; p->name; p++) {
 if (perm & p->perm) {
-char *old = result;
-result = g_strdup_printf("%s%s%s", old, *old ? ", " : "", p->name);
-g_free(old);
+if (result->len > 0) {
+g_string_append(result, ", ");
+}
+g_string_append(result, p->name);
 }
 }
 
-return result;
+return g_string_free(result, FALSE);
 }
 
 /*
-- 
2.20.1




Re: [PATCH 66/86] ppc:ppc440_bamboo/sam460ex: drop RAM size fixup

2020-01-10 Thread Igor Mammedov
On Thu, 2 Jan 2020 16:52:50 +0100 (CET)
BALATON Zoltan  wrote:

> On Thu, 2 Jan 2020, Igor Mammedov wrote:
> > On Wed, 1 Jan 2020 12:54:37 +0100 (CET)
> > BALATON Zoltan  wrote:  
> >> On Tue, 31 Dec 2019, Igor Mammedov wrote:  
> >>> If user provided non-sense RAM size, board will complain and
> >>> continue running with max RAM size supported.
> >>> Also RAM is going to be allocated by generic code, so it won't be
> >>> possible for board to fix things up for user.
> >>>
> >>> Make it error message and exit to force user fix CLI,
> >>> instead of accepting non-sense CLI values.
> >>>
> >>> Signed-off-by: Igor Mammedov 
> >>> ---
> >>> include/hw/ppc/ppc4xx.h |  9 -
> >>> hw/ppc/ppc440_bamboo.c  | 11 ---
> >>> hw/ppc/ppc4xx_devs.c| 26 --
> >>> hw/ppc/sam460ex.c   |  5 ++---
> >>> 4 files changed, 26 insertions(+), 25 deletions(-)
> >>>
> >>> diff --git a/include/hw/ppc/ppc4xx.h b/include/hw/ppc/ppc4xx.h
> >>> index 7d82259..1a28127 100644
> >>> --- a/include/hw/ppc/ppc4xx.h
> >>> +++ b/include/hw/ppc/ppc4xx.h
> >>> @@ -42,11 +42,10 @@ enum {
> >>> qemu_irq *ppcuic_init (CPUPPCState *env, qemu_irq *irqs,
> >>>uint32_t dcr_base, int has_ssr, int has_vr);
> >>>
> >>> -ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks,
> >>> -   MemoryRegion ram_memories[],
> >>> -   hwaddr ram_bases[],
> >>> -   hwaddr ram_sizes[],
> >>> -   const ram_addr_t sdram_bank_sizes[]);
> >>> +void ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks,
> >>> + MemoryRegion ram_memories[],
> >>> + hwaddr ram_bases[], hwaddr ram_sizes[],
> >>> + const ram_addr_t sdram_bank_sizes[]);  
> >>
> >> With this change this function does not adjust ram size any more so it may
> >> need to be renamed, e.g. ppc4xx_sdram_banks or something else.
> >>
> >> A better patch title may be
> >>
> >> ppc/{ppc440_bamboo,sam460x}: drop RAM size fixup
> >>
> >> (or without curly braces at your preference).  
> > I'll rename and use this subj as you suggest on v2.
> >  
> >> This is inconvenient for the user because it worked whatever number
> >> they've given but now they have to do the math. So it suggests that what
> >> you're replacing this with may not support all the existing use cases. If
> >> that can't be fixed to allow checking and changing ram size (maybe via a
> >> callback in board code similar to above adjust function returning adjusted
> >> size) it may be OK to drop this convenience for the sake of cleaning up
> >> code elsewhere.  
> >
> > There were few boards that did fix up and in all cases it was to cover up
> > invalid CLI input.
> > Creating callback for fixing user mistake doesn't seems to me justified,
> > I'd much prefer to have a hard error and consistent behavior across all
> > the boards versus being lax on error checking.
> >
> > [...]
> >
> >  
> >>> @@ -699,10 +698,19 @@ ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, 
> >>> int nr_banks,
> >>> }
> >>> }
> >>>
> >>> -ram_size -= size_left;
> >>> if (size_left) {
> >>> -error_report("Truncating memory to %" PRId64 " MiB to fit SDRAM"
> >>> - " controller limits", ram_size / MiB);
> >>> +char *s = g_strdup("");
> >>> +for (i = 0; sdram_bank_sizes[i]; i++) {
> >>> +char *t = g_strdup_printf("%s%" PRIi64 "%s", s, 
> >>> sdram_bank_sizes[i],
> >>> +  sdram_bank_sizes[i + 1] ? " ," : 
> >>> "");
> >>> +g_free(s);
> >>> +s = t;
> >>> +}
> >>> +error_report("Invalid RAM size, unable to fit all RAM into RAM 
> >>> banks"
> >>> + " (unassigned RAM: %" PRIi64 ")",  size_left);
> >>> +error_report("Supported: %d banks and sizes/bank: %s", nr_banks, 
> >>> s);  
> >
> > Do you have any suggestions how to make error message better?
> > (maybe do calculation here and dump all valid -m variants instead of 
> > "#bank,size/bank")  
> 
> Listing the valid values would certainly help users who don't know what 
> the constraints of the SoC or SPD ROMs are (which I think most users don't 
> have a clue about and we should not expect them to know).
I gave it a shot, in case of bamboo board it ends up with huge ~80 entries list,

Perhaps it might be better to avoid combinatorial explosion and keep managable

   error_report("Supported: %d banks and sizes/bank: %s", nr_banks, s);
   error_report("Invalid RAM size, unable to fit all RAM into RAM banks"
" (unassigned RAM: %" PRIi64 ")",  size_left);

   maybe also print relative to user provided value, nearest valid "above" and 
"below" sizes,
   instead of remainder.


[...]
> 
> Regards,
> BALATON Zoltan
> 




Re: [PATCH] virtio: Prevent double swap due to target pre 1.0 VirtIO

2020-01-10 Thread André Silva
> Unrelated, -enable-kvm isn't needed since...

Thanks.

> Could you try your patch against master with if=virtio and the
> -global above ?

There you go! I got the same error as you!
This looks like the only case that makes slof complain. If I use
virtio-blk without the -global option slof works fine.
Virtio-net (with if=scsi) and Virtio-scsi plus my patch plus the
-global option work fine too, no slof error.

Thanks Greg, I will investigate this virtio-blk side in qemu/slof on
how to make it work with the patch.

andré

On Fri, Jan 10, 2020 at 11:50 AM Greg Kurz  wrote:
>
> On Fri, 10 Jan 2020 09:00:50 -0300
> André Silva  wrote:
>
> > > What are the symptoms without your patch ? What's the QEMU version ?
> >
> > If using virtio for networking, guest vtnet0 interface appears with
> > 'status: no carrier'. Applying the patch the interface appears as
> > 'status: active' and works normally.
> > I tested with branches stable-4.1 and master.
> >
> > > Do you hit the issue with upstream QEMU ?
> >
> > No, I tested it with master and got the same fw as you, 'FW Version =
> > git-9546892a80d5a4c7' and had no problems...
> > Not sure if there are some parameter to quemu that may your side work,
> > but I'm invoking qemu like this:
> >
> > $ sudo ./qemu/build/release/ppc64-softmmu/qemu-system-ppc64 -drive
> > file=disc1.qcow2,if=scsi,format=qcow2 -enable-kvm -machine
>
> Hmm if I have to pass if=virtio to end up with a virtio-blk device.
> Unrelated, -enable-kvm isn't needed since...
>
> > pseries,accel=kvm,cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken,cap-hpt-max-page-size=16M
>
> ... accel=kvm is passed to the machine.
>
> > -mem-prealloc -mem-path /dev/hugepages -vnc :74 -nographic -vga none
> > -smp 20 -m 4G -net tap -netdev tap,id=n1 -device
> > virtio-net-pci,netdev=n1
> >
>
> I enforce the use of legacy virtio by adding:
>
> -global virtio-pci.disable-modern=on
>
> Could you try your patch against master with if=virtio and the
> -global above ?
>
> > Thanks,
> > andré
> >
> > On Fri, Jan 10, 2020 at 5:55 AM Greg Kurz  wrote:
> > >
> > > On Thu, 9 Jan 2020 18:18:57 -0300
> > > André Silva  wrote:
> > >
> > > > Hi Greg,
> > > >
> > >
> > > Hi André,
> > >
> > > > Thanks for the commit info.
> > > > But I'm testing in this scenario, that is, a ppc64le host with a ppc64
> > > > BE guest, and without my patch I can't get virtio to work. The patch
> > >
> > > What are the symptoms without your patch ? What's the QEMU version ?
> > >
> > > > makes virtio 0.95 (legacy) net, scsi, blk work. I don't get the
> > > > firmware error. I also tested with a ppc64le guest and had no problems
> > > > either. Maybe we have different firmware versions?
> > > >
> > > > My firmware output:
> > > >
> > > > SLOF 
> > > > **
> > > > QEMU Starting
> > > >  Build Date = Jul  3 2019 12:26:14
> > > >  FW Version = git-ba1ab360eebe6338
> > >
> > > I'm using the latest SLOF from the QEMU tree (pc-bios/slof.bin):
> > >
> > > SLOF 
> > > **
> > > QEMU Starting
> > >  Build Date = Dec 17 2019 11:31:13
> > >  FW Version = git-9546892a80d5a4c7
> > >
> > > Do you hit the issue with upstream QEMU ?
> > >
> > > >  Press "s" to enter Open Firmware.
> > > >
> > > > Populating /vdevice methods
> > > > Populating /vdevice/vty@7100
> > > > Populating /vdevice/nvram@7101
> > > > Populating /vdevice/v-scsi@7102
> > > >SCSI: Looking for devices
> > > >   8200 CD-ROM   : "QEMU QEMU CD-ROM  2.5+"
> > > > Populating /pci@8002000
> > > >  00  (D) : 1af4 1000virtio [ net ]
> > > >  00 0800 (D) : 1af4 1001virtio [ block ]
> > > > No NVRAM common partition, re-initializing...
> > > > Scanning USB
> > > > Using default console: /vdevice/vty@7100
> > > >
> > > >   Welcome to Open Firmware
> > > >
> > > >   Copyright (c) 2004, 2017 IBM Corporation All rights reserved.
> > > >   This program and the accompanying materials are made available
> > > >   under the terms of the BSD License available at
> > > >   http://www.opensource.org/licenses/bsd-license.php
> > > >
> > > >
> > > > Trying to load:  from: /pci@8002000/scsi@1 ...   Successfully 
> > > > loaded
> > > >
> > > > >> FreeBSD/powerpc Open Firmware boot block
> > > >Boot path:   /pci@8002000/scsi@1
> > > >Boot loader: /boot/loader
> > > >Boot volume:   /pci@8002000/scsi@1:2
> > > > Consoles: Open Firmware console
> > > >
> > > > FreeBSD/powerpc64 Open Firmware loader, Revision 0.1
> > > > (Mon Nov 11 22:33:43 -02 2019 jenkins@FreeBSD_x86)
> > > > Memory: 4194304KB
> > > > Booted from: /pci@8002000/scsi@1
> > > >
> > > > Loading /boot/defaults/loader.conf
> > > > /boot/kernel/kernel data=0x129f658+0x4aaa88 
> > > > syms=[0x8+0x105120+0x8+0x125429]
> > > > ...
> > > >
> > > > Until now, I was able to test the patch 

Re: [PULL 0/3] capstone update

2020-01-10 Thread Peter Maydell
On Fri, 10 Jan 2020 at 16:07, Peter Maydell  wrote:
>
> On Wed, 8 Jan 2020 at 04:23, Richard Henderson
>  wrote:
> >
> > The following changes since commit 035eed4c0d257c905a556fa0f4865a0c077b4e7f:
> >
> >   Merge remote-tracking branch 
> > 'remotes/vivier/tags/q800-for-5.0-pull-request' into staging (2020-01-07 
> > 17:08:21 +)
> >
> > are available in the Git repository at:
> >
> >   https://github.com/rth7680/qemu.git tags/pull-cap-20200108
> >
> > for you to fetch changes up to 7cc3836eac04a3e358b2496fbca704b3ee5197ae:
> >
> >   capstone: Add skipdata hook for s390x (2020-01-08 14:53:54 +1100)
> >
> > 
> > Update capstone to next
> >
> > 
> > Richard Henderson (3):
> >   capstone: Update to next
> >   capstone: Enable disassembly for s390x
> >   capstone: Add skipdata hook for s390x
>
> Build failures:
>
>   CC  aarch64-linux-user/disas.o
> In file included from
> /home/ubuntu/qemu/capstone/include/capstone/capstone.h:302:0,
>  from /home/ubuntu/qemu/include/disas/capstone.h:6,
>  from /home/ubuntu/qemu/disas.c:9:
> /home/ubuntu/qemu/capstone/include/capstone/riscv.h:16:10: fatal
> error: capstone/platform.h: No such file or directory
>  #include "capstone/platform.h"
>   ^
> compilation terminated.
>
> (same on most hosts)
>
> aarch64 host had this complaint instead:
>
> /home/pm/qemu/disas.c:187:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or
> ‘__attribute__’ before ‘cap_skipdata_s390x_cb’
>  cap_skipdata_s390x_cb(const uint8_t *code, size_t code_size,
>  ^
> /home/pm/qemu/disas.c:211:17: error: ‘cap_skipdata_s390x_cb’
> undeclared here (not in a function); did you mean
> ‘cap_skipdata_s390x’?
>  .callback = cap_skipdata_s390x_cb
>  ^
>  cap_skipdata_s390x

...and applying this merge also did something that broke the
build directories such that rolling back to before the merge
to current trunk then failed to build with errors about
missing 'capstone.h'. I had to blow away the build trees and
recreate them.

thanks
-- PMM



Re: [PATCH 0/4] buildsys: Build quicker (mostly tools and linux-user)

2020-01-10 Thread Philippe Mathieu-Daudé

On 1/10/20 3:03 PM, Laurent Vivier wrote:

Le 10/01/2020 à 10:17, Philippe Mathieu-Daudé a écrit :

Le ven. 10 janv. 2020 09:36, Laurent Vivier mailto:laur...@vivier.eu>> a écrit :

 Le 09/01/2020 à 16:39, Philippe Mathieu-Daudé a écrit :
 > In some configuration (linux-user, tools) we can ignore building
 > various objects (and the libfdt).
 >
 > Philippe Mathieu-Daudé (4):
 >   configure: Do not build libfdt is not required
 >   Makefile: Clarify all the codebase requires qom/ objects
 >   Makefile: Restrict system emulation and tools objects
 >   Makefile: Remove unhelpful comment
 >
 >  configure     |  2 ++
 >  Makefile.objs | 31 ++-
 >  2 files changed, 12 insertions(+), 21 deletions(-)
 >

 Did you test this with all the combinations of --[enable|disable]-tools,
 --[enable|disable]-user and --[enable|disable]-system


I tested 12 of 27 because I thought some sets might overlap but I might
have missed something, what combination is giving you problem?



I didn't test your series, but I did this kind of change in the past and
sometime enabling tools without enabling softmmu can show missing
objects at build time, or you can also see if tools are built with
softmmu while tools are disabled.

I used to test with something like

for user in enable disable; do
 for tools in enable disable; do
 for system in enable disable; do
 rm -fr build
 mkdir build && \
 (cd build && \
  ../configure --$user-user \
   --$system-system \
   --$tools-tools && \
  make || exit)
 done
 done
done


I tested all these 8 combinations, no problem.




Re: [PATCH v2 4/4] migration: Check in savevm_state_handler_insert for dups

2020-01-10 Thread Juan Quintela
Peter Xu  wrote:
> Before finally register one SaveStateEntry, we detect for duplicated
> entries.  This could be helpful to notify us asap instead of get
> silent migration failures which could be hard to diagnose.
>
> For example, this patch will generate a message like this (if without
> previous fixes on x2apic) as long as we wants to boot a VM instance
> with "-smp 200,maxcpus=288,sockets=2,cores=72,threads=2" and QEMU will
> bail out even before VM starts:
>
> savevm_state_handler_insert: Detected duplicate SaveStateEntry: id=apic, 
> instance_id=0x0
>
> Suggested-by: Dr. David Alan Gilbert 
> Signed-off-by: Peter Xu 

Hi peter

I have to drop this one.  There is something on current tree (I think
that it is the VMSTATE_IF) that make isa-ide choke for migration on
"make check".  Will take a look to it later.

Later, Juan.




[Bug 1859081] Re: Mouse way too fast when Qemu is on a Windows VM with a OS 9 Guest

2020-01-10 Thread Roman Bäriswyl
The command line I currently use is:

".\qemu-4.2.0-win64\qemu-system-ppc.exe" -L pc-bios -boot c -M mac99,via=pmu -m 
512 ^
-prom-env "auto-boot?=true" -prom-env "boot-args=-v" -prom-env "vga-ndrv?=true" 
^
-drive file=c:\qemu\MacOS9.2.img,format=raw,media=disk ^
-drive file=c:\qemu\MacOS9.2.2_Universal_Install.iso,format=raw,media=cdrom ^
-sdl ^
-netdev user,id=network01 -device sungem,netdev=network01 ^
-device VGA,edid=on

I also tried by adding "-device usb-mouse" but it does not make any difference.
I now tried with 4.2.0 from omledom (yesterday with 4.1.0 from weilnetz.
There is no difference in 4.1.0 and 4.2.0 with or without the usb-mouse.

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

Title:
  Mouse way too fast when Qemu is on a Windows VM with a OS 9 Guest

Status in QEMU:
  New

Bug description:
  On a server, I have a Windows 10 VM with Qemu 4.1.0 (latest) from 
https://qemu.weilnetz.de/w64/ installed.
  There I have a Mac OS 9.2.2 machine.
  Now if I connect to the Windows VM with VNC or RDP or even VMWare console, 
the Mouse in the Mac OS Guest inside Qemu is wy to fast. Even when lowering 
the mouse speed in the Mac OS mouse setting, one pixel in the Host (Windows 10 
VM) still moves the mouse by 10 pixels inside the Qemu machine.
  I tried different resolutions but that does not help.
  Is there any way to fix this or any way how I can provide more information?
  Thanks

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



[PATCH v1 2/2] tests/tcg: add a vtimer test for aarch64

2020-01-10 Thread Alex Bennée
Bug: https://bugs.launchpad.net/bugs/1859021

Signed-off-by: Alex Bennée 
---
 tests/tcg/aarch64/system/vtimer.c | 80 +++
 tests/tcg/aarch64/Makefile.softmmu-target |  4 ++
 2 files changed, 84 insertions(+)
 create mode 100644 tests/tcg/aarch64/system/vtimer.c

diff --git a/tests/tcg/aarch64/system/vtimer.c 
b/tests/tcg/aarch64/system/vtimer.c
new file mode 100644
index 000..2f6299b5d2c
--- /dev/null
+++ b/tests/tcg/aarch64/system/vtimer.c
@@ -0,0 +1,80 @@
+/*
+ * Simple Virtual Timer Tests
+ *
+ * Note: kvm-unit-tests has a much more comprehensive exercising of
+ * the timer sub-system. However this test case can tweak _EL2 values
+ * to trigger bugs which can't be done with that.
+ *
+ * Copyright (c) 2020 Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include 
+#include 
+
+/* grabbed from Linux */
+#define __stringify_1(x...) #x
+#define __stringify(x...)   __stringify_1(x)
+
+#define read_sysreg(r) ({   \
+uint64_t __val; \
+asm volatile("mrs %0, " __stringify(r) : "=r" (__val)); \
+__val;  \
+})
+
+#define write_sysreg(r, v) do { \
+uint64_t __val = (uint64_t)(v); \
+asm volatile("msr " __stringify(r) ", %x0"  \
+ : : "rZ" (__val)); \
+} while (0)
+
+/* Physical Counter */
+static uint64_t last_pct;
+/* Timer Values */
+static uint32_t last_phys_tval;
+static uint32_t last_virt_tval;
+
+static void dump_status(void)
+{
+uint64_t pct = read_sysreg(cntpct_el0);
+uint32_t phys_tval = read_sysreg(cntp_tval_el0);
+uint32_t virt_tval = read_sysreg(cntv_tval_el0);
+
+ml_printf("timer values:\n");
+/* the physical timer monotonically increments */
+ml_printf("cntpct_el0=%ld (+%ld)\n", pct, pct - last_pct);
+/* the various tvals decrement based on cval */
+ml_printf("cntp_tval_el0=%ld (-%ld)\n", phys_tval,
+  last_phys_tval - phys_tval);
+ml_printf("cntv_tval_el0=%ld (-%ld)\n", virt_tval,
+  last_virt_tval - virt_tval);
+
+last_pct = pct;
+last_phys_tval = phys_tval;
+last_virt_tval = virt_tval;
+}
+
+int main(void)
+{
+int i;
+
+ml_printf("VTimer Tests\n");
+
+dump_status();
+
+ml_printf("Tweaking voff_el2 and cval\n");
+write_sysreg(cntvoff_el2, 1);
+write_sysreg(cntv_cval_el0, -1);
+
+dump_status();
+
+ml_printf("Enabling timer IRQs\n");
+write_sysreg(cntv_ctl_el0, 1);
+/* for bug 1859021 we hang here */
+
+dump_status();
+
+ml_printf("End of Vtimer test\n");
+return 0;
+}
diff --git a/tests/tcg/aarch64/Makefile.softmmu-target 
b/tests/tcg/aarch64/Makefile.softmmu-target
index 7b4eede3f07..62cdddbb215 100644
--- a/tests/tcg/aarch64/Makefile.softmmu-target
+++ b/tests/tcg/aarch64/Makefile.softmmu-target
@@ -62,3 +62,7 @@ run-memory-replay: memory-replay run-memory-record
  "$< on $(TARGET_NAME)")
 
 EXTRA_TESTS+=memory-record memory-replay
+
+# vtimer test
+QEMU_EL2_MACHINE=-machine virt,virtualization=on,gic-version=2 -cpu cortex-a57 
-smp 4
+run-vtimer: QEMU_OPTS=$(QEMU_EL2_MACHINE) $(QEMU_SEMIHOST)  -kernel
-- 
2.20.1




[PATCH v1 1/2] target/arm: detect 64 bit overflow caused by high cval + voff

2020-01-10 Thread Alex Bennée
If we don't detect this we will be stuck in a busy loop as we schedule
a timer for before now which will continually trigger gt_recalc_timer
even though we haven't reached the state required to trigger the IRQ.

Bug: https://bugs.launchpad.net/bugs/1859021
Cc: 1859...@bugs.launchpad.net
Signed-off-by: Alex Bennée 
---
 target/arm/helper.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 19a57a17da5..eb17106f7bd 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -2481,6 +2481,9 @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
 } else {
 /* Next transition is when we hit cval */
 nexttick = gt->cval + offset;
+if (nexttick < gt->cval) {
+nexttick = UINT64_MAX;
+}
 }
 /* Note that the desired next expiry time might be beyond the
  * signed-64-bit range of a QEMUTimer -- in this case we just
-- 
2.20.1




[PATCH v1 0/2] fix for bug 1859021

2020-01-10 Thread Alex Bennée
Hi,

This is a fairly trivial fix for a uint64_t overflow however I spent
some time making sure I understood why we got stuck in a busy loop and
adding tests to both tcg and kvm-unit-tests.

Alex Bennée (2):
  target/arm: detect 64 bit overflow caused by high cval + voff
  tests/tcg: add a vtimer test for aarch64

 target/arm/helper.c   |  3 +
 tests/tcg/aarch64/system/vtimer.c | 80 +++
 tests/tcg/aarch64/Makefile.softmmu-target |  4 ++
 3 files changed, 87 insertions(+)
 create mode 100644 tests/tcg/aarch64/system/vtimer.c

-- 
2.20.1




Re: [PULL 0/3] capstone update

2020-01-10 Thread Peter Maydell
On Wed, 8 Jan 2020 at 04:23, Richard Henderson
 wrote:
>
> The following changes since commit 035eed4c0d257c905a556fa0f4865a0c077b4e7f:
>
>   Merge remote-tracking branch 
> 'remotes/vivier/tags/q800-for-5.0-pull-request' into staging (2020-01-07 
> 17:08:21 +)
>
> are available in the Git repository at:
>
>   https://github.com/rth7680/qemu.git tags/pull-cap-20200108
>
> for you to fetch changes up to 7cc3836eac04a3e358b2496fbca704b3ee5197ae:
>
>   capstone: Add skipdata hook for s390x (2020-01-08 14:53:54 +1100)
>
> 
> Update capstone to next
>
> 
> Richard Henderson (3):
>   capstone: Update to next
>   capstone: Enable disassembly for s390x
>   capstone: Add skipdata hook for s390x

Build failures:

  CC  aarch64-linux-user/disas.o
In file included from
/home/ubuntu/qemu/capstone/include/capstone/capstone.h:302:0,
 from /home/ubuntu/qemu/include/disas/capstone.h:6,
 from /home/ubuntu/qemu/disas.c:9:
/home/ubuntu/qemu/capstone/include/capstone/riscv.h:16:10: fatal
error: capstone/platform.h: No such file or directory
 #include "capstone/platform.h"
  ^
compilation terminated.

(same on most hosts)

aarch64 host had this complaint instead:

/home/pm/qemu/disas.c:187:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or
‘__attribute__’ before ‘cap_skipdata_s390x_cb’
 cap_skipdata_s390x_cb(const uint8_t *code, size_t code_size,
 ^
/home/pm/qemu/disas.c:211:17: error: ‘cap_skipdata_s390x_cb’
undeclared here (not in a function); did you mean
‘cap_skipdata_s390x’?
 .callback = cap_skipdata_s390x_cb
 ^
 cap_skipdata_s390x

thanks
-- PMM



Re: [PATCH 014/104] virtiofsd: Add options for virtio

2020-01-10 Thread Dr. David Alan Gilbert
* Daniel P. Berrangé (berra...@redhat.com) wrote:
> On Thu, Dec 12, 2019 at 04:37:34PM +, Dr. David Alan Gilbert (git) wrote:
> > From: "Dr. David Alan Gilbert" 
> > 
> > Add options to specify parameters for virtio-fs paths, i.e.
> > 
> >./virtiofsd -o vhost_user_socket=/tmp/vhostqemu
> > 
> > Signed-off-by: Dr. David Alan Gilbert 
> > ---
> >  tools/virtiofsd/fuse_i.h|  1 +
> >  tools/virtiofsd/fuse_lowlevel.c | 17 -
> >  tools/virtiofsd/helper.c| 22 +++---
> >  3 files changed, 24 insertions(+), 16 deletions(-)
> > 
> > diff --git a/tools/virtiofsd/fuse_i.h b/tools/virtiofsd/fuse_i.h
> > index 0b5acc8765..f58be71e4b 100644
> > --- a/tools/virtiofsd/fuse_i.h
> > +++ b/tools/virtiofsd/fuse_i.h
> > @@ -63,6 +63,7 @@ struct fuse_session {
> >  struct fuse_notify_req notify_list;
> >  size_t bufsize;
> >  int error;
> > +char *vu_socket_path;
> >  };
> >  
> >  struct fuse_chan {
> > diff --git a/tools/virtiofsd/fuse_lowlevel.c 
> > b/tools/virtiofsd/fuse_lowlevel.c
> > index 167701b453..da708161e1 100644
> > --- a/tools/virtiofsd/fuse_lowlevel.c
> > +++ b/tools/virtiofsd/fuse_lowlevel.c
> > @@ -2118,8 +2118,12 @@ reply_err:
> >  }
> >  
> >  static const struct fuse_opt fuse_ll_opts[] = {
> > -LL_OPTION("debug", debug, 1), LL_OPTION("-d", debug, 1),
> > -LL_OPTION("--debug", debug, 1), LL_OPTION("allow_root", deny_others, 
> > 1),
> > +LL_OPTION("debug", debug, 1),
> > +LL_OPTION("-d", debug, 1),
> > +LL_OPTION("--debug", debug, 1),
> 
> Pre-existing, but I'm not convinced we really need 3 different
> ways to enable debugging - I would think -d / --debug is sufficient,
> without needing "-o debug".

Given it's existing, I'll leave that.

> > +LL_OPTION("allow_root", deny_others, 1),
> > +LL_OPTION("--socket-path=%s", vu_socket_path, 0),
> > +LL_OPTION("vhost_user_socket=%s", vu_socket_path, 0),
> 
> Similarly here I'm not convinced we need to add both
> "--socket-path PATH" and "-o vhost_user_socket=PATH"
> 
> 
> IIRC, we need --socket-path for compliance with QEMU's
> standard execution model for vhost helpers.

OK, deleted -o vhost_user_socket   - it was there because
our existing kata glue and test setups were using it.


Dave

> >  FUSE_OPT_END
> >  };
> >  
> > @@ -2135,9 +2139,12 @@ void fuse_lowlevel_help(void)
> >   * These are not all options, but the ones that are
> >   * potentially of interest to an end-user
> >   */
> > -printf("-o allow_other allow access by all users\n"
> > -   "-o allow_root  allow access by root\n"
> > -   "-o auto_unmountauto unmount on process 
> > termination\n");
> > +printf(
> > +"-o allow_other allow access by all users\n"
> > +"-o allow_root  allow access by root\n"
> > +"--socket-path=PATH path for the vhost-user socket\n"
> > +"-o vhost_user_socket=PATH  path for the vhost-user socket\n"
> > +"-o auto_unmountauto unmount on process 
> > termination\n");
> >  }
> >  
> >  void fuse_session_destroy(struct fuse_session *se)
> > diff --git a/tools/virtiofsd/helper.c b/tools/virtiofsd/helper.c
> > index 8afccfc15e..48e38a7963 100644
> > --- a/tools/virtiofsd/helper.c
> > +++ b/tools/virtiofsd/helper.c
> > @@ -128,17 +128,17 @@ static const struct fuse_opt conn_info_opt_spec[] = {
> >  
> >  void fuse_cmdline_help(void)
> >  {
> > -printf(
> > -"-h   --helpprint help\n"
> > -"-V   --version print version\n"
> > -"-d   -o debug  enable debug output (implies -f)\n"
> > -"-f foreground operation\n"
> > -"-s disable multi-threaded operation\n"
> > -"-o clone_fduse separate fuse device fd for each "
> > -"thread\n"
> > -"   (may improve performance)\n"
> > -"-o max_idle_threadsthe maximum number of idle worker 
> > threads\n"
> > -"   allowed (default: 10)\n");
> > +printf("-h   --helpprint help\n"
> > +   "-V   --version print version\n"
> > +   "-d   -o debug  enable debug output (implies 
> > -f)\n"
> > +   "-f foreground operation\n"
> > +   "-s disable multi-threaded 
> > operation\n"
> > +   "-o clone_fduse separate fuse device fd for 
> > "
> > +   "each thread\n"
> > +   "   (may improve performance)\n"
> > +   "-o max_idle_threadsthe maximum number of idle 
> > worker "
> > +   "threads\n"
> > +   "   allowed (default: 10)\n");
> >  }
> >  
> >  static int 

Re: [PATCH 068/104] virtiofsd: passthrough_ll: control readdirplus

2020-01-10 Thread Miklos Szeredi
On Fri, Jan 10, 2020 at 4:40 PM Vivek Goyal  wrote:
>
> On Fri, Jan 10, 2020 at 04:30:01PM +0100, Miklos Szeredi wrote:
> > On Fri, Jan 10, 2020 at 4:18 PM Daniel P. Berrangé  
> > wrote:
> > >
> > > On Fri, Jan 10, 2020 at 04:13:08PM +0100, Miklos Szeredi wrote:
> > > > On Fri, Jan 10, 2020 at 4:04 PM Dr. David Alan Gilbert
> > > >  wrote:
> > > > >
> > > > > * Daniel P. Berrangé (berra...@redhat.com) wrote:
> > > > > > On Thu, Dec 12, 2019 at 04:38:28PM +, Dr. David Alan Gilbert 
> > > > > > (git) wrote:
> > > > > > > From: Miklos Szeredi 
> > > > > > >
> > > > > >
> > > > > > What is readdirplus and what do we need a command line option to
> > > > > > control it ? What's the user benefit of changing the setting ?
> > > > >
> > > > > cc'ing Miklos who understands this better than me.
> > > > >
> > > > > My understanding is that readdirplus is a heuristic inherited from NFS
> > > > > where when you iterate over the directory you also pick up stat() data
> > > > > for each entry in the directory.  You then cache that stat data
> > > > > somewhere.
> > > > > The Plus-ness is that a lot of directory operations involve you 
> > > > > stating
> > > > > each entry (e.g. to figure out if you can access it etc) so rolling it
> > > > > into one op avoids the separate stat.  The unplus-ness is that it's an
> > > > > overhead and I think changes some of the caching behaviour.
> > > >
> > > > Yeah, so either may give better performance and it's hard to pick a
> > > > clear winner.  NFS also has an option to control this.
> > >
> > > IIUC from the man page, the NFS option for controlling this is a client
> > > side mount option. This makes sense as only the client really has 
> > > knowledge
> > > of whether its workload will benefit.
> > >
> > > With this in mind, should the readdirplus control for virtio-fs also be a
> > > guest mount option instead of a host virtiofsd CLI option ? The guest 
> > > admin
> > > seems best placed to know whether their workload will benefit or not.
> >
> > Definitely.   In fact other options, e.g. ones that control caching,
> > should probably also be client side (cache=XXX, writeback,
> > timeout=XXX, etc).
>
> I am not sure about cache options. So if we want to share a directory
> between multiple guests with stronger coherency (cache=none), then admin
> should decide that cache=always/auto is not supported on this export.
>
> Also, how will one client know whether there are other clients same
> directory with strong coherency requirements and it should use cache=none
> instead of cache=always/auto.
>
> Having said that, it also makes sense that client knows its workoad
> and can decide if cache=auto works best for it and use that instead.
>
> May be we need both client and server side options. Client will request
> certain cache=xxx options and server can deny these if admin decides
> not to enable that option for that particular mount.
>
> For example, if admin decides that we can only support cache=none on
> this particular dir due to other guest sharing it, then daemon should
> be able to deny cache=auto/always requests from client.

Makes sense.  The server dictates policy, the client just passes the
options onto the server.

Thanks,
Miklos




Re: [PULL 00/41] tcg patch queue

2020-01-10 Thread Peter Maydell
On Wed, 8 Jan 2020 at 03:45, Richard Henderson
 wrote:
>
> The following changes since commit 035eed4c0d257c905a556fa0f4865a0c077b4e7f:
>
>   Merge remote-tracking branch 
> 'remotes/vivier/tags/q800-for-5.0-pull-request' into staging (2020-01-07 
> 17:08:21 +)
>
> are available in the Git repository at:
>
>   https://github.com/rth7680/qemu.git tags/pull-tcg-20200108
>
> for you to fetch changes up to 5e7ef51cbe47e726f76bfbc208e167085cf398c4:
>
>   MAINTAINERS: Replace Claudio Fontana for tcg/aarch64 (2020-01-08 11:54:12 
> +1100)
>
> 
> Improve -static and -pie linking
> Add cpu_{ld,st}*_mmuidx_ra
> Remove MMU_MODE*_SUFFIX
> Move tcg headers under include/

This makes the x86-64 'ls' binary in the linux-user-tests
tarball segfault:

/home/petmay01/linaro/qemu-for-merges/build/all-linux-static/x86_64-linux-user/qemu-x86_64
-L ./gnemul/qemu-x86_64 x86_64/ls -l dummyfile
qemu: uncaught target signal 11 (Segmentation fault) - core dumped

(probably
http://people.linaro.org/~peter.maydell/linux-user-test-modified-pmm.tgz
if you don't have a copy to hand)

thanks
-- PMM



Re: [PATCH 00/26] Various qom & qdev enhancements

2020-01-10 Thread Marc-André Lureau
Hi


Something went wrong with git-publish & "git branch
--edit-description" interaction (which I started to play with - I
think git-publish should make use of it). It seems it got the mail
summary from git-publish and content from git description, fun :)

On Fri, Jan 10, 2020 at 7:31 PM Marc-André Lureau
 wrote:
>
> aa bpkwef

That should read instead:

The following series has some qom/qdev cleanups, moves qdev instance
properties to class properites, and return the default values in help
and QMP commands.

Thanks

> Marc-André Lureau (26):
>   object: add extra sanity checks
>   qdev: remove duplicated qdev_property_add_static() doc
>   qdev: remove extraneous error
>   qdev: move helper function to monitor/misc
>   object: avoid extra class property key duplication
>   object: add class property initializer
>   object: add object_property_get_defaut()
>   object: make object_class_property_add* return property
>   qstring: add qstring_free()
>   object: add object_property_set_defaut_{bool,str,int,uint}()
>   object: do not free class properties
>   object: check strong flag with &
>   object: rename link "child" to "target"
>   object: add direct link flag
>   object: express const link with link property
>   object: add object_class_property_add_link()
>   object: release all props
>   object: return self in object_ref()
>   qdev: set properties with device_class_set_props()
>   qdev: move instance properties to class properties
>   qdev: register properties as class properties
>   vl: print default value in object help
>   qom: simplify qmp_device_list_properties()
>   qom: introduce object_property_help()
>   qapi/qmp: add ObjectPropertyInfo.default-value
>   qdev: use object_property_help()
>
>  qapi/qom.json   |   7 +-
>  include/hw/qdev-core.h  |   8 +-
>  include/hw/qdev-properties.h|   3 +-
>  include/qapi/qmp/qstring.h  |   1 +
>  include/qom/object.h| 126 ++--
>  hw/9pfs/virtio-9p-device.c  |   2 +-
>  hw/acpi/generic_event_device.c  |   2 +-
>  hw/acpi/piix4.c |   2 +-
>  hw/acpi/vmgenid.c   |   2 +-
>  hw/arm/armsse.c |   2 +-
>  hw/arm/armv7m.c |   4 +-
>  hw/arm/aspeed_soc.c |   2 +-
>  hw/arm/bcm2836.c|   2 +-
>  hw/arm/integratorcp.c   |   2 +-
>  hw/arm/msf2-soc.c   |   2 +-
>  hw/arm/musicpal.c   |   2 +-
>  hw/arm/nrf51_soc.c  |   2 +-
>  hw/arm/pxa2xx.c |   4 +-
>  hw/arm/pxa2xx_gpio.c|   2 +-
>  hw/arm/smmu-common.c|   2 +-
>  hw/arm/spitz.c  |   2 +-
>  hw/arm/stm32f205_soc.c  |   2 +-
>  hw/arm/strongarm.c  |   2 +-
>  hw/arm/xlnx-versal.c|   2 +-
>  hw/arm/xlnx-zynqmp.c|   2 +-
>  hw/audio/ac97.c |   2 +-
>  hw/audio/adlib.c|   2 +-
>  hw/audio/cs4231.c   |   2 +-
>  hw/audio/cs4231a.c  |   2 +-
>  hw/audio/es1370.c   |   2 +-
>  hw/audio/gus.c  |   2 +-
>  hw/audio/hda-codec.c|   2 +-
>  hw/audio/intel-hda.c|   4 +-
>  hw/audio/milkymist-ac97.c   |   2 +-
>  hw/audio/pcspk.c|   2 +-
>  hw/audio/pl041.c|   2 +-
>  hw/audio/sb16.c |   2 +-
>  hw/audio/wm8750.c   |   2 +-
>  hw/block/fdc.c  |   8 +-
>  hw/block/m25p80.c   |   2 +-
>  hw/block/nand.c |   2 +-
>  hw/block/nvme.c |   2 +-
>  hw/block/onenand.c  |   2 +-
>  hw/block/pflash_cfi01.c |   2 +-
>  hw/block/pflash_cfi02.c |   2 +-
>  hw/block/swim.c |   2 +-
>  hw/block/vhost-user-blk.c   |   2 +-
>  hw/block/virtio-blk.c   |   2 +-
>  hw/block/xen-block.c|   2 +-
>  hw/char/bcm2835_aux.c   |   2 +-
>  hw/char/cadence_uart.c  |   2 +-
>  hw/char/cmsdk-apb-uart.c|   2 +-
>  hw/char/debugcon.c  |   2 +-
>  hw/char/digic-uart.c|   2 +-
>  hw/char/escc.c  |   2 +-
>  hw/char/etraxfs_ser.c   |   2 +-
>  hw/char/exynos4210_uart.c   |   2 +-
>  hw/char/grlib_apbuart.c |   2 +-
>  hw/char/imx_serial.c|   2 +-
>  hw/char/ipoctal232.c|   2 +-
>  hw/char/lm32_juart.c|   2 +-
>  hw/char/lm32_uart.c |   2 +-
>  hw/char/mcf_uart.c  |   2 +-
>  hw/char/milkymist-uart.c|   2 +-
>  hw/char/nrf51_uart.c|   2 +-
>  hw/char/parallel.c  |   2 +-
>  hw/char/pl011.c |   2 +-
>  hw/char/sclpconsole-lm.c|   

[PATCH 26/26] qdev: use object_property_help()

2020-01-10 Thread Marc-André Lureau
Use the common function introduced earlier, and report default value.

Signed-off-by: Marc-André Lureau 
---
 qdev-monitor.c | 15 +--
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/qdev-monitor.c b/qdev-monitor.c
index 3465a1e2d0..0f83770e02 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -286,16 +286,11 @@ int qdev_device_help(QemuOpts *opts)
 qemu_printf("There are no options for %s.\n", driver);
 }
 for (prop = prop_list; prop; prop = prop->next) {
-int len;
-qemu_printf("  %s=<%s>%n", prop->value->name, prop->value->type, );
-if (prop->value->has_description) {
-if (len < 24) {
-qemu_printf("%*s", 24 - len, "");
-}
-qemu_printf(" - %s\n", prop->value->description);
-} else {
-qemu_printf("\n");
-}
+g_autofree char *help = object_property_help(prop->value->name,
+ prop->value->type,
+ 
prop->value->default_value,
+ prop->value->description);
+qemu_printf("%s\n", help);
 }
 
 qapi_free_ObjectPropertyInfoList(prop_list);
-- 
2.25.0.rc1.20.g2443f3f80d.dirty




[PATCH 25/26] qapi/qmp: add ObjectPropertyInfo.default-value

2020-01-10 Thread Marc-André Lureau
Report the default value associated with a property.

Signed-off-by: Marc-André Lureau 
---
 qapi/qom.json  | 7 ++-
 qom/qom-qmp-cmds.c | 4 
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/qapi/qom.json b/qapi/qom.json
index 32db96ffc4..471e4b484b 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -26,10 +26,15 @@
 #
 # @description: if specified, the description of the property.
 #
+# @default-value: the default value, if any (since 5.0)
+#
 # Since: 1.2
 ##
 { 'struct': 'ObjectPropertyInfo',
-  'data': { 'name': 'str', 'type': 'str', '*description': 'str' } }
+  'data': { 'name': 'str',
+'type': 'str',
+'*description': 'str',
+'*default-value': 'str' } }
 
 ##
 # @qom-list:
diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
index 8785816c1f..68f0a41bca 100644
--- a/qom/qom-qmp-cmds.c
+++ b/qom/qom-qmp-cmds.c
@@ -177,6 +177,10 @@ ObjectPropertyInfoList *qmp_device_list_properties(const 
char *typename,
 info->type = g_strdup(prop->type);
 info->has_description = !!prop->description;
 info->description = g_strdup(prop->description);
+if (prop->get_default) {
+info->default_value = prop->get_default(prop);
+info->has_default_value = !!info->default_value;
+}
 
 entry = g_malloc0(sizeof(*entry));
 entry->value = info;
-- 
2.25.0.rc1.20.g2443f3f80d.dirty




[PATCH 23/26] qom: simplify qmp_device_list_properties()

2020-01-10 Thread Marc-André Lureau
All qdev properties are object properties, no need for
make_device_property_info() helper.

Signed-off-by: Marc-André Lureau 
---
 qom/qom-qmp-cmds.c | 52 +-
 1 file changed, 5 insertions(+), 47 deletions(-)

diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
index f4494f98ac..8785816c1f 100644
--- a/qom/qom-qmp-cmds.c
+++ b/qom/qom-qmp-cmds.c
@@ -121,48 +121,6 @@ ObjectTypeInfoList *qmp_qom_list_types(bool has_implements,
 return ret;
 }
 
-/* Return a DevicePropertyInfo for a qdev property.
- *
- * If a qdev property with the given name does not exist, use the given default
- * type.  If the qdev property info should not be shown, return NULL.
- *
- * The caller must free the return value.
- */
-static ObjectPropertyInfo *make_device_property_info(ObjectClass *klass,
-  const char *name,
-  const char *default_type,
-  const char *description)
-{
-ObjectPropertyInfo *info;
-Property *prop;
-
-do {
-for (prop = DEVICE_CLASS(klass)->props; prop && prop->name; prop++) {
-if (strcmp(name, prop->name) != 0) {
-continue;
-}
-
-info = g_malloc0(sizeof(*info));
-info->name = g_strdup(prop->name);
-info->type = default_type ? g_strdup(default_type)
-  : g_strdup(prop->info->name);
-info->has_description = !!prop->info->description;
-info->description = g_strdup(prop->info->description);
-return info;
-}
-klass = object_class_get_parent(klass);
-} while (klass != object_class_by_name(TYPE_DEVICE));
-
-/* Not a qdev property, use the default type */
-info = g_malloc0(sizeof(*info));
-info->name = g_strdup(name);
-info->type = g_strdup(default_type);
-info->has_description = !!description;
-info->description = g_strdup(description);
-
-return info;
-}
-
 ObjectPropertyInfoList *qmp_device_list_properties(const char *typename,
 Error **errp)
 {
@@ -214,11 +172,11 @@ ObjectPropertyInfoList *qmp_device_list_properties(const 
char *typename,
 continue;
 }
 
-info = make_device_property_info(klass, prop->name, prop->type,
- prop->description);
-if (!info) {
-continue;
-}
+info = g_new0(ObjectPropertyInfo, 1);
+info->name = g_strdup(prop->name);
+info->type = g_strdup(prop->type);
+info->has_description = !!prop->description;
+info->description = g_strdup(prop->description);
 
 entry = g_malloc0(sizeof(*entry));
 entry->value = info;
-- 
2.25.0.rc1.20.g2443f3f80d.dirty




[PATCH 18/26] object: return self in object_ref()

2020-01-10 Thread Marc-André Lureau
This allow for simpler assignment with ref: foo = object_ref(bar)

Signed-off-by: Marc-André Lureau 
---
 include/qom/object.h | 3 ++-
 qom/object.c | 5 +++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index ead9129ac8..933e5c6cb9 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1013,8 +1013,9 @@ GSList *object_class_get_list_sorted(const char 
*implements_type,
  *
  * Increase the reference count of a object.  A object cannot be freed as long
  * as its reference count is greater than zero.
+ * Returns: @obj
  */
-void object_ref(Object *obj);
+Object *object_ref(Object *obj);
 
 /**
  * object_unref:
diff --git a/qom/object.c b/qom/object.c
index 3924678ec3..9f76a330ff 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1098,12 +1098,13 @@ GSList *object_class_get_list_sorted(const char 
*implements_type,
 object_class_cmp);
 }
 
-void object_ref(Object *obj)
+Object *object_ref(Object *obj)
 {
 if (!obj) {
-return;
+return NULL;
 }
 atomic_inc(>ref);
+return obj;
 }
 
 void object_unref(Object *obj)
-- 
2.25.0.rc1.20.g2443f3f80d.dirty




[PATCH 16/26] object: add object_class_property_add_link()

2020-01-10 Thread Marc-André Lureau
Signed-off-by: Marc-André Lureau 
---
 include/qom/object.h |  9 +
 qom/object.c | 46 +++-
 2 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index 5b02be68ec..ead9129ac8 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1531,6 +1531,7 @@ typedef enum {
 
 /* private */
 OBJ_PROP_LINK_DIRECT = 0x2,
+OBJ_PROP_LINK_CLASS = 0x4,
 } ObjectPropertyLinkFlags;
 
 /**
@@ -1579,6 +1580,14 @@ void object_property_add_link(Object *obj, const char 
*name,
   ObjectPropertyLinkFlags flags,
   Error **errp);
 
+ObjectProperty *object_class_property_add_link(ObjectClass *oc,
+  const char *name,
+  const char *type, ptrdiff_t offset,
+  void (*check)(const Object *obj, const char 
*name,
+Object *val, Error **errp),
+  ObjectPropertyLinkFlags flags,
+  Error **errp);
+
 /**
  * object_property_add_str:
  * @obj: the object to add a property to
diff --git a/qom/object.c b/qom/object.c
index 09d960f254..04f2991716 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1723,6 +1723,7 @@ typedef struct {
 union {
 Object **targetp;
 Object *target; /* if OBJ_PROP_LINK_DIRECT, when holding the pointer  
*/
+ptrdiff_t offset; /* if OBJ_PROP_LINK_CLASS */
 };
 void (*check)(const Object *, const char *, Object *, Error **);
 ObjectPropertyLinkFlags flags;
@@ -1733,6 +1734,8 @@ object_link_get_targetp(Object *obj, LinkProperty *lprop)
 {
 if (lprop->flags & OBJ_PROP_LINK_DIRECT) {
 return >target;
+} else if (lprop->flags & OBJ_PROP_LINK_CLASS) {
+return (void *)obj + lprop->offset;
 } else {
 return lprop->targetp;
 }
@@ -1848,7 +1851,9 @@ static void object_release_link_property(Object *obj, 
const char *name,
 if ((prop->flags & OBJ_PROP_LINK_STRONG) && *targetp) {
 object_unref(*targetp);
 }
-g_free(prop);
+if (!(prop->flags & OBJ_PROP_LINK_CLASS)) {
+g_free(prop);
+}
 }
 
 static void object_add_link_prop(Object *obj, const char *name,
@@ -1901,6 +1906,45 @@ void object_property_add_link(Object *obj, const char 
*name,
 object_add_link_prop(obj, name, type, targetp, check, flags, errp);
 }
 
+ObjectProperty *
+object_class_property_add_link(ObjectClass *oc,
+const char *name,
+const char *type, ptrdiff_t offset,
+void (*check)(const Object *obj, const char *name,
+  Object *val, Error **errp),
+ObjectPropertyLinkFlags flags,
+Error **errp)
+{
+Error *local_err = NULL;
+LinkProperty *prop = g_new0(LinkProperty, 1);
+gchar *full_type;
+ObjectProperty *op;
+
+prop->offset = offset;
+prop->check = check;
+prop->flags = flags | OBJ_PROP_LINK_CLASS;
+
+full_type = g_strdup_printf("link<%s>", type);
+
+op = object_class_property_add(oc, name, full_type,
+   object_get_link_property,
+   check ? object_set_link_property : NULL,
+   object_release_link_property,
+   prop,
+   _err);
+if (local_err) {
+error_propagate(errp, local_err);
+g_free(prop);
+goto out;
+}
+
+op->resolve = object_resolve_link_property;
+
+out:
+g_free(full_type);
+return op;
+}
+
 void object_property_add_const_link(Object *obj, const char *name,
 Object *target, Error **errp)
 {
-- 
2.25.0.rc1.20.g2443f3f80d.dirty




[PATCH 14/26] object: add direct link flag

2020-01-10 Thread Marc-André Lureau
Allow the link property to hold the pointer to the target, instead of
indirectly through another variable.

Signed-off-by: Marc-André Lureau 
---
 include/qom/object.h |  3 +++
 qom/object.c | 26 --
 2 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index 7e66bc78c9..5b02be68ec 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1528,6 +1528,9 @@ void object_property_add_child(Object *obj, const char 
*name,
 typedef enum {
 /* Unref the link pointer when the property is deleted */
 OBJ_PROP_LINK_STRONG = 0x1,
+
+/* private */
+OBJ_PROP_LINK_DIRECT = 0x2,
 } ObjectPropertyLinkFlags;
 
 /**
diff --git a/qom/object.c b/qom/object.c
index 47d8be81a6..30eee0f36b 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1720,17 +1720,30 @@ void object_property_allow_set_link(const Object *obj, 
const char *name,
 }
 
 typedef struct {
-Object **targetp;
+union {
+Object **targetp;
+Object *target; /* if OBJ_PROP_LINK_DIRECT, when holding the pointer  
*/
+};
 void (*check)(const Object *, const char *, Object *, Error **);
 ObjectPropertyLinkFlags flags;
 } LinkProperty;
 
+static Object **
+object_link_get_targetp(Object *obj, LinkProperty *lprop)
+{
+if (lprop->flags & OBJ_PROP_LINK_DIRECT) {
+return >target;
+} else {
+return lprop->targetp;
+}
+}
+
 static void object_get_link_property(Object *obj, Visitor *v,
  const char *name, void *opaque,
  Error **errp)
 {
 LinkProperty *lprop = opaque;
-Object **targetp = lprop->targetp;
+Object **targetp = object_link_get_targetp(obj, lprop);
 gchar *path;
 
 if (*targetp) {
@@ -1789,7 +1802,7 @@ static void object_set_link_property(Object *obj, Visitor 
*v,
 {
 Error *local_err = NULL;
 LinkProperty *prop = opaque;
-Object **targetp = prop->targetp;
+Object **targetp = object_link_get_targetp(obj, prop);
 Object *old_target = *targetp;
 Object *new_target = NULL;
 char *path = NULL;
@@ -1823,16 +1836,17 @@ static Object *object_resolve_link_property(Object 
*parent, void *opaque, const
 {
 LinkProperty *lprop = opaque;
 
-return *lprop->targetp;
+return *object_link_get_targetp(parent, lprop);
 }
 
 static void object_release_link_property(Object *obj, const char *name,
  void *opaque)
 {
 LinkProperty *prop = opaque;
+Object **targetp = object_link_get_targetp(obj, prop);
 
-if ((prop->flags & OBJ_PROP_LINK_STRONG) && *prop->targetp) {
-object_unref(*prop->targetp);
+if ((prop->flags & OBJ_PROP_LINK_STRONG) && *targetp) {
+object_unref(*targetp);
 }
 g_free(prop);
 }
-- 
2.25.0.rc1.20.g2443f3f80d.dirty




Re: [PATCH 068/104] virtiofsd: passthrough_ll: control readdirplus

2020-01-10 Thread Vivek Goyal
On Fri, Jan 10, 2020 at 04:30:01PM +0100, Miklos Szeredi wrote:
> On Fri, Jan 10, 2020 at 4:18 PM Daniel P. Berrangé  
> wrote:
> >
> > On Fri, Jan 10, 2020 at 04:13:08PM +0100, Miklos Szeredi wrote:
> > > On Fri, Jan 10, 2020 at 4:04 PM Dr. David Alan Gilbert
> > >  wrote:
> > > >
> > > > * Daniel P. Berrangé (berra...@redhat.com) wrote:
> > > > > On Thu, Dec 12, 2019 at 04:38:28PM +, Dr. David Alan Gilbert 
> > > > > (git) wrote:
> > > > > > From: Miklos Szeredi 
> > > > > >
> > > > >
> > > > > What is readdirplus and what do we need a command line option to
> > > > > control it ? What's the user benefit of changing the setting ?
> > > >
> > > > cc'ing Miklos who understands this better than me.
> > > >
> > > > My understanding is that readdirplus is a heuristic inherited from NFS
> > > > where when you iterate over the directory you also pick up stat() data
> > > > for each entry in the directory.  You then cache that stat data
> > > > somewhere.
> > > > The Plus-ness is that a lot of directory operations involve you stating
> > > > each entry (e.g. to figure out if you can access it etc) so rolling it
> > > > into one op avoids the separate stat.  The unplus-ness is that it's an
> > > > overhead and I think changes some of the caching behaviour.
> > >
> > > Yeah, so either may give better performance and it's hard to pick a
> > > clear winner.  NFS also has an option to control this.
> >
> > IIUC from the man page, the NFS option for controlling this is a client
> > side mount option. This makes sense as only the client really has knowledge
> > of whether its workload will benefit.
> >
> > With this in mind, should the readdirplus control for virtio-fs also be a
> > guest mount option instead of a host virtiofsd CLI option ? The guest admin
> > seems best placed to know whether their workload will benefit or not.
> 
> Definitely.   In fact other options, e.g. ones that control caching,
> should probably also be client side (cache=XXX, writeback,
> timeout=XXX, etc).

I am not sure about cache options. So if we want to share a directory
between multiple guests with stronger coherency (cache=none), then admin
should decide that cache=always/auto is not supported on this export.

Also, how will one client know whether there are other clients same
directory with strong coherency requirements and it should use cache=none
instead of cache=always/auto.

Having said that, it also makes sense that client knows its workoad
and can decide if cache=auto works best for it and use that instead.

May be we need both client and server side options. Client will request
certain cache=xxx options and server can deny these if admin decides
not to enable that option for that particular mount.

For example, if admin decides that we can only support cache=none on
this particular dir due to other guest sharing it, then daemon should
be able to deny cache=auto/always requests from client.

Thanks
Vivek




[PATCH 13/26] object: rename link "child" to "target"

2020-01-10 Thread Marc-André Lureau
A child property is a different kind of property. Let's use "target"
for the link target.

Signed-off-by: Marc-André Lureau 
---
 include/qom/object.h |  4 ++--
 qom/object.c | 24 
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index fb133d693f..7e66bc78c9 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1545,7 +1545,7 @@ void object_property_allow_set_link(const Object *, const 
char *,
  * @obj: the object to add a property to
  * @name: the name of the property
  * @type: the qobj type of the link
- * @child: a pointer to where the link object reference is stored
+ * @targetp: a pointer to where the link object reference is stored
  * @check: callback to veto setting or NULL if the property is read-only
  * @flags: additional options for the link
  * @errp: if an error occurs, a pointer to an area to store the error
@@ -1570,7 +1570,7 @@ void object_property_allow_set_link(const Object *, const 
char *,
  * modified.
  */
 void object_property_add_link(Object *obj, const char *name,
-  const char *type, Object **child,
+  const char *type, Object **targetp,
   void (*check)(const Object *obj, const char 
*name,
 Object *val, Error **errp),
   ObjectPropertyLinkFlags flags,
diff --git a/qom/object.c b/qom/object.c
index 9df4c14226..47d8be81a6 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1720,7 +1720,7 @@ void object_property_allow_set_link(const Object *obj, 
const char *name,
 }
 
 typedef struct {
-Object **child;
+Object **targetp;
 void (*check)(const Object *, const char *, Object *, Error **);
 ObjectPropertyLinkFlags flags;
 } LinkProperty;
@@ -1730,11 +1730,11 @@ static void object_get_link_property(Object *obj, 
Visitor *v,
  Error **errp)
 {
 LinkProperty *lprop = opaque;
-Object **child = lprop->child;
+Object **targetp = lprop->targetp;
 gchar *path;
 
-if (*child) {
-path = object_get_canonical_path(*child);
+if (*targetp) {
+path = object_get_canonical_path(*targetp);
 visit_type_str(v, name, , errp);
 g_free(path);
 } else {
@@ -1789,8 +1789,8 @@ static void object_set_link_property(Object *obj, Visitor 
*v,
 {
 Error *local_err = NULL;
 LinkProperty *prop = opaque;
-Object **child = prop->child;
-Object *old_target = *child;
+Object **targetp = prop->targetp;
+Object *old_target = *targetp;
 Object *new_target = NULL;
 char *path = NULL;
 
@@ -1812,7 +1812,7 @@ static void object_set_link_property(Object *obj, Visitor 
*v,
 return;
 }
 
-*child = new_target;
+*targetp = new_target;
 if (prop->flags & OBJ_PROP_LINK_STRONG) {
 object_ref(new_target);
 object_unref(old_target);
@@ -1823,7 +1823,7 @@ static Object *object_resolve_link_property(Object 
*parent, void *opaque, const
 {
 LinkProperty *lprop = opaque;
 
-return *lprop->child;
+return *lprop->targetp;
 }
 
 static void object_release_link_property(Object *obj, const char *name,
@@ -1831,14 +1831,14 @@ static void object_release_link_property(Object *obj, 
const char *name,
 {
 LinkProperty *prop = opaque;
 
-if ((prop->flags & OBJ_PROP_LINK_STRONG) && *prop->child) {
-object_unref(*prop->child);
+if ((prop->flags & OBJ_PROP_LINK_STRONG) && *prop->targetp) {
+object_unref(*prop->targetp);
 }
 g_free(prop);
 }
 
 void object_property_add_link(Object *obj, const char *name,
-  const char *type, Object **child,
+  const char *type, Object **targetp,
   void (*check)(const Object *, const char *,
 Object *, Error **),
   ObjectPropertyLinkFlags flags,
@@ -1849,7 +1849,7 @@ void object_property_add_link(Object *obj, const char 
*name,
 gchar *full_type;
 ObjectProperty *op;
 
-prop->child = child;
+prop->targetp = targetp;
 prop->check = check;
 prop->flags = flags;
 
-- 
2.25.0.rc1.20.g2443f3f80d.dirty




Re: [PATCH 062/104] virtiofsd: Handle hard reboot

2020-01-10 Thread Dr. David Alan Gilbert
* Daniel P. Berrangé (berra...@redhat.com) wrote:
> On Thu, Dec 12, 2019 at 04:38:22PM +, Dr. David Alan Gilbert (git) wrote:
> > From: "Dr. David Alan Gilbert" 
> > 
> > Handle a
> >   mount
> >   hard reboot (without unmount)
> >   mount
> > 
> > we get another 'init' which FUSE doesn't normally expect.
> > 
> > Signed-off-by: Dr. David Alan Gilbert 
> > ---
> >  tools/virtiofsd/fuse_lowlevel.c | 16 +++-
> >  1 file changed, 15 insertions(+), 1 deletion(-)
> > 
> > diff --git a/tools/virtiofsd/fuse_lowlevel.c 
> > b/tools/virtiofsd/fuse_lowlevel.c
> > index 2d1d1a2e59..45125ef66a 100644
> > --- a/tools/virtiofsd/fuse_lowlevel.c
> > +++ b/tools/virtiofsd/fuse_lowlevel.c
> > @@ -2436,7 +2436,21 @@ void fuse_session_process_buf_int(struct 
> > fuse_session *se,
> >  goto reply_err;
> >  }
> >  } else if (in->opcode == FUSE_INIT || in->opcode == CUSE_INIT) {
> > -goto reply_err;
> > +if (fuse_lowlevel_is_virtio(se)) {
> > +/*
> > + * TODO: This is after a hard reboot typically, we need to do
> > + * a destroy, but we can't reply to this request yet so
> > + * we can't use do_destroy
> > + */
> > +fuse_log(FUSE_LOG_DEBUG, "%s: reinit\n", __func__);
> > +se->got_destroy = 1;
> > +se->got_init = 0;
> > +if (se->op.destroy) {
> > +se->op.destroy(se->userdata);
> > +}
> > +} else {
> > +goto reply_err;
> > +}
> 
> In doing this, is there any danger we're exposed to from a malicious
> guest which does
> 
>mount
>mount
> 
> without a reboot in between ?

I don't think so - or at least not from the daemon side of things; if it
were to do that (and get two FUSE_INIT's) then the state of it's first
mount would be rather messed up; but the only thing to suffer would be
the kernel doing that odd re-init, so I don't think the maliciousness
should break anyone else.


> I'm thinking not so if its ok, then
> 
>  Reviewed-by: Daniel P. Berrangé 

Thanks.

> 
> Regards,
> Daniel
> -- 
> |: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org -o-https://fstop138.berrange.com :|
> |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




[PATCH 22/26] vl: print default value in object help

2020-01-10 Thread Marc-André Lureau
Signed-off-by: Marc-André Lureau 
---
 qom/object_interfaces.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index 46cd6eab5c..edb4cc4a3d 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -185,6 +185,7 @@ bool user_creatable_print_help(const char *type, QemuOpts 
*opts)
 object_class_property_iter_init(, klass);
 while ((prop = object_property_iter_next())) {
 GString *str;
+char *defval;
 
 if (!prop->set) {
 continue;
@@ -192,6 +193,11 @@ bool user_creatable_print_help(const char *type, QemuOpts 
*opts)
 
 str = g_string_new(NULL);
 g_string_append_printf(str, "  %s=<%s>", prop->name, prop->type);
+defval = object_property_get_default(prop);
+if (defval) {
+g_string_append_printf(str, " (default: %s)", defval);
+g_free(defval);
+}
 if (prop->description) {
 if (str->len < 24) {
 g_string_append_printf(str, "%*s", 24 - (int)str->len, "");
-- 
2.25.0.rc1.20.g2443f3f80d.dirty




  1   2   3   >