Re: [PATCH v3 0/3] various: Remove unnecessary casts

2020-05-14 Thread Markus Armbruster
Philippe Mathieu-Daudé  writes:

> Remove unnecessary casts using coccinelle scripts.
>
> The CPU()/OBJECT() patches don't introduce logical change,
> The DEVICE() one removes various OBJECT_CHECK() calls.

Queued, thanks!

Managing expecations: I'm not a QOM maintainer, I don't want to become
one, and I don't normally queue QOM patches :)




Re: [PATCH v2 00/18] qom: Spring cleaning

2020-05-14 Thread Markus Armbruster
Markus Armbruster  writes:

> Paolo, would you like me to do the pull request myself?

I take that as a "yes" :)

I'll throw in Philippe's "[PATCH v3 0/3] various: Remove unnecessary
casts".  Simple and amply reviewed.




Re: proposal: deprecate -readconfig/-writeconfig

2020-05-14 Thread Markus Armbruster
Paolo Bonzini  writes:

> On 14/05/20 10:56, Daniel P. Berrangé wrote:
>> On Thu, May 14, 2020 at 10:09:21AM +0200, Paolo Bonzini wrote:
>>> IMHO configuration files are in general a failed experiment.  In
>>> practice, they do not add much value over just a shell script because
>>> they don't allow configuring all QEMU options, they are very much fixed
>>> (by their nature).  I think it's more or less agreed that they are not
>>> solving any problem for higher-level management stacks as well; those
>>> would prefer to configure the VM via QMP or another API.
>>>
>>> So, any objections to deprecating -readconfig and -writeconfig?
>> 
>> Libvirt would like to have a config file for QEMU, but it would have
>> to be one that actually covers all the config options QEMU supports,
>> and ideally using a data format in common with that used for runtime
>> changes. So for libvirt's needs the current readconfig is entirely
>> useless.
>
> Yes, this is what I was thinking about.
>
>> For a less general purpose mgmt app, that targets some specific use
>> cases I could imagine people might have used readconfig. [...]
>> If we deprecate them, the only alternative users have right now is
>> to go back to passing CLI args. [...] We'd be deciding to kill the
>> feature with no direct replacement, even though it is potentially
>> useful in some limited scenarios.
>> 
>> If we have a general strategy to eliminate QemuOpts and move entirely
>> to QAPI based config, then I can see -readcofig/-writeconfig may be
>> creating a burden of back compatibility on maintainers.
>
> I don't see QemuOpts going away anytime soon, but I do see more QMP/QAPI
> and less command line in the future as far as management tools are
> concerned.  QemuOpts and HMP will remain for direct usage, for the
> foreseeable future.

I'd prefer not to have two separate configuration infrastructures.

> So I guess we can keep -readconfig but deprecate, or even remove,
> -writeconfig.

Deprecate both as stable interfaces, remove neither.




Re: [PATCH v2 0/5] fix migration with bitmaps and mirror

2020-05-14 Thread Vladimir Sementsov-Ogievskiy

14.05.2020 21:29, Eric Blake wrote:

reviving this thread...

On 4/3/20 6:23 AM, Peter Krempa wrote:

On Fri, Apr 03, 2020 at 14:02:47 +0300, Vladimir Sementsov-Ogievskiy wrote:

19.12.2019 13:36, Peter Krempa wrote:

On Thu, Dec 19, 2019 at 11:51:01 +0300, Vladimir Sementsov-Ogievskiy wrote:

Hi all!

It's a continuation for
"bitmap migration bug with -drive while block mirror runs"
<315cff78-dcdb-a3ce-2742-da3cc9f0c...@redhat.com>
https://lists.gnu.org/archive/html/qemu-devel/2019-09/msg07241.html

The problem is that bitmaps migrated to node with same node-name or
blk-parent name. And currently only the latter actually work in libvirt.
And with mirror-top filter it doesn't work, because
bdrv_get_device_or_node_name don't go through filters.


I want to point out that since libvirt-5.10 we use -blockdev to
configure the backend of storage devices with qemu-4.2 and later. This
means unfortunately that the BlockBackend of the drive does not have a
name any more and thus the above will not work even if you make the
lookup code to see through filters.


Not that this series doesn't make things worse, as it loops through named
block backends when trying to use their name for migration. So with these
patches applied, qemu will just work in more possible scenarios.


Okay, if that's so it's fair enough in this case.

I'm just very firmly against baking in the assumption that
node names mean the same thing accross migration, because that will
create a precedent situation and more stuff may be baked in on top of
this in the future. It seems that it has already happened though and
it's wrong. And the worst part is that it's never mentioned that this
might occur. But again, don't do that and preferrably remove the
matching of node names for bitmaps altogether until we can control it
arbitrarily.

We've also seen this already before with the backend name of memory
devices being baked in to the migration stream which creates an unwanted
dependancy.


Max is trying to tackle the node-name issue:
https://lists.gnu.org/archive/html/qemu-devel/2020-05/msg03358.html

And trying to apply that patch after staging this series hits a conflict in 
mnigration/block-dirty-bitmap.c.  Which one should go in first?



My patches are needed to fix migration for the pre-blockdev configuration with 
mirror-top filter.

We ofcrouse need them in Virtuozzo, but it's not hard to keep the in 
downstream-only.. And it will be not simple to use new command from Max in 
pre-blockdev libvirt configuration, with auto-generated node-names.

How much we care about pre-blockdev libvirt now in upstream Qemu?

If we don't care, than these series are only for downstreams, and we don't need 
to apply them upstream..

On the other hand, Max have to resend anyway, to handle old code, which uses 
device name instead of node-name. And if we don't want to drop now the code 
which can use device name (needed for old libvirt), why not to apply the 
series, which just make old code better?



In other words: do we still support pre-blockdev libvirt (and any other 
pre-blockdev users)?

If we support, than, as I said somewhere, I need to resend these series as I 
have updated version in our downstream. And I think, I can rebase Max's patch 
by myself and send together with this all, if no objections.

--
Best regards,
Vladimir



Re: proposal: deprecate -readconfig/-writeconfig

2020-05-14 Thread Markus Armbruster
Daniel P. Berrangé  writes:

> On Thu, May 14, 2020 at 10:40:40AM -0400, John Snow wrote:
>> 
>> 
>> On 5/14/20 4:56 AM, Daniel P. Berrangé wrote:
>> > On Thu, May 14, 2020 at 10:09:21AM +0200, Paolo Bonzini wrote:
>> >> IMHO configuration files are in general a failed experiment.  In
>> >> practice, they do not add much value over just a shell script because
>> >> they don't allow configuring all QEMU options, they are very much fixed
>> >> (by their nature).  I think it's more or less agreed that they are not
>> >> solving any problem for higher-level management stacks as well; those
>> >> would prefer to configure the VM via QMP or another API.
>> >>
>> >> So, any objections to deprecating -readconfig and -writeconfig?
>> > 
>> > Libvirt would like to have a config file for QEMU, but it would have
>> > to be one that actually covers all the config options QEMU supports,
>> > and ideally using a data format in common with that used for runtime
>> > changes. So for libvirt's needs the current readconfig is entirely
>> > useless.
>> > 
>> 
>> Yeah. In this sense, would a json/yaml config file help, under the
>> premise that you could just cat it into the pipe to configure a machine?
>> 
>> (Assuming we had proper runtime configuration commands, of course.)
>
> Yeah, the key thing is that you really want to be able to provide the
> whole initial config in one go as an atomic action. I don't want to
> issue 100 individual QMP commands to load each initial device. With
> that in mind it doesn't really matter whether you do
>
>   $ qemu -qmp stdio
>   (qmp) load-config /some/file.yaml
>
> vs
>
>   $ qemu -qmp stdio -load-config /some/file.yaml
>
> though the latter is probably slightly nicer as it lets you grep
> for the VM based on the filename visible in the CLI. 

Once QEMU can do the former, providing the latter should be trivial.
Not providing it would be unadvisable.

Yes, a management application that talks QMP anyway can be expected to
be quite happy with having to do initial configuration via QMP, with or
without a load-config command.

But human users won't be happy.  Having to use a wrapper program to feed
their configuration file to QMP adds undue complexity.

[...]




Re: [PATCH Kernel v20 6/8] vfio iommu: Update UNMAP_DMA ioctl to get dirty bitmap before unmap

2020-05-14 Thread Alex Williamson
On Fri, 15 May 2020 09:46:43 +0530
Kirti Wankhede  wrote:

> On 5/15/2020 8:57 AM, Alex Williamson wrote:
> > On Fri, 15 May 2020 02:07:45 +0530
> > Kirti Wankhede  wrote:
> >   
> >> DMA mapped pages, including those pinned by mdev vendor drivers, might
> >> get unpinned and unmapped while migration is active and device is still
> >> running. For example, in pre-copy phase while guest driver could access
> >> those pages, host device or vendor driver can dirty these mapped pages.
> >> Such pages should be marked dirty so as to maintain memory consistency
> >> for a user making use of dirty page tracking.
> >>
> >> To get bitmap during unmap, user should allocate memory for bitmap, set
> >> it all zeros, set size of allocated memory, set page size to be
> >> considered for bitmap and set flag VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP.
> >>
> >> Signed-off-by: Kirti Wankhede 
> >> Reviewed-by: Neo Jia 
> >> ---
> >>   drivers/vfio/vfio_iommu_type1.c | 77 
> >> ++---
> >>   include/uapi/linux/vfio.h   | 10 ++
> >>   2 files changed, 75 insertions(+), 12 deletions(-)
> >>
> >> diff --git a/drivers/vfio/vfio_iommu_type1.c 
> >> b/drivers/vfio/vfio_iommu_type1.c
> >> index b76d3b14abfd..a1dc57bcece5 100644
> >> --- a/drivers/vfio/vfio_iommu_type1.c
> >> +++ b/drivers/vfio/vfio_iommu_type1.c
> >> @@ -195,11 +195,15 @@ static void vfio_unlink_dma(struct vfio_iommu 
> >> *iommu, struct vfio_dma *old)
> >>   static int vfio_dma_bitmap_alloc(struct vfio_dma *dma, size_t pgsize)
> >>   {
> >>uint64_t npages = dma->size / pgsize;
> >> +  size_t bitmap_size;
> >>   
> >>if (npages > DIRTY_BITMAP_PAGES_MAX)
> >>return -EINVAL;
> >>   
> >> -  dma->bitmap = kvzalloc(DIRTY_BITMAP_BYTES(npages), GFP_KERNEL);
> >> +  /* Allocate extra 64 bits which are used for bitmap manipulation */
> >> +  bitmap_size = DIRTY_BITMAP_BYTES(npages) + sizeof(u64);
> >> +
> >> +  dma->bitmap = kvzalloc(bitmap_size, GFP_KERNEL);
> >>if (!dma->bitmap)
> >>return -ENOMEM;
> >>   
> >> @@ -999,23 +1003,25 @@ static int verify_bitmap_size(uint64_t npages, 
> >> uint64_t bitmap_size)
> >>   }
> >>   
> >>   static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
> >> -   struct vfio_iommu_type1_dma_unmap *unmap)
> >> +   struct vfio_iommu_type1_dma_unmap *unmap,
> >> +   struct vfio_bitmap *bitmap)
> >>   {
> >> -  uint64_t mask;
> >>struct vfio_dma *dma, *dma_last = NULL;
> >> -  size_t unmapped = 0;
> >> +  size_t unmapped = 0, pgsize;
> >>int ret = 0, retries = 0;
> >> +  unsigned long pgshift;
> >>   
> >>mutex_lock(>lock);
> >>   
> >> -  mask = ((uint64_t)1 << __ffs(iommu->pgsize_bitmap)) - 1;
> >> +  pgshift = __ffs(iommu->pgsize_bitmap);
> >> +  pgsize = (size_t)1 << pgshift;
> >>   
> >> -  if (unmap->iova & mask) {
> >> +  if (unmap->iova & (pgsize - 1)) {
> >>ret = -EINVAL;
> >>goto unlock;
> >>}
> >>   
> >> -  if (!unmap->size || unmap->size & mask) {
> >> +  if (!unmap->size || unmap->size & (pgsize - 1)) {
> >>ret = -EINVAL;
> >>goto unlock;
> >>}
> >> @@ -1026,9 +1032,15 @@ static int vfio_dma_do_unmap(struct vfio_iommu 
> >> *iommu,
> >>goto unlock;
> >>}
> >>   
> >> -  WARN_ON(mask & PAGE_MASK);
> >> -again:
> >> +  /* When dirty tracking is enabled, allow only min supported pgsize */
> >> +  if ((unmap->flags & VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP) &&
> >> +  (!iommu->dirty_page_tracking || (bitmap->pgsize != pgsize))) {
> >> +  ret = -EINVAL;
> >> +  goto unlock;
> >> +  }
> >>   
> >> +  WARN_ON((pgsize - 1) & PAGE_MASK);
> >> +again:
> >>/*
> >> * vfio-iommu-type1 (v1) - User mappings were coalesced together to
> >> * avoid tracking individual mappings.  This means that the granularity
> >> @@ -1066,6 +1078,7 @@ static int vfio_dma_do_unmap(struct vfio_iommu 
> >> *iommu,
> >>ret = -EINVAL;
> >>goto unlock;
> >>}
> >> +
> >>dma = vfio_find_dma(iommu, unmap->iova + unmap->size - 1, 0);
> >>if (dma && dma->iova + dma->size != unmap->iova + unmap->size) {
> >>ret = -EINVAL;
> >> @@ -1083,6 +1096,23 @@ static int vfio_dma_do_unmap(struct vfio_iommu 
> >> *iommu,
> >>if (dma->task->mm != current->mm)
> >>break;
> >>   
> >> +  if ((unmap->flags & VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP) &&
> >> +  (dma_last != dma)) {
> >> +
> >> +  /*
> >> +   * mark all pages dirty if all pages are pinned and
> >> +   * mapped
> >> +   */
> >> +  if (dma->iommu_mapped)
> >> +  bitmap_set(dma->bitmap, 0,
> >> + dma->size >> pgshift);  
> > 
> > Nit, all the callers of update_user_bitmap() precede the call with this
> > 

Re: proposal: deprecate -readconfig/-writeconfig

2020-05-14 Thread Markus Armbruster
Daniel P. Berrangé  writes:

> On Thu, May 14, 2020 at 05:51:02PM +0200, Paolo Bonzini wrote:
>> On 14/05/20 17:34, Daniel P. Berrangé wrote:
>> > Yeah, the key thing is that you really want to be able to provide the
>> > whole initial config in one go as an atomic action. I don't want to
>> > issue 100 individual QMP commands to load each initial device.
>> 
>> Why?  I think if we do something like the qemu-vm-$TARGET that you
>> propose below, there's absolutely no difference between the two.
>
> Ok, I should clarify. I don't want to do 100 individual serialized
> round-trip request+reply, as that'd create latency on startup.
> 100 pipelined/parallelized request+reply would be ok, as you'll
> not have the synchronization delay for each command.
>
> Today the biggest cause of slow startup in libvirt, is issuing
> something like 100+ serialized QMP calls to check status of
> individual CPUID features. Possibly this is already just a libvirt
> bug we can could just stuff all 100 qom-get queries down the pipe
> in one go and have 1 wait for replies to arrive.

Hundreds of serialized QMP roundtrips are certainly bad.

Sending hundreds of QMP commands before reading any QMP output would
also be bad: it relies on QEMU to buffer the output.  It does, but
unlimited buffering is bad, and you shouldn't rely on it to stay.

Instead, send your input as fast as QEMU accepts it (it *will* stop
reading if you send input faster than it can process it), and also
receive output as fast as you can, until you got it all.

[...]




Re: [PATCH v2] bitmaps: Update maintainer

2020-05-14 Thread Vladimir Sementsov-Ogievskiy

14.05.2020 21:00, Eric Blake wrote:

Dirty bitmaps are important to incremental backups, including exposure
over NBD where I'm already maintainer.  Also, I'm aware that lately I
have been doing as much code/review on bitmaps as John Snow who is
trying to scale back in order to focus elsewhere; and many of the
recent patches have come from Vladimir, who is also interested in
taking on maintainer duties, but would like to start with
co-maintainership.  Therefore, it's time to revamp the ownership of
this category, as agreed between the three of us.

Signed-off-by: Eric Blake 
---

v2: further tweak to maintainership, update T: listing

  MAINTAINERS | 7 ---
  1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index d11f3cb97613..ae23062a51ac 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2001,8 +2001,9 @@ F: qapi/transaction.json
  T: git https://repo.or.cz/qemu/armbru.git block-next

  Dirty Bitmaps
-M: John Snow 
-R: Vladimir Sementsov-Ogievskiy 
+M: Eric Blake 
+M: Vladimir Sementsov-Ogievskiy 
+R: John Snow 
  L: qemu-bl...@nongnu.org
  S: Supported
  F: include/qemu/hbitmap.h
@@ -2013,7 +2014,7 @@ F: migration/block-dirty-bitmap.c
  F: util/hbitmap.c
  F: tests/test-hbitmap.c
  F: docs/interop/bitmaps.rst
-T: git https://github.com/jnsnow/qemu.git bitmaps
+T: git https://repo.or.cz/qemu/ericb.git bitmaps

  Character device backends
  M: Marc-André Lureau 



Reviewed-by: Vladimir Sementsov-Ogievskiy 

--
Best regards,
Vladimir



Re: proposal: deprecate -readconfig/-writeconfig

2020-05-14 Thread Markus Armbruster
Gerd Hoffmann  writes:

> On Thu, May 14, 2020 at 10:09:21AM +0200, Paolo Bonzini wrote:
>> IMHO configuration files are in general a failed experiment.  In
>> practice, they do not add much value over just a shell script because
>> they don't allow configuring all QEMU options, they are very much fixed
>> (by their nature).  I think it's more or less agreed that they are not
>> solving any problem for higher-level management stacks as well; those
>> would prefer to configure the VM via QMP or another API.
>> 
>> So, any objections to deprecating -readconfig and -writeconfig?
>
> -writeconfig surely can go away, it never reached the point where it
> could write out an configuration which is actually complete.
>
> -readconfig is a bit more tricky, it's actually useful.  I'm using it
> sometimes.

I use it all the time.

> Also we have docs/config/ with a bunch of files you can
> pass to -readconfig.

True.

> I can see that it'll stand in the way if we want move away from QemuOpts
> to something else (say qom-based yaml/json config files), so I wouldn't
> veto deprecation, but I'd prefer it not being actually dropped until the
> replacement is ready and the stuff in docs/config/ being converted to
> the new scheme.

I want QemuOpts replaced, and I want its replacement to support
configuration files.

The replacement effort needs some license for incompatible change.  The
less license, the harder the job becomes.

The configuration file format is among the things that'll change.

QemuOpts was a reasonable step forward back when you invented it, and it
served us well for some time, but we've outgrown it.  It's basically
two-level: configuration group ("drive", "chardev", "device", ...) and
option parameter (for "chardev": "backend", "path", "host", ...).  We
really need trees now.  I can't see how to grow the current INI-like
configuration file syntax compatibly to trees without making it overly
verbose.

Telling users now not to rely on the configuration file format to remain
compatible makes sense to me.




Re: [PATCH v2 4/9] riscv: Initial commit of OpenTitan machine

2020-05-14 Thread Bin Meng
On Fri, May 8, 2020 at 3:26 AM Alistair Francis
 wrote:
>
> This adds a barebone OpenTitan machine to QEMU.
>
> Signed-off-by: Alistair Francis 
> ---
>  MAINTAINERS |  10 ++
>  default-configs/riscv32-softmmu.mak |   1 +
>  default-configs/riscv64-softmmu.mak |  11 +-
>  hw/riscv/Kconfig|   5 +
>  hw/riscv/Makefile.objs  |   1 +
>  hw/riscv/opentitan.c| 169 
>  include/hw/riscv/opentitan.h|  63 +++
>  7 files changed, 259 insertions(+), 1 deletion(-)
>  create mode 100644 hw/riscv/opentitan.c
>  create mode 100644 include/hw/riscv/opentitan.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 1f84e3ae2c..c3d77f0861 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1229,6 +1229,16 @@ F: pc-bios/canyonlands.dt[sb]
>  F: pc-bios/u-boot-sam460ex-20100605.bin
>  F: roms/u-boot-sam460ex
>
> +RISC-V Machines
> +-

nits: please make --- end at an aligned place to the line before

> +OpenTitan
> +M: Alistair Francis 
> +L: qemu-ri...@nongnu.org
> +S: Supported
> +F: hw/riscv/opentitan.c
> +F: include/hw/riscv/opentitan.h
> +
> +
>  SH4 Machines
>  
>  R2D
> diff --git a/default-configs/riscv32-softmmu.mak 
> b/default-configs/riscv32-softmmu.mak
> index 1ae077ed87..94a236c9c2 100644
> --- a/default-configs/riscv32-softmmu.mak
> +++ b/default-configs/riscv32-softmmu.mak
> @@ -10,3 +10,4 @@ CONFIG_SPIKE=y
>  CONFIG_SIFIVE_E=y
>  CONFIG_SIFIVE_U=y
>  CONFIG_RISCV_VIRT=y
> +CONFIG_OPENTITAN=y
> diff --git a/default-configs/riscv64-softmmu.mak 
> b/default-configs/riscv64-softmmu.mak
> index 235c6f473f..aaf6d735bb 100644
> --- a/default-configs/riscv64-softmmu.mak
> +++ b/default-configs/riscv64-softmmu.mak
> @@ -1,3 +1,12 @@
>  # Default configuration for riscv64-softmmu
>
> -include riscv32-softmmu.mak
> +# Uncomment the following lines to disable these optional devices:
> +#
> +#CONFIG_PCI_DEVICES=n
> +
> +# Boards:
> +#
> +CONFIG_SPIKE=y
> +CONFIG_SIFIVE_E=y
> +CONFIG_SIFIVE_U=y
> +CONFIG_RISCV_VIRT=y
> diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
> index ff9fbe958a..94d19571f7 100644
> --- a/hw/riscv/Kconfig
> +++ b/hw/riscv/Kconfig
> @@ -27,6 +27,11 @@ config SPIKE
>  select HTIF
>  select SIFIVE
>
> +config OPENTITAN
> +bool
> +select HART
> +select UNIMP
> +
>  config RISCV_VIRT
>  bool
>  imply PCI_DEVICES
> diff --git a/hw/riscv/Makefile.objs b/hw/riscv/Makefile.objs
> index fc3c6dd7c8..57cc708f5d 100644
> --- a/hw/riscv/Makefile.objs
> +++ b/hw/riscv/Makefile.objs
> @@ -1,6 +1,7 @@
>  obj-y += boot.o
>  obj-$(CONFIG_SPIKE) += riscv_htif.o
>  obj-$(CONFIG_HART) += riscv_hart.o
> +obj-$(CONFIG_OPENTITAN) += opentitan.o
>  obj-$(CONFIG_SIFIVE_E) += sifive_e.o
>  obj-$(CONFIG_SIFIVE_E) += sifive_e_prci.o
>  obj-$(CONFIG_SIFIVE) += sifive_clint.o
> diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
> new file mode 100644
> index 00..c00f0720ab
> --- /dev/null
> +++ b/hw/riscv/opentitan.c
> @@ -0,0 +1,169 @@
> +/*
> + * QEMU RISC-V Board Compatible with OpenTitan FPGA platform
> + *
> + * Copyright (c) 2020 Western Digital
> + *
> + * Provides a board compatible with the OpenTitan FPGA platform:
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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 "hw/riscv/opentitan.h"
> +#include "qapi/error.h"
> +#include "hw/boards.h"
> +#include "hw/misc/unimp.h"
> +#include "hw/riscv/boot.h"
> +#include "exec/address-spaces.h"
> +
> +static const struct MemmapEntry {
> +hwaddr base;
> +hwaddr size;
> +} ibex_memmap[] = {
> +[IBEX_ROM] ={  0x8000,   0xc000 },
> +[IBEX_RAM] ={  0x1000,  0x1 },
> +[IBEX_FLASH] =  {  0x2000,  0x8 },
> +[IBEX_UART] =   {  0x4000,  0x1 },
> +[IBEX_GPIO] =   {  0x4001,  0x1 },
> +[IBEX_SPI] ={  0x4002,  0x1 },
> +[IBEX_FLASH_CTRL] = {  0x4003,  0x1 },
> +[IBEX_PINMUX] = {  0x4007,  0x1 },
> +[IBEX_RV_TIMER] =   {  0x4008,  0x1 },
> +[IBEX_PLIC] =   {  0x4009,  0x1 },
> +[IBEX_AES] ={  0x4011,  0x1 },
> +[IBEX_HMAC] =   {  0x4012,  0x1 },
> +[IBEX_ALERT_HANDLER] =  {  0x4013,  0x1 },
> +[IBEX_USBDEV] = {  

Re: [PATCH v2 1/9] riscv/boot: Add a missing header include

2020-05-14 Thread Bin Meng
Hi Alistair,

On Thu, May 14, 2020 at 11:38 PM Alistair Francis  wrote:
>
> On Thu, May 14, 2020 at 8:34 AM Bin Meng  wrote:
> >
> > On Fri, May 8, 2020 at 3:24 AM Alistair Francis
> >  wrote:
> > >
> > > Signed-off-by: Alistair Francis 
> > > ---
> > >  include/hw/riscv/boot.h | 1 +
> > >  1 file changed, 1 insertion(+)
> > >
> > > diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
> > > index 474a940ad5..9daa98da08 100644
> > > --- a/include/hw/riscv/boot.h
> > > +++ b/include/hw/riscv/boot.h
> > > @@ -21,6 +21,7 @@
> > >  #define RISCV_BOOT_H
> > >
> > >  #include "exec/cpu-defs.h"
> > > +#include "hw/loader.h"
> >
> > Why is this needed? Currently this does not break build.
>
> Currently every c file that includes boot.h also includes loader.h
> before it. Which is why the build works fine. We should be able to
> include just boot.h though so this is a small fixup to allow that.
>

Please include such in the commit message to help people understand.

Reviewed-by: Bin Meng 

Regards,
Bin



Re: [PATCH v2 3/9] target/riscv: Add the lowRISC Ibex CPU

2020-05-14 Thread Bin Meng
On Fri, May 8, 2020 at 3:23 AM Alistair Francis
 wrote:
>

Please include some commit message to have a brief introduction of this new CPU.

> Signed-off-by: Alistair Francis 
> ---
>  target/riscv/cpu.c | 10 ++
>  target/riscv/cpu.h |  1 +
>  2 files changed, 11 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 8f837edf8d..235101f685 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -160,6 +160,15 @@ static void rv32gcsu_priv1_10_0_cpu_init(Object *obj)
>  set_feature(env, RISCV_FEATURE_PMP);
>  }
>
> +static void rv32imcu_nommu_cpu_init(Object *obj)
> +{
> +CPURISCVState *env = _CPU(obj)->env;
> +set_misa(env, RV32 | RVI | RVM | RVC | RVU);
> +set_priv_version(env, PRIV_VERSION_1_10_0);
> +set_resetvec(env, 0x8088);
> +set_feature(env, RISCV_FEATURE_PMP);
> +}
> +
>  static void rv32imacu_nommu_cpu_init(Object *obj)
>  {
>  CPURISCVState *env = _CPU(obj)->env;
> @@ -620,6 +629,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>  DEFINE_CPU(TYPE_RISCV_CPU_ANY,  riscv_any_cpu_init),
>  #if defined(TARGET_RISCV32)
>  DEFINE_CPU(TYPE_RISCV_CPU_BASE32,   riscv_base32_cpu_init),
> +DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32imcu_nommu_cpu_init),
>  DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31,   rv32imacu_nommu_cpu_init),
>  DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34,   rv32imafcu_nommu_cpu_init),
>  DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34,   
> rv32gcsu_priv1_10_0_cpu_init),
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index d0e7f5b9c5..8733d7467f 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -35,6 +35,7 @@
>  #define TYPE_RISCV_CPU_ANY  RISCV_CPU_TYPE_NAME("any")
>  #define TYPE_RISCV_CPU_BASE32   RISCV_CPU_TYPE_NAME("rv32")
>  #define TYPE_RISCV_CPU_BASE64   RISCV_CPU_TYPE_NAME("rv64")
> +#define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex")
>  #define TYPE_RISCV_CPU_SIFIVE_E31   RISCV_CPU_TYPE_NAME("sifive-e31")
>  #define TYPE_RISCV_CPU_SIFIVE_E34   RISCV_CPU_TYPE_NAME("sifive-e34")
>  #define TYPE_RISCV_CPU_SIFIVE_E51   RISCV_CPU_TYPE_NAME("sifive-e51")
> --

Otherwise, looks good to me.
Reviewed-by: Bin Meng 

Regards,
Bin



Re: [PATCH v2 2/9] target/riscv: Don't overwrite the reset vector

2020-05-14 Thread Bin Meng
On Fri, May 15, 2020 at 5:51 AM Alistair Francis  wrote:
>
> On Thu, May 14, 2020 at 10:54 AM Philippe Mathieu-Daudé
>  wrote:
> >
> > On 5/7/20 9:13 PM, Alistair Francis wrote:
> > > If the reset vector is set in the init function don't set it again in
> > > realise.
> >
> > typo "realize".
>
> It's not a typo, just correct English :)
>
> I have changed it.
>
> >
> > >
> > > Signed-off-by: Alistair Francis 
> > > ---
> > >   target/riscv/cpu.c | 20 +++-
> > >   1 file changed, 11 insertions(+), 9 deletions(-)
> > >
> > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > > index 059d71f2c7..8f837edf8d 100644
> > > --- a/target/riscv/cpu.c
> > > +++ b/target/riscv/cpu.c
> > > @@ -111,6 +111,14 @@ static void set_feature(CPURISCVState *env, int 
> > > feature)
> > >   env->features |= (1ULL << feature);
> > >   }
> > >
> > > +static int get_resetvec(CPURISCVState *env)
> > > +{
> > > +#ifndef CONFIG_USER_ONLY
> > > +return env->resetvec;
> > > +#endif
> > > +return 0;
> >
> > Don't you get an error about double return? Maybe use #else?
>
> Apparently not, I have changed it though.
>
> Alistair
>
> >
> > > +}
> > > +
> > >   static void set_resetvec(CPURISCVState *env, int resetvec)
> > >   {
> > >   #ifndef CONFIG_USER_ONLY
> > > @@ -123,7 +131,6 @@ static void riscv_any_cpu_init(Object *obj)
> > >   CPURISCVState *env = _CPU(obj)->env;
> > >   set_misa(env, RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVU);
> > >   set_priv_version(env, PRIV_VERSION_1_11_0);
> > > -set_resetvec(env, DEFAULT_RSTVEC);
> > >   }
> > >
> > >   #if defined(TARGET_RISCV32)
> > > @@ -140,7 +147,6 @@ static void rv32gcsu_priv1_09_1_cpu_init(Object *obj)
> > >   CPURISCVState *env = _CPU(obj)->env;
> > >   set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> > >   set_priv_version(env, PRIV_VERSION_1_09_1);
> > > -set_resetvec(env, DEFAULT_RSTVEC);
> > >   set_feature(env, RISCV_FEATURE_MMU);
> > >   set_feature(env, RISCV_FEATURE_PMP);
> > >   }
> > > @@ -150,7 +156,6 @@ static void rv32gcsu_priv1_10_0_cpu_init(Object *obj)
> > >   CPURISCVState *env = _CPU(obj)->env;
> > >   set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> > >   set_priv_version(env, PRIV_VERSION_1_10_0);
> > > -set_resetvec(env, DEFAULT_RSTVEC);
> > >   set_feature(env, RISCV_FEATURE_MMU);
> > >   set_feature(env, RISCV_FEATURE_PMP);
> > >   }
> > > @@ -160,7 +165,6 @@ static void rv32imacu_nommu_cpu_init(Object *obj)
> > >   CPURISCVState *env = _CPU(obj)->env;
> > >   set_misa(env, RV32 | RVI | RVM | RVA | RVC | RVU);
> > >   set_priv_version(env, PRIV_VERSION_1_10_0);
> > > -set_resetvec(env, DEFAULT_RSTVEC);
> > >   set_feature(env, RISCV_FEATURE_PMP);
> > >   }
> > >
> > > @@ -169,7 +173,6 @@ static void rv32imafcu_nommu_cpu_init(Object *obj)
> > >   CPURISCVState *env = _CPU(obj)->env;
> > >   set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVC | RVU);
> > >   set_priv_version(env, PRIV_VERSION_1_10_0);
> > > -set_resetvec(env, DEFAULT_RSTVEC);
> > >   set_feature(env, RISCV_FEATURE_PMP);
> > >   }
> > >
> > > @@ -187,7 +190,6 @@ static void rv64gcsu_priv1_09_1_cpu_init(Object *obj)
> > >   CPURISCVState *env = _CPU(obj)->env;
> > >   set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> > >   set_priv_version(env, PRIV_VERSION_1_09_1);
> > > -set_resetvec(env, DEFAULT_RSTVEC);
> > >   set_feature(env, RISCV_FEATURE_MMU);
> > >   set_feature(env, RISCV_FEATURE_PMP);
> > >   }
> > > @@ -197,7 +199,6 @@ static void rv64gcsu_priv1_10_0_cpu_init(Object *obj)
> > >   CPURISCVState *env = _CPU(obj)->env;
> > >   set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> > >   set_priv_version(env, PRIV_VERSION_1_10_0);
> > > -set_resetvec(env, DEFAULT_RSTVEC);
> > >   set_feature(env, RISCV_FEATURE_MMU);
> > >   set_feature(env, RISCV_FEATURE_PMP);
> > >   }
> > > @@ -207,7 +208,6 @@ static void rv64imacu_nommu_cpu_init(Object *obj)
> > >   CPURISCVState *env = _CPU(obj)->env;
> > >   set_misa(env, RV64 | RVI | RVM | RVA | RVC | RVU);
> > >   set_priv_version(env, PRIV_VERSION_1_10_0);
> > > -set_resetvec(env, DEFAULT_RSTVEC);
> > >   set_feature(env, RISCV_FEATURE_PMP);
> > >   }
> > >
> > > @@ -399,7 +399,9 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
> > > **errp)
> > >   }
> > >
> > >   set_priv_version(env, priv_version);
> > > -set_resetvec(env, DEFAULT_RSTVEC);
> > > +if (!get_resetvec(env)) {

What if we have a RISC-V CPU whose reset vector is at address 0?

> > > +set_resetvec(env, DEFAULT_RSTVEC);
> > > +}
> > >
> > >   if (cpu->cfg.mmu) {
> > >   set_feature(env, RISCV_FEATURE_MMU);
> > >

Regards,
Bin



Re: [Virtio-fs] [PATCH] virtiofsd: remove symlink fallbacks

2020-05-14 Thread Miklos Szeredi
On Fri, May 15, 2020 at 5:43 AM Liu Bo  wrote:
>
> On Thu, May 14, 2020 at 04:07:36PM +0200, Miklos Szeredi wrote:
> > Path lookup in the kernel has special rules for looking up magic symlinks
> > under /proc.  If a filesystem operation is instructed to follow symlinks
> > (e.g. via AT_SYMLINK_FOLLOW or lack of AT_SYMLINK_NOFOLLOW), and the final
> > component is such a proc symlink, then the target of the magic symlink is
> > used for the operation, even if the target itself is a symlink.  I.e. path
> > lookup is always terminated after following a final magic symlink.
> >
>
> Hi Miklos,
>
> Are these mentioned special rules supported by a recent kernel version
> or are they there from day one linux?

Hi Liubo,

AFAICS, these rules have been there from day one.

Thanks,
Miklos




[PATCH 3/3] migration/colo: Merge multi checkpoint request into one.

2020-05-14 Thread Zhang Chen
From: Zhang Chen 

When COLO guest occur issues, COLO-compare will catch lots of
different network packet and trigger notification multi times,
force periodic may happen at the same time. So this can be
efficient merge checkpoint request within COLO_CHECKPOINT_INTERVAL.

Signed-off-by: Zhang Chen 
---
 migration/colo.c | 22 --
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/migration/colo.c b/migration/colo.c
index d5bced22cb..e6a7d8c6e2 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -47,6 +47,9 @@ static COLOMode last_colo_mode;
 
 #define COLO_BUFFER_BASE_SIZE (4 * 1024 * 1024)
 
+/* Default COLO_CHECKPOINT_INTERVAL is 1000 ms */
+#define COLO_CHECKPOINT_INTERVAL 1000
+
 bool migration_in_colo_state(void)
 {
 MigrationState *s = migrate_get_current();
@@ -651,13 +654,20 @@ out:
 void colo_checkpoint_notify(void *opaque)
 {
 MigrationState *s = opaque;
-int64_t next_notify_time;
+int64_t now = qemu_clock_get_ms(QEMU_CLOCK_HOST);
 
-qemu_sem_post(>colo_checkpoint_sem);
-s->colo_checkpoint_time = qemu_clock_get_ms(QEMU_CLOCK_HOST);
-next_notify_time = s->colo_checkpoint_time +
-s->parameters.x_checkpoint_delay;
-timer_mod(s->colo_delay_timer, next_notify_time);
+/*
+ * When COLO guest occur issues, COLO-compare will catch lots of
+ * different network packet and trigger notification multi times,
+ * force periodic may happen at the same time. So this can be
+ * efficient merge checkpoint request within COLO_CHECKPOINT_INTERVAL.
+ */
+if (now > s->colo_checkpoint_time + COLO_CHECKPOINT_INTERVAL) {
+qemu_sem_post(>colo_checkpoint_sem);
+timer_mod(s->colo_delay_timer, now +
+  s->parameters.x_checkpoint_delay);
+s->colo_checkpoint_time = now;
+}
 }
 
 void migrate_start_colo_process(MigrationState *s)
-- 
2.17.1




[PATCH 2/3] migration/colo: Update checkpoint time lately

2020-05-14 Thread Zhang Chen
From: Zhang Chen 

Previous operation(like vm_start and replication_start_all) will consume
extra time for first forced synchronization, so reduce it in this patch.

Signed-off-by: Zhang Chen 
---
 migration/colo.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/migration/colo.c b/migration/colo.c
index 5ef69b885d..d5bced22cb 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -531,7 +531,6 @@ static void colo_process_checkpoint(MigrationState *s)
 {
 QIOChannelBuffer *bioc;
 QEMUFile *fb = NULL;
-int64_t current_time = qemu_clock_get_ms(QEMU_CLOCK_HOST);
 Error *local_err = NULL;
 int ret;
 
@@ -580,8 +579,8 @@ static void colo_process_checkpoint(MigrationState *s)
 qemu_mutex_unlock_iothread();
 trace_colo_vm_state_change("stop", "run");
 
-timer_mod(s->colo_delay_timer,
-current_time + s->parameters.x_checkpoint_delay);
+timer_mod(s->colo_delay_timer, qemu_clock_get_ms(QEMU_CLOCK_HOST) +
+  s->parameters.x_checkpoint_delay);
 
 while (s->state == MIGRATION_STATUS_COLO) {
 if (failover_get_state() != FAILOVER_STATUS_NONE) {
-- 
2.17.1




Re: [PATCH v3 2/3] various: Remove unnecessary OBJECT() cast

2020-05-14 Thread Markus Armbruster
Philippe Mathieu-Daudé  writes:

> The OBJECT() macro is defined as:
>
>   #define OBJECT(obj) ((Object *)(obj))
>
> Remove the unnecessary OBJECT() casts when we already know the
> pointer is of Object type.
>
> Patch created mechanically using spatch with this script:
>
>   @@
>   typedef Object;
>   Object *o;
>   @@
>   -   OBJECT(o)
>   +   o
>
> Acked-by: Cornelia Huck 
> Acked-by: Corey Minyard 
> Acked-by: John Snow 
> Reviewed-by: Richard Henderson 
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Markus Armbruster 




[PATCH 0/3] migration/colo: Optimize COLO framework code

2020-05-14 Thread Zhang Chen
From: Zhang Chen 

This series optimize some code of COLO, please review.

Zhang Chen (3):
  migration/colo: Optimize COLO boot code path
  migration/colo: Update checkpoint time lately
  migration/colo: Merge multi checkpoint request into one.

 migration/colo.c  | 29 ++---
 migration/migration.c | 17 ++---
 2 files changed, 28 insertions(+), 18 deletions(-)

-- 
2.17.1




[PATCH 1/3] migration/colo: Optimize COLO boot code path

2020-05-14 Thread Zhang Chen
From: Zhang Chen 

No need to reuse MIGRATION_STATUS_ACTIVE boot COLO.

Signed-off-by: Zhang Chen 
---
 migration/colo.c  |  2 --
 migration/migration.c | 17 ++---
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/migration/colo.c b/migration/colo.c
index d015d4f84e..5ef69b885d 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -669,8 +669,6 @@ void migrate_start_colo_process(MigrationState *s)
 colo_checkpoint_notify, s);
 
 qemu_sem_init(>colo_exit_sem, 0);
-migrate_set_state(>state, MIGRATION_STATUS_ACTIVE,
-  MIGRATION_STATUS_COLO);
 colo_process_checkpoint(s);
 qemu_mutex_lock_iothread();
 }
diff --git a/migration/migration.c b/migration/migration.c
index 0bb042a0f7..c889ef6eb7 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2972,7 +2972,10 @@ static void migration_completion(MigrationState *s)
 goto fail_invalidate;
 }
 
-if (!migrate_colo_enabled()) {
+if (migrate_colo_enabled()) {
+migrate_set_state(>state, current_active_state,
+  MIGRATION_STATUS_COLO);
+} else {
 migrate_set_state(>state, current_active_state,
   MIGRATION_STATUS_COMPLETED);
 }
@@ -3304,12 +3307,7 @@ static void migration_iteration_finish(MigrationState *s)
 migration_calculate_complete(s);
 runstate_set(RUN_STATE_POSTMIGRATE);
 break;
-
-case MIGRATION_STATUS_ACTIVE:
-/*
- * We should really assert here, but since it's during
- * migration, let's try to reduce the usage of assertions.
- */
+case MIGRATION_STATUS_COLO:
 if (!migrate_colo_enabled()) {
 error_report("%s: critical error: calling COLO code without "
  "COLO enabled", __func__);
@@ -3319,6 +3317,11 @@ static void migration_iteration_finish(MigrationState *s)
  * Fixme: we will run VM in COLO no matter its old running state.
  * After exited COLO, we will keep running.
  */
+case MIGRATION_STATUS_ACTIVE:
+/*
+ * We should really assert here, but since it's during
+ * migration, let's try to reduce the usage of assertions.
+ */
 s->vm_was_running = true;
 /* Fallthrough */
 case MIGRATION_STATUS_FAILED:
-- 
2.17.1




[PATCH v4 2/3] tests/util-sockets: add abstract unix socket cases

2020-05-14 Thread xiaoqiang zhao
add cases to test tight and non-tight for abstract address type

Signed-off-by: xiaoqiang zhao 
---
 tests/test-util-sockets.c | 91 +++
 1 file changed, 91 insertions(+)

diff --git a/tests/test-util-sockets.c b/tests/test-util-sockets.c
index 5fd947c7bf..c21a90634a 100644
--- a/tests/test-util-sockets.c
+++ b/tests/test-util-sockets.c
@@ -227,6 +227,92 @@ static void test_socket_fd_pass_num_nocli(void)
 g_free(addr.u.fd.str);
 }
 
+static gchar *abstract_sock_name;
+
+static gpointer unix_server_thread_func(gpointer user_data)
+{
+SocketAddress addr;
+Error *err = NULL;
+int fd = -1;
+int connfd = -1;
+struct sockaddr_un un;
+socklen_t len = sizeof(un);
+
+addr.type = SOCKET_ADDRESS_TYPE_UNIX;
+addr.u.q_unix.path = abstract_sock_name;
+addr.u.q_unix.tight = user_data != NULL;
+addr.u.q_unix.abstract = true;
+
+fd = socket_listen(, 1, );
+g_assert_cmpint(fd, >=, 0);
+g_assert(fd_is_socket(fd));
+
+connfd = accept(fd, (struct sockaddr *), );
+g_assert_cmpint(connfd, !=, -1);
+
+close(fd);
+
+return NULL;
+}
+
+static gpointer unix_client_thread_func(gpointer user_data)
+{
+SocketAddress addr;
+Error *err = NULL;
+int fd = -1;
+
+addr.type = SOCKET_ADDRESS_TYPE_UNIX;
+addr.u.q_unix.path = abstract_sock_name;
+addr.u.q_unix.tight = user_data != NULL;
+addr.u.q_unix.abstract = true;
+
+fd = socket_connect(, );
+
+g_assert_cmpint(fd, >=, 0);
+
+close(fd);
+
+return NULL;
+}
+
+static void test_socket_unix_abstract_good(void)
+{
+
+GRand *r = g_rand_new();
+
+abstract_sock_name = g_strdup_printf("unix-%d-%d", getpid(),
+g_rand_int_range(r, 100, 1000));
+
+/* non tight socklen serv and cli */
+GThread *serv = g_thread_new("abstract_unix_server",
+ unix_server_thread_func,
+ NULL);
+
+sleep(1);
+
+GThread *cli = g_thread_new("abstruct_unix_client",
+unix_client_thread_func,
+NULL);
+
+g_thread_join(cli);
+g_thread_join(serv);
+
+/* tight socklen serv and cli */
+serv = g_thread_new("abstract_unix_server",
+unix_server_thread_func,
+(gpointer)1);
+
+sleep(1);
+
+cli = g_thread_new("abstruct_unix_client",
+   unix_client_thread_func,
+   (gpointer)1);
+
+g_thread_join(cli);
+g_thread_join(serv);
+
+g_free(abstract_sock_name);
+}
 
 int main(int argc, char **argv)
 {
@@ -265,6 +351,11 @@ int main(int argc, char **argv)
 test_socket_fd_pass_num_nocli);
 }
 
+#ifdef __linux__
+g_test_add_func("/util/socket/unix-abstract/good",
+test_socket_unix_abstract_good);
+#endif
+
 end:
 return g_test_run();
 }
-- 
2.17.1




[PATCH v4 1/3] qemu-sockets: add abstract UNIX domain socket support

2020-05-14 Thread xiaoqiang zhao
unix_listen/connect_saddr now support abstract address types

two aditional BOOL switches are introduced:
tight: whether to set @addrlen to the minimal string length,
   or the maximum sun_path length. default is TRUE
abstract: whether we use abstract address. default is FALSE

cli example:
-monitor unix:/tmp/unix.socket,abstract,tight=off
OR
-chardev socket,path=/tmp/unix.socket,id=unix1,abstract,tight=on

Signed-off-by: xiaoqiang zhao 
Reviewed-by: Daniel P. Berrangé 
---
 chardev/char-socket.c |  4 
 chardev/char.c|  7 +++
 qapi/sockets.json |  8 +++-
 util/qemu-sockets.c   | 39 ---
 4 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 185fe38dda..16f2211091 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -1380,6 +1380,8 @@ static void qemu_chr_parse_socket(QemuOpts *opts, 
ChardevBackend *backend,
 const char *host = qemu_opt_get(opts, "host");
 const char *port = qemu_opt_get(opts, "port");
 const char *fd = qemu_opt_get(opts, "fd");
+bool tight = qemu_opt_get_bool(opts, "tight", true);
+bool abstract = qemu_opt_get_bool(opts, "abstract", false);
 SocketAddressLegacy *addr;
 ChardevSocket *sock;
 
@@ -1431,6 +1433,8 @@ static void qemu_chr_parse_socket(QemuOpts *opts, 
ChardevBackend *backend,
 addr->type = SOCKET_ADDRESS_LEGACY_KIND_UNIX;
 q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
 q_unix->path = g_strdup(path);
+q_unix->tight = tight;
+q_unix->abstract = abstract;
 } else if (host) {
 addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET;
 addr->u.inet.data = g_new(InetSocketAddress, 1);
diff --git a/chardev/char.c b/chardev/char.c
index e77564060d..f44fda3a92 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -939,6 +939,13 @@ QemuOptsList qemu_chardev_opts = {
 },{
 .name = "logappend",
 .type = QEMU_OPT_BOOL,
+},{
+.name = "tight",
+.type = QEMU_OPT_BOOL,
+.def_value_str = "on",
+},{
+.name = "abstract",
+.type = QEMU_OPT_BOOL,
 },
 { /* end of list */ }
 },
diff --git a/qapi/sockets.json b/qapi/sockets.json
index ea933ed4b2..cbd6ef35d0 100644
--- a/qapi/sockets.json
+++ b/qapi/sockets.json
@@ -73,12 +73,18 @@
 # Captures a socket address in the local ("Unix socket") namespace.
 #
 # @path: filesystem path to use
+# @tight: pass a socket address length confined to the minimum length of the
+# abstract string, rather than the full sockaddr_un record length
+# (only matters for abstract sockets, default true). (Since 5.1)
+# @abstract: whether this is an abstract address, default false. (Since 5.1)
 #
 # Since: 1.3
 ##
 { 'struct': 'UnixSocketAddress',
   'data': {
-'path': 'str' } }
+'path': 'str',
+'*tight': 'bool',
+'*abstract': 'bool' } }
 
 ##
 # @VsockSocketAddress:
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 86c48b9fa5..b37d288866 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -863,6 +863,7 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,
 char *pathbuf = NULL;
 const char *path;
 size_t pathlen;
+size_t addrlen;
 
 sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
 if (sock < 0) {
@@ -879,9 +880,11 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,
 }
 
 pathlen = strlen(path);
-if (pathlen > sizeof(un.sun_path)) {
+if (pathlen > sizeof(un.sun_path) ||
+(saddr->abstract && pathlen > (sizeof(un.sun_path) - 1))) {
 error_setg(errp, "UNIX socket path '%s' is too long", path);
 error_append_hint(errp, "Path must be less than %zu bytes\n",
+  saddr->abstract ? sizeof(un.sun_path) - 1 :
   sizeof(un.sun_path));
 goto err;
 }
@@ -903,7 +906,7 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,
 close(fd);
 }
 
-if (unlink(path) < 0 && errno != ENOENT) {
+if (!saddr->abstract && unlink(path) < 0 && errno != ENOENT) {
 error_setg_errno(errp, errno,
  "Failed to unlink socket %s", path);
 goto err;
@@ -911,9 +914,19 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,
 
 memset(, 0, sizeof(un));
 un.sun_family = AF_UNIX;
-memcpy(un.sun_path, path, pathlen);
+addrlen = sizeof(un);
 
-if (bind(sock, (struct sockaddr*) , sizeof(un)) < 0) {
+if (saddr->abstract) {
+un.sun_path[0] = '\0';
+memcpy(_path[1], path, pathlen);
+if (saddr->tight) {
+addrlen = offsetof(struct sockaddr_un, sun_path) + 1 + pathlen;
+}
+} else {
+memcpy(un.sun_path, path, pathlen);
+}
+
+if (bind(sock, (struct sockaddr *) , addrlen) < 0) {
 error_setg_errno(errp, errno, "Failed to bind socket to %s", path);

[PATCH v4 3/3] qemu-options: updates for abstract unix sockets

2020-05-14 Thread xiaoqiang zhao
add options documents changes for -chardev

Signed-off-by: xiaoqiang zhao 
Reviewed-by: Daniel P. Berrangé 
---
 qemu-options.hx | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index e2dca8a4e9..e63cc1b4b4 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2938,7 +2938,7 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev,
 " 
[,server][,nowait][,telnet][,websocket][,reconnect=seconds][,mux=on|off]\n"
 " [,logfile=PATH][,logappend=on|off][,tls-creds=ID][,tls-authz=ID] 
(tcp)\n"
 "-chardev 
socket,id=id,path=path[,server][,nowait][,telnet][,websocket][,reconnect=seconds]\n"
-" [,mux=on|off][,logfile=PATH][,logappend=on|off] (unix)\n"
+" 
[,mux=on|off][,logfile=PATH][,logappend=on|off][,tight=on|off][,abstract=on|off]
 (unix)\n"
 "-chardev udp,id=id[,host=host],port=port[,localaddr=localaddr]\n"
 " [,localport=localport][,ipv4][,ipv6][,mux=on|off]\n"
 " [,logfile=PATH][,logappend=on|off]\n"
@@ -3105,9 +3105,14 @@ The available backends are:
 
 ``nodelay`` disables the Nagle algorithm.
 
-``unix options: path=path``
+``unix options: path=path[,tight=on|off][,abstract=on|off]``
 ``path`` specifies the local path of the unix socket. ``path``
 is required.
+   ``tight`` whether to set @addrlen to the minimal string length,
+or the maximum sun_path length. defaults to true. ``tight`` is
+optional.
+   ``abstract`` whether use abstract address. defaults to false.
+   ``abstract`` is optional.
 
 ``-chardev 
udp,id=id[,host=host],port=port[,localaddr=localaddr][,localport=localport][,ipv4][,ipv6]``
 Sends all traffic from the guest to a remote host over UDP.
-- 
2.17.1




[PATCH v4 0/3] qemu-sockets: add abstract UNIX domain socket support

2020-05-14 Thread xiaoqiang zhao
qemu does not support abstract UNIX domain
socket address. Add this ability to make qemu handy
when abstract address is needed.

Changes since v3: 
* rebase on master
* refine qapi document statement
* use random names to avoid name clash in unit test

Xiaoqiang Zhao (3):
  qemu-sockets: add abstract UNIX domain socket support
  tests/util-sockets: add abstract unix socket cases
  qemu-options: updates for abstract unix sockets

 chardev/char-socket.c |  4 ++
 chardev/char.c|  7 +++
 qapi/sockets.json |  8 +++-
 qemu-options.hx   |  9 +++-
 tests/test-util-sockets.c | 91 +++
 util/qemu-sockets.c   | 39 ++---
 6 files changed, 148 insertions(+), 10 deletions(-)

-- 
2.17.1




Re: Questionable aspects of QEMU Error's design

2020-05-14 Thread Markus Armbruster
Vladimir Sementsov-Ogievskiy  writes:

> 28.04.2020 08:20, Vladimir Sementsov-Ogievskiy wrote:
>> 27.04.2020 18:36, Markus Armbruster wrote:
>>> Markus Armbruster  writes:
>>>
 Markus Armbruster  writes:

> QEMU's Error was patterned after GLib's GError.  Differences include:
 [...]
> * Return value conventions
>
>    Common: non-void functions return a distinct error value on failure
>    when such a value can be defined.  Patterns:
>
>    - Functions returning non-null pointers on success return null pointer
>  on failure.
>
>    - Functions returning non-negative integers on success return a
>  negative error code on failure.
>
>    Different: GLib discourages void functions, because these lead to
>    awkward error checking code.  We have tons of them, and tons of
>    awkward error checking code:
>
>  Error *err = NULL;
>  frobnicate(arg, );
>  if (err) {
>  ... recover ...
>  error_propagate(errp, err);
>  }
>
>    instead of
>
>  if (!frobnicate(arg, errp))
>  ... recover ...
>  }
>
>    Can also lead to pointless creation of Error objects.
>
>    I consider this a design mistake.  Can we still fix it?  We have more
>    than 2000 void functions taking an Error ** parameter...
>
>    Transforming code that receives and checks for errors with Coccinelle
>    shouldn't be hard.  Transforming code that returns errors seems more
>    difficult.  We need to transform explicit and implicit return to
>    either return true or return false, depending on what we did to the
>    @errp parameter on the way to the return.  Hmm.
 [...]

 To figure out what functions with an Error ** parameter return, I used
 Coccinelle to find such function definitions and print the return types.
 Summary of results:

     2155 void
  873 signed integer
  494 pointer
  153 bool
   33 unsigned integer
    6 enum
     -
     3714 total

 I then used Coccinelle to find checked calls of void functions (passing
 _fatal or _abort is not considered "checking" here).  These
 calls become simpler if we make the functions return a useful value.  I
 found a bit under 600 direct calls, and some 50 indirect calls.

 Most frequent direct calls:

  127 object_property_set_bool
   27 qemu_opts_absorb_qdict
   16 visit_type_str
   14 visit_type_int
   10 visit_type_uint32

 Let's have a closer look at object_property_set() & friends.  Out of
 almost 1000 calls, some 150 are checked.  While I'm sure many of the
 unchecked calls can't actually fail, I am concerned some unchecked calls
 can.

 If we adopt the convention to return a value that indicates success /
 failure, we should consider converting object.h to it sooner rather than
 later.

 Please understand these are rough numbers from quick & dirty scripts.
>>>
>>> FYI, I'm working on converting QemuOpts, QAPI visitors and QOM.  I keep
>>> running into bugs.  So far:
>>>
>>>  [PATCH v2 for-5.1 0/9] qemu-option: Fix corner cases and clean up
>>>  [PATCH for-5.1 0/5] qobject: Minor spring cleaning
>>>  [PATCH v2 00/14] Miscellaneous error handling fixes
>>>  [PATCH 0/4] Subject: [PATCH 0/4] smbus: SPD fixes
>>>  [PATCH 0/3] fuzz: Probably there is a better way to do this
>>>  [PATCH v2 00/15] qapi: Spring cleaning
>>>  [PATCH 00/11] More miscellaneous error handling fixes
>>>
>>> I got another one coming for QOM and qdev before I can post the
>>> conversion.
>>>
>>> Vladimir, since the conversion will mess with error_propagate(), I'd
>>> like to get it in before your auto-propagation work.
>>>
>>
>> OK, just let me know when to regenerate the series, it's not hard.
>>
>
> Hi! Is all that merged? Should I resend now?

I ran into many bugs and fell into a few rabbit holes.  I'm busy
finishing and flushing the patches.




[PATCH v2] cpus: Fix botched configure_icount() error API violation fix

2020-05-14 Thread Markus Armbruster
Before recent commit abc9bf69a66, configure_icount() returned early
when option "shift" was absent: succeed when option "align" was also
absent, else fail.

Since then, it still errors out when only "align" is present, but
continues when both are absent.  Crashes when examining the value of
"shift" further.  Reproducer: -icount "".

Revert this erroneous part of the commit.

Fixes: abc9bf69a66a11499a801ff545b8fe7adbb3a04c
Fixes: Coverity CID 1428754
Signed-off-by: Markus Armbruster 
---
 cpus.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/cpus.c b/cpus.c
index 5670c96bcf..ee906dd08f 100644
--- a/cpus.c
+++ b/cpus.c
@@ -803,8 +803,10 @@ void configure_icount(QemuOpts *opts, Error **errp)
 bool align = qemu_opt_get_bool(opts, "align", false);
 long time_shift = -1;
 
-if (!option && qemu_opt_get(opts, "align")) {
-error_setg(errp, "Please specify shift option when using align");
+if (!option) {
+if (qemu_opt_get(opts, "align") != NULL) {
+error_setg(errp, "Please specify shift option when using align");
+}
 return;
 }
 
-- 
2.21.1




Re: [PATCH Kernel v20 6/8] vfio iommu: Update UNMAP_DMA ioctl to get dirty bitmap before unmap

2020-05-14 Thread Kirti Wankhede




On 5/15/2020 8:57 AM, Alex Williamson wrote:

On Fri, 15 May 2020 02:07:45 +0530
Kirti Wankhede  wrote:


DMA mapped pages, including those pinned by mdev vendor drivers, might
get unpinned and unmapped while migration is active and device is still
running. For example, in pre-copy phase while guest driver could access
those pages, host device or vendor driver can dirty these mapped pages.
Such pages should be marked dirty so as to maintain memory consistency
for a user making use of dirty page tracking.

To get bitmap during unmap, user should allocate memory for bitmap, set
it all zeros, set size of allocated memory, set page size to be
considered for bitmap and set flag VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP.

Signed-off-by: Kirti Wankhede 
Reviewed-by: Neo Jia 
---
  drivers/vfio/vfio_iommu_type1.c | 77 ++---
  include/uapi/linux/vfio.h   | 10 ++
  2 files changed, 75 insertions(+), 12 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index b76d3b14abfd..a1dc57bcece5 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -195,11 +195,15 @@ static void vfio_unlink_dma(struct vfio_iommu *iommu, 
struct vfio_dma *old)
  static int vfio_dma_bitmap_alloc(struct vfio_dma *dma, size_t pgsize)
  {
uint64_t npages = dma->size / pgsize;
+   size_t bitmap_size;
  
  	if (npages > DIRTY_BITMAP_PAGES_MAX)

return -EINVAL;
  
-	dma->bitmap = kvzalloc(DIRTY_BITMAP_BYTES(npages), GFP_KERNEL);

+   /* Allocate extra 64 bits which are used for bitmap manipulation */
+   bitmap_size = DIRTY_BITMAP_BYTES(npages) + sizeof(u64);
+
+   dma->bitmap = kvzalloc(bitmap_size, GFP_KERNEL);
if (!dma->bitmap)
return -ENOMEM;
  
@@ -999,23 +1003,25 @@ static int verify_bitmap_size(uint64_t npages, uint64_t bitmap_size)

  }
  
  static int vfio_dma_do_unmap(struct vfio_iommu *iommu,

-struct vfio_iommu_type1_dma_unmap *unmap)
+struct vfio_iommu_type1_dma_unmap *unmap,
+struct vfio_bitmap *bitmap)
  {
-   uint64_t mask;
struct vfio_dma *dma, *dma_last = NULL;
-   size_t unmapped = 0;
+   size_t unmapped = 0, pgsize;
int ret = 0, retries = 0;
+   unsigned long pgshift;
  
  	mutex_lock(>lock);
  
-	mask = ((uint64_t)1 << __ffs(iommu->pgsize_bitmap)) - 1;

+   pgshift = __ffs(iommu->pgsize_bitmap);
+   pgsize = (size_t)1 << pgshift;
  
-	if (unmap->iova & mask) {

+   if (unmap->iova & (pgsize - 1)) {
ret = -EINVAL;
goto unlock;
}
  
-	if (!unmap->size || unmap->size & mask) {

+   if (!unmap->size || unmap->size & (pgsize - 1)) {
ret = -EINVAL;
goto unlock;
}
@@ -1026,9 +1032,15 @@ static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
goto unlock;
}
  
-	WARN_ON(mask & PAGE_MASK);

-again:
+   /* When dirty tracking is enabled, allow only min supported pgsize */
+   if ((unmap->flags & VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP) &&
+   (!iommu->dirty_page_tracking || (bitmap->pgsize != pgsize))) {
+   ret = -EINVAL;
+   goto unlock;
+   }
  
+	WARN_ON((pgsize - 1) & PAGE_MASK);

+again:
/*
 * vfio-iommu-type1 (v1) - User mappings were coalesced together to
 * avoid tracking individual mappings.  This means that the granularity
@@ -1066,6 +1078,7 @@ static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
ret = -EINVAL;
goto unlock;
}
+
dma = vfio_find_dma(iommu, unmap->iova + unmap->size - 1, 0);
if (dma && dma->iova + dma->size != unmap->iova + unmap->size) {
ret = -EINVAL;
@@ -1083,6 +1096,23 @@ static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
if (dma->task->mm != current->mm)
break;
  
+		if ((unmap->flags & VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP) &&

+   (dma_last != dma)) {
+
+   /*
+* mark all pages dirty if all pages are pinned and
+* mapped
+*/
+   if (dma->iommu_mapped)
+   bitmap_set(dma->bitmap, 0,
+  dma->size >> pgshift);


Nit, all the callers of update_user_bitmap() precede the call with this
identical operation, we should probably push it into the function to do
it.


+
+   ret = update_user_bitmap(bitmap->data, dma,
+unmap->iova, pgsize);
+   if (ret)
+   break;
+   }
+


As noted last time, the above is just busy work if pfn_list is not
already empty.  The entire 

Re: [PATCH] vhost-user: add support for VHOST_USER_SET_STATUS

2020-05-14 Thread Jason Wang



On 2020/5/14 下午6:14, Maxime Coquelin wrote:


On 5/14/20 9:53 AM, Jason Wang wrote:

On 2020/5/14 下午3:33, Maxime Coquelin wrote:

It is usefull for the Vhost-user backend to know
about about the Virtio device status updates,
especially when the driver sets the DRIVER_OK bit.

With that information, no more need to do hazardous
assumptions on when the driver is done with the
device configuration.

Signed-off-by: Maxime Coquelin 
---

This patch applies on top of Cindy's "vDPA support in qemu"
series, which introduces the .vhost_set_state vhost-backend
ops.

   docs/interop/vhost-user.rst | 12 
   hw/net/vhost_net.c  | 10 +-
   hw/virtio/vhost-user.c  | 35 +++
   3 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst
index 3b1b6602c7..f108de7458 100644
--- a/docs/interop/vhost-user.rst
+++ b/docs/interop/vhost-user.rst
@@ -815,6 +815,7 @@ Protocol features
     #define VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD   12
     #define VHOST_USER_PROTOCOL_F_RESET_DEVICE 13
     #define VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS 14
+  #define VHOST_USER_PROTOCOL_F_STATUS   15
     Master message types
   
@@ -1263,6 +1264,17 @@ Master message types
       The state.num field is currently reserved and must be set to 0.
   +``VHOST_USER_SET_STATUS``
+  :id: 36
+  :equivalent ioctl: VHOST_VDPA_SET_STATUS
+  :slave payload: N/A
+  :master payload: ``u64``
+
+  When the ``VHOST_USER_PROTOCOL_F_STATUS`` protocol feature has been
+  successfully negotiated, this message is submitted by the master to
+  notify the backend with updated device status as defined in the Virtio
+  specification.
+
   Slave message types
   ---
   diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 463e333531..37f3156dbc 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -517,10 +517,10 @@ int vhost_set_state(NetClientState *nc, int state)
   {
   struct vhost_net *net = get_vhost_net(nc);
   struct vhost_dev *hdev = >dev;
-    if (nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) {
-    if (hdev->vhost_ops->vhost_set_state) {
-    return hdev->vhost_ops->vhost_set_state(hdev, state);
- }
-    }
+
+    if (hdev->vhost_ops->vhost_set_state) {
+    return hdev->vhost_ops->vhost_set_state(hdev, state);
+    }
+
   return 0;
   }
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index ec21e8fbe8..b7e52d97fc 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -59,6 +59,7 @@ enum VhostUserProtocolFeature {
   VHOST_USER_PROTOCOL_F_HOST_NOTIFIER = 11,
   VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD = 12,
   VHOST_USER_PROTOCOL_F_RESET_DEVICE = 13,
+    VHOST_USER_PROTOCOL_F_STATUS = 15,
   VHOST_USER_PROTOCOL_F_MAX
   };
   @@ -100,6 +101,7 @@ typedef enum VhostUserRequest {
   VHOST_USER_SET_INFLIGHT_FD = 32,
   VHOST_USER_GPU_SET_SOCKET = 33,
   VHOST_USER_RESET_DEVICE = 34,
+    VHOST_USER_SET_STATUS = 36,
   VHOST_USER_MAX
   } VhostUserRequest;
   @@ -1886,6 +1888,38 @@ static int vhost_user_set_inflight_fd(struct
vhost_dev *dev,
   return 0;
   }
   +static int vhost_user_set_state(struct vhost_dev *dev, int state)
+{
+    bool reply_supported = virtio_has_feature(dev->protocol_features,
+
VHOST_USER_PROTOCOL_F_REPLY_ACK);
+
+    VhostUserMsg msg = {
+    .hdr.request = VHOST_USER_SET_STATUS,
+    .hdr.flags = VHOST_USER_VERSION,
+    .hdr.size = sizeof(msg.payload.u64),
+    .payload.u64 = (uint64_t)state,
+    };
+
+    if (!virtio_has_feature(dev->protocol_features,
+    VHOST_USER_PROTOCOL_F_STATUS)) {
+    return -1;
+    }
+
+    if (reply_supported) {
+    msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
+    }
+
+    if (vhost_user_write(dev, , NULL, 0) < 0) {
+    return -1;
+    }
+
+    if (reply_supported) {
+    return process_message_reply(dev, );
+    }
+
+    return 0;
+}


Interesting, I wonder how vm stop will be handled in this case.

For now, my DPDK series only use DRIVER_OK to help determine when the
driver is done with the initialization. For VM stop, it still relies on
GET_VRING_BASE.

GET_VRING_BASE arrives before DRIVER_OK bit is cleared is the tests I've
done (logs from backend side):

VHOST_CONFIG: read message VHOST_USER_GET_VRING_BASE

destroy port /tmp/vhost-user1, did: 0
VHOST_CONFIG: vring base idx:0 file:41
VHOST_CONFIG: read message VHOST_USER_GET_VRING_BASE
VHOST_CONFIG: vring base idx:1 file:0
VHOST_CONFIG: read message VHOST_USER_SET_STATUS
VHOST_CONFIG: New device status(0x000b):
-ACKNOWLEDGE: 1
-DRIVER: 1
-FEATURES_OK: 1
-DRIVER_OK: 0
-DEVICE_NEED_RESET: 0
-FAILED: 0



Then it looks like a function duplication, e.g backend could be stopped 
either via GET_VRING_BASE or VHOST_USER_SET_STATUS(0).


And I guess 

Re: [Virtio-fs] [PATCH] virtiofsd: remove symlink fallbacks

2020-05-14 Thread Liu Bo
On Thu, May 14, 2020 at 04:07:36PM +0200, Miklos Szeredi wrote:
> Path lookup in the kernel has special rules for looking up magic symlinks
> under /proc.  If a filesystem operation is instructed to follow symlinks
> (e.g. via AT_SYMLINK_FOLLOW or lack of AT_SYMLINK_NOFOLLOW), and the final
> component is such a proc symlink, then the target of the magic symlink is
> used for the operation, even if the target itself is a symlink.  I.e. path
> lookup is always terminated after following a final magic symlink.
>

Hi Miklos,

Are these mentioned special rules supported by a recent kernel version
or are they there from day one linux?

thanks,
liubo

> I was erronously assuming that in the above case the target symlink would
> also be followed, and so workarounds were added for a couple of operations
> to handle the symlink case.  Since the symlink can be handled simply by
> following the proc symlink, these workardouds are not needed.
> 
> Also remove the "norace" option, which disabled the workarounds.
> 
> Commit bdfd66788349 ("virtiofsd: Fix xattr operations") already dealt with
> the same issue for xattr operations.
> 
> Signed-off-by: Miklos Szeredi 
> ---
>  tools/virtiofsd/passthrough_ll.c | 175 ++-
>  1 file changed, 6 insertions(+), 169 deletions(-)
> 
> diff --git a/tools/virtiofsd/passthrough_ll.c 
> b/tools/virtiofsd/passthrough_ll.c
> index 3ba1d9098460..2ce7c96085bf 100644
> --- a/tools/virtiofsd/passthrough_ll.c
> +++ b/tools/virtiofsd/passthrough_ll.c
> @@ -140,7 +140,6 @@ enum {
>  struct lo_data {
>  pthread_mutex_t mutex;
>  int debug;
> -int norace;
>  int writeback;
>  int flock;
>  int posix_lock;
> @@ -176,7 +175,6 @@ static const struct fuse_opt lo_opts[] = {
>  { "cache=none", offsetof(struct lo_data, cache), CACHE_NONE },
>  { "cache=auto", offsetof(struct lo_data, cache), CACHE_AUTO },
>  { "cache=always", offsetof(struct lo_data, cache), CACHE_ALWAYS },
> -{ "norace", offsetof(struct lo_data, norace), 1 },
>  { "readdirplus", offsetof(struct lo_data, readdirplus_set), 1 },
>  { "no_readdirplus", offsetof(struct lo_data, readdirplus_clear), 1 },
>  FUSE_OPT_END
> @@ -592,136 +590,6 @@ static void lo_getattr(fuse_req_t req, fuse_ino_t ino,
>  fuse_reply_attr(req, , lo->timeout);
>  }
>  
> -/*
> - * Increments parent->nlookup and caller must release refcount using
> - * lo_inode_put().
> - */
> -static int lo_parent_and_name(struct lo_data *lo, struct lo_inode *inode,
> -  char path[PATH_MAX], struct lo_inode **parent)
> -{
> -char procname[64];
> -char *last;
> -struct stat stat;
> -struct lo_inode *p;
> -int retries = 2;
> -int res;
> -
> -retry:
> -sprintf(procname, "%i", inode->fd);
> -
> -res = readlinkat(lo->proc_self_fd, procname, path, PATH_MAX);
> -if (res < 0) {
> -fuse_log(FUSE_LOG_WARNING, "%s: readlink failed: %m\n", __func__);
> -goto fail_noretry;
> -}
> -
> -if (res >= PATH_MAX) {
> -fuse_log(FUSE_LOG_WARNING, "%s: readlink overflowed\n", __func__);
> -goto fail_noretry;
> -}
> -path[res] = '\0';
> -
> -last = strrchr(path, '/');
> -if (last == NULL) {
> -/* Shouldn't happen */
> -fuse_log(
> -FUSE_LOG_WARNING,
> -"%s: INTERNAL ERROR: bad path read from proc\n", __func__);
> -goto fail_noretry;
> -}
> -if (last == path) {
> -p = >root;
> -pthread_mutex_lock(>mutex);
> -p->nlookup++;
> -g_atomic_int_inc(>refcount);
> -pthread_mutex_unlock(>mutex);
> -} else {
> -*last = '\0';
> -res = fstatat(AT_FDCWD, last == path ? "/" : path, , 0);
> -if (res == -1) {
> -if (!retries) {
> -fuse_log(FUSE_LOG_WARNING,
> - "%s: failed to stat parent: %m\n", __func__);
> -}
> -goto fail;
> -}
> -p = lo_find(lo, );
> -if (p == NULL) {
> -if (!retries) {
> -fuse_log(FUSE_LOG_WARNING,
> - "%s: failed to find parent\n", __func__);
> -}
> -goto fail;
> -}
> -}
> -last++;
> -res = fstatat(p->fd, last, , AT_SYMLINK_NOFOLLOW);
> -if (res == -1) {
> -if (!retries) {
> -fuse_log(FUSE_LOG_WARNING,
> - "%s: failed to stat last\n", __func__);
> -}
> -goto fail_unref;
> -}
> -if (stat.st_dev != inode->key.dev || stat.st_ino != inode->key.ino) {
> -if (!retries) {
> -fuse_log(FUSE_LOG_WARNING,
> - "%s: failed to match last\n", __func__);
> -}
> -goto fail_unref;
> -}
> -*parent = p;
> -memmove(path, last, strlen(last) + 1);
> -
> -return 0;
> -
> -fail_unref:
> -unref_inode_lolocked(lo, p, 1);
> -lo_inode_put(lo, );
> -fail:
> -if 

RE: About migration/colo issue

2020-05-14 Thread Zhang, Chen


From: Zhanghailiang 
Sent: Friday, May 15, 2020 11:29 AM
To: Zhang, Chen ; Dr . David Alan Gilbert 
; qemu-devel ; Li Zhijian 

Cc: Jason Wang ; Lukas Straub 
Subject: RE: About migration/colo issue

Hi Zhang Chen,

>From your tracing log, it seems to be hanged in colo_flush_ram_cache()?
Does it come across a dead loop there ?

Maybe, I haven't looked in depth.

I'll test it by using the new qemu.

Thanks

Thanks,
Hailiang

From: Zhang, Chen [mailto:chen.zh...@intel.com]
Sent: Friday, May 15, 2020 11:16 AM
To: Zhanghailiang 
mailto:zhang.zhanghaili...@huawei.com>>; Dr . 
David Alan Gilbert mailto:dgilb...@redhat.com>>; 
qemu-devel mailto:qemu-devel@nongnu.org>>; Li Zhijian 
mailto:lizhij...@cn.fujitsu.com>>
Cc: Jason Wang mailto:jasow...@redhat.com>>; Lukas Straub 
mailto:lukasstra...@web.de>>
Subject: About migration/colo issue

Hi Hailiang/Dave.

I found a urgent problem in current upstream code, COLO will stuck on secondary 
checkpoint and later.
The guest will stuck by this issue.
I have bisect upstream code, this issue caused by Hailiang's optimize patch:

>From 0393031a16735835a441b6d6e0495a1bd14adb90 Mon Sep 17 00:00:00 2001
From: zhanghailiang 
mailto:zhang.zhanghaili...@huawei.com>>
Date: Mon, 24 Feb 2020 14:54:10 +0800
Subject: [PATCH] COLO: Optimize memory back-up process

This patch will reduce the downtime of VM for the initial process,
Previously, we copied all these memory in preparing stage of COLO
while we need to stop VM, which is a time-consuming process.
Here we optimize it by a trick, back-up every page while in migration
process while COLO is enabled, though it affects the speed of the
migration, but it obviously reduce the downtime of back-up all SVM'S
memory in COLO preparing stage.

Signed-off-by: zhanghailiang 
mailto:zhang.zhanghaili...@huawei.com>>
Message-Id: 
<20200224065414.36524-5-zhang.zhanghaili...@huawei.com>
Signed-off-by: Dr. David Alan Gilbert 
mailto:dgilb...@redhat.com>>
  minor typo fixes

Hailiang, do you have time to look into it?


The detail log:
Primary node:
13322@1589511271.917346:colo_receive_message
 Receive 'checkpoint-ready' message
{"timestamp": {"seconds": 1589511271, "microseconds": 917406}, "event": 
"RESUME"}
13322@1589511271.917842:colo_vm_state_change
 Change 'stop' => 'run'
13322@1589511291.243346:colo_send_message
 Send 'checkpoint-request' message
13322@1589511291.243978:colo_receive_message
 Receive 'checkpoint-reply' message
{"timestamp": {"seconds": 1589511291, "microseconds": 244096}, "event": "STOP"}
13322@1589511291.24:colo_vm_state_change
 Change 'run' => 'stop'
13322@1589511291.244561:colo_send_message
 Send 'vmstate-send' message
13322@1589511291.258594:colo_send_message
 Send 'vmstate-size' message
13322@1589511305.412479:colo_receive_message
 Receive 'vmstate-received' message
13322@1589511309.031826:colo_receive_message
 Receive 'vmstate-loaded' message
{"timestamp": {"seconds": 1589511309, "microseconds": 31862}, "event": "RESUME"}
13322@1589511309.033075:colo_vm_state_change
 Change 'stop' => 'run'
{"timestamp": {"seconds": 1589511311, "microseconds": 111617}, "event": 
"VNC_CONNECTED", "data": {"server": {"auth": "none", "family": "ipv4", 
"service": "5907", "host": "0.0.0.0", "websocket": false}, "client": {"family": 
"ipv4", "service": "51564", "host": "10.239.13.19", "websocket": false}}}
{"timestamp": {"seconds": 1589511311, "microseconds": 116197}, "event": 
"VNC_INITIALIZED", "data": {"server": {"auth": "none", "family": "ipv4", 
"service": "5907", "host": "0.0.0.0", "websocket": false}, "client": {"family": 
"ipv4", "service": "51564", "host": "10.239.13.19", "websocket": false}}}
13322@1589511311.243271:colo_send_message
 Send 'checkpoint-request' message
13322@1589511311.351361:colo_receive_message
 Receive 'checkpoint-reply' message
{"timestamp": {"seconds": 1589511311, "microseconds": 351439}, "event": "STOP"}
13322@1589511311.415779:colo_vm_state_change
 Change 'run' => 'stop'
13322@1589511311.416001:colo_send_message
 Send 'vmstate-send' message
13322@1589511311.418620:colo_send_message
 Send 'vmstate-size' message

Secondary node:
{"timestamp": {"seconds": 1589510920, "microseconds": 

Re: [PATCH Kernel v20 0/8] Add UAPIs to support migration for VFIO devices

2020-05-14 Thread Alex Williamson
Hi Yan & Intel folks,

I'm starting to run out of comments on this series, where are you with
porting GVT-g migration to this API?  Are there remaining blocking
issues?  Are we satisfied that the API is sufficient to support vIOMMU
now?  Thanks,

Alex


On Fri, 15 May 2020 02:07:39 +0530
Kirti Wankhede  wrote:

> Hi,
> 
> This patch set adds:
> * IOCTL VFIO_IOMMU_DIRTY_PAGES to get dirty pages bitmap with
>   respect to IOMMU container rather than per device. All pages pinned by
>   vendor driver through vfio_pin_pages external API has to be marked as
>   dirty during  migration. When IOMMU capable device is present in the
>   container and all pages are pinned and mapped, then all pages are marked
>   dirty.
>   When there are CPU writes, CPU dirty page tracking can identify dirtied
>   pages, but any page pinned by vendor driver can also be written by
>   device. As of now there is no device which has hardware support for
>   dirty page tracking. So all pages which are pinned should be considered
>   as dirty.
>   This ioctl is also used to start/stop dirty pages tracking for pinned and
>   unpinned pages while migration is active.
> 
> * Updated IOCTL VFIO_IOMMU_UNMAP_DMA to get dirty pages bitmap before
>   unmapping IO virtual address range.
>   With vIOMMU, during pre-copy phase of migration, while CPUs are still
>   running, IO virtual address unmap can happen while device still keeping
>   reference of guest pfns. Those pages should be reported as dirty before
>   unmap, so that VFIO user space application can copy content of those
>   pages from source to destination.
> 
> * Patch 8 detect if IOMMU capable device driver is smart to report pages
>   to be marked dirty by pinning pages using vfio_pin_pages() API.
> 
> 
> Yet TODO:
> Since there is no device which has hardware support for system memmory
> dirty bitmap tracking, right now there is no other API from vendor driver
> to VFIO IOMMU module to report dirty pages. In future, when such hardware
> support will be implemented, an API will be required such that vendor
> driver could report dirty pages to VFIO module during migration phases.
> 
> Adding revision history from previous QEMU patch set to understand KABI
> changes done till now
> 
> v19 -> v20
> - Fixed ioctl to get dirty bitmap to get bitmap of multiple vfio_dmas
> - Fixed unmap ioctl to get dirty bitmap of multiple vfio_dmas.
> - Removed flag definition from migration capability.
> 
> v18 -> v19
> - Updated migration capability with supported page sizes bitmap for dirty
>   page tracking and  maximum bitmap size supported by kernel module.
> - Added patch to calculate and cache pgsize_bitmap when iommu->domain_list
>   is updated.
> - Removed extra buffers added in previous version for bitmap manipulation
>   and optimised the code.
> 
> v17 -> v18
> - Add migration capability to the capability chain for VFIO_IOMMU_GET_INFO
>   ioctl
> - Updated UMAP_DMA ioctl to return bitmap of multiple vfio_dma
> 
> v16 -> v17
> - Fixed errors reported by kbuild test robot  on i386
> 
> v15 -> v16
> - Minor edits and nit picks (Auger Eric)
> - On copying bitmap to user, re-populated bitmap only for pinned pages,
>   excluding unmapped pages and CPU dirtied pages.
> - Patches are on tag: next-20200318 and 1-3 patches from Yan's series
>   https://lkml.org/lkml/2020/3/12/1255
> 
> v14 -> v15
> - Minor edits and nit picks.
> - In the verification of user allocated bitmap memory, added check of
>maximum size.
> - Patches are on tag: next-20200318 and 1-3 patches from Yan's series
>   https://lkml.org/lkml/2020/3/12/1255
> 
> v13 -> v14
> - Added struct vfio_bitmap to kabi. updated structure
>   vfio_iommu_type1_dirty_bitmap_get and vfio_iommu_type1_dma_unmap.
> - All small changes suggested by Alex.
> - Patches are on tag: next-20200318 and 1-3 patches from Yan's series
>   https://lkml.org/lkml/2020/3/12/1255
> 
> v12 -> v13
> - Changed bitmap allocation in vfio_iommu_type1 to per vfio_dma
> - Changed VFIO_IOMMU_DIRTY_PAGES ioctl behaviour to be per vfio_dma range.
> - Changed vfio_iommu_type1_dirty_bitmap structure to have separate data
>   field.
> 
> v11 -> v12
> - Changed bitmap allocation in vfio_iommu_type1.
> - Remove atomicity of ref_count.
> - Updated comments for migration device state structure about error
>   reporting.
> - Nit picks from v11 reviews
> 
> v10 -> v11
> - Fix pin pages API to free vpfn if it is marked as unpinned tracking page.
> - Added proposal to detect if IOMMU capable device calls external pin pages
>   API to mark pages dirty.
> - Nit picks from v10 reviews
> 
> v9 -> v10:
> - Updated existing VFIO_IOMMU_UNMAP_DMA ioctl to get dirty pages bitmap
>   during unmap while migration is active
> - Added flag in VFIO_IOMMU_GET_INFO to indicate driver support dirty page
>   tracking.
> - If iommu_mapped, mark all pages dirty.
> - Added unpinned pages tracking while migration is active.
> - Updated comments for migration device state structure with bit
>   combination 

RE: About migration/colo issue

2020-05-14 Thread Zhanghailiang
Hi Zhang Chen,

>From your tracing log, it seems to be hanged in colo_flush_ram_cache()?
Does it come across a dead loop there ?
I'll test it by using the new qemu.

Thanks,
Hailiang

From: Zhang, Chen [mailto:chen.zh...@intel.com]
Sent: Friday, May 15, 2020 11:16 AM
To: Zhanghailiang ; Dr . David Alan Gilbert 
; qemu-devel ; Li Zhijian 

Cc: Jason Wang ; Lukas Straub 
Subject: About migration/colo issue

Hi Hailiang/Dave.

I found a urgent problem in current upstream code, COLO will stuck on secondary 
checkpoint and later.
The guest will stuck by this issue.
I have bisect upstream code, this issue caused by Hailiang's optimize patch:

>From 0393031a16735835a441b6d6e0495a1bd14adb90 Mon Sep 17 00:00:00 2001
From: zhanghailiang 
mailto:zhang.zhanghaili...@huawei.com>>
Date: Mon, 24 Feb 2020 14:54:10 +0800
Subject: [PATCH] COLO: Optimize memory back-up process

This patch will reduce the downtime of VM for the initial process,
Previously, we copied all these memory in preparing stage of COLO
while we need to stop VM, which is a time-consuming process.
Here we optimize it by a trick, back-up every page while in migration
process while COLO is enabled, though it affects the speed of the
migration, but it obviously reduce the downtime of back-up all SVM'S
memory in COLO preparing stage.

Signed-off-by: zhanghailiang 
mailto:zhang.zhanghaili...@huawei.com>>
Message-Id: 
<20200224065414.36524-5-zhang.zhanghaili...@huawei.com>
Signed-off-by: Dr. David Alan Gilbert 
mailto:dgilb...@redhat.com>>
  minor typo fixes

Hailiang, do you have time to look into it?


The detail log:
Primary node:
13322@1589511271.917346:colo_receive_message
 Receive 'checkpoint-ready' message
{"timestamp": {"seconds": 1589511271, "microseconds": 917406}, "event": 
"RESUME"}
13322@1589511271.917842:colo_vm_state_change
 Change 'stop' => 'run'
13322@1589511291.243346:colo_send_message
 Send 'checkpoint-request' message
13322@1589511291.243978:colo_receive_message
 Receive 'checkpoint-reply' message
{"timestamp": {"seconds": 1589511291, "microseconds": 244096}, "event": "STOP"}
13322@1589511291.24:colo_vm_state_change
 Change 'run' => 'stop'
13322@1589511291.244561:colo_send_message
 Send 'vmstate-send' message
13322@1589511291.258594:colo_send_message
 Send 'vmstate-size' message
13322@1589511305.412479:colo_receive_message
 Receive 'vmstate-received' message
13322@1589511309.031826:colo_receive_message
 Receive 'vmstate-loaded' message
{"timestamp": {"seconds": 1589511309, "microseconds": 31862}, "event": "RESUME"}
13322@1589511309.033075:colo_vm_state_change
 Change 'stop' => 'run'
{"timestamp": {"seconds": 1589511311, "microseconds": 111617}, "event": 
"VNC_CONNECTED", "data": {"server": {"auth": "none", "family": "ipv4", 
"service": "5907", "host": "0.0.0.0", "websocket": false}, "client": {"family": 
"ipv4", "service": "51564", "host": "10.239.13.19", "websocket": false}}}
{"timestamp": {"seconds": 1589511311, "microseconds": 116197}, "event": 
"VNC_INITIALIZED", "data": {"server": {"auth": "none", "family": "ipv4", 
"service": "5907", "host": "0.0.0.0", "websocket": false}, "client": {"family": 
"ipv4", "service": "51564", "host": "10.239.13.19", "websocket": false}}}
13322@1589511311.243271:colo_send_message
 Send 'checkpoint-request' message
13322@1589511311.351361:colo_receive_message
 Receive 'checkpoint-reply' message
{"timestamp": {"seconds": 1589511311, "microseconds": 351439}, "event": "STOP"}
13322@1589511311.415779:colo_vm_state_change
 Change 'run' => 'stop'
13322@1589511311.416001:colo_send_message
 Send 'vmstate-send' message
13322@1589511311.418620:colo_send_message
 Send 'vmstate-size' message

Secondary node:
{"timestamp": {"seconds": 1589510920, "microseconds": 778207}, "event": 
"RESUME"}
23619@1589510920.778835:colo_vm_state_change
 Change 'stop' => 'run'
23619@1589510920.778891:colo_send_message
 Send 'checkpoint-ready' message
23619@1589510940.105539:colo_receive_message
 Receive 'checkpoint-request' message
{"timestamp": {"seconds": 

Re: [PATCH Kernel v20 5/8] vfio iommu: Implementation of ioctl for dirty pages tracking

2020-05-14 Thread Alex Williamson
On Fri, 15 May 2020 02:07:44 +0530
Kirti Wankhede  wrote:

> VFIO_IOMMU_DIRTY_PAGES ioctl performs three operations:
> - Start dirty pages tracking while migration is active
> - Stop dirty pages tracking.
> - Get dirty pages bitmap. Its user space application's responsibility to
>   copy content of dirty pages from source to destination during migration.
> 
> To prevent DoS attack, memory for bitmap is allocated per vfio_dma
> structure. Bitmap size is calculated considering smallest supported page
> size. Bitmap is allocated for all vfio_dmas when dirty logging is enabled
> 
> Bitmap is populated for already pinned pages when bitmap is allocated for
> a vfio_dma with the smallest supported page size. Update bitmap from
> pinning functions when tracking is enabled. When user application queries
> bitmap, check if requested page size is same as page size used to
> populated bitmap. If it is equal, copy bitmap, but if not equal, return
> error.
> 
> Signed-off-by: Kirti Wankhede 
> Reviewed-by: Neo Jia 
> 
> Fixed error reported by build bot by changing pgsize type from uint64_t
> to size_t.
> Reported-by: kbuild test robot 
> ---
>  drivers/vfio/vfio_iommu_type1.c | 294 
> +++-
>  1 file changed, 288 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
> index de17787ffece..b76d3b14abfd 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -72,6 +72,7 @@ struct vfio_iommu {
>   uint64_tpgsize_bitmap;
>   boolv2;
>   boolnesting;
> + booldirty_page_tracking;
>  };
>  
>  struct vfio_domain {
> @@ -92,6 +93,7 @@ struct vfio_dma {
>   boollock_cap;   /* capable(CAP_IPC_LOCK) */
>   struct task_struct  *task;
>   struct rb_root  pfn_list;   /* Ex-user pinned pfn list */
> + unsigned long   *bitmap;
>  };
>  
>  struct vfio_group {
> @@ -126,6 +128,19 @@ struct vfio_regions {
>  #define IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu)  \
>   (!list_empty(>domain_list))
>  
> +#define DIRTY_BITMAP_BYTES(n)(ALIGN(n, BITS_PER_TYPE(u64)) / 
> BITS_PER_BYTE)
> +
> +/*
> + * Input argument of number of bits to bitmap_set() is unsigned integer, 
> which
> + * further casts to signed integer for unaligned multi-bit operation,
> + * __bitmap_set().
> + * Then maximum bitmap size supported is 2^31 bits divided by 2^3 bits/byte,
> + * that is 2^28 (256 MB) which maps to 2^31 * 2^12 = 2^43 (8TB) on 4K page
> + * system.
> + */
> +#define DIRTY_BITMAP_PAGES_MAX((u64)INT_MAX)
> +#define DIRTY_BITMAP_SIZE_MAX 
> DIRTY_BITMAP_BYTES(DIRTY_BITMAP_PAGES_MAX)
> +
>  static int put_pfn(unsigned long pfn, int prot);
>  
>  /*
> @@ -176,6 +191,74 @@ static void vfio_unlink_dma(struct vfio_iommu *iommu, 
> struct vfio_dma *old)
>   rb_erase(>node, >dma_list);
>  }
>  
> +
> +static int vfio_dma_bitmap_alloc(struct vfio_dma *dma, size_t pgsize)
> +{
> + uint64_t npages = dma->size / pgsize;
> +
> + if (npages > DIRTY_BITMAP_PAGES_MAX)
> + return -EINVAL;
> +
> + dma->bitmap = kvzalloc(DIRTY_BITMAP_BYTES(npages), GFP_KERNEL);
> + if (!dma->bitmap)
> + return -ENOMEM;
> +
> + return 0;
> +}
> +
> +static void vfio_dma_bitmap_free(struct vfio_dma *dma)
> +{
> + kfree(dma->bitmap);
> + dma->bitmap = NULL;
> +}
> +
> +static void vfio_dma_populate_bitmap(struct vfio_dma *dma, size_t pgsize)
> +{
> + struct rb_node *p;
> +
> + for (p = rb_first(>pfn_list); p; p = rb_next(p)) {
> + struct vfio_pfn *vpfn = rb_entry(p, struct vfio_pfn, node);
> +
> + bitmap_set(dma->bitmap, (vpfn->iova - dma->iova) / pgsize, 1);
> + }
> +}
> +
> +static int vfio_dma_bitmap_alloc_all(struct vfio_iommu *iommu, size_t pgsize)
> +{
> + struct rb_node *n = rb_first(>dma_list);
> +
> + for (; n; n = rb_next(n)) {
> + struct vfio_dma *dma = rb_entry(n, struct vfio_dma, node);
> + int ret;
> +
> + ret = vfio_dma_bitmap_alloc(dma, pgsize);
> + if (ret) {
> + struct rb_node *p = rb_prev(n);
> +
> + for (; p; p = rb_prev(p)) {
> + struct vfio_dma *dma = rb_entry(n,
> + struct vfio_dma, node);
> +
> + vfio_dma_bitmap_free(dma);
> + }
> + return ret;
> + }
> + vfio_dma_populate_bitmap(dma, pgsize);
> + }
> + return 0;
> +}
> +
> +static void vfio_dma_bitmap_free_all(struct vfio_iommu *iommu)
> +{
> + struct rb_node *n = rb_first(>dma_list);
> +
> + for (; n; n = rb_next(n)) {
> + struct vfio_dma *dma = rb_entry(n, struct vfio_dma, node);
> +
> +  

Re: [PATCH v3 1/2] chardev: enable distinct input for -chardev file

2020-05-14 Thread Markus Armbruster
Alexander Bulekov  writes:

> char-file already supports distinct paths for input/output but it was
> only possible to specify a distinct input through QMP. With this change,
> we can also specify a distinct input with the -chardev file argument:
> qemu -chardev file,id=char1,path=/out/file,pathin=/in/file
>
> Signed-off-by: Alexander Bulekov 
> Reviewed-by: Stefan Hajnoczi 
> Reviewed-by: Darren Kenny 
> ---
>  chardev/char-file.c | 5 +
>  chardev/char.c  | 3 +++
>  qemu-options.hx | 7 +--
>  3 files changed, 13 insertions(+), 2 deletions(-)
[...]
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 292d4e7c0c..488961099b 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -2938,7 +2938,7 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev,
>  "-chardev 
> vc,id=id[[,width=width][,height=height]][[,cols=cols][,rows=rows]]\n"
>  " [,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
>  "-chardev ringbuf,id=id[,size=size][,logfile=PATH][,logappend=on|off]\n"
> -"-chardev 
> file,id=id,path=path[,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
> +"-chardev 
> file,id=id,path=path[,pathin=PATH][,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
>  "-chardev 
> pipe,id=id,path=path[,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
>  #ifdef _WIN32
>  "-chardev console,id=id[,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
> @@ -3137,13 +3137,16 @@ The available backends are:
>  Create a ring buffer with fixed size ``size``. size must be a power
>  of two and defaults to ``64K``.
>  
> -``-chardev file,id=id,path=path``
> +``-chardev file,id=id,path=path[,pathin=pathin]``
>  Log all traffic received from the guest to a file.
>  
>  ``path`` specifies the path of the file to be opened. This file will
>  be created if it does not already exist, and overwritten if it does.
>  ``path`` is required.
>  
> +``pathin`` specifies a separate file as the input to the chardev. If
> +``pathin`` is omitted, ``path`` is used for both input and output
> +
>  ``-chardev pipe,id=id,path=path``
>  Create a two-way connection to the guest. The behaviour differs
>  slightly between Windows hosts and other hosts:

"pathin" is ugly.  What about "path-input"?




Re: [PATCH Kernel v20 6/8] vfio iommu: Update UNMAP_DMA ioctl to get dirty bitmap before unmap

2020-05-14 Thread Alex Williamson
On Fri, 15 May 2020 02:07:45 +0530
Kirti Wankhede  wrote:

> DMA mapped pages, including those pinned by mdev vendor drivers, might
> get unpinned and unmapped while migration is active and device is still
> running. For example, in pre-copy phase while guest driver could access
> those pages, host device or vendor driver can dirty these mapped pages.
> Such pages should be marked dirty so as to maintain memory consistency
> for a user making use of dirty page tracking.
> 
> To get bitmap during unmap, user should allocate memory for bitmap, set
> it all zeros, set size of allocated memory, set page size to be
> considered for bitmap and set flag VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP.
> 
> Signed-off-by: Kirti Wankhede 
> Reviewed-by: Neo Jia 
> ---
>  drivers/vfio/vfio_iommu_type1.c | 77 
> ++---
>  include/uapi/linux/vfio.h   | 10 ++
>  2 files changed, 75 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
> index b76d3b14abfd..a1dc57bcece5 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -195,11 +195,15 @@ static void vfio_unlink_dma(struct vfio_iommu *iommu, 
> struct vfio_dma *old)
>  static int vfio_dma_bitmap_alloc(struct vfio_dma *dma, size_t pgsize)
>  {
>   uint64_t npages = dma->size / pgsize;
> + size_t bitmap_size;
>  
>   if (npages > DIRTY_BITMAP_PAGES_MAX)
>   return -EINVAL;
>  
> - dma->bitmap = kvzalloc(DIRTY_BITMAP_BYTES(npages), GFP_KERNEL);
> + /* Allocate extra 64 bits which are used for bitmap manipulation */
> + bitmap_size = DIRTY_BITMAP_BYTES(npages) + sizeof(u64);
> +
> + dma->bitmap = kvzalloc(bitmap_size, GFP_KERNEL);
>   if (!dma->bitmap)
>   return -ENOMEM;
>  
> @@ -999,23 +1003,25 @@ static int verify_bitmap_size(uint64_t npages, 
> uint64_t bitmap_size)
>  }
>  
>  static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
> -  struct vfio_iommu_type1_dma_unmap *unmap)
> +  struct vfio_iommu_type1_dma_unmap *unmap,
> +  struct vfio_bitmap *bitmap)
>  {
> - uint64_t mask;
>   struct vfio_dma *dma, *dma_last = NULL;
> - size_t unmapped = 0;
> + size_t unmapped = 0, pgsize;
>   int ret = 0, retries = 0;
> + unsigned long pgshift;
>  
>   mutex_lock(>lock);
>  
> - mask = ((uint64_t)1 << __ffs(iommu->pgsize_bitmap)) - 1;
> + pgshift = __ffs(iommu->pgsize_bitmap);
> + pgsize = (size_t)1 << pgshift;
>  
> - if (unmap->iova & mask) {
> + if (unmap->iova & (pgsize - 1)) {
>   ret = -EINVAL;
>   goto unlock;
>   }
>  
> - if (!unmap->size || unmap->size & mask) {
> + if (!unmap->size || unmap->size & (pgsize - 1)) {
>   ret = -EINVAL;
>   goto unlock;
>   }
> @@ -1026,9 +1032,15 @@ static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
>   goto unlock;
>   }
>  
> - WARN_ON(mask & PAGE_MASK);
> -again:
> + /* When dirty tracking is enabled, allow only min supported pgsize */
> + if ((unmap->flags & VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP) &&
> + (!iommu->dirty_page_tracking || (bitmap->pgsize != pgsize))) {
> + ret = -EINVAL;
> + goto unlock;
> + }
>  
> + WARN_ON((pgsize - 1) & PAGE_MASK);
> +again:
>   /*
>* vfio-iommu-type1 (v1) - User mappings were coalesced together to
>* avoid tracking individual mappings.  This means that the granularity
> @@ -1066,6 +1078,7 @@ static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
>   ret = -EINVAL;
>   goto unlock;
>   }
> +
>   dma = vfio_find_dma(iommu, unmap->iova + unmap->size - 1, 0);
>   if (dma && dma->iova + dma->size != unmap->iova + unmap->size) {
>   ret = -EINVAL;
> @@ -1083,6 +1096,23 @@ static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
>   if (dma->task->mm != current->mm)
>   break;
>  
> + if ((unmap->flags & VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP) &&
> + (dma_last != dma)) {
> +
> + /*
> +  * mark all pages dirty if all pages are pinned and
> +  * mapped
> +  */
> + if (dma->iommu_mapped)
> + bitmap_set(dma->bitmap, 0,
> +dma->size >> pgshift);

Nit, all the callers of update_user_bitmap() precede the call with this
identical operation, we should probably push it into the function to do
it.

> +
> + ret = update_user_bitmap(bitmap->data, dma,
> +  unmap->iova, pgsize);
> + if (ret)
> + break;
> + }
> +

As noted last 

About migration/colo issue

2020-05-14 Thread Zhang, Chen
Hi Hailiang/Dave.

I found a urgent problem in current upstream code, COLO will stuck on secondary 
checkpoint and later.
The guest will stuck by this issue.
I have bisect upstream code, this issue caused by Hailiang's optimize patch:

>From 0393031a16735835a441b6d6e0495a1bd14adb90 Mon Sep 17 00:00:00 2001
From: zhanghailiang 
Date: Mon, 24 Feb 2020 14:54:10 +0800
Subject: [PATCH] COLO: Optimize memory back-up process

This patch will reduce the downtime of VM for the initial process,
Previously, we copied all these memory in preparing stage of COLO
while we need to stop VM, which is a time-consuming process.
Here we optimize it by a trick, back-up every page while in migration
process while COLO is enabled, though it affects the speed of the
migration, but it obviously reduce the downtime of back-up all SVM'S
memory in COLO preparing stage.

Signed-off-by: zhanghailiang 
Message-Id: <20200224065414.36524-5-zhang.zhanghaili...@huawei.com>
Signed-off-by: Dr. David Alan Gilbert 
  minor typo fixes

Hailiang, do you have time to look into it?


The detail log:
Primary node:
13322@1589511271.917346:colo_receive_message Receive 'checkpoint-ready' message
{"timestamp": {"seconds": 1589511271, "microseconds": 917406}, "event": 
"RESUME"}
13322@1589511271.917842:colo_vm_state_change Change 'stop' => 'run'
13322@1589511291.243346:colo_send_message Send 'checkpoint-request' message
13322@1589511291.243978:colo_receive_message Receive 'checkpoint-reply' message
{"timestamp": {"seconds": 1589511291, "microseconds": 244096}, "event": "STOP"}
13322@1589511291.24:colo_vm_state_change Change 'run' => 'stop'
13322@1589511291.244561:colo_send_message Send 'vmstate-send' message
13322@1589511291.258594:colo_send_message Send 'vmstate-size' message
13322@1589511305.412479:colo_receive_message Receive 'vmstate-received' message
13322@1589511309.031826:colo_receive_message Receive 'vmstate-loaded' message
{"timestamp": {"seconds": 1589511309, "microseconds": 31862}, "event": "RESUME"}
13322@1589511309.033075:colo_vm_state_change Change 'stop' => 'run'
{"timestamp": {"seconds": 1589511311, "microseconds": 111617}, "event": 
"VNC_CONNECTED", "data": {"server": {"auth": "none", "family": "ipv4", 
"service": "5907", "host": "0.0.0.0", "websocket": false}, "client": {"family": 
"ipv4", "service": "51564", "host": "10.239.13.19", "websocket": false}}}
{"timestamp": {"seconds": 1589511311, "microseconds": 116197}, "event": 
"VNC_INITIALIZED", "data": {"server": {"auth": "none", "family": "ipv4", 
"service": "5907", "host": "0.0.0.0", "websocket": false}, "client": {"family": 
"ipv4", "service": "51564", "host": "10.239.13.19", "websocket": false}}}
13322@1589511311.243271:colo_send_message Send 'checkpoint-request' message
13322@1589511311.351361:colo_receive_message Receive 'checkpoint-reply' message
{"timestamp": {"seconds": 1589511311, "microseconds": 351439}, "event": "STOP"}
13322@1589511311.415779:colo_vm_state_change Change 'run' => 'stop'
13322@1589511311.416001:colo_send_message Send 'vmstate-send' message
13322@1589511311.418620:colo_send_message Send 'vmstate-size' message

Secondary node:
{"timestamp": {"seconds": 1589510920, "microseconds": 778207}, "event": 
"RESUME"}
23619@1589510920.778835:colo_vm_state_change Change 'stop' => 'run'
23619@1589510920.778891:colo_send_message Send 'checkpoint-ready' message
23619@1589510940.105539:colo_receive_message Receive 'checkpoint-request' 
message
{"timestamp": {"seconds": 1589510940, "microseconds": 105712}, "event": "STOP"}
23619@1589510940.105917:colo_vm_state_change Change 'run' => 'stop'
23619@1589510940.105971:colo_send_message Send 'checkpoint-reply' message
23619@1589510940.106767:colo_receive_message Receive 'vmstate-send' message
23619@1589510940.122808:colo_flush_ram_cache_begin dirty_pages 2456
23619@1589510953.618672:colo_flush_ram_cache_end
23619@1589510953.945083:colo_receive_message Receive 'vmstate-size' message
23619@1589510954.274816:colo_send_message Send 'vmstate-received' message
qemu-system-x86_64: warning: TSC frequency mismatch between VM (2792980 kHz) 
and host (2925999 kHz), and TSC scaling unavailable
{"timestamp": {"seconds": 1589510957, "microseconds": 754184}, "event": 
"RESUME"}
23619@1589510957.894113:colo_vm_state_change Change 'stop' => 'run'
23619@1589510957.894162:colo_send_message Send 'vmstate-loaded' message
23619@1589510960.105977:colo_receive_message Receive 'checkpoint-request' 
message
{"timestamp": {"seconds": 1589510960, "microseconds": 106148}, "event": "STOP"}
23619@1589510960.213773:colo_vm_state_change Change 'run' => 'stop'
23619@1589510960.213797:colo_send_message Send 'checkpoint-reply' message
23619@1589510960.278771:colo_receive_message Receive 'vmstate-send' message
23619@1589510960.423268:colo_flush_ram_cache_begin dirty_pages 25









[Bug 1856335] Re: Cache Layout wrong on many Zen Arch CPUs

2020-05-14 Thread Jan Klos
The problem is that disabled cores are not taken into account.. ALL Zen2
CPUs have L3 cache group per CCX and every CCX has 4 cores, the problem
is that some cores in each CCX (1 for 6 and 12-core CPUs, 2 for 3100)
are disabled for some models, but they still use their core ids (as can
be seen in virsh capabilities | grep "cpu id" output in above comments).
Looking at target/i386/cpu.c:5529, this is not taken into account.

Maybe the cleanest way to fix this is to emulate the host topology by
also skipping disabled core ids in the VM? That way, die offset will
actually match the real host CPU topology...

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

Title:
  Cache Layout wrong on many Zen Arch CPUs

Status in QEMU:
  New

Bug description:
  AMD CPUs have L3 cache per 2, 3 or 4 cores. Currently, TOPOEXT seems
  to always map Cache ass if it was an 4-Core per CCX CPU, which is
  incorrect, and costs upwards 30% performance (more realistically 10%)
  in L3 Cache Layout aware applications.

  Example on a 4-CCX CPU (1950X /w 8 Cores and no SMT):

    
  EPYC-IBPB
  AMD
  

  In windows, coreinfo reports correctly:

    Unified Cache 1, Level 3,8 MB, Assoc  16, LineSize  64
    Unified Cache 6, Level 3,8 MB, Assoc  16, LineSize  64

  On a 3-CCX CPU (3960X /w 6 cores and no SMT):

   
  EPYC-IBPB
  AMD
  

  in windows, coreinfo reports incorrectly:

  --  Unified Cache  1, Level 3,8 MB, Assoc  16, LineSize  64
  **  Unified Cache  6, Level 3,8 MB, Assoc  16, LineSize  64

  Validated against 3.0, 3.1, 4.1 and 4.2 versions of qemu-kvm.

  With newer Qemu there is a fix (that does behave correctly) in using the dies 
parameter:
   

  The problem is that the dies are exposed differently than how AMD does
  it natively, they are exposed to Windows as sockets, which means, that
  if you are nto a business user, you can't ever have a machine with
  more than two CCX (6 cores) as consumer versions of Windows only
  supports two sockets. (Should this be reported as a separate bug?)

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



RE: [PATCH 6/6] migration/colo.c: Move colo_notify_compares_event to the right place

2020-05-14 Thread Zhanghailiang
Reviewed-by: zhanghailiang 

> -Original Message-
> From: Lukas Straub [mailto:lukasstra...@web.de]
> Sent: Monday, May 11, 2020 7:11 PM
> To: qemu-devel 
> Cc: Zhanghailiang ; Juan Quintela
> ; Dr. David Alan Gilbert 
> Subject: [PATCH 6/6] migration/colo.c: Move colo_notify_compares_event
> to the right place
> 
> If the secondary has to failover during checkpointing, it still is in the old 
> state
> (i.e. different state than primary). Thus we can't expose the primary state
> until after the checkpoint is sent.
> 
> This fixes sporadic connection reset of client connections during failover.
> 
> Signed-off-by: Lukas Straub 
> ---
>  migration/colo.c | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/migration/colo.c b/migration/colo.c index
> a69782efc5..a3fc21e86e 100644
> --- a/migration/colo.c
> +++ b/migration/colo.c
> @@ -430,12 +430,6 @@ static int
> colo_do_checkpoint_transaction(MigrationState *s,
>  goto out;
>  }
> 
> -qemu_event_reset(>colo_checkpoint_event);
> -colo_notify_compares_event(NULL, COLO_EVENT_CHECKPOINT,
> _err);
> -if (local_err) {
> -goto out;
> -}
> -
>  /* Disable block migration */
>  migrate_set_block_enabled(false, _err);
>  qemu_mutex_lock_iothread();
> @@ -494,6 +488,12 @@ static int
> colo_do_checkpoint_transaction(MigrationState *s,
>  goto out;
>  }
> 
> +qemu_event_reset(>colo_checkpoint_event);
> +colo_notify_compares_event(NULL, COLO_EVENT_CHECKPOINT,
> _err);
> +if (local_err) {
> +goto out;
> +}
> +
>  colo_receive_check_message(s->rp_state.from_dst_file,
> COLO_MESSAGE_VMSTATE_LOADED, _err);
>  if (local_err) {
> --
> 2.20.1



Re: [RFC 16/18] use errp for gmpo kvm_init

2020-05-14 Thread David Gibson
On Thu, May 14, 2020 at 06:09:46PM +0100, Dr. David Alan Gilbert wrote:
> Dave:
>   You've got some screwy mail headers here, the qemu-devel@nongnu.-rg is
> the best one anmd the p...@us.redhat.com is weird as well.

Yeah, apparently I forgot how to type when I entered my git-publish
command line :/.

> 
> * David Gibson (da...@gibson.dropbear.id.au) wrote:
> > ---
> >  accel/kvm/kvm-all.c|  4 +++-
> >  include/exec/guest-memory-protection.h |  2 +-
> >  target/i386/sev.c  | 32 +-
> >  3 files changed, 20 insertions(+), 18 deletions(-)
> > 
> > diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
> > index 5451728425..392ab02867 100644
> > --- a/accel/kvm/kvm-all.c
> > +++ b/accel/kvm/kvm-all.c
> > @@ -2045,9 +2045,11 @@ static int kvm_init(MachineState *ms)
> >  if (ms->gmpo) {
> >  GuestMemoryProtectionClass *gmpc =
> >  GUEST_MEMORY_PROTECTION_GET_CLASS(ms->gmpo);
> > +Error *local_err = NULL;
> >  
> > -ret = gmpc->kvm_init(ms->gmpo);
> > +ret = gmpc->kvm_init(ms->gmpo, _err);
> >  if (ret < 0) {
> > +error_report_err(local_err);
> >  goto err;
> >  }
> >  }
> > diff --git a/include/exec/guest-memory-protection.h 
> > b/include/exec/guest-memory-protection.h
> > index 7d959b4910..2a88475136 100644
> > --- a/include/exec/guest-memory-protection.h
> > +++ b/include/exec/guest-memory-protection.h
> > @@ -32,7 +32,7 @@ typedef struct GuestMemoryProtection 
> > GuestMemoryProtection;
> >  typedef struct GuestMemoryProtectionClass {
> >  InterfaceClass parent;
> >  
> > -int (*kvm_init)(GuestMemoryProtection *);
> > +int (*kvm_init)(GuestMemoryProtection *, Error **);
> >  int (*encrypt_data)(GuestMemoryProtection *, uint8_t *, uint64_t);
> >  } GuestMemoryProtectionClass;
> >  
> > diff --git a/target/i386/sev.c b/target/i386/sev.c
> > index 2051fae0c1..82f16b2f3b 100644
> > --- a/target/i386/sev.c
> > +++ b/target/i386/sev.c
> > @@ -617,7 +617,7 @@ sev_vm_state_change(void *opaque, int running, RunState 
> > state)
> >  }
> >  }
> >  
> > -static int sev_kvm_init(GuestMemoryProtection *gmpo)
> > +static int sev_kvm_init(GuestMemoryProtection *gmpo, Error **errp)
> >  {
> >  SevGuestState *sev = SEV_GUEST(gmpo);
> >  char *devname;
> > @@ -633,14 +633,14 @@ static int sev_kvm_init(GuestMemoryProtection *gmpo)
> >  host_cbitpos = ebx & 0x3f;
> >  
> >  if (host_cbitpos != sev->cbitpos) {
> > -error_report("%s: cbitpos check failed, host '%d' requested '%d'",
> > - __func__, host_cbitpos, sev->cbitpos);
> > +error_setg(errp, "%s: cbitpos check failed, host '%d' requested 
> > '%d'",
> > +   __func__, host_cbitpos, sev->cbitpos);
> >  goto err;
> >  }
> >  
> >  if (sev->reduced_phys_bits < 1) {
> > -error_report("%s: reduced_phys_bits check failed, it should be 
> > >=1,"
> > - " requested '%d'", __func__, sev->reduced_phys_bits);
> > +error_setg(errp, "%s: reduced_phys_bits check failed, it should be 
> > >=1,"
> > +   " requested '%d'", __func__, sev->reduced_phys_bits);
> >  goto err;
> >  }
> >  
> > @@ -649,20 +649,20 @@ static int sev_kvm_init(GuestMemoryProtection *gmpo)
> >  devname = object_property_get_str(OBJECT(sev), "sev-device", NULL);
> >  sev->sev_fd = open(devname, O_RDWR);
> >  if (sev->sev_fd < 0) {
> > -error_report("%s: Failed to open %s '%s'", __func__,
> > - devname, strerror(errno));
> > -}
> > -g_free(devname);
> > -if (sev->sev_fd < 0) {
> > +g_free(devname);
> > +error_setg(errp, "%s: Failed to open %s '%s'", __func__,
> > +   devname, strerror(errno));
> > +g_free(devname);
> 
> You seem to have double free'd devname - would g_autofree work here?
> 
> other than that, looks OK to me.
> 
> Dave
> 
> >  goto err;
> >  }
> > +g_free(devname);
> >  
> >  ret = sev_platform_ioctl(sev->sev_fd, SEV_PLATFORM_STATUS, ,
> >   _error);
> >  if (ret) {
> > -error_report("%s: failed to get platform status ret=%d "
> > - "fw_error='%d: %s'", __func__, ret, fw_error,
> > - fw_error_to_str(fw_error));
> > +error_setg(errp, "%s: failed to get platform status ret=%d "
> > +   "fw_error='%d: %s'", __func__, ret, fw_error,
> > +   fw_error_to_str(fw_error));
> >  goto err;
> >  }
> >  sev->build_id = status.build;
> > @@ -672,14 +672,14 @@ static int sev_kvm_init(GuestMemoryProtection *gmpo)
> >  trace_kvm_sev_init();
> >  ret = sev_ioctl(sev->sev_fd, KVM_SEV_INIT, NULL, _error);
> >  if (ret) {
> > -error_report("%s: failed to initialize ret=%d fw_error=%d '%s'",
> > - __func__, ret, fw_error, 

Re: [RFC 16/18] use errp for gmpo kvm_init

2020-05-14 Thread David Gibson
On Thu, May 14, 2020 at 06:09:46PM +0100, Dr. David Alan Gilbert wrote:
> * David Gibson (da...@gibson.dropbear.id.au) wrote:
[snip]
> > @@ -649,20 +649,20 @@ static int sev_kvm_init(GuestMemoryProtection *gmpo)
> >  devname = object_property_get_str(OBJECT(sev), "sev-device", NULL);
> >  sev->sev_fd = open(devname, O_RDWR);
> >  if (sev->sev_fd < 0) {
> > -error_report("%s: Failed to open %s '%s'", __func__,
> > - devname, strerror(errno));
> > -}
> > -g_free(devname);
> > -if (sev->sev_fd < 0) {
> > +g_free(devname);
> > +error_setg(errp, "%s: Failed to open %s '%s'", __func__,
> > +   devname, strerror(errno));
> > +g_free(devname);
> 
> You seem to have double free'd devname - would g_autofree work here?

Oops, fixed.  I'm not really familiar with the g_autofree stuff as
yet, so, maybe?

I also entirely forgot to write a non-placeholder commit message for
this patch.  Oops.

> other than that, looks OK to me.



> 
> Dave
> 
> >  goto err;
> >  }
> > +g_free(devname);
> >  
> >  ret = sev_platform_ioctl(sev->sev_fd, SEV_PLATFORM_STATUS, ,
> >   _error);
> >  if (ret) {
> > -error_report("%s: failed to get platform status ret=%d "
> > - "fw_error='%d: %s'", __func__, ret, fw_error,
> > - fw_error_to_str(fw_error));
> > +error_setg(errp, "%s: failed to get platform status ret=%d "
> > +   "fw_error='%d: %s'", __func__, ret, fw_error,
> > +   fw_error_to_str(fw_error));
> >  goto err;
> >  }
> >  sev->build_id = status.build;
> > @@ -672,14 +672,14 @@ static int sev_kvm_init(GuestMemoryProtection *gmpo)
> >  trace_kvm_sev_init();
> >  ret = sev_ioctl(sev->sev_fd, KVM_SEV_INIT, NULL, _error);
> >  if (ret) {
> > -error_report("%s: failed to initialize ret=%d fw_error=%d '%s'",
> > - __func__, ret, fw_error, fw_error_to_str(fw_error));
> > +error_setg(errp, "%s: failed to initialize ret=%d fw_error=%d 
> > '%s'",
> > +   __func__, ret, fw_error, fw_error_to_str(fw_error));
> >  goto err;
> >  }
> >  
> >  ret = sev_launch_start(sev);
> >  if (ret) {
> > -error_report("%s: failed to create encryption context", __func__);
> > +error_setg(errp, "%s: failed to create encryption context", 
> > __func__);
> >  goto err;
> >  }
> >  

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


signature.asc
Description: PGP signature


RE: [PATCH 6/6] migration/colo.c: Move colo_notify_compares_event to the right place

2020-05-14 Thread Zhanghailiang
> -Original Message-
> From: Lukas Straub [mailto:lukasstra...@web.de]
> Sent: Thursday, May 14, 2020 10:31 PM
> To: Zhanghailiang 
> Cc: qemu-devel ; Zhang Chen
> ; Juan Quintela ; Dr. David
> Alan Gilbert 
> Subject: Re: [PATCH 6/6] migration/colo.c: Move
> colo_notify_compares_event to the right place
> 
> On Thu, 14 May 2020 13:27:30 +
> Zhanghailiang  wrote:
> 
> > Cc: Zhang Chen 
> >
> > >
> > > If the secondary has to failover during checkpointing, it still is
> > > in the old state (i.e. different state than primary). Thus we can't
> > > expose the primary state until after the checkpoint is sent.
> > >
> >
> > Hmm, do you mean we should not flush the net packages to client
> > connection until checkpointing Process almost success because it may fail
> during checkpointing ?
> 
> No.
> If the primary fails/crashes during checkpointing, the secondary is still in
> different state than the primary because it didn't receive the full 
> checkpoint.
> We can release the miscompared packets only after both primary and
> secondary are in the same state.
> 
> Example:
> 1. Client opens a TCP connection, sends SYN.
> 2. Primary accepts the connection with SYN-ACK, but due to
> nondeterministic execution the secondary is delayed.
> 3. Checkpoint happens, primary releases the SYN-ACK packet but then
> crashes while sending the checkpoint.
> 4. The Secondary fails over. At this point it is still in the old state where 
> it
> hasn't sent the SYN-ACK packet.
> 5. The client responds with ACK to the SYN-ACK packet.
> 6. Because it doesn't know the connection, the secondary responds with RST,
> connection reset.
> 

Good example. For this patch, it is OK, I will add reviewed-by in your origin 
patch.


> Regards,
> Lukas Straub
> 
> > > This fixes sporadic connection reset of client connections during 
> > > failover.
> > >
> > > Signed-off-by: Lukas Straub 
> > > ---
> > >  migration/colo.c | 12 ++--
> > >  1 file changed, 6 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/migration/colo.c b/migration/colo.c index
> > > a69782efc5..a3fc21e86e 100644
> > > --- a/migration/colo.c
> > > +++ b/migration/colo.c
> > > @@ -430,12 +430,6 @@ static int
> > > colo_do_checkpoint_transaction(MigrationState *s,
> > >  goto out;
> > >  }
> > >
> > > -qemu_event_reset(>colo_checkpoint_event);
> > > -colo_notify_compares_event(NULL, COLO_EVENT_CHECKPOINT,
> > > _err);
> > > -if (local_err) {
> > > -goto out;
> > > -}
> > > -
> > >  /* Disable block migration */
> > >  migrate_set_block_enabled(false, _err);
> > >  qemu_mutex_lock_iothread();
> > > @@ -494,6 +488,12 @@ static int
> > > colo_do_checkpoint_transaction(MigrationState *s,
> > >  goto out;
> > >  }
> > >
> > > +qemu_event_reset(>colo_checkpoint_event);
> > > +colo_notify_compares_event(NULL, COLO_EVENT_CHECKPOINT,
> > > _err);
> > > +if (local_err) {
> > > +goto out;
> > > +}
> > > +
> > >  colo_receive_check_message(s->rp_state.from_dst_file,
> > > COLO_MESSAGE_VMSTATE_LOADED,
> _err);
> > >  if (local_err) {
> > > --
> > > 2.20.1




Re: [virtio-dev] Re: Fwd: Qemu Support for Virtio Video V4L2 driver

2020-05-14 Thread Nicolas Dufresne
Le lundi 11 mai 2020 à 20:49 +0900, Keiichi Watanabe a écrit :
> Hi,
> 
> Thanks Saket for your feedback. As Dmitry mentioned, we're focusing on
> video encoding and decoding, not camera. So, my reply was about how to
> implement paravirtualized video codec devices.
> 
> On Mon, May 11, 2020 at 8:25 PM Dmitry Sepp 
> wrote:
> > Hi Saket,
> > 
> > On Montag, 11. Mai 2020 13:05:53 CEST Saket Sinha wrote:
> > > Hi Keiichi,
> > > 
> > > I do not support the approach of  QEMU implementation forwarding
> > > requests to the host's vicodec module since  this can limit the scope
> > > of the virtio-video device only for testing,
> > 
> > That was my understanding as well.
> 
> Not really because the API which the vicodec provides is V4L2 stateful
> decoder interface [1], which are also used by other video drivers on
> Linux.
> The difference between vicodec and actual device drivers is that
> vicodec performs decoding in the kernel space without using special
> video devices. In other words, vicodec is a software decoder in kernel
> space which provides the same interface with actual video drivers.
> Thus, if the QEMU implementation can forward virtio-video requests to
> vicodec, it can forward them to the actual V4L2 video decoder devices
> as well and VM gets access to a paravirtualized video device.
> 
> The reason why we discussed vicodec in the previous thread was it'll
> allow us to test the virtio-video driver without hardware requirement.
> 
> [1] https://www.kernel.org/doc/html/latest/media/uapi/v4l/dev-decoder.html
> 
> > > which instead can be used with multiple use cases such as -
> > > 
> > > 1. VM gets access to paravirtualized  camera devices which shares the
> > > video frames input through actual HW camera attached to Host.
> > 
> > This use-case is out of the scope of virtio-video. Initially I had a plan to
> > support capture-only streams like camera as well, but later the decision was
> > made upstream that camera should be implemented as separate device type. We
> > still plan to implement a simple frame capture capability as a downstream
> > patch though.
> > 
> > > 2. If Host has multiple video devices (especially in ARM SOCs over
> > > MIPI interfaces or USB), different VM can be started or hotplugged
> > > with selective video streams from actual HW video devices.
> > 
> > We do support this in our device implementation. But spec in general has no
> > requirements or instructions regarding this. And it is in fact flexible
> > enough
> > to provide abstraction on top of several HW devices.
> > 
> > > Also instead of using libraries like Gstreamer in Host userspace, they
> > > can also be used inside the VM userspace after getting access to
> > > paravirtualized HW camera devices .
> 
> Regarding Gstreamer, I intended this video decoding API [2]. If QEMU
> can translate virtio-video requests to this API, we can easily support
> multiple platforms.
> I'm not sure how feasible it is though, as I have no experience of
> using this API by myself...

Not sure which API you aim exactly, but what one need to remember is that
mapping virtio-video CODEC on top of VAAPI, V4L2 Stateless, NVDEC or other type
of "stateless" CODEC is not trivial and can't be done without userspace. Notably
because we don't want to do bitstream parsing in the kernel on the main CPU as
security would otherwise be very hard to guaranty. The other driver using same
API as virtio-video do bitstream parsing on a dedicated co-processor (through
firmware blobs though).

Having bridges between virtio-video, qemu and some abstraction library like
FFMPEG or GStreamer is certainly the best solution if you want to virtualize any
type of HW accelerated decoder or if you need to virtualized something
proprietary (like NVDEC). Please shout if you need help.

> 
> [2] 
> https://gstreamer.freedesktop.org/documentation/tutorials/playback/hardware-accelerated-video-decoding.html
> 
> Best regards,
> Keiichi
> 
> > 
> > Regarding the cameras, unfortunately same as above.
> > 
> > Best regards,
> > Dmitry.
> > 
> > > Regards,
> > > Saket Sinha
> > > 
> > > On Mon, May 11, 2020 at 12:20 PM Keiichi Watanabe 
> > wrote:
> > > > Hi Dmitry,
> > > > 
> > > > On Mon, May 11, 2020 at 6:40 PM Dmitry Sepp  > > > >
> > wrote:
> > > > > Hi Saket and all,
> > > > > 
> > > > > As we are working with automotive platforms, unfortunately we don't
> > > > > plan
> > > > > any Qemu reference implementation so far.
> > > > > 
> > > > > Of course we are ready to support the community if any help is needed.
> > > > > Is
> > > > > there interest in support for the FWHT format only for testing purpose
> > > > > or you want a full-featured implementation on the QEMU side?
> > > > 
> > > > I guess we don't need to implement the codec algorithm in QEMU.
> > > > Rather, QEMU forwards virtio-video requests to the host video device
> > > > or a software library such as GStreamer or ffmpeg.
> > > > So, what we need to implement in QEMU is a kind of API translation,
> > > 

[Bug 1856335] Re: Cache Layout wrong on many Zen Arch CPUs

2020-05-14 Thread Jan Klos
Same problem here on 5.0 and 3900x (3 cores per CCX). And as stated
before - declaring NUMA nodes is definitely not the right solution if
the aim is to emulate the host CPU as close as possible.

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

Title:
  Cache Layout wrong on many Zen Arch CPUs

Status in QEMU:
  New

Bug description:
  AMD CPUs have L3 cache per 2, 3 or 4 cores. Currently, TOPOEXT seems
  to always map Cache ass if it was an 4-Core per CCX CPU, which is
  incorrect, and costs upwards 30% performance (more realistically 10%)
  in L3 Cache Layout aware applications.

  Example on a 4-CCX CPU (1950X /w 8 Cores and no SMT):

    
  EPYC-IBPB
  AMD
  

  In windows, coreinfo reports correctly:

    Unified Cache 1, Level 3,8 MB, Assoc  16, LineSize  64
    Unified Cache 6, Level 3,8 MB, Assoc  16, LineSize  64

  On a 3-CCX CPU (3960X /w 6 cores and no SMT):

   
  EPYC-IBPB
  AMD
  

  in windows, coreinfo reports incorrectly:

  --  Unified Cache  1, Level 3,8 MB, Assoc  16, LineSize  64
  **  Unified Cache  6, Level 3,8 MB, Assoc  16, LineSize  64

  Validated against 3.0, 3.1, 4.1 and 4.2 versions of qemu-kvm.

  With newer Qemu there is a fix (that does behave correctly) in using the dies 
parameter:
   

  The problem is that the dies are exposed differently than how AMD does
  it natively, they are exposed to Windows as sockets, which means, that
  if you are nto a business user, you can't ever have a machine with
  more than two CCX (6 cores) as consumer versions of Windows only
  supports two sockets. (Should this be reported as a separate bug?)

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



Re: Ping Re: [PATCH 0/5] target/i386: fxtract, fscale fixes

2020-05-14 Thread Paolo Bonzini
On 14/05/20 20:25, Joseph Myers wrote:
> Ping for this patch series 
> .
> 
> Although my three patch series so far for floatx80 and i386 floating-point 
> instructions fixes are independent of each other, it's likely future patch 
> series in this area will depend on some of the previous patch series.

Sorry, I'm lagging behind on my QEMU reviews.  I'll get to it tomorrow
or next week.

Thanks,

Paolo




Re: [PATCH v2 5/9] hw/char: Initial commit of Ibex UART

2020-05-14 Thread Alistair Francis
On Thu, May 14, 2020 at 11:00 AM Philippe Mathieu-Daudé
 wrote:
>
> Hi Alistair,
>
> On 5/7/20 9:13 PM, Alistair Francis wrote:
> > This is the initial commit of the Ibex UART device. Serial TX is
> > working, while RX has been implemeneted but untested.
> >
> > This is based on the documentation from:
> > https://docs.opentitan.org/hw/ip/uart/doc/
> >
> > Signed-off-by: Alistair Francis 
> > ---
> >   MAINTAINERS |   2 +
> >   hw/char/Makefile.objs   |   1 +
> >   hw/char/ibex_uart.c | 490 
> >   hw/riscv/Kconfig|   4 +
> >   include/hw/char/ibex_uart.h | 110 
> >   5 files changed, 607 insertions(+)
> >   create mode 100644 hw/char/ibex_uart.c
> >   create mode 100644 include/hw/char/ibex_uart.h
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index c3d77f0861..d3d47564ce 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -1236,7 +1236,9 @@ M: Alistair Francis 
> >   L: qemu-ri...@nongnu.org
> >   S: Supported
> >   F: hw/riscv/opentitan.c
> > +F: hw/char/ibex_uart.c
> >   F: include/hw/riscv/opentitan.h
> > +F: include/hw/char/ibex_uart.h
> >
> >
> >   SH4 Machines
> > diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
> > index 9e9a6c1aff..633996be5b 100644
> > --- a/hw/char/Makefile.objs
> > +++ b/hw/char/Makefile.objs
> > @@ -12,6 +12,7 @@ common-obj-$(CONFIG_VIRTIO_SERIAL) += virtio-console.o
> >   common-obj-$(CONFIG_XILINX) += xilinx_uartlite.o
> >   common-obj-$(CONFIG_XEN) += xen_console.o
> >   common-obj-$(CONFIG_CADENCE) += cadence_uart.o
> > +common-obj-$(CONFIG_IBEX) += ibex_uart.o
> >
> >   common-obj-$(CONFIG_EXYNOS4) += exynos4210_uart.o
> >   common-obj-$(CONFIG_COLDFIRE) += mcf_uart.o
> > diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c
> > new file mode 100644
> > index 00..f6215ae23d
> > --- /dev/null
> > +++ b/hw/char/ibex_uart.c
> > @@ -0,0 +1,490 @@
> > +/*
> > + * QEMU lowRISC Ibex UART device
> > + *
> > + * Copyright (c) 2020 Western Digital
> > + *
> > + * For details check the documentation here:
> > + *https://docs.opentitan.org/hw/ip/uart/doc/
> > + *
> > + * Permission is hereby granted, free of charge, to any person obtaining a 
> > copy
> > + * of this software and associated documentation files (the "Software"), 
> > to deal
> > + * in the Software without restriction, including without limitation the 
> > rights
> > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or 
> > sell
> > + * copies of the Software, and to permit persons to whom the Software is
> > + * furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice shall be included 
> > in
> > + * all copies or substantial portions of the Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
> > OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
> > OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
> > FROM,
> > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
> > IN
> > + * THE SOFTWARE.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "hw/char/ibex_uart.h"
> > +#include "hw/irq.h"
> > +#include "hw/qdev-properties.h"
> > +#include "migration/vmstate.h"
> > +#include "qemu/log.h"
> > +#include "qemu/module.h"
> > +
> > +static void ibex_uart_update_irqs(IbexUartState *s)
> > +{
> > +if (s->uart_intr_state & s->uart_intr_enable & 
> > INTR_STATE_TX_WATERMARK) {
> > +qemu_set_irq(s->tx_watermark, 1);
> > +} else {
> > +qemu_set_irq(s->tx_watermark, 0);
> > +}
> > +
> > +if (s->uart_intr_state & s->uart_intr_enable & 
> > INTR_STATE_RX_WATERMARK) {
> > +qemu_set_irq(s->rx_watermark, 1);
> > +} else {
> > +qemu_set_irq(s->rx_watermark, 0);
>
> I wonder if having both bit separate can't lead to odd pulse behavior
> (this function should have the same result if you invert the RX/TX
> processing here). I'd be safer using a local 'raise_watermark' boolean
> variable, then call qemu_set_irq() once.

I'm not sure what you mean. Are you worried that TX and RX will both
go high/low at the same time?

Alistair

>
> > +}
> > +
> > +if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_TX_EMPTY) {
> > +qemu_set_irq(s->tx_empty, 1);
> > +} else {
> > +qemu_set_irq(s->tx_empty, 0);
> > +}
> > +
> > +if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_RX_OVERFLOW) 
> > {
> > +qemu_set_irq(s->rx_overflow, 1);
> > +} else {
> > +qemu_set_irq(s->rx_overflow, 0);
> > +}
> > +}
> [...]
>



[PATCH v2 1/1] virtio-ccw: auto-manage VIRTIO_F_IOMMU_PLATFORM if PV

2020-05-14 Thread Halil Pasic
The virtio specification tells that the device is to present
VIRTIO_F_ACCESS_PLATFORM (a.k.a. VIRTIO_F_IOMMU_PLATFORM) when the
device "can only access certain memory addresses with said access
specified and/or granted by the platform". This is the case for a
protected VMs, as the device can access only memory addresses that are
in pages that are currently shared (only the guest can share/unsare its
pages).

No VM, however, starts out as a protected VM, but some VMs may be
converted to protected VMs if the guest decides so.

Making the end user explicitly manage the VIRTIO_F_ACCESS_PLATFORM via
the property iommu_on is a minor disaster. Since the correctness of the
paravirtualized virtio devices depends (and thus in a sense the
correctness of the hypervisor) it, then the hypervisor should have the
last word about whether VIRTIO_F_ACCESS_PLATFORM is to be presented or
not.

Currently presenting a PV guest with a (paravirtualized) virtio-ccw
device has catastrophic consequences for the VM (after the hypervisors
access to protected memory). This is especially grave in case of device
hotplug (because in this case the guest is more likely to be in the
middle of something important).

Let us manage the VIRTIO_F_ACCESS_PLATFORM virtio feature automatically
for virtio-ccw devices, i.e. force it before we start the protected VM.
If the VM should cease to be protected, the original value is restored.

Signed-off-by: Halil Pasic 
---

NOTES:

* Doing more system_resets() is a big hack.  We should look into this.
* The user interface implications of this patch are also an ugly can of
worms. We need to discuss them.


v1 --> v2:
* Use the default or user supplied iommu_on flag when when !PV
* Use virtio functions for feature manipulation

Link to v1:
https://www.mail-archive.com/qemu-devel@nongnu.org/msg683775.html

Unfortunately the v1 did not see much discussion because we had more
pressing issues.

---
 hw/s390x/s390-virtio-ccw.c |  2 ++
 hw/s390x/virtio-ccw.c  | 14 ++
 hw/s390x/virtio-ccw.h  |  1 +
 3 files changed, 17 insertions(+)

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index f660070d22..705e6b153a 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -330,6 +330,7 @@ static void s390_machine_unprotect(S390CcwMachineState *ms)
 migrate_del_blocker(pv_mig_blocker);
 error_free_or_abort(_mig_blocker);
 qemu_balloon_inhibit(false);
+subsystem_reset();
 }
 
 static int s390_machine_protect(S390CcwMachineState *ms)
@@ -382,6 +383,7 @@ static int s390_machine_protect(S390CcwMachineState *ms)
 if (rc) {
 goto out_err;
 }
+subsystem_reset();
 return rc;
 
 out_err:
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 64f928fc7d..67d5bc68ba 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -874,6 +874,20 @@ static void virtio_ccw_reset(DeviceState *d)
 VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
 VirtIODevice *vdev = virtio_bus_get_device(>bus);
 VirtIOCCWDeviceClass *vdc = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
+S390CcwMachineState *ms = S390_CCW_MACHINE(qdev_get_machine());
+
+/*
+ * An attempt to use a paravirt device without VIRTIO_F_IOMMU_PLATFORM
+ * in PV, has catastrophic consequences for the VM. Let's force
+ * VIRTIO_F_IOMMU_PLATFORM not already specified.
+ */
+if (ms->pv && !virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) {
+virtio_add_feature(>host_features, VIRTIO_F_IOMMU_PLATFORM);
+dev->forced_iommu_platform = true;
+} else if (!ms->pv && dev->forced_iommu_platform) {
+virtio_clear_feature(>host_features, VIRTIO_F_IOMMU_PLATFORM);
+dev->forced_iommu_platform = false;
+}
 
 virtio_ccw_reset_virtio(dev, vdev);
 if (vdc->parent_reset) {
diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h
index 3453aa1f98..34ff7b0b4e 100644
--- a/hw/s390x/virtio-ccw.h
+++ b/hw/s390x/virtio-ccw.h
@@ -99,6 +99,7 @@ struct VirtioCcwDevice {
 IndAddr *summary_indicator;
 uint64_t ind_bit;
 bool force_revision_1;
+bool forced_iommu_platform;
 };
 
 /* The maximum virtio revision we support. */

base-commit: 0ffd3d64bd1bb8b84950e52159a0062fdab34628
-- 
2.17.1




Re: [PATCH v2 6/9] hw/intc: Initial commit of lowRISC Ibex PLIC

2020-05-14 Thread Alistair Francis
On Thu, May 14, 2020 at 11:40 AM Philippe Mathieu-Daudé
 wrote:
>
> On 5/7/20 9:13 PM, Alistair Francis wrote:
> > The Ibex core contains a PLIC that although similar to the RISC-V spec
> > is not RISC-V spec compliant.
> >
> > This patch implements a Ibex PLIC in a somewhat generic way.
> >
> > As the current RISC-V PLIC needs tidying up, my hope is that as the Ibex
> > PLIC move towards spec compliance this PLIC implementation can be
> > updated until it can replace the current PLIC.
> >
> > Signed-off-by: Alistair Francis 
> > ---
> >   MAINTAINERS |   2 +
> >   hw/intc/Makefile.objs   |   1 +
> >   hw/intc/ibex_plic.c | 261 
> >   include/hw/intc/ibex_plic.h |  63 +
> >   4 files changed, 327 insertions(+)
> >   create mode 100644 hw/intc/ibex_plic.c
> >   create mode 100644 include/hw/intc/ibex_plic.h
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index d3d47564ce..f8c3cf6182 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -1237,8 +1237,10 @@ L: qemu-ri...@nongnu.org
> >   S: Supported
> >   F: hw/riscv/opentitan.c
> >   F: hw/char/ibex_uart.c
> > +F: hw/intc/ibex_plic.c
> >   F: include/hw/riscv/opentitan.h
> >   F: include/hw/char/ibex_uart.h
> > +F: include/hw/intc/ibex_plic.h
> >
> >
> >   SH4 Machines
> > diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
> > index f726d87532..a61e6728fe 100644
> > --- a/hw/intc/Makefile.objs
> > +++ b/hw/intc/Makefile.objs
> > @@ -49,3 +49,4 @@ obj-$(CONFIG_ARM_GIC) += arm_gicv3_cpuif.o
> >   obj-$(CONFIG_MIPS_CPS) += mips_gic.o
> >   obj-$(CONFIG_NIOS2) += nios2_iic.o
> >   obj-$(CONFIG_OMPIC) += ompic.o
> > +obj-$(CONFIG_IBEX) += ibex_plic.o
> > diff --git a/hw/intc/ibex_plic.c b/hw/intc/ibex_plic.c
> > new file mode 100644
> > index 00..35c52d9d16
> > --- /dev/null
> > +++ b/hw/intc/ibex_plic.c
> > @@ -0,0 +1,261 @@
> > +/*
> > + * QEMU RISC-V lowRISC Ibex PLIC
> > + *
> > + * Copyright (c) 2020 Western Digital
> > + *
> > + * Documentation avaliable: https://docs.opentitan.org/hw/ip/rv_plic/doc/
> > + *
> > + * This program is free software; you can redistribute it and/or modify it
> > + * under the terms and conditions of the GNU General Public License,
> > + * version 2 or later, as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope 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 "qemu/log.h"
> > +#include "hw/qdev-properties.h"
> > +#include "hw/core/cpu.h"
> > +#include "hw/boards.h"
> > +#include "hw/pci/msi.h"
> > +#include "target/riscv/cpu_bits.h"
> > +#include "target/riscv/cpu.h"
> > +#include "hw/intc/ibex_plic.h"
> > +
> > +static bool addr_between(uint32_t addr, uint32_t base, uint32_t num)
> > +{
> > +uint32_t end = base + (num * 0x04);
> > +
> > +if (addr >= base && addr < end) {
> > +return true;
> > +}
> > +
> > +return false;
> > +}
> > +
> > +static void ibex_plic_irqs_set_pending(IbexPlicState *s, int irq, bool 
> > level)
> > +{
> > +int pending_num = irq / 32;
> > +
> > +s->pending[pending_num] |= level << (irq % 32);
> > +}
> > +
> > +static bool ibex_plic_irqs_pending(IbexPlicState *s, uint32_t context)
> > +{
> > +int i;
> > +
> > +for (i = 0; i < s->pending_num; i++) {
> > +uint32_t irq_num = ctz64(s->pending[i]) + (i * 32);
> > +
> > +if (!(s->pending[i] & s->enable[i])) {
> > +/* No pending and enabled IRQ */
> > +continue;
> > +}
> > +
> > +if (s->priority[irq_num] > s->threshold) {
> > +if (!s->claim) {
> > +s->claim = irq_num;
> > +}
> > +return true;
> > +}
> > +}
> > +
> > +return 0;
>
> return 'false'.

Fixed.

>
> > +}
> > +
> > +static void ibex_plic_update(IbexPlicState *s)
> > +{
> > +CPUState *cpu;
> > +int level, i;
> > +
> > +for (i = 0; i < s->num_cpus; i++) {
> > +cpu = qemu_get_cpu(i);
> > +
> > +if (!cpu) {
> > +continue;
> > +}
> > +
> > +level = ibex_plic_irqs_pending(s, 0);
> > +
> > +riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, 
> > BOOL_TO_MASK(level));
> > +}
> > +}
> > +
> > +static void ibex_plic_reset(DeviceState *dev)
> > +{
> > +IbexPlicState *s = IBEX_PLIC(dev);
> > +
> > +s->threshold = 0x;
> > +s->claim = 0x;
>
> I haven't check the datasheet reset values, for the rest:
> Reviewed-by: Philippe Mathieu-Daudé 

Thanks for reviewing these :)

Alistair



[Bug 1878134] Re: Assertion failures in ati_reg_read_offs/ati_reg_write_offs

2020-05-14 Thread Rafael David Tinoco
Hello Alexander,

I believe your fuzz test result was meant to the upstream project so I
moved it.

o/

** Also affects: qemu
   Importance: Undecided
   Status: New

** No longer affects: qemu-kvm (Ubuntu)

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

Title:
  Assertion failures in ati_reg_read_offs/ati_reg_write_offs

Status in QEMU:
  New

Bug description:
  Hello,
  While fuzzing, I found inputs that trigger assertion failures in
  ati_reg_read_offs/ati_reg_write_offs

  uint32_t extract32(uint32_t, int, int): Assertion `start >= 0 &&
  length > 0 && length <= 32 - start' failed

  #3  0x76866092 in __GI___assert_fail (assertion=0x56e760c0  
"start >= 0 && length > 0 && length <= 32 - start", file=0x56e76120  
"/home/alxndr/Development/qemu/include/qemu/bitops.h", line=0x12c, 
function=0x56e76180 <__PRETTY_FUNCTION__.extract32> "uint32_t 
extract32(uint32_t, int, int)") at assert.c:101
  #4  0x5653d8a7 in ati_mm_read (opaque=, addr=0x1a, 
size=) at 
/home/alxndr/Development/qemu/include/qemu/log-for-trace.h:29
  #5  0x5653c825 in ati_mm_read (opaque=, addr=0x4, 
size=) at /home/alxndr/Development/qemu/hw/display/ati.c:289
  #6  0x5601446e in memory_region_read_accessor (mr=0x6314dc20, 
addr=, value=, size=, 
shift=, mask=, attrs=...) at 
/home/alxndr/Development/qemu/memory.c:434
  #7  0x56001a70 in access_with_adjusted_size (addr=, 
value=, size=, access_size_min=, 
access_size_max=, access_fn=, mr=0x6314dc20, 
attrs=...) at /home/alxndr/Development/qemu/memory.c:544
  #8  0x56001a70 in memory_region_dispatch_read1 (mr=0x6314dc20, 
addr=0x4, pval=, size=0x4, attrs=...) at 
/home/alxndr/Development/qemu/memory.c:1396

  
  I can reproduce it in qemu 5.0 built with using:
  cat << EOF | ~/Development/qemu/build/i386-softmmu/qemu-system-i386 -M 
pc-q35-5.0 -device ati-vga -nographic -qtest stdio -monitor none -serial none
  outl 0xcf8 0x80001018
  outl 0xcfc 0xe200
  outl 0xcf8 0x8000101c
  outl 0xcf8 0x80001004
  outw 0xcfc 0x7
  outl 0xcf8 0x8000fa20
  write 0xe204 0x1 0x1a
  readq 0xe200
  EOF

  Similarly for ati_reg_write_offs:
  cat << EOF | ~/Development/qemu/build/i386-softmmu/qemu-system-i386 -M 
pc-q35-5.0 -device ati-vga -nographic -qtest stdio -monitor none -serial none
  outl 0xcf8 0x80001018
  outl 0xcfc 0xe200
  outl 0xcf8 0x8000101c
  outl 0xcf8 0x80001004
  outw 0xcfc 0x7
  outl 0xcf8 0x8000fa20
  write 0xe200 0x8 0x6a006a00
  EOF

  I also attached the traces to this launchpad report, in case the
  formatting is broken:

  qemu-system-i386 -M pc-q35-5.0 -device ati-vga -nographic -qtest stdio
  -monitor none -serial none < attachment

  Please let me know if I can provide any further info.
  -Alex

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



Re: [PATCH v2 2/9] target/riscv: Don't overwrite the reset vector

2020-05-14 Thread Alistair Francis
On Thu, May 14, 2020 at 10:54 AM Philippe Mathieu-Daudé
 wrote:
>
> On 5/7/20 9:13 PM, Alistair Francis wrote:
> > If the reset vector is set in the init function don't set it again in
> > realise.
>
> typo "realize".

It's not a typo, just correct English :)

I have changed it.

>
> >
> > Signed-off-by: Alistair Francis 
> > ---
> >   target/riscv/cpu.c | 20 +++-
> >   1 file changed, 11 insertions(+), 9 deletions(-)
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 059d71f2c7..8f837edf8d 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -111,6 +111,14 @@ static void set_feature(CPURISCVState *env, int 
> > feature)
> >   env->features |= (1ULL << feature);
> >   }
> >
> > +static int get_resetvec(CPURISCVState *env)
> > +{
> > +#ifndef CONFIG_USER_ONLY
> > +return env->resetvec;
> > +#endif
> > +return 0;
>
> Don't you get an error about double return? Maybe use #else?

Apparently not, I have changed it though.

Alistair

>
> > +}
> > +
> >   static void set_resetvec(CPURISCVState *env, int resetvec)
> >   {
> >   #ifndef CONFIG_USER_ONLY
> > @@ -123,7 +131,6 @@ static void riscv_any_cpu_init(Object *obj)
> >   CPURISCVState *env = _CPU(obj)->env;
> >   set_misa(env, RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVU);
> >   set_priv_version(env, PRIV_VERSION_1_11_0);
> > -set_resetvec(env, DEFAULT_RSTVEC);
> >   }
> >
> >   #if defined(TARGET_RISCV32)
> > @@ -140,7 +147,6 @@ static void rv32gcsu_priv1_09_1_cpu_init(Object *obj)
> >   CPURISCVState *env = _CPU(obj)->env;
> >   set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> >   set_priv_version(env, PRIV_VERSION_1_09_1);
> > -set_resetvec(env, DEFAULT_RSTVEC);
> >   set_feature(env, RISCV_FEATURE_MMU);
> >   set_feature(env, RISCV_FEATURE_PMP);
> >   }
> > @@ -150,7 +156,6 @@ static void rv32gcsu_priv1_10_0_cpu_init(Object *obj)
> >   CPURISCVState *env = _CPU(obj)->env;
> >   set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> >   set_priv_version(env, PRIV_VERSION_1_10_0);
> > -set_resetvec(env, DEFAULT_RSTVEC);
> >   set_feature(env, RISCV_FEATURE_MMU);
> >   set_feature(env, RISCV_FEATURE_PMP);
> >   }
> > @@ -160,7 +165,6 @@ static void rv32imacu_nommu_cpu_init(Object *obj)
> >   CPURISCVState *env = _CPU(obj)->env;
> >   set_misa(env, RV32 | RVI | RVM | RVA | RVC | RVU);
> >   set_priv_version(env, PRIV_VERSION_1_10_0);
> > -set_resetvec(env, DEFAULT_RSTVEC);
> >   set_feature(env, RISCV_FEATURE_PMP);
> >   }
> >
> > @@ -169,7 +173,6 @@ static void rv32imafcu_nommu_cpu_init(Object *obj)
> >   CPURISCVState *env = _CPU(obj)->env;
> >   set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVC | RVU);
> >   set_priv_version(env, PRIV_VERSION_1_10_0);
> > -set_resetvec(env, DEFAULT_RSTVEC);
> >   set_feature(env, RISCV_FEATURE_PMP);
> >   }
> >
> > @@ -187,7 +190,6 @@ static void rv64gcsu_priv1_09_1_cpu_init(Object *obj)
> >   CPURISCVState *env = _CPU(obj)->env;
> >   set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> >   set_priv_version(env, PRIV_VERSION_1_09_1);
> > -set_resetvec(env, DEFAULT_RSTVEC);
> >   set_feature(env, RISCV_FEATURE_MMU);
> >   set_feature(env, RISCV_FEATURE_PMP);
> >   }
> > @@ -197,7 +199,6 @@ static void rv64gcsu_priv1_10_0_cpu_init(Object *obj)
> >   CPURISCVState *env = _CPU(obj)->env;
> >   set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> >   set_priv_version(env, PRIV_VERSION_1_10_0);
> > -set_resetvec(env, DEFAULT_RSTVEC);
> >   set_feature(env, RISCV_FEATURE_MMU);
> >   set_feature(env, RISCV_FEATURE_PMP);
> >   }
> > @@ -207,7 +208,6 @@ static void rv64imacu_nommu_cpu_init(Object *obj)
> >   CPURISCVState *env = _CPU(obj)->env;
> >   set_misa(env, RV64 | RVI | RVM | RVA | RVC | RVU);
> >   set_priv_version(env, PRIV_VERSION_1_10_0);
> > -set_resetvec(env, DEFAULT_RSTVEC);
> >   set_feature(env, RISCV_FEATURE_PMP);
> >   }
> >
> > @@ -399,7 +399,9 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
> > **errp)
> >   }
> >
> >   set_priv_version(env, priv_version);
> > -set_resetvec(env, DEFAULT_RSTVEC);
> > +if (!get_resetvec(env)) {
> > +set_resetvec(env, DEFAULT_RSTVEC);
> > +}
> >
> >   if (cpu->cfg.mmu) {
> >   set_feature(env, RISCV_FEATURE_MMU);
> >
>



[PATCH 5/6] target/arm: Split helper_crypto_sha1_3reg

2020-05-14 Thread Richard Henderson
Rather than passing an opcode to a helper, fully decode the
operation at translate time.  Use clear_tail_16 to zap the
balance of the SVE register with the AdvSIMD write.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.h |  5 +-
 target/arm/neon-dp.decode   |  6 +-
 target/arm/crypto_helper.c  | 99 +
 target/arm/translate-a64.c  | 29 --
 target/arm/translate-neon.inc.c | 46 ---
 5 files changed, 93 insertions(+), 92 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index cee23adbfc..13475ecf81 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -513,7 +513,10 @@ DEF_HELPER_FLAGS_2(neon_qzip32, TCG_CALL_NO_RWG, void, 
ptr, ptr)
 DEF_HELPER_FLAGS_4(crypto_aese, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_3(crypto_aesmc, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
 
-DEF_HELPER_FLAGS_4(crypto_sha1_3reg, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(crypto_sha1su0, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(crypto_sha1c, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(crypto_sha1p, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(crypto_sha1m, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_3(crypto_sha1h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
 DEF_HELPER_FLAGS_3(crypto_sha1su1, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
 
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
index 5b2fc65d72..8af7c53d8b 100644
--- a/target/arm/neon-dp.decode
+++ b/target/arm/neon-dp.decode
@@ -168,8 +168,10 @@ VQRDMLAH_3s   001 1 0 . ..   1011 ... 1 
 @3same
 @3same_crypto        \
  &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0 q=1
 
-SHA1_3s   001 0 0 . optype:2   1100 . 1 . 0  \
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
+SHA1C_3s  001 0 0 . 00   1100 . 1 . 0  @3same_crypto
+SHA1P_3s  001 0 0 . 01   1100 . 1 . 0  @3same_crypto
+SHA1M_3s  001 0 0 . 10   1100 . 1 . 0  @3same_crypto
+SHA1SU0_3s    001 0 0 . 11   1100 . 1 . 0  @3same_crypto
 SHA256H_3s    001 1 0 . 00   1100 . 1 . 0  @3same_crypto
 SHA256H2_3s   001 1 0 . 01   1100 . 1 . 0  @3same_crypto
 SHA256SU1_3s  001 1 0 . 10   1100 . 1 . 0  @3same_crypto
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
index 7124745c32..636683d0f1 100644
--- a/target/arm/crypto_helper.c
+++ b/target/arm/crypto_helper.c
@@ -24,11 +24,11 @@ union CRYPTO_STATE {
 };
 
 #ifdef HOST_WORDS_BIGENDIAN
-#define CR_ST_BYTE(state, i)   (state.bytes[(15 - (i)) ^ 8])
-#define CR_ST_WORD(state, i)   (state.words[(3 - (i)) ^ 2])
+#define CR_ST_BYTE(state, i)   ((state).bytes[(15 - (i)) ^ 8])
+#define CR_ST_WORD(state, i)   ((state).words[(3 - (i)) ^ 2])
 #else
-#define CR_ST_BYTE(state, i)   (state.bytes[i])
-#define CR_ST_WORD(state, i)   (state.words[i])
+#define CR_ST_BYTE(state, i)   ((state).bytes[i])
+#define CR_ST_WORD(state, i)   ((state).words[i])
 #endif
 
 /*
@@ -258,49 +258,74 @@ static uint32_t maj(uint32_t x, uint32_t y, uint32_t z)
 return (x & y) | ((x | y) & z);
 }
 
-void HELPER(crypto_sha1_3reg)(void *vd, void *vn, void *vm, uint32_t op)
+void HELPER(crypto_sha1su0)(void *vd, void *vn, void *vm, uint32_t desc)
+{
+uint64_t *d = vd, *n = vn, *m = vm;
+uint64_t d0, d1;
+
+d0 = d[1] ^ d[0] ^ m[0];
+d1 = n[0] ^ d[1] ^ m[1];
+d[0] = d0;
+d[1] = d1;
+
+clear_tail_16(vd, desc);
+}
+
+static inline void crypto_sha1_3reg(uint64_t *rd, uint64_t *rn,
+uint64_t *rm, uint32_t desc,
+uint32_t (*fn)(union CRYPTO_STATE *d))
 {
-uint64_t *rd = vd;
-uint64_t *rn = vn;
-uint64_t *rm = vm;
 union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
 union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
 union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
+int i;
 
-if (op == 3) { /* sha1su0 */
-d.l[0] ^= d.l[1] ^ m.l[0];
-d.l[1] ^= n.l[0] ^ m.l[1];
-} else {
-int i;
+for (i = 0; i < 4; i++) {
+uint32_t t = fn();
 
-for (i = 0; i < 4; i++) {
-uint32_t t;
+t += rol32(CR_ST_WORD(d, 0), 5) + CR_ST_WORD(n, 0)
+ + CR_ST_WORD(m, i);
 
-switch (op) {
-case 0: /* sha1c */
-t = cho(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3));
-break;
-case 1: /* sha1p */
-t = par(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3));
-break;
-case 2: /* sha1m */
-t = maj(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3));
-break;
-default:
-g_assert_not_reached();
-  

[PATCH 4/6] target/arm: Convert sha1 and sha256 to gvec helpers

2020-05-14 Thread Richard Henderson
Do not yet convert the helpers to loop over opr_sz, but the
descriptor allows the vector tail to be cleared.  Which fixes
an existing bug vs SVE.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.h |  12 ++--
 target/arm/neon-dp.decode   |  12 ++--
 target/arm/crypto_helper.c  |  24 +--
 target/arm/translate-a64.c  |  34 -
 target/arm/translate-neon.inc.c | 124 +---
 target/arm/translate.c  |  24 ++-
 6 files changed, 67 insertions(+), 163 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 784dc29ce2..cee23adbfc 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -514,13 +514,13 @@ DEF_HELPER_FLAGS_4(crypto_aese, TCG_CALL_NO_RWG, void, 
ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_3(crypto_aesmc, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_4(crypto_sha1_3reg, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_2(crypto_sha1h, TCG_CALL_NO_RWG, void, ptr, ptr)
-DEF_HELPER_FLAGS_2(crypto_sha1su1, TCG_CALL_NO_RWG, void, ptr, ptr)
+DEF_HELPER_FLAGS_3(crypto_sha1h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(crypto_sha1su1, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
 
-DEF_HELPER_FLAGS_3(crypto_sha256h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
-DEF_HELPER_FLAGS_3(crypto_sha256h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
-DEF_HELPER_FLAGS_2(crypto_sha256su0, TCG_CALL_NO_RWG, void, ptr, ptr)
-DEF_HELPER_FLAGS_3(crypto_sha256su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
+DEF_HELPER_FLAGS_4(crypto_sha256h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(crypto_sha256h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(crypto_sha256su0, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(crypto_sha256su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_4(crypto_sha512h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(crypto_sha512h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
index 8beb1db768..5b2fc65d72 100644
--- a/target/arm/neon-dp.decode
+++ b/target/arm/neon-dp.decode
@@ -165,14 +165,14 @@ VPADD_3s  001 0 0 . ..   1011 . . . 1 
 @3same_q0
 
 VQRDMLAH_3s   001 1 0 . ..   1011 ... 1  @3same
 
+@3same_crypto        \
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0 q=1
+
 SHA1_3s   001 0 0 . optype:2   1100 . 1 . 0  \
  vm=%vm_dp vn=%vn_dp vd=%vd_dp
-SHA256H_3s    001 1 0 . 00   1100 . 1 . 0  \
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
-SHA256H2_3s   001 1 0 . 01   1100 . 1 . 0  \
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
-SHA256SU1_3s  001 1 0 . 10   1100 . 1 . 0  \
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
+SHA256H_3s    001 1 0 . 00   1100 . 1 . 0  @3same_crypto
+SHA256H2_3s   001 1 0 . 01   1100 . 1 . 0  @3same_crypto
+SHA256SU1_3s  001 1 0 . 10   1100 . 1 . 0  @3same_crypto
 
 VFMA_fp_3s    001 0 0 . 0 .   1100 ... 1  @3same_fp
 VFMS_fp_3s    001 0 0 . 1 .   1100 ... 1  @3same_fp
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
index 637e4c00bb..7124745c32 100644
--- a/target/arm/crypto_helper.c
+++ b/target/arm/crypto_helper.c
@@ -303,7 +303,7 @@ void HELPER(crypto_sha1_3reg)(void *vd, void *vn, void *vm, 
uint32_t op)
 rd[1] = d.l[1];
 }
 
-void HELPER(crypto_sha1h)(void *vd, void *vm)
+void HELPER(crypto_sha1h)(void *vd, void *vm, uint32_t desc)
 {
 uint64_t *rd = vd;
 uint64_t *rm = vm;
@@ -314,9 +314,11 @@ void HELPER(crypto_sha1h)(void *vd, void *vm)
 
 rd[0] = m.l[0];
 rd[1] = m.l[1];
+
+clear_tail_16(vd, desc);
 }
 
-void HELPER(crypto_sha1su1)(void *vd, void *vm)
+void HELPER(crypto_sha1su1)(void *vd, void *vm, uint32_t desc)
 {
 uint64_t *rd = vd;
 uint64_t *rm = vm;
@@ -330,6 +332,8 @@ void HELPER(crypto_sha1su1)(void *vd, void *vm)
 
 rd[0] = d.l[0];
 rd[1] = d.l[1];
+
+clear_tail_16(vd, desc);
 }
 
 /*
@@ -357,7 +361,7 @@ static uint32_t s1(uint32_t x)
 return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10);
 }
 
-void HELPER(crypto_sha256h)(void *vd, void *vn, void *vm)
+void HELPER(crypto_sha256h)(void *vd, void *vn, void *vm, uint32_t desc)
 {
 uint64_t *rd = vd;
 uint64_t *rn = vn;
@@ -388,9 +392,11 @@ void HELPER(crypto_sha256h)(void *vd, void *vn, void *vm)
 
 rd[0] = d.l[0];
 rd[1] = d.l[1];
+
+clear_tail_16(vd, desc);
 }
 
-void HELPER(crypto_sha256h2)(void *vd, void *vn, void *vm)
+void HELPER(crypto_sha256h2)(void *vd, void *vn, void *vm, uint32_t desc)
 {
 uint64_t *rd = vd;
 uint64_t *rn = vn;
@@ -413,9 +419,11 @@ void HELPER(crypto_sha256h2)(void *vd, void *vn, void *vm)
 
 rd[0] = d.l[0];
 rd[1] = d.l[1];
+
+

[PATCH 6/6] target/arm: Split helper_crypto_sm3tt

2020-05-14 Thread Richard Henderson
Rather than passing an opcode to a helper, fully decode the
operation at translate time.  Use clear_tail_16 to zap the
balance of the SVE register with the AdvSIMD write.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.h|  5 -
 target/arm/crypto_helper.c | 24 ++--
 target/arm/translate-a64.c | 21 +
 3 files changed, 27 insertions(+), 23 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 13475ecf81..2a20c8174c 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -531,7 +531,10 @@ DEF_HELPER_FLAGS_3(crypto_sha512su0, TCG_CALL_NO_RWG, 
void, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(crypto_sha512su1, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, i32)
 
-DEF_HELPER_FLAGS_5(crypto_sm3tt, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32, 
i32)
+DEF_HELPER_FLAGS_4(crypto_sm3tt1a, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(crypto_sm3tt1b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(crypto_sm3tt2a, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(crypto_sm3tt2b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(crypto_sm3partw1, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(crypto_sm3partw2, TCG_CALL_NO_RWG,
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
index 636683d0f1..c76806dc8d 100644
--- a/target/arm/crypto_helper.c
+++ b/target/arm/crypto_helper.c
@@ -632,15 +632,14 @@ void HELPER(crypto_sm3partw2)(void *vd, void *vn, void 
*vm, uint32_t desc)
 clear_tail_16(vd, desc);
 }
 
-void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,
-  uint32_t opcode)
+static inline void QEMU_ALWAYS_INLINE
+crypto_sm3tt(uint64_t *rd, uint64_t *rn, uint64_t *rm,
+ uint32_t desc, uint32_t opcode)
 {
-uint64_t *rd = vd;
-uint64_t *rn = vn;
-uint64_t *rm = vm;
 union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
 union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
 union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
+uint32_t imm2 = simd_data(desc);
 uint32_t t;
 
 assert(imm2 < 4);
@@ -655,7 +654,7 @@ void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, 
uint32_t imm2,
 /* SM3TT2B */
 t = cho(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
 } else {
-g_assert_not_reached();
+qemu_build_not_reached();
 }
 
 t += CR_ST_WORD(d, 0) + CR_ST_WORD(m, imm2);
@@ -680,8 +679,21 @@ void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, 
uint32_t imm2,
 
 rd[0] = d.l[0];
 rd[1] = d.l[1];
+
+clear_tail_16(rd, desc);
 }
 
+#define DO_SM3TT(NAME, OPCODE) \
+void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
+{ crypto_sm3tt(vd, vn, vm, desc, OPCODE); }
+
+DO_SM3TT(crypto_sm3tt1a, 0)
+DO_SM3TT(crypto_sm3tt1b, 1)
+DO_SM3TT(crypto_sm3tt2a, 2)
+DO_SM3TT(crypto_sm3tt2b, 3)
+
+#undef DO_SM3TT
+
 static uint8_t const sm4_sbox[] = {
 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7,
 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 49ca7ac76e..9c1ebcc8e3 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -13861,13 +13861,15 @@ static void disas_crypto_xar(DisasContext *s, 
uint32_t insn)
  */
 static void disas_crypto_three_reg_imm2(DisasContext *s, uint32_t insn)
 {
+static gen_helper_gvec_3 * const fns[4] = {
+gen_helper_crypto_sm3tt1a, gen_helper_crypto_sm3tt1b,
+gen_helper_crypto_sm3tt2a, gen_helper_crypto_sm3tt2b,
+};
 int opcode = extract32(insn, 10, 2);
 int imm2 = extract32(insn, 12, 2);
 int rm = extract32(insn, 16, 5);
 int rn = extract32(insn, 5, 5);
 int rd = extract32(insn, 0, 5);
-TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
-TCGv_i32 tcg_imm2, tcg_opcode;
 
 if (!dc_isar_feature(aa64_sm3, s)) {
 unallocated_encoding(s);
@@ -13878,20 +13880,7 @@ static void disas_crypto_three_reg_imm2(DisasContext 
*s, uint32_t insn)
 return;
 }
 
-tcg_rd_ptr = vec_full_reg_ptr(s, rd);
-tcg_rn_ptr = vec_full_reg_ptr(s, rn);
-tcg_rm_ptr = vec_full_reg_ptr(s, rm);
-tcg_imm2   = tcg_const_i32(imm2);
-tcg_opcode = tcg_const_i32(opcode);
-
-gen_helper_crypto_sm3tt(tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr, tcg_imm2,
-tcg_opcode);
-
-tcg_temp_free_ptr(tcg_rd_ptr);
-tcg_temp_free_ptr(tcg_rn_ptr);
-tcg_temp_free_ptr(tcg_rm_ptr);
-tcg_temp_free_i32(tcg_imm2);
-tcg_temp_free_i32(tcg_opcode);
+gen_gvec_op3_ool(s, true, rd, rn, rm, imm2, fns[opcode]);
 }
 
 /* C3.6 Data processing - SIMD, inc Crypto
-- 
2.20.1




[PATCH 3/6] target/arm: Convert sha512 and sm3 to gvec helpers

2020-05-14 Thread Richard Henderson
Do not yet convert the helpers to loop over opr_sz, but the
descriptor allows the vector tail to be cleared.  Which fixes
an existing bug vs SVE.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.h| 15 +++-
 target/arm/crypto_helper.c | 37 +++-
 target/arm/translate-a64.c | 50 --
 3 files changed, 55 insertions(+), 47 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 6c4eb9befb..784dc29ce2 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -522,14 +522,17 @@ DEF_HELPER_FLAGS_3(crypto_sha256h2, TCG_CALL_NO_RWG, 
void, ptr, ptr, ptr)
 DEF_HELPER_FLAGS_2(crypto_sha256su0, TCG_CALL_NO_RWG, void, ptr, ptr)
 DEF_HELPER_FLAGS_3(crypto_sha256su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
 
-DEF_HELPER_FLAGS_3(crypto_sha512h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
-DEF_HELPER_FLAGS_3(crypto_sha512h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
-DEF_HELPER_FLAGS_2(crypto_sha512su0, TCG_CALL_NO_RWG, void, ptr, ptr)
-DEF_HELPER_FLAGS_3(crypto_sha512su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
+DEF_HELPER_FLAGS_4(crypto_sha512h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(crypto_sha512h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(crypto_sha512su0, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(crypto_sha512su1, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_5(crypto_sm3tt, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32, 
i32)
-DEF_HELPER_FLAGS_3(crypto_sm3partw1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
-DEF_HELPER_FLAGS_3(crypto_sm3partw2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
+DEF_HELPER_FLAGS_4(crypto_sm3partw1, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(crypto_sm3partw2, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_4(crypto_sm4e, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
index 372d8350e4..637e4c00bb 100644
--- a/target/arm/crypto_helper.c
+++ b/target/arm/crypto_helper.c
@@ -31,6 +31,19 @@ union CRYPTO_STATE {
 #define CR_ST_WORD(state, i)   (state.words[i])
 #endif
 
+/*
+ * The caller has not been converted to full gvec, and so only
+ * modifies the low 16 bytes of the vector register.
+ */
+static void clear_tail_16(void *vd, uint32_t desc)
+{
+int opr_sz = simd_oprsz(desc);
+int max_sz = simd_maxsz(desc);
+
+assert(opr_sz == 16);
+clear_tail(vd, opr_sz, max_sz);
+}
+
 static void do_crypto_aese(uint64_t *rd, uint64_t *rn,
uint64_t *rm, bool decrypt)
 {
@@ -470,7 +483,7 @@ static uint64_t s1_512(uint64_t x)
 return ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6);
 }
 
-void HELPER(crypto_sha512h)(void *vd, void *vn, void *vm)
+void HELPER(crypto_sha512h)(void *vd, void *vn, void *vm, uint32_t desc)
 {
 uint64_t *rd = vd;
 uint64_t *rn = vn;
@@ -483,9 +496,11 @@ void HELPER(crypto_sha512h)(void *vd, void *vn, void *vm)
 
 rd[0] = d0;
 rd[1] = d1;
+
+clear_tail_16(vd, desc);
 }
 
-void HELPER(crypto_sha512h2)(void *vd, void *vn, void *vm)
+void HELPER(crypto_sha512h2)(void *vd, void *vn, void *vm, uint32_t desc)
 {
 uint64_t *rd = vd;
 uint64_t *rn = vn;
@@ -498,9 +513,11 @@ void HELPER(crypto_sha512h2)(void *vd, void *vn, void *vm)
 
 rd[0] = d0;
 rd[1] = d1;
+
+clear_tail_16(vd, desc);
 }
 
-void HELPER(crypto_sha512su0)(void *vd, void *vn)
+void HELPER(crypto_sha512su0)(void *vd, void *vn, uint32_t desc)
 {
 uint64_t *rd = vd;
 uint64_t *rn = vn;
@@ -512,9 +529,11 @@ void HELPER(crypto_sha512su0)(void *vd, void *vn)
 
 rd[0] = d0;
 rd[1] = d1;
+
+clear_tail_16(vd, desc);
 }
 
-void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm)
+void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm, uint32_t desc)
 {
 uint64_t *rd = vd;
 uint64_t *rn = vn;
@@ -522,9 +541,11 @@ void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm)
 
 rd[0] += s1_512(rn[0]) + rm[0];
 rd[1] += s1_512(rn[1]) + rm[1];
+
+clear_tail_16(vd, desc);
 }
 
-void HELPER(crypto_sm3partw1)(void *vd, void *vn, void *vm)
+void HELPER(crypto_sm3partw1)(void *vd, void *vn, void *vm, uint32_t desc)
 {
 uint64_t *rd = vd;
 uint64_t *rn = vn;
@@ -548,9 +569,11 @@ void HELPER(crypto_sm3partw1)(void *vd, void *vn, void *vm)
 
 rd[0] = d.l[0];
 rd[1] = d.l[1];
+
+clear_tail_16(vd, desc);
 }
 
-void HELPER(crypto_sm3partw2)(void *vd, void *vn, void *vm)
+void HELPER(crypto_sm3partw2)(void *vd, void *vn, void *vm, uint32_t desc)
 {
 uint64_t *rd = vd;
 uint64_t *rn = vn;
@@ -568,6 +591,8 @@ void HELPER(crypto_sm3partw2)(void *vd, void *vn, void *vm)
 
 rd[0] = d.l[0];
 rd[1] = d.l[1];
+
+clear_tail_16(vd, desc);
 }
 
 void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,

[PATCH 0/6] target/arm: Convert crypto to gvec

2020-05-14 Thread Richard Henderson
In addition, this fixes the missing tail clearing for SVE.

The sha1, sha256, sm3 routines that are not fully generalized
are not used by sve -- it only supports the newer algorithms.

I'm not sure that this:

Based-on: <20200508151055.5832-1-richard.hender...@linaro.org>
("tcg vector rotate operations")

will be sufficient for patchew, because it also relies on
today's target-arm.next merge to master.  But you get the idea.


r~


Richard Henderson (6):
  target/arm: Convert aes and sm4 to gvec helpers
  target/arm: Convert rax1 to gvec helpers
  target/arm: Convert sha512 and sm3 to gvec helpers
  target/arm: Convert sha1 and sha256 to gvec helpers
  target/arm: Split helper_crypto_sha1_3reg
  target/arm: Split helper_crypto_sm3tt

 target/arm/helper.h |  45 --
 target/arm/translate-a64.h  |   3 +
 target/arm/vec_internal.h   |  33 
 target/arm/neon-dp.decode   |  18 ++-
 target/arm/crypto_helper.c  | 267 +++-
 target/arm/translate-a64.c  | 198 ++-
 target/arm/translate-neon.inc.c | 172 
 target/arm/translate.c  |  51 +++---
 target/arm/vec_helper.c |  12 +-
 9 files changed, 403 insertions(+), 396 deletions(-)
 create mode 100644 target/arm/vec_internal.h

-- 
2.20.1




[PATCH 1/6] target/arm: Convert aes and sm4 to gvec helpers

2020-05-14 Thread Richard Henderson
With this conversion, we will be able to use the same helpers
with sve.  In particular, pass 3 vector parameters for the
3-operand operations; for advsimd the destination register
is also an input.

This also fixes a bug in which we failed to clear the high bits
of the SVE register after an AdvSIMD operation.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.h|  6 ++--
 target/arm/vec_internal.h  | 33 +
 target/arm/crypto_helper.c | 72 +++---
 target/arm/translate-a64.c | 55 ++---
 target/arm/translate.c | 27 +++---
 target/arm/vec_helper.c| 12 +--
 6 files changed, 138 insertions(+), 67 deletions(-)
 create mode 100644 target/arm/vec_internal.h

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 49336dc432..42759f82aa 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -510,7 +510,7 @@ DEF_HELPER_FLAGS_2(neon_qzip8, TCG_CALL_NO_RWG, void, ptr, 
ptr)
 DEF_HELPER_FLAGS_2(neon_qzip16, TCG_CALL_NO_RWG, void, ptr, ptr)
 DEF_HELPER_FLAGS_2(neon_qzip32, TCG_CALL_NO_RWG, void, ptr, ptr)
 
-DEF_HELPER_FLAGS_3(crypto_aese, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(crypto_aese, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_3(crypto_aesmc, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_4(crypto_sha1_3reg, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
@@ -531,8 +531,8 @@ DEF_HELPER_FLAGS_5(crypto_sm3tt, TCG_CALL_NO_RWG, void, 
ptr, ptr, ptr, i32, i32)
 DEF_HELPER_FLAGS_3(crypto_sm3partw1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
 DEF_HELPER_FLAGS_3(crypto_sm3partw2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
 
-DEF_HELPER_FLAGS_2(crypto_sm4e, TCG_CALL_NO_RWG, void, ptr, ptr)
-DEF_HELPER_FLAGS_3(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
+DEF_HELPER_FLAGS_4(crypto_sm4e, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
 DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
diff --git a/target/arm/vec_internal.h b/target/arm/vec_internal.h
new file mode 100644
index 00..00a8277765
--- /dev/null
+++ b/target/arm/vec_internal.h
@@ -0,0 +1,33 @@
+/*
+ * ARM AdvSIMD / SVE Vector Helpers
+ *
+ * Copyright (c) 2020 Linaro
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#ifndef TARGET_ARM_VEC_INTERNALS_H
+#define TARGET_ARM_VEC_INTERNALS_H
+
+static inline void clear_tail(void *vd, uintptr_t opr_sz, uintptr_t max_sz)
+{
+uint64_t *d = vd + opr_sz;
+uintptr_t i;
+
+for (i = opr_sz; i < max_sz; i += 8) {
+*d++ = 0;
+}
+}
+
+#endif /* TARGET_ARM_VEC_INTERNALS_H */
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
index f800266727..6bd5a3d2d0 100644
--- a/target/arm/crypto_helper.c
+++ b/target/arm/crypto_helper.c
@@ -13,7 +13,9 @@
 
 #include "cpu.h"
 #include "exec/helper-proto.h"
+#include "tcg/tcg-gvec-desc.h"
 #include "crypto/aes.h"
+#include "vec_internal.h"
 
 union CRYPTO_STATE {
 uint8_tbytes[16];
@@ -29,18 +31,15 @@ union CRYPTO_STATE {
 #define CR_ST_WORD(state, i)   (state.words[i])
 #endif
 
-void HELPER(crypto_aese)(void *vd, void *vm, uint32_t decrypt)
+static void do_crypto_aese(uint64_t *rd, uint64_t *rn,
+   uint64_t *rm, bool decrypt)
 {
 static uint8_t const * const sbox[2] = { AES_sbox, AES_isbox };
 static uint8_t const * const shift[2] = { AES_shifts, AES_ishifts };
-uint64_t *rd = vd;
-uint64_t *rm = vm;
 union CRYPTO_STATE rk = { .l = { rm[0], rm[1] } };
-union CRYPTO_STATE st = { .l = { rd[0], rd[1] } };
+union CRYPTO_STATE st = { .l = { rn[0], rn[1] } };
 int i;
 
-assert(decrypt < 2);
-
 /* xor state vector with round key */
 rk.l[0] ^= st.l[0];
 rk.l[1] ^= st.l[1];
@@ -54,7 +53,18 @@ void HELPER(crypto_aese)(void *vd, void *vm, uint32_t 
decrypt)
 rd[1] = st.l[1];
 }
 
-void HELPER(crypto_aesmc)(void *vd, void *vm, uint32_t decrypt)
+void HELPER(crypto_aese)(void *vd, void *vn, void *vm, uint32_t desc)
+{
+intptr_t i, opr_sz = simd_oprsz(desc);
+bool decrypt = simd_data(desc);
+
+for (i = 0; i < opr_sz; i += 16) {
+do_crypto_aese(vd + i, vn + i, vm + i, decrypt);
+}
+clear_tail(vd, opr_sz, 

[PATCH 2/6] target/arm: Convert rax1 to gvec helpers

2020-05-14 Thread Richard Henderson
With this conversion, we will be able to use the same helpers
with sve.  This also fixes a bug in which we failed to clear
the high bits of the SVE register after an AdvSIMD operation.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.h|  2 ++
 target/arm/translate-a64.h |  3 ++
 target/arm/crypto_helper.c | 11 +++
 target/arm/translate-a64.c | 59 --
 4 files changed, 47 insertions(+), 28 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 42759f82aa..6c4eb9befb 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -534,6 +534,8 @@ DEF_HELPER_FLAGS_3(crypto_sm3partw2, TCG_CALL_NO_RWG, void, 
ptr, ptr, ptr)
 DEF_HELPER_FLAGS_4(crypto_sm4e, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 
+DEF_HELPER_FLAGS_4(crypto_rax1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
 DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
 DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
 
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
index f02fbb63a4..da0f59a2ce 100644
--- a/target/arm/translate-a64.h
+++ b/target/arm/translate-a64.h
@@ -115,4 +115,7 @@ static inline int vec_full_reg_size(DisasContext *s)
 
 bool disas_sve(DisasContext *, uint32_t);
 
+void gen_gvec_rax1(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+   uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+
 #endif /* TARGET_ARM_TRANSLATE_A64_H */
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
index 6bd5a3d2d0..372d8350e4 100644
--- a/target/arm/crypto_helper.c
+++ b/target/arm/crypto_helper.c
@@ -725,3 +725,14 @@ void HELPER(crypto_sm4ekey)(void *vd, void *vn, void* vm, 
uint32_t desc)
 }
 clear_tail(vd, opr_sz, simd_maxsz(desc));
 }
+
+void HELPER(crypto_rax1)(void *vd, void *vn, void *vm, uint32_t desc)
+{
+intptr_t i, opr_sz = simd_oprsz(desc);
+uint64_t *d = vd, *n = vn, *m = vm;
+
+for (i = 0; i < opr_sz / 8; ++i) {
+d[i] = n[i] ^ rol64(m[i], 1);
+}
+clear_tail(vd, opr_sz, simd_maxsz(desc));
+}
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 1e511529b8..4d7a8fd2bb 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -13579,6 +13579,32 @@ static void disas_crypto_two_reg_sha(DisasContext *s, 
uint32_t insn)
 tcg_temp_free_ptr(tcg_rn_ptr);
 }
 
+static void gen_rax1_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m)
+{
+tcg_gen_rotli_i64(d, m, 1);
+tcg_gen_xor_i64(d, d, n);
+}
+
+static void gen_rax1_vec(unsigned vece, TCGv_vec d, TCGv_vec n, TCGv_vec m)
+{
+tcg_gen_rotli_vec(vece, d, m, 1);
+tcg_gen_xor_vec(vece, d, d, n);
+}
+
+void gen_gvec_rax1(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+   uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+static const TCGOpcode vecop_list[] = { INDEX_op_rotli_vec, 0 };
+static const GVecGen3 op = {
+.fni8 = gen_rax1_i64,
+.fniv = gen_rax1_vec,
+.opt_opc = vecop_list,
+.fno = gen_helper_crypto_rax1,
+.vece = MO_64,
+};
+tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, );
+}
+
 /* Crypto three-reg SHA512
  *  31   21 20  16 15  14  13 12  11  10  95 40
  * +---+--+---+---+-++--+--+
@@ -13595,6 +13621,7 @@ static void disas_crypto_three_reg_sha512(DisasContext 
*s, uint32_t insn)
 bool feature;
 CryptoThreeOpFn *genfn = NULL;
 gen_helper_gvec_3 *oolfn = NULL;
+GVecGen3Fn *gvecfn = NULL;
 
 if (o == 0) {
 switch (opcode) {
@@ -13612,7 +13639,7 @@ static void disas_crypto_three_reg_sha512(DisasContext 
*s, uint32_t insn)
 break;
 case 3: /* RAX1 */
 feature = dc_isar_feature(aa64_sha3, s);
-genfn = NULL;
+gvecfn = gen_gvec_rax1;
 break;
 default:
 g_assert_not_reached();
@@ -13648,10 +13675,9 @@ static void disas_crypto_three_reg_sha512(DisasContext 
*s, uint32_t insn)
 
 if (oolfn) {
 gen_gvec_op3_ool(s, true, rd, rn, rm, 0, oolfn);
-return;
-}
-
-if (genfn) {
+} else if (gvecfn) {
+gen_gvec_fn3(s, true, rd, rn, rm, gvecfn, MO_64);
+} else {
 TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
 
 tcg_rd_ptr = vec_full_reg_ptr(s, rd);
@@ -13663,29 +13689,6 @@ static void disas_crypto_three_reg_sha512(DisasContext 
*s, uint32_t insn)
 tcg_temp_free_ptr(tcg_rd_ptr);
 tcg_temp_free_ptr(tcg_rn_ptr);
 tcg_temp_free_ptr(tcg_rm_ptr);
-} else {
-TCGv_i64 tcg_op1, tcg_op2, tcg_res[2];
-int pass;
-
-tcg_op1 = tcg_temp_new_i64();
-tcg_op2 = tcg_temp_new_i64();
-tcg_res[0] = tcg_temp_new_i64();
-tcg_res[1] = tcg_temp_new_i64();
-
-for (pass = 0; pass < 2; pass++) {
-

Re: [PATCH v3 1/1] qemu_img: add cvtnum_full to print error reports

2020-05-14 Thread Eric Blake

On 5/13/20 8:36 AM, Eyal Moscovici wrote:

All calls to cvtnum check the return value and print the same error message more
or less. And so error reporting moved to cvtnum_full to reduce code
duplication and provide a single error message. Additionally, cvtnum now wraps
cvtnum_full with the existing default range of 0 to MAX_INT64.

Acked-by: Mark Kanda 
Signed-off-by: Eyal Moscovici 
---



-static int64_t cvtnum(const char *s)
+static int64_t cvtnum_full(const char *name, const char *value, int64_t min,
+   int64_t max)
  {
  int err;
-uint64_t value;
-
-err = qemu_strtosz(s, NULL, );
-if (err < 0) {
+uint64_t res;
+
+err = qemu_strtosz(value, NULL, );
+if (err < 0 && err != -ERANGE) {
+error_report("Invalid %s specified. You may use "
+ "k, M, G, T, P or E suffixes for ", name);
+error_report("kilobytes, megabytes, gigabytes, terabytes, "
+ "petabytes and exabytes.");


Consecutive error_report() calls each output a newline, which means your 
new output includes a trailing space.



@@ -572,16 +584,8 @@ static int img_create(int argc, char **argv)
  if (optind < argc) {
  int64_t sval;
  
-sval = cvtnum(argv[optind++]);

+sval = cvtnum("image size", argv[optind++]);
  if (sval < 0) {
-if (sval == -ERANGE) {
-error_report("Image size must be less than 8 EiB!");
-} else {
-error_report("Invalid image size specified! You may use k, M, "
-  "G, T, P or E suffixes for ");
-error_report("kilobytes, megabytes, gigabytes, terabytes, "
- "petabytes and exabytes.");
-}


True, that's what some of the old code was doing, but...


+++ b/tests/qemu-iotests/049.out


  
  qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- 1kilobyte

-qemu-img: Invalid image size specified! You may use k, M, G, T, P or E 
suffixes for
+qemu-img: Invalid image size specified. You may use k, M, G, T, P or E 
suffixes for


where it gets hairy is that our iotests _intentionally_ strip trailing 
space before comparing to expected output, because it is such a pain to 
commit files with trailing spaces into the repository.  We're better off 
making the expected output precisely match what qemu-img actually 
outputs, which means using this as an opportunity to fix qemu-img to not 
output trailing space in the first place.


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




[PATCH Kernel v20 8/8] vfio: Selective dirty page tracking if IOMMU backed device pins pages

2020-05-14 Thread Kirti Wankhede
Added a check such that only singleton IOMMU groups can pin pages.
>From the point when vendor driver pins any pages, consider IOMMU group
dirty page scope to be limited to pinned pages.

To optimize to avoid walking list often, added flag
pinned_page_dirty_scope to indicate if all of the vfio_groups for each
vfio_domain in the domain_list dirty page scope is limited to pinned
pages. This flag is updated on first pinned pages request for that IOMMU
group and on attaching/detaching group.

Signed-off-by: Kirti Wankhede 
Reviewed-by: Neo Jia 
---
 drivers/vfio/vfio.c |  13 +++--
 drivers/vfio/vfio_iommu_type1.c | 104 
 include/linux/vfio.h|   4 +-
 3 files changed, 109 insertions(+), 12 deletions(-)

diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 765e0e5d83ed..580099afeaff 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -85,6 +85,7 @@ struct vfio_group {
atomic_topened;
wait_queue_head_t   container_q;
boolnoiommu;
+   unsigned intdev_counter;
struct kvm  *kvm;
struct blocking_notifier_head   notifier;
 };
@@ -555,6 +556,7 @@ struct vfio_device *vfio_group_create_device(struct 
vfio_group *group,
 
mutex_lock(>device_lock);
list_add(>group_next, >device_list);
+   group->dev_counter++;
mutex_unlock(>device_lock);
 
return device;
@@ -567,6 +569,7 @@ static void vfio_device_release(struct kref *kref)
struct vfio_group *group = device->group;
 
list_del(>group_next);
+   group->dev_counter--;
mutex_unlock(>device_lock);
 
dev_set_drvdata(device->dev, NULL);
@@ -1945,6 +1948,9 @@ int vfio_pin_pages(struct device *dev, unsigned long 
*user_pfn, int npage,
if (!group)
return -ENODEV;
 
+   if (group->dev_counter > 1)
+   return -EINVAL;
+
ret = vfio_group_add_container_user(group);
if (ret)
goto err_pin_pages;
@@ -1952,7 +1958,8 @@ int vfio_pin_pages(struct device *dev, unsigned long 
*user_pfn, int npage,
container = group->container;
driver = container->iommu_driver;
if (likely(driver && driver->ops->pin_pages))
-   ret = driver->ops->pin_pages(container->iommu_data, user_pfn,
+   ret = driver->ops->pin_pages(container->iommu_data,
+group->iommu_group, user_pfn,
 npage, prot, phys_pfn);
else
ret = -ENOTTY;
@@ -2050,8 +2057,8 @@ int vfio_group_pin_pages(struct vfio_group *group,
driver = container->iommu_driver;
if (likely(driver && driver->ops->pin_pages))
ret = driver->ops->pin_pages(container->iommu_data,
-user_iova_pfn, npage,
-prot, phys_pfn);
+group->iommu_group, user_iova_pfn,
+npage, prot, phys_pfn);
else
ret = -ENOTTY;
 
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index 3edb3c3e6170..a52c4ae8907b 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -73,6 +73,7 @@ struct vfio_iommu {
boolv2;
boolnesting;
booldirty_page_tracking;
+   boolpinned_page_dirty_scope;
 };
 
 struct vfio_domain {
@@ -100,6 +101,7 @@ struct vfio_group {
struct iommu_group  *iommu_group;
struct list_headnext;
boolmdev_group; /* An mdev group */
+   boolpinned_page_dirty_scope;
 };
 
 struct vfio_iova {
@@ -143,6 +145,10 @@ struct vfio_regions {
 
 static int put_pfn(unsigned long pfn, int prot);
 
+static struct vfio_group *vfio_iommu_find_iommu_group(struct vfio_iommu *iommu,
+  struct iommu_group *iommu_group);
+
+static void update_pinned_page_dirty_scope(struct vfio_iommu *iommu);
 /*
  * This code handles mapping and unmapping of user data buffers
  * into DMA'ble space using the IOMMU
@@ -590,11 +596,13 @@ static int vfio_unpin_page_external(struct vfio_dma *dma, 
dma_addr_t iova,
 }
 
 static int vfio_iommu_type1_pin_pages(void *iommu_data,
+ struct iommu_group *iommu_group,
  unsigned long *user_pfn,
  int npage, int prot,
  unsigned long *phys_pfn)
 {
struct vfio_iommu *iommu = iommu_data;
+   struct vfio_group *group;
int i, j, ret;
unsigned long remote_vaddr;
struct vfio_dma *dma;
@@ 

[PATCH Kernel v20 3/8] vfio iommu: Cache pgsize_bitmap in struct vfio_iommu

2020-05-14 Thread Kirti Wankhede
Calculate and cache pgsize_bitmap when iommu->domain_list is updated
and iommu->external_domain is set for mdev device.
Add iommu->lock protection when cached pgsize_bitmap is accessed.

Signed-off-by: Kirti Wankhede 
Reviewed-by: Neo Jia 
---
 drivers/vfio/vfio_iommu_type1.c | 88 +++--
 1 file changed, 49 insertions(+), 39 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index fa735047b04d..de17787ffece 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -69,6 +69,7 @@ struct vfio_iommu {
struct rb_root  dma_list;
struct blocking_notifier_head notifier;
unsigned intdma_avail;
+   uint64_tpgsize_bitmap;
boolv2;
boolnesting;
 };
@@ -805,15 +806,14 @@ static void vfio_remove_dma(struct vfio_iommu *iommu, 
struct vfio_dma *dma)
iommu->dma_avail++;
 }
 
-static unsigned long vfio_pgsize_bitmap(struct vfio_iommu *iommu)
+static void vfio_pgsize_bitmap(struct vfio_iommu *iommu)
 {
struct vfio_domain *domain;
-   unsigned long bitmap = ULONG_MAX;
 
-   mutex_lock(>lock);
+   iommu->pgsize_bitmap = ULONG_MAX;
+
list_for_each_entry(domain, >domain_list, next)
-   bitmap &= domain->domain->pgsize_bitmap;
-   mutex_unlock(>lock);
+   iommu->pgsize_bitmap &= domain->domain->pgsize_bitmap;
 
/*
 * In case the IOMMU supports page sizes smaller than PAGE_SIZE
@@ -823,12 +823,10 @@ static unsigned long vfio_pgsize_bitmap(struct vfio_iommu 
*iommu)
 * granularity while iommu driver can use the sub-PAGE_SIZE size
 * to map the buffer.
 */
-   if (bitmap & ~PAGE_MASK) {
-   bitmap &= PAGE_MASK;
-   bitmap |= PAGE_SIZE;
+   if (iommu->pgsize_bitmap & ~PAGE_MASK) {
+   iommu->pgsize_bitmap &= PAGE_MASK;
+   iommu->pgsize_bitmap |= PAGE_SIZE;
}
-
-   return bitmap;
 }
 
 static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
@@ -839,19 +837,28 @@ static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
size_t unmapped = 0;
int ret = 0, retries = 0;
 
-   mask = ((uint64_t)1 << __ffs(vfio_pgsize_bitmap(iommu))) - 1;
+   mutex_lock(>lock);
+
+   mask = ((uint64_t)1 << __ffs(iommu->pgsize_bitmap)) - 1;
+
+   if (unmap->iova & mask) {
+   ret = -EINVAL;
+   goto unlock;
+   }
+
+   if (!unmap->size || unmap->size & mask) {
+   ret = -EINVAL;
+   goto unlock;
+   }
 
-   if (unmap->iova & mask)
-   return -EINVAL;
-   if (!unmap->size || unmap->size & mask)
-   return -EINVAL;
if (unmap->iova + unmap->size - 1 < unmap->iova ||
-   unmap->size > SIZE_MAX)
-   return -EINVAL;
+   unmap->size > SIZE_MAX) {
+   ret = -EINVAL;
+   goto unlock;
+   }
 
WARN_ON(mask & PAGE_MASK);
 again:
-   mutex_lock(>lock);
 
/*
 * vfio-iommu-type1 (v1) - User mappings were coalesced together to
@@ -930,6 +937,7 @@ static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
blocking_notifier_call_chain(>notifier,
VFIO_IOMMU_NOTIFY_DMA_UNMAP,
_unmap);
+   mutex_lock(>lock);
goto again;
}
unmapped += dma->size;
@@ -1045,24 +1053,28 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu,
if (map->size != size || map->vaddr != vaddr || map->iova != iova)
return -EINVAL;
 
-   mask = ((uint64_t)1 << __ffs(vfio_pgsize_bitmap(iommu))) - 1;
-
-   WARN_ON(mask & PAGE_MASK);
-
/* READ/WRITE from device perspective */
if (map->flags & VFIO_DMA_MAP_FLAG_WRITE)
prot |= IOMMU_WRITE;
if (map->flags & VFIO_DMA_MAP_FLAG_READ)
prot |= IOMMU_READ;
 
-   if (!prot || !size || (size | iova | vaddr) & mask)
-   return -EINVAL;
+   mutex_lock(>lock);
 
-   /* Don't allow IOVA or virtual address wrap */
-   if (iova + size - 1 < iova || vaddr + size - 1 < vaddr)
-   return -EINVAL;
+   mask = ((uint64_t)1 << __ffs(iommu->pgsize_bitmap)) - 1;
 
-   mutex_lock(>lock);
+   WARN_ON(mask & PAGE_MASK);
+
+   if (!prot || !size || (size | iova | vaddr) & mask) {
+   ret = -EINVAL;
+   goto out_unlock;
+   }
+
+   /* Don't allow IOVA or virtual address wrap */
+   if (iova + size - 1 < iova || vaddr + size - 1 < vaddr) {
+   ret = -EINVAL;
+   goto out_unlock;
+   }
 
if (vfio_find_dma(iommu, iova, size)) {
ret = -EEXIST;
@@ -1668,6 +1680,7 @@ static 

[PATCH Kernel v20 6/8] vfio iommu: Update UNMAP_DMA ioctl to get dirty bitmap before unmap

2020-05-14 Thread Kirti Wankhede
DMA mapped pages, including those pinned by mdev vendor drivers, might
get unpinned and unmapped while migration is active and device is still
running. For example, in pre-copy phase while guest driver could access
those pages, host device or vendor driver can dirty these mapped pages.
Such pages should be marked dirty so as to maintain memory consistency
for a user making use of dirty page tracking.

To get bitmap during unmap, user should allocate memory for bitmap, set
it all zeros, set size of allocated memory, set page size to be
considered for bitmap and set flag VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP.

Signed-off-by: Kirti Wankhede 
Reviewed-by: Neo Jia 
---
 drivers/vfio/vfio_iommu_type1.c | 77 ++---
 include/uapi/linux/vfio.h   | 10 ++
 2 files changed, 75 insertions(+), 12 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index b76d3b14abfd..a1dc57bcece5 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -195,11 +195,15 @@ static void vfio_unlink_dma(struct vfio_iommu *iommu, 
struct vfio_dma *old)
 static int vfio_dma_bitmap_alloc(struct vfio_dma *dma, size_t pgsize)
 {
uint64_t npages = dma->size / pgsize;
+   size_t bitmap_size;
 
if (npages > DIRTY_BITMAP_PAGES_MAX)
return -EINVAL;
 
-   dma->bitmap = kvzalloc(DIRTY_BITMAP_BYTES(npages), GFP_KERNEL);
+   /* Allocate extra 64 bits which are used for bitmap manipulation */
+   bitmap_size = DIRTY_BITMAP_BYTES(npages) + sizeof(u64);
+
+   dma->bitmap = kvzalloc(bitmap_size, GFP_KERNEL);
if (!dma->bitmap)
return -ENOMEM;
 
@@ -999,23 +1003,25 @@ static int verify_bitmap_size(uint64_t npages, uint64_t 
bitmap_size)
 }
 
 static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
-struct vfio_iommu_type1_dma_unmap *unmap)
+struct vfio_iommu_type1_dma_unmap *unmap,
+struct vfio_bitmap *bitmap)
 {
-   uint64_t mask;
struct vfio_dma *dma, *dma_last = NULL;
-   size_t unmapped = 0;
+   size_t unmapped = 0, pgsize;
int ret = 0, retries = 0;
+   unsigned long pgshift;
 
mutex_lock(>lock);
 
-   mask = ((uint64_t)1 << __ffs(iommu->pgsize_bitmap)) - 1;
+   pgshift = __ffs(iommu->pgsize_bitmap);
+   pgsize = (size_t)1 << pgshift;
 
-   if (unmap->iova & mask) {
+   if (unmap->iova & (pgsize - 1)) {
ret = -EINVAL;
goto unlock;
}
 
-   if (!unmap->size || unmap->size & mask) {
+   if (!unmap->size || unmap->size & (pgsize - 1)) {
ret = -EINVAL;
goto unlock;
}
@@ -1026,9 +1032,15 @@ static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
goto unlock;
}
 
-   WARN_ON(mask & PAGE_MASK);
-again:
+   /* When dirty tracking is enabled, allow only min supported pgsize */
+   if ((unmap->flags & VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP) &&
+   (!iommu->dirty_page_tracking || (bitmap->pgsize != pgsize))) {
+   ret = -EINVAL;
+   goto unlock;
+   }
 
+   WARN_ON((pgsize - 1) & PAGE_MASK);
+again:
/*
 * vfio-iommu-type1 (v1) - User mappings were coalesced together to
 * avoid tracking individual mappings.  This means that the granularity
@@ -1066,6 +1078,7 @@ static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
ret = -EINVAL;
goto unlock;
}
+
dma = vfio_find_dma(iommu, unmap->iova + unmap->size - 1, 0);
if (dma && dma->iova + dma->size != unmap->iova + unmap->size) {
ret = -EINVAL;
@@ -1083,6 +1096,23 @@ static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
if (dma->task->mm != current->mm)
break;
 
+   if ((unmap->flags & VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP) &&
+   (dma_last != dma)) {
+
+   /*
+* mark all pages dirty if all pages are pinned and
+* mapped
+*/
+   if (dma->iommu_mapped)
+   bitmap_set(dma->bitmap, 0,
+  dma->size >> pgshift);
+
+   ret = update_user_bitmap(bitmap->data, dma,
+unmap->iova, pgsize);
+   if (ret)
+   break;
+   }
+
if (!RB_EMPTY_ROOT(>pfn_list)) {
struct vfio_iommu_type1_dma_unmap nb_unmap;
 
@@ -2447,17 +2477,40 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
 
} else if (cmd == VFIO_IOMMU_UNMAP_DMA) {
struct vfio_iommu_type1_dma_unmap unmap;
-   long ret;

[PATCH Kernel v20 2/8] vfio iommu: Remove atomicity of ref_count of pinned pages

2020-05-14 Thread Kirti Wankhede
vfio_pfn.ref_count is always updated while holding iommu->lock, using
atomic variable is overkill.

Signed-off-by: Kirti Wankhede 
Reviewed-by: Neo Jia 
Reviewed-by: Eric Auger 
Reviewed-by: Cornelia Huck 
---
 drivers/vfio/vfio_iommu_type1.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index a0c60f895b24..fa735047b04d 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -112,7 +112,7 @@ struct vfio_pfn {
struct rb_node  node;
dma_addr_t  iova;   /* Device address */
unsigned long   pfn;/* Host pfn */
-   atomic_tref_count;
+   unsigned intref_count;
 };
 
 struct vfio_regions {
@@ -233,7 +233,7 @@ static int vfio_add_to_pfn_list(struct vfio_dma *dma, 
dma_addr_t iova,
 
vpfn->iova = iova;
vpfn->pfn = pfn;
-   atomic_set(>ref_count, 1);
+   vpfn->ref_count = 1;
vfio_link_pfn(dma, vpfn);
return 0;
 }
@@ -251,7 +251,7 @@ static struct vfio_pfn *vfio_iova_get_vfio_pfn(struct 
vfio_dma *dma,
struct vfio_pfn *vpfn = vfio_find_vpfn(dma, iova);
 
if (vpfn)
-   atomic_inc(>ref_count);
+   vpfn->ref_count++;
return vpfn;
 }
 
@@ -259,7 +259,8 @@ static int vfio_iova_put_vfio_pfn(struct vfio_dma *dma, 
struct vfio_pfn *vpfn)
 {
int ret = 0;
 
-   if (atomic_dec_and_test(>ref_count)) {
+   vpfn->ref_count--;
+   if (!vpfn->ref_count) {
ret = put_pfn(vpfn->pfn, dma->prot);
vfio_remove_from_pfn_list(dma, vpfn);
}
-- 
2.7.0




[PATCH Kernel v20 5/8] vfio iommu: Implementation of ioctl for dirty pages tracking

2020-05-14 Thread Kirti Wankhede
VFIO_IOMMU_DIRTY_PAGES ioctl performs three operations:
- Start dirty pages tracking while migration is active
- Stop dirty pages tracking.
- Get dirty pages bitmap. Its user space application's responsibility to
  copy content of dirty pages from source to destination during migration.

To prevent DoS attack, memory for bitmap is allocated per vfio_dma
structure. Bitmap size is calculated considering smallest supported page
size. Bitmap is allocated for all vfio_dmas when dirty logging is enabled

Bitmap is populated for already pinned pages when bitmap is allocated for
a vfio_dma with the smallest supported page size. Update bitmap from
pinning functions when tracking is enabled. When user application queries
bitmap, check if requested page size is same as page size used to
populated bitmap. If it is equal, copy bitmap, but if not equal, return
error.

Signed-off-by: Kirti Wankhede 
Reviewed-by: Neo Jia 

Fixed error reported by build bot by changing pgsize type from uint64_t
to size_t.
Reported-by: kbuild test robot 
---
 drivers/vfio/vfio_iommu_type1.c | 294 +++-
 1 file changed, 288 insertions(+), 6 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index de17787ffece..b76d3b14abfd 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -72,6 +72,7 @@ struct vfio_iommu {
uint64_tpgsize_bitmap;
boolv2;
boolnesting;
+   booldirty_page_tracking;
 };
 
 struct vfio_domain {
@@ -92,6 +93,7 @@ struct vfio_dma {
boollock_cap;   /* capable(CAP_IPC_LOCK) */
struct task_struct  *task;
struct rb_root  pfn_list;   /* Ex-user pinned pfn list */
+   unsigned long   *bitmap;
 };
 
 struct vfio_group {
@@ -126,6 +128,19 @@ struct vfio_regions {
 #define IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu)\
(!list_empty(>domain_list))
 
+#define DIRTY_BITMAP_BYTES(n)  (ALIGN(n, BITS_PER_TYPE(u64)) / BITS_PER_BYTE)
+
+/*
+ * Input argument of number of bits to bitmap_set() is unsigned integer, which
+ * further casts to signed integer for unaligned multi-bit operation,
+ * __bitmap_set().
+ * Then maximum bitmap size supported is 2^31 bits divided by 2^3 bits/byte,
+ * that is 2^28 (256 MB) which maps to 2^31 * 2^12 = 2^43 (8TB) on 4K page
+ * system.
+ */
+#define DIRTY_BITMAP_PAGES_MAX  ((u64)INT_MAX)
+#define DIRTY_BITMAP_SIZE_MAX   DIRTY_BITMAP_BYTES(DIRTY_BITMAP_PAGES_MAX)
+
 static int put_pfn(unsigned long pfn, int prot);
 
 /*
@@ -176,6 +191,74 @@ static void vfio_unlink_dma(struct vfio_iommu *iommu, 
struct vfio_dma *old)
rb_erase(>node, >dma_list);
 }
 
+
+static int vfio_dma_bitmap_alloc(struct vfio_dma *dma, size_t pgsize)
+{
+   uint64_t npages = dma->size / pgsize;
+
+   if (npages > DIRTY_BITMAP_PAGES_MAX)
+   return -EINVAL;
+
+   dma->bitmap = kvzalloc(DIRTY_BITMAP_BYTES(npages), GFP_KERNEL);
+   if (!dma->bitmap)
+   return -ENOMEM;
+
+   return 0;
+}
+
+static void vfio_dma_bitmap_free(struct vfio_dma *dma)
+{
+   kfree(dma->bitmap);
+   dma->bitmap = NULL;
+}
+
+static void vfio_dma_populate_bitmap(struct vfio_dma *dma, size_t pgsize)
+{
+   struct rb_node *p;
+
+   for (p = rb_first(>pfn_list); p; p = rb_next(p)) {
+   struct vfio_pfn *vpfn = rb_entry(p, struct vfio_pfn, node);
+
+   bitmap_set(dma->bitmap, (vpfn->iova - dma->iova) / pgsize, 1);
+   }
+}
+
+static int vfio_dma_bitmap_alloc_all(struct vfio_iommu *iommu, size_t pgsize)
+{
+   struct rb_node *n = rb_first(>dma_list);
+
+   for (; n; n = rb_next(n)) {
+   struct vfio_dma *dma = rb_entry(n, struct vfio_dma, node);
+   int ret;
+
+   ret = vfio_dma_bitmap_alloc(dma, pgsize);
+   if (ret) {
+   struct rb_node *p = rb_prev(n);
+
+   for (; p; p = rb_prev(p)) {
+   struct vfio_dma *dma = rb_entry(n,
+   struct vfio_dma, node);
+
+   vfio_dma_bitmap_free(dma);
+   }
+   return ret;
+   }
+   vfio_dma_populate_bitmap(dma, pgsize);
+   }
+   return 0;
+}
+
+static void vfio_dma_bitmap_free_all(struct vfio_iommu *iommu)
+{
+   struct rb_node *n = rb_first(>dma_list);
+
+   for (; n; n = rb_next(n)) {
+   struct vfio_dma *dma = rb_entry(n, struct vfio_dma, node);
+
+   vfio_dma_bitmap_free(dma);
+   }
+}
+
 /*
  * Helper Functions for host iova-pfn list
  */
@@ -568,6 +651,17 @@ static int vfio_iommu_type1_pin_pages(void *iommu_data,
vfio_unpin_page_external(dma, iova, do_accounting);

[PATCH Kernel v20 4/8] vfio iommu: Add ioctl definition for dirty pages tracking

2020-05-14 Thread Kirti Wankhede
IOMMU container maintains a list of all pages pinned by vfio_pin_pages API.
All pages pinned by vendor driver through this API should be considered as
dirty during migration. When container consists of IOMMU capable device and
all pages are pinned and mapped, then all pages are marked dirty.
Added support to start/stop dirtied pages tracking and to get bitmap of all
dirtied pages for requested IO virtual address range.

Signed-off-by: Kirti Wankhede 
Reviewed-by: Neo Jia 
---
 include/uapi/linux/vfio.h | 55 +++
 1 file changed, 55 insertions(+)

diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index ad9bb5af3463..123de3bc2dce 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -1033,6 +1033,12 @@ struct vfio_iommu_type1_dma_map {
 
 #define VFIO_IOMMU_MAP_DMA _IO(VFIO_TYPE, VFIO_BASE + 13)
 
+struct vfio_bitmap {
+   __u64pgsize;/* page size for bitmap in bytes */
+   __u64size;  /* in bytes */
+   __u64 __user *data; /* one bit per page */
+};
+
 /**
  * VFIO_IOMMU_UNMAP_DMA - _IOWR(VFIO_TYPE, VFIO_BASE + 14,
  * struct vfio_dma_unmap)
@@ -1059,6 +1065,55 @@ struct vfio_iommu_type1_dma_unmap {
 #define VFIO_IOMMU_ENABLE  _IO(VFIO_TYPE, VFIO_BASE + 15)
 #define VFIO_IOMMU_DISABLE _IO(VFIO_TYPE, VFIO_BASE + 16)
 
+/**
+ * VFIO_IOMMU_DIRTY_PAGES - _IOWR(VFIO_TYPE, VFIO_BASE + 17,
+ * struct vfio_iommu_type1_dirty_bitmap)
+ * IOCTL is used for dirty pages tracking.
+ * Caller should set flag depending on which operation to perform, details as
+ * below:
+ *
+ * When IOCTL is called with VFIO_IOMMU_DIRTY_PAGES_FLAG_START set, indicates
+ * migration is active and IOMMU module should track pages which are dirtied or
+ * potentially dirtied by device.
+ * Dirty pages are tracked until tracking is stopped by user application by
+ * setting VFIO_IOMMU_DIRTY_PAGES_FLAG_STOP flag.
+ *
+ * When IOCTL is called with VFIO_IOMMU_DIRTY_PAGES_FLAG_STOP set, indicates
+ * IOMMU should stop tracking dirtied pages.
+ *
+ * When IOCTL is called with VFIO_IOMMU_DIRTY_PAGES_FLAG_GET_BITMAP flag set,
+ * IOCTL returns dirty pages bitmap for IOMMU container during migration for
+ * given IOVA range. User must provide data[] as the structure
+ * vfio_iommu_type1_dirty_bitmap_get through which user provides IOVA range and
+ * pgsize. This interface supports to get bitmap of smallest supported pgsize
+ * only and can be modified in future to get bitmap of specified pgsize.
+ * User must allocate memory for bitmap, zero the bitmap memory  and set size
+ * of allocated memory in bitmap.size field. One bit is used to represent one
+ * page consecutively starting from iova offset. User should provide page size
+ * in bitmap.pgsize field. Bit set in bitmap indicates page at that offset from
+ * iova is dirty. Caller must set argsz including size of structure
+ * vfio_iommu_type1_dirty_bitmap_get.
+ *
+ * Only one of the flags _START, STOP and _GET may be specified at a time.
+ *
+ */
+struct vfio_iommu_type1_dirty_bitmap {
+   __u32argsz;
+   __u32flags;
+#define VFIO_IOMMU_DIRTY_PAGES_FLAG_START  (1 << 0)
+#define VFIO_IOMMU_DIRTY_PAGES_FLAG_STOP   (1 << 1)
+#define VFIO_IOMMU_DIRTY_PAGES_FLAG_GET_BITMAP (1 << 2)
+   __u8 data[];
+};
+
+struct vfio_iommu_type1_dirty_bitmap_get {
+   __u64  iova;/* IO virtual address */
+   __u64  size;/* Size of iova range */
+   struct vfio_bitmap bitmap;
+};
+
+#define VFIO_IOMMU_DIRTY_PAGES _IO(VFIO_TYPE, VFIO_BASE + 17)
+
 /*  Additional API for SPAPR TCE (Server POWERPC) IOMMU  */
 
 /*
-- 
2.7.0




[PATCH Kernel v20 7/8] vfio iommu: Add migration capability to report supported features

2020-05-14 Thread Kirti Wankhede
Added migration capability in IOMMU info chain.
User application should check IOMMU info chain for migration capability
to use dirty page tracking feature provided by kernel module.
User application must check page sizes supported and maximum dirty
bitmap size returned by this capability structure for ioctls used to get
dirty bitmap.

Signed-off-by: Kirti Wankhede 
---
 drivers/vfio/vfio_iommu_type1.c | 23 ++-
 include/uapi/linux/vfio.h   | 22 ++
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index a1dc57bcece5..3edb3c3e6170 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -2387,6 +2387,22 @@ static int vfio_iommu_iova_build_caps(struct vfio_iommu 
*iommu,
return ret;
 }
 
+static int vfio_iommu_migration_build_caps(struct vfio_iommu *iommu,
+  struct vfio_info_cap *caps)
+{
+   struct vfio_iommu_type1_info_cap_migration cap_mig;
+
+   cap_mig.header.id = VFIO_IOMMU_TYPE1_INFO_CAP_MIGRATION;
+   cap_mig.header.version = 1;
+
+   cap_mig.flags = 0;
+   /* support minimum pgsize */
+   cap_mig.pgsize_bitmap = (size_t)1 << __ffs(iommu->pgsize_bitmap);
+   cap_mig.max_dirty_bitmap_size = DIRTY_BITMAP_SIZE_MAX;
+
+   return vfio_info_add_capability(caps, _mig.header, sizeof(cap_mig));
+}
+
 static long vfio_iommu_type1_ioctl(void *iommu_data,
   unsigned int cmd, unsigned long arg)
 {
@@ -2433,8 +2449,13 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
 
info.iova_pgsizes = iommu->pgsize_bitmap;
 
-   ret = vfio_iommu_iova_build_caps(iommu, );
+   ret = vfio_iommu_migration_build_caps(iommu, );
+
+   if (!ret)
+   ret = vfio_iommu_iova_build_caps(iommu, );
+
mutex_unlock(>lock);
+
if (ret)
return ret;
 
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index 0a0c7315ddd6..ab1d0150bbd3 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -1013,6 +1013,28 @@ struct vfio_iommu_type1_info_cap_iova_range {
struct  vfio_iova_range iova_ranges[];
 };
 
+/*
+ * The migration capability allows to report supported features for migration.
+ *
+ * The structures below define version 1 of this capability.
+ *
+ * The existence of this capability indicates IOMMU kernel driver supports
+ * dirty page tracking.
+ *
+ * pgsize_bitmap: Kernel driver returns supported page sizes bitmap for dirty
+ * page tracking.
+ * max_dirty_bitmap_size: Kernel driver returns maximum supported dirty bitmap
+ * size in bytes to be used by user application for ioctls to get dirty bitmap.
+ */
+#define VFIO_IOMMU_TYPE1_INFO_CAP_MIGRATION  1
+
+struct vfio_iommu_type1_info_cap_migration {
+   struct  vfio_info_cap_header header;
+   __u32   flags;
+   __u64   pgsize_bitmap;
+   __u64   max_dirty_bitmap_size;  /* in bytes */
+};
+
 #define VFIO_IOMMU_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12)
 
 /**
-- 
2.7.0




[PATCH Kernel v20 0/8] Add UAPIs to support migration for VFIO devices

2020-05-14 Thread Kirti Wankhede
Hi,

This patch set adds:
* IOCTL VFIO_IOMMU_DIRTY_PAGES to get dirty pages bitmap with
  respect to IOMMU container rather than per device. All pages pinned by
  vendor driver through vfio_pin_pages external API has to be marked as
  dirty during  migration. When IOMMU capable device is present in the
  container and all pages are pinned and mapped, then all pages are marked
  dirty.
  When there are CPU writes, CPU dirty page tracking can identify dirtied
  pages, but any page pinned by vendor driver can also be written by
  device. As of now there is no device which has hardware support for
  dirty page tracking. So all pages which are pinned should be considered
  as dirty.
  This ioctl is also used to start/stop dirty pages tracking for pinned and
  unpinned pages while migration is active.

* Updated IOCTL VFIO_IOMMU_UNMAP_DMA to get dirty pages bitmap before
  unmapping IO virtual address range.
  With vIOMMU, during pre-copy phase of migration, while CPUs are still
  running, IO virtual address unmap can happen while device still keeping
  reference of guest pfns. Those pages should be reported as dirty before
  unmap, so that VFIO user space application can copy content of those
  pages from source to destination.

* Patch 8 detect if IOMMU capable device driver is smart to report pages
  to be marked dirty by pinning pages using vfio_pin_pages() API.


Yet TODO:
Since there is no device which has hardware support for system memmory
dirty bitmap tracking, right now there is no other API from vendor driver
to VFIO IOMMU module to report dirty pages. In future, when such hardware
support will be implemented, an API will be required such that vendor
driver could report dirty pages to VFIO module during migration phases.

Adding revision history from previous QEMU patch set to understand KABI
changes done till now

v19 -> v20
- Fixed ioctl to get dirty bitmap to get bitmap of multiple vfio_dmas
- Fixed unmap ioctl to get dirty bitmap of multiple vfio_dmas.
- Removed flag definition from migration capability.

v18 -> v19
- Updated migration capability with supported page sizes bitmap for dirty
  page tracking and  maximum bitmap size supported by kernel module.
- Added patch to calculate and cache pgsize_bitmap when iommu->domain_list
  is updated.
- Removed extra buffers added in previous version for bitmap manipulation
  and optimised the code.

v17 -> v18
- Add migration capability to the capability chain for VFIO_IOMMU_GET_INFO
  ioctl
- Updated UMAP_DMA ioctl to return bitmap of multiple vfio_dma

v16 -> v17
- Fixed errors reported by kbuild test robot  on i386

v15 -> v16
- Minor edits and nit picks (Auger Eric)
- On copying bitmap to user, re-populated bitmap only for pinned pages,
  excluding unmapped pages and CPU dirtied pages.
- Patches are on tag: next-20200318 and 1-3 patches from Yan's series
  https://lkml.org/lkml/2020/3/12/1255

v14 -> v15
- Minor edits and nit picks.
- In the verification of user allocated bitmap memory, added check of
   maximum size.
- Patches are on tag: next-20200318 and 1-3 patches from Yan's series
  https://lkml.org/lkml/2020/3/12/1255

v13 -> v14
- Added struct vfio_bitmap to kabi. updated structure
  vfio_iommu_type1_dirty_bitmap_get and vfio_iommu_type1_dma_unmap.
- All small changes suggested by Alex.
- Patches are on tag: next-20200318 and 1-3 patches from Yan's series
  https://lkml.org/lkml/2020/3/12/1255

v12 -> v13
- Changed bitmap allocation in vfio_iommu_type1 to per vfio_dma
- Changed VFIO_IOMMU_DIRTY_PAGES ioctl behaviour to be per vfio_dma range.
- Changed vfio_iommu_type1_dirty_bitmap structure to have separate data
  field.

v11 -> v12
- Changed bitmap allocation in vfio_iommu_type1.
- Remove atomicity of ref_count.
- Updated comments for migration device state structure about error
  reporting.
- Nit picks from v11 reviews

v10 -> v11
- Fix pin pages API to free vpfn if it is marked as unpinned tracking page.
- Added proposal to detect if IOMMU capable device calls external pin pages
  API to mark pages dirty.
- Nit picks from v10 reviews

v9 -> v10:
- Updated existing VFIO_IOMMU_UNMAP_DMA ioctl to get dirty pages bitmap
  during unmap while migration is active
- Added flag in VFIO_IOMMU_GET_INFO to indicate driver support dirty page
  tracking.
- If iommu_mapped, mark all pages dirty.
- Added unpinned pages tracking while migration is active.
- Updated comments for migration device state structure with bit
  combination table and state transition details.

v8 -> v9:
- Split patch set in 2 sets, Kernel and QEMU.
- Dirty pages bitmap is queried from IOMMU container rather than from
  vendor driver for per device. Added 2 ioctls to achieve this.

v7 -> v8:
- Updated comments for KABI
- Added BAR address validation check during PCI device's config space load
  as suggested by Dr. David Alan Gilbert.
- Changed vfio_migration_set_state() to set or clear device state flags.
- Some nit fixes.

v6 -> v7:
- Fix build failures.

v5 -> v6:
- Fix build 

[PATCH Kernel v20 1/8] vfio: UAPI for migration interface for device state

2020-05-14 Thread Kirti Wankhede
- Defined MIGRATION region type and sub-type.

- Defined vfio_device_migration_info structure which will be placed at the
  0th offset of migration region to get/set VFIO device related
  information. Defined members of structure and usage on read/write access.

- Defined device states and state transition details.

- Defined sequence to be followed while saving and resuming VFIO device.

Signed-off-by: Kirti Wankhede 
Reviewed-by: Neo Jia 
---
 include/uapi/linux/vfio.h | 228 ++
 1 file changed, 228 insertions(+)

diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index 015516bcfaa3..ad9bb5af3463 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -305,6 +305,7 @@ struct vfio_region_info_cap_type {
 #define VFIO_REGION_TYPE_PCI_VENDOR_MASK   (0x)
 #define VFIO_REGION_TYPE_GFX(1)
 #define VFIO_REGION_TYPE_CCW   (2)
+#define VFIO_REGION_TYPE_MIGRATION  (3)
 
 /* sub-types for VFIO_REGION_TYPE_PCI_* */
 
@@ -379,6 +380,233 @@ struct vfio_region_gfx_edid {
 /* sub-types for VFIO_REGION_TYPE_CCW */
 #define VFIO_REGION_SUBTYPE_CCW_ASYNC_CMD  (1)
 
+/* sub-types for VFIO_REGION_TYPE_MIGRATION */
+#define VFIO_REGION_SUBTYPE_MIGRATION   (1)
+
+/*
+ * The structure vfio_device_migration_info is placed at the 0th offset of
+ * the VFIO_REGION_SUBTYPE_MIGRATION region to get and set VFIO device related
+ * migration information. Field accesses from this structure are only supported
+ * at their native width and alignment. Otherwise, the result is undefined and
+ * vendor drivers should return an error.
+ *
+ * device_state: (read/write)
+ *  - The user application writes to this field to inform the vendor driver
+ *about the device state to be transitioned to.
+ *  - The vendor driver should take the necessary actions to change the
+ *device state. After successful transition to a given state, the
+ *vendor driver should return success on write(device_state, state)
+ *system call. If the device state transition fails, the vendor driver
+ *should return an appropriate -errno for the fault condition.
+ *  - On the user application side, if the device state transition fails,
+ *   that is, if write(device_state, state) returns an error, read
+ *   device_state again to determine the current state of the device from
+ *   the vendor driver.
+ *  - The vendor driver should return previous state of the device unless
+ *the vendor driver has encountered an internal error, in which case
+ *the vendor driver may report the device_state 
VFIO_DEVICE_STATE_ERROR.
+ *  - The user application must use the device reset ioctl to recover the
+ *device from VFIO_DEVICE_STATE_ERROR state. If the device is
+ *indicated to be in a valid device state by reading device_state, the
+ *user application may attempt to transition the device to any valid
+ *state reachable from the current state or terminate itself.
+ *
+ *  device_state consists of 3 bits:
+ *  - If bit 0 is set, it indicates the _RUNNING state. If bit 0 is clear,
+ *it indicates the _STOP state. When the device state is changed to
+ *_STOP, driver should stop the device before write() returns.
+ *  - If bit 1 is set, it indicates the _SAVING state, which means that the
+ *driver should start gathering device state information that will be
+ *provided to the VFIO user application to save the device's state.
+ *  - If bit 2 is set, it indicates the _RESUMING state, which means that
+ *the driver should prepare to resume the device. Data provided through
+ *the migration region should be used to resume the device.
+ *  Bits 3 - 31 are reserved for future use. To preserve them, the user
+ *  application should perform a read-modify-write operation on this
+ *  field when modifying the specified bits.
+ *
+ *  +--- _RESUMING
+ *  |+-- _SAVING
+ *  ||+- _RUNNING
+ *  |||
+ *  000b => Device Stopped, not saving or resuming
+ *  001b => Device running, which is the default state
+ *  010b => Stop the device & save the device state, stop-and-copy state
+ *  011b => Device running and save the device state, pre-copy state
+ *  100b => Device stopped and the device state is resuming
+ *  101b => Invalid state
+ *  110b => Error state
+ *  111b => Invalid state
+ *
+ * State transitions:
+ *
+ *  _RESUMING  _RUNNINGPre-copyStop-and-copy   _STOP
+ *(100b) (001b) (011b)(010b)   (000b)
+ * 0. Running or default state
+ * |
+ *
+ * 1. Normal Shutdown (optional)
+ * |->|
+ *
+ * 2. Save the state or suspend
+ * |->|-->|
+ *
+ * 3. 

Re: [PATCH 3/3] MAINTAINERS: Add myself as fulong2e co-maintainer

2020-05-14 Thread Aleksandar Markovic
сре, 8. апр 2020. у 11:08 Huacai Chen  је написао/ла:
>
> I submitted the MIPS/fulong2e support about ten years ago, and after
> that I became a MIPS kernel developer. Last year, Philippe Mathieu-
> Daudé asked me that whether I can be a reviewer of MIPS/fulong2e, and I
> promised that I will do some QEMU work in the next year (i.e., 2020 and
> later). I think now (and also in future) I can have some spare time, so
> I can finally do some real work on QEMU/MIPS. And if possible, I hope I
> can be a co-maintainer of MIPS/fulong2e.
>
> Cc: Jiaxun Yang 
> Signed-off-by: Huacai Chen 
> ---

Reviewed-by: Aleksandar Markovic 


>  MAINTAINERS | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 642c8e0..3281ff2 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1073,6 +1073,7 @@ F: hw/mips/mips_r4k.c
>  Fulong 2E
>  M: Philippe Mathieu-Daudé 
>  M: Aleksandar Markovic 
> +M: Huacai Chen 
>  S: Odd Fixes
>  F: hw/mips/mips_fulong2e.c
>  F: hw/isa/vt82c686.c
> --
> 2.7.0
>



[PATCH v1 2/2] sifive_e: Support the revB machine

2020-05-14 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 hw/riscv/sifive_e.c | 35 +++
 include/hw/riscv/sifive_e.h |  1 +
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index 472a98970b..cb7818341b 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -98,10 +98,14 @@ static void riscv_sifive_e_init(MachineState *machine)
 memmap[SIFIVE_E_DTIM].base, main_mem);
 
 /* Mask ROM reset vector */
-uint32_t reset_vec[2] = {
-0x204002b7,/* 0x1000: lui t0,0x20400 */
-0x00028067,/* 0x1004: jr  t0 */
-};
+uint32_t reset_vec[2];
+
+if (s->revb) {
+reset_vec[0] = 0x200102b7;/* 0x1000: lui t0,0x20010 */
+} else {
+reset_vec[0] = 0x204002b7;/* 0x1000: lui t0,0x20400 */
+}
+reset_vec[1] = 0x00028067;/* 0x1004: jr  t0 */
 
 /* copy in the reset vector in little_endian byte order */
 for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
@@ -115,8 +119,31 @@ static void riscv_sifive_e_init(MachineState *machine)
 }
 }
 
+static bool sifive_e_machine_get_revb(Object *obj, Error **errp)
+{
+SiFiveEState *s = RISCV_E_MACHINE(obj);
+
+return s->revb;
+}
+
+static void sifive_e_machine_set_revb(Object *obj, bool value, Error **errp)
+{
+SiFiveEState *s = RISCV_E_MACHINE(obj);
+
+s->revb = value;
+}
+
 static void sifive_e_machine_instance_init(Object *obj)
 {
+SiFiveEState *s = RISCV_E_MACHINE(obj);
+
+s->revb = false;
+object_property_add_bool(obj, "revb", sifive_e_machine_get_revb,
+ sifive_e_machine_set_revb, NULL);
+object_property_set_description(obj, "revb",
+"Set on to tell QEMU that it should model "
+"the revB HiFive1 board",
+NULL);
 }
 
 static void sifive_e_machine_class_init(ObjectClass *oc, void *data)
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
index 414992119e..0d3cd07fcc 100644
--- a/include/hw/riscv/sifive_e.h
+++ b/include/hw/riscv/sifive_e.h
@@ -45,6 +45,7 @@ typedef struct SiFiveEState {
 
 /*< public >*/
 SiFiveESoCState soc;
+bool revb;
 } SiFiveEState;
 
 #define TYPE_RISCV_E_MACHINE MACHINE_TYPE_NAME("sifive_e")
-- 
2.26.2




[PATCH v1 1/2] riscv: sifive_e: Manually define the machine

2020-05-14 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 hw/riscv/sifive_e.c | 41 +++--
 include/hw/riscv/sifive_e.h |  4 
 2 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index b53109521e..472a98970b 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -79,7 +79,7 @@ static void riscv_sifive_e_init(MachineState *machine)
 {
 const struct MemmapEntry *memmap = sifive_e_memmap;
 
-SiFiveEState *s = g_new0(SiFiveEState, 1);
+SiFiveEState *s = RISCV_E_MACHINE(machine);
 MemoryRegion *sys_mem = get_system_memory();
 MemoryRegion *main_mem = g_new(MemoryRegion, 1);
 int i;
@@ -115,6 +115,35 @@ static void riscv_sifive_e_init(MachineState *machine)
 }
 }
 
+static void sifive_e_machine_instance_init(Object *obj)
+{
+}
+
+static void sifive_e_machine_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+
+mc->desc = "RISC-V Board compatible with SiFive E SDK";
+mc->init = riscv_sifive_e_init;
+mc->max_cpus = 1;
+mc->default_cpu_type = SIFIVE_E_CPU;
+}
+
+static const TypeInfo sifive_e_machine_typeinfo = {
+.name   = MACHINE_TYPE_NAME("sifive_e"),
+.parent = TYPE_MACHINE,
+.class_init = sifive_e_machine_class_init,
+.instance_init = sifive_e_machine_instance_init,
+.instance_size = sizeof(SiFiveEState),
+};
+
+static void sifive_e_machine_init_register_types(void)
+{
+type_register_static(_e_machine_typeinfo);
+}
+
+type_init(sifive_e_machine_init_register_types)
+
 static void riscv_sifive_e_soc_init(Object *obj)
 {
 MachineState *ms = MACHINE(qdev_get_machine());
@@ -214,16 +243,6 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, 
Error **errp)
 >xip_mem);
 }
 
-static void riscv_sifive_e_machine_init(MachineClass *mc)
-{
-mc->desc = "RISC-V Board compatible with SiFive E SDK";
-mc->init = riscv_sifive_e_init;
-mc->max_cpus = 1;
-mc->default_cpu_type = SIFIVE_E_CPU;
-}
-
-DEFINE_MACHINE("sifive_e", riscv_sifive_e_machine_init)
-
 static void riscv_sifive_e_soc_class_init(ObjectClass *oc, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(oc);
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
index 25ce7aa9d5..414992119e 100644
--- a/include/hw/riscv/sifive_e.h
+++ b/include/hw/riscv/sifive_e.h
@@ -47,6 +47,10 @@ typedef struct SiFiveEState {
 SiFiveESoCState soc;
 } SiFiveEState;
 
+#define TYPE_RISCV_E_MACHINE MACHINE_TYPE_NAME("sifive_e")
+#define RISCV_E_MACHINE(obj) \
+OBJECT_CHECK(SiFiveEState, (obj), TYPE_RISCV_E_MACHINE)
+
 enum {
 SIFIVE_E_DEBUG,
 SIFIVE_E_MROM,
-- 
2.26.2




Re: [PATCH 10/10] ui/gtk: use native keyboard scancodes on Windows

2020-05-14 Thread Volker Rümelin


> since that time, we no longer support Debian Jessie, since Debian Buster
> is now released. We also no longer support Ubuntu Xenial (16.04), since
> we now only need Ubuntu Bionic (18.04) and Focal (20.04).
>
> So we can justify moving the minium Gtk in QEMU to 3.22 at this time.
>
> This will avoid you needing to do versioned ifdef for this new functionality.

Hi Daniel,

I noticed there are already seven versioned ifdefs in ui/gtk.c. I would prefer 
to leave my patch as it is at the moment and send in a separate follow up patch 
which increases the minimum GTK version in configure to 3.22 and removes all 
versioned code in ui/gtk.c. Just like your patch from 2018. I think this is 
easier to revert if someone complains about the removal.

With best regards,
Volker



Re: [PATCH] hw/ide/ahci: Log lost IRQs

2020-05-14 Thread John Snow



On 5/4/20 5:48 AM, Philippe Mathieu-Daudé wrote:
> One might find interesting to look at AHCI IRQs.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/ide/ahci.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index 13d91e109a..fc82cbd5f1 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -1509,6 +1509,7 @@ static void ahci_cmd_done(IDEDMA *dma)
>  
>  static void ahci_irq_set(void *opaque, int n, int level)
>  {
> +qemu_log_mask(LOG_UNIMP, "ahci: IRQ#%d level:%d\n", n, level);
>  }
>  
>  static const IDEDMAOps ahci_dma_ops = {
> 

Reviewed-by: John Snow 

Sorry, just drowning in backlog. Thanks for the ping on IRC.

Acked-by: John Snow 

^ Feel free to take through trivial tree.

--js




Re: [PATCH] hw/ide: Make IDEDMAOps handlers take a const IDEDMA pointer

2020-05-14 Thread John Snow



On 5/12/20 3:49 PM, Philippe Mathieu-Daudé wrote:
> Handlers don't need to modify the IDEDMA structure.
> Make it const.
> 
> Signed-off-by: Philippe Mathieu-Daudé 

I'll trust your judgment. As long as it still compiles and passes
qtests, I'm happy if you're happy.

Acked-by: John Snow 

> ---
>  include/hw/ide/internal.h | 12 ++--
>  hw/ide/ahci.c | 18 +-
>  hw/ide/core.c |  6 +++---
>  hw/ide/macio.c|  6 +++---
>  hw/ide/pci.c  | 12 ++--
>  5 files changed, 27 insertions(+), 27 deletions(-)
> 
> diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
> index 55da35d768..1a7869e85d 100644
> --- a/include/hw/ide/internal.h
> +++ b/include/hw/ide/internal.h
> @@ -322,12 +322,12 @@ typedef enum { IDE_HD, IDE_CD, IDE_CFATA } IDEDriveKind;
>  
>  typedef void EndTransferFunc(IDEState *);
>  
> -typedef void DMAStartFunc(IDEDMA *, IDEState *, BlockCompletionFunc *);
> -typedef void DMAVoidFunc(IDEDMA *);
> -typedef int DMAIntFunc(IDEDMA *, bool);
> -typedef int32_t DMAInt32Func(IDEDMA *, int32_t len);
> -typedef void DMAu32Func(IDEDMA *, uint32_t);
> -typedef void DMAStopFunc(IDEDMA *, bool);
> +typedef void DMAStartFunc(const IDEDMA *, IDEState *, BlockCompletionFunc *);
> +typedef void DMAVoidFunc(const IDEDMA *);
> +typedef int DMAIntFunc(const IDEDMA *, bool);
> +typedef int32_t DMAInt32Func(const IDEDMA *, int32_t len);
> +typedef void DMAu32Func(const IDEDMA *, uint32_t);
> +typedef void DMAStopFunc(const IDEDMA *, bool);
>  
>  struct unreported_events {
>  bool eject_request;
> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index 13d91e109a..168d34e9f2 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -44,7 +44,7 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot);
>  static void ahci_reset_port(AHCIState *s, int port);
>  static bool ahci_write_fis_d2h(AHCIDevice *ad);
>  static void ahci_init_d2h(AHCIDevice *ad);
> -static int ahci_dma_prepare_buf(IDEDMA *dma, int32_t limit);
> +static int ahci_dma_prepare_buf(const IDEDMA *dma, int32_t limit);
>  static bool ahci_map_clb_address(AHCIDevice *ad);
>  static bool ahci_map_fis_address(AHCIDevice *ad);
>  static void ahci_unmap_clb_address(AHCIDevice *ad);
> @@ -1338,7 +1338,7 @@ out:
>  }
>  
>  /* Transfer PIO data between RAM and device */
> -static void ahci_pio_transfer(IDEDMA *dma)
> +static void ahci_pio_transfer(const IDEDMA *dma)
>  {
>  AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
>  IDEState *s = >port.ifs[0];
> @@ -1397,7 +1397,7 @@ out:
>  }
>  }
>  
> -static void ahci_start_dma(IDEDMA *dma, IDEState *s,
> +static void ahci_start_dma(const IDEDMA *dma, IDEState *s,
> BlockCompletionFunc *dma_cb)
>  {
>  AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
> @@ -1406,7 +1406,7 @@ static void ahci_start_dma(IDEDMA *dma, IDEState *s,
>  dma_cb(s, 0);
>  }
>  
> -static void ahci_restart_dma(IDEDMA *dma)
> +static void ahci_restart_dma(const IDEDMA *dma)
>  {
>  /* Nothing to do, ahci_start_dma already resets s->io_buffer_offset.  */
>  }
> @@ -1415,7 +1415,7 @@ static void ahci_restart_dma(IDEDMA *dma)
>   * IDE/PIO restarts are handled by the core layer, but NCQ commands
>   * need an extra kick from the AHCI HBA.
>   */
> -static void ahci_restart(IDEDMA *dma)
> +static void ahci_restart(const IDEDMA *dma)
>  {
>  AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
>  int i;
> @@ -1432,7 +1432,7 @@ static void ahci_restart(IDEDMA *dma)
>   * Called in DMA and PIO R/W chains to read the PRDT.
>   * Not shared with NCQ pathways.
>   */
> -static int32_t ahci_dma_prepare_buf(IDEDMA *dma, int32_t limit)
> +static int32_t ahci_dma_prepare_buf(const IDEDMA *dma, int32_t limit)
>  {
>  AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
>  IDEState *s = >port.ifs[0];
> @@ -1453,7 +1453,7 @@ static int32_t ahci_dma_prepare_buf(IDEDMA *dma, 
> int32_t limit)
>   * Called via dma_buf_commit, for both DMA and PIO paths.
>   * sglist destruction is handled within dma_buf_commit.
>   */
> -static void ahci_commit_buf(IDEDMA *dma, uint32_t tx_bytes)
> +static void ahci_commit_buf(const IDEDMA *dma, uint32_t tx_bytes)
>  {
>  AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
>  
> @@ -1461,7 +1461,7 @@ static void ahci_commit_buf(IDEDMA *dma, uint32_t 
> tx_bytes)
>  ad->cur_cmd->status = cpu_to_le32(tx_bytes);
>  }
>  
> -static int ahci_dma_rw_buf(IDEDMA *dma, bool is_write)
> +static int ahci_dma_rw_buf(const IDEDMA *dma, bool is_write)
>  {
>  AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
>  IDEState *s = >port.ifs[0];
> @@ -1486,7 +1486,7 @@ static int ahci_dma_rw_buf(IDEDMA *dma, bool is_write)
>  return 1;
>  }
>  
> -static void ahci_cmd_done(IDEDMA *dma)
> +static void ahci_cmd_done(const IDEDMA *dma)
>  {
>  AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
>  
> diff --git a/hw/ide/core.c b/hw/ide/core.c
> index 689bb36409..d997a78e47 100644

[PATCH 3/3] iotests: Categorize NOTRUN messages as INFO, not WARNING

2020-05-14 Thread John Snow
It's not really a warning; we don't want to see it if we're not running
in at least a verbose mode. We can see it on the test summary just fine.

Signed-off-by: John Snow 
---
 tests/qemu-iotests/iotests.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 9231767acf..8e479e1c6f 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -986,7 +986,7 @@ def notrun(reason):
 seq = os.path.basename(sys.argv[0])
 
 open('%s/%s.notrun' % (output_dir, seq), 'w').write(reason + '\n')
-logger.warning("%s not run: %s", seq, reason)
+logger.info("%s not run: %s", seq, reason)
 sys.exit(0)
 
 def case_notrun(reason):
-- 
2.21.1




[PATCH 1/3] iotests: log messages from notrun()

2020-05-14 Thread John Snow
Shift the logging initialization up to occur prior to validation checks,
so that notrun() messages still get printed to console.

(Also, remove the "debugging messages active" message, because we don't
need to see that hundreds of times per iotest suite run.)

Signed-off-by: John Snow 
---
 tests/qemu-iotests/iotests.py | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 6c0e781af7..1caa7812de 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -1168,18 +1168,17 @@ def execute_setup_common(supported_fmts: Sequence[str] 
= (),
 sys.stderr.write('Please run this test via the "check" script\n')
 sys.exit(os.EX_USAGE)
 
+debug = '-d' in sys.argv
+if debug:
+sys.argv.remove('-d')
+logging.basicConfig(level=(logging.DEBUG if debug else logging.WARN))
+
 _verify_image_format(supported_fmts, unsupported_fmts)
 _verify_protocol(supported_protocols, unsupported_protocols)
 _verify_platform(supported=supported_platforms)
 _verify_cache_mode(supported_cache_modes)
 _verify_aio_mode(supported_aio_modes)
 
-debug = '-d' in sys.argv
-if debug:
-sys.argv.remove('-d')
-logging.basicConfig(level=(logging.DEBUG if debug else logging.WARN))
-logger.debug("iotests debugging messages active")
-
 return debug
 
 def execute_test(*args, test_function=None, **kwargs):
-- 
2.21.1




[PATCH 2/3] iotests: log to stderr instead of stdout

2020-05-14 Thread John Snow
Separate the streams; stdout is for test diff output, stderr is for
control messages and things for the human to look at.

(Cough, unfortunately, I didn't realize that ./check actually just
always redirects both, so even on STDERR, you can't see warnings.
Oh well...)

Signed-off-by: John Snow 
---
 tests/qemu-iotests/iotests.py | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 1caa7812de..9231767acf 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -1171,7 +1171,11 @@ def execute_setup_common(supported_fmts: Sequence[str] = 
(),
 debug = '-d' in sys.argv
 if debug:
 sys.argv.remove('-d')
-logging.basicConfig(level=(logging.DEBUG if debug else logging.WARN))
+
+logging.basicConfig(
+level=logging.DEBUG if debug else logging.WARN,
+stream=sys.stderr,
+)
 
 _verify_image_format(supported_fmts, unsupported_fmts)
 _verify_protocol(supported_protocols, unsupported_protocols)
-- 
2.21.1




[PATCH 0/3] iotests: enable logging prior to notrun() invocation

2020-05-14 Thread John Snow
Hi, you can take just patch 1. patches 2-3 admittedly don't do a whole
heck of a lot, because I didn't realize that ./check discards *all*
output from either stdout or stderr.

The changes are tiny, though, and maybe still worth doing in the long
run? Hm. They are archived on the list now, anyway.

--js

John Snow (3):
  iotests: log messages from notrun()
  iotests: log to stderr instead of stdout
  iotests: Categorize NOTRUN messages as INFO, not WARNING

 tests/qemu-iotests/iotests.py | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

-- 
2.21.1




[PATCH] es1370: check total frame count against current frame

2020-05-14 Thread P J P
From: Prasad J Pandit 

A guest user may set channel frame count via es1370_write()
such that, in es1370_transfer_audio(), total frame count
'size' is lesser than the number of frames that are processed
'cnt'.

int cnt = d->frame_cnt >> 16;
int size = d->frame_cnt & 0x;

if (size < cnt), it results in incorrect calculations leading
to OOB access issue(s). Add check to avoid it.

Reported-by: Ren Ding 
Reported-by: Hanqing Zhao 
Signed-off-by: Prasad J Pandit 
---
 hw/audio/es1370.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c
index 89c4dabcd4..5f8a83ff56 100644
--- a/hw/audio/es1370.c
+++ b/hw/audio/es1370.c
@@ -643,6 +643,9 @@ static void es1370_transfer_audio (ES1370State *s, struct 
chan *d, int loop_sel,
 int csc_bytes = (csc + 1) << d->shift;
 int cnt = d->frame_cnt >> 16;
 int size = d->frame_cnt & 0x;
+if (size < cnt) {
+return;
+}
 int left = ((size - cnt + 1) << 2) + d->leftover;
 int transferred = 0;
 int temp = MIN (max, MIN (left, csc_bytes));
@@ -651,7 +654,7 @@ static void es1370_transfer_audio (ES1370State *s, struct 
chan *d, int loop_sel,
 addr += (cnt << 2) + d->leftover;
 
 if (index == ADC_CHANNEL) {
-while (temp) {
+while (temp > 0) {
 int acquired, to_copy;
 
 to_copy = MIN ((size_t) temp, sizeof (tmpbuf));
@@ -669,7 +672,7 @@ static void es1370_transfer_audio (ES1370State *s, struct 
chan *d, int loop_sel,
 else {
 SWVoiceOut *voice = s->dac_voice[index];
 
-while (temp) {
+while (temp > 0) {
 int copied, to_copy;
 
 to_copy = MIN ((size_t) temp, sizeof (tmpbuf));
-- 
2.25.4




Re: [PATCH v10 14/14] iotests: use python logging for iotests.log()

2020-05-14 Thread John Snow



On 5/14/20 6:06 AM, Kevin Wolf wrote:
> Am 14.05.2020 um 08:24 hat John Snow geschrieben:
>> On 3/31/20 9:44 AM, Kevin Wolf wrote:
>>> Am 31.03.2020 um 02:00 hat John Snow geschrieben:
 We can turn logging on/off globally instead of per-function.

 Remove use_log from run_job, and use python logging to turn on
 diffable output when we run through a script entry point.

 iotest 245 changes output order due to buffering reasons.


 An extended note on python logging:

 A NullHandler is added to `qemu.iotests` to stop output from being
 generated if this code is used as a library without configuring logging.
 A NullHandler is only needed at the root, so a duplicate handler is not
 needed for `qemu.iotests.diff_io`.

 When logging is not configured, messages at the 'WARNING' levels or
 above are printed with default settings. The NullHandler stops this from
 occurring, which is considered good hygiene for code used as a library.

 See https://docs.python.org/3/howto/logging.html#library-config

 When logging is actually enabled (always at the behest of an explicit
 call by a client script), a root logger is implicitly created at the
 root, which allows messages to propagate upwards and be handled/emitted
 from the root logger with default settings.

 When we want iotest logging, we attach a handler to the
 qemu.iotests.diff_io logger and disable propagation to avoid possible
 double-printing.

 For more information on python logging infrastructure, I highly
 recommend downloading the pip package `logging_tree`, which provides
 convenient visualizations of the hierarchical logging configuration
 under different circumstances.

 See https://pypi.org/project/logging_tree/ for more information.

 Signed-off-by: John Snow 
 Reviewed-by: Max Reitz 
>>>
>>> Should we enable logger if -d is given?
>>>
>>> Previously we had:
>>>
>>> $ ./check -d -T -raw 281
>>> [...]
>>> 281 not run: not suitable for this image format: raw
>>> 281  not run[15:39:03] [15:39:04]not suitable 
>>> for this image format: raw
>>> Not run: 281
>>>
>>> After this series, the first line of output from notrun() is missing.
>>> Not that I think it's important to have the line, but as long as we
>>> bother to call logger.warning(), I thought that maybe we want to be able
>>> to actually see the effect of it somehwere?
>>>
>>> Kevin
>>>
>>
>> Uh, okay. So this is weirder than I thought it was going to be!
>>
>> So, if you move the debug configuration up above the _verify calls,
>> you'll see the message printed out to the debug stream:
>>
>> DEBUG:qemu.iotests:iotests debugging messages active
>> WARNING:qemu.iotests:281 not run: not suitable for this image format: raw
>>
>> ...but if you omit the `-d` flag, the message vanishes into a black
>> hole. Did it always work like that ...?
> 
> Yes, this is how it used to work. It's a result of ./check only printing
> the test output with -d, and such log messages are basically just test
> output.
> 
> And I think it's exactly what we want: Without -d, you want only the
> summary, i.e. a single line that says "pass", "fail" or "notrun",
> potentially with a small note at the end of the line, but that's it.
> 

OK, maybe. So I guess what happens here is that if you don't use -d, the
output gets redirected to file, and that file is summarily deleted.

Your phrase "but as long as we bother to call logger.warning(), I
thought that maybe we want to be able to actually see the effect of it
somewhere" stuck with me -- I think you're right.

I kind of do expect that if I call a function called warning() that it's
gonna do some damage. principle of least surprise, etc.

So two things:

(1) Maybe the iotest logger ought to always use stderr, and we should
see any calls to warning() or error() even when debugging is off.

(2) These skip notifications are not warnings, they are informational
and can be disabled when `-d` is omitted. (Especially because they are
represented through another channel.)

--js


(I'll send the fixup for the simpler thing first, and you can take or
leave the second thing.)




[PATCH v4 0/2] Makefile: libfdt: build only the strict necessary

2020-05-14 Thread Claudio Fontana
v3 -> v4: NB! only useful when updating to latest dtc (not in QEMU yet)

* changed the approach to leverage new upstream dtc Makefile,
  needs dtc submodule update to include upstream dtc commit
  85e5d839847af54efab170f2b1331b2a6421e647.

* LIBFDT_srcdir does not exist anymore in upstream dtc: it is also
  not used anymore.

* LIBFDT_lib: need to avoid building libfdt.so at least for now, so pass as
  empty to avoid building the .so. This is to avoid breaking existing
  trees with objects already compiled without -fPIC.

* clean: no need to make dtc clean target, every artifact is captured by
  global clean rule

v2 -> v3:

* changed into a 2 patch series; in the second patch we remove the old
  compatibility gunks that were meant for removal some time after 4.1.

* renamed the libfdt PHONY rule to dtc/all, with the intent to make
  existing working trees forward and backward compatible across the change.

v1 -> v2:

* fix error generated when running UNCHECKED_GOALS without prior configure,
  for example during make docker-image-fedora. Without configure, DSOSUF is
  empty, and the module pattern rule in rules.mak that uses this variable
  can match too much; provide a default in the Makefile to avoid it.

* only attempt to build the archive when there is a non-empty list of objects.
  This could be done in general for the %.a: pattern in rules.mak, but maybe
  there are valid reasons to build an empty .a?

* removed some intermediate variables that did not add much value
  (LIBFDT_srcdir, LIBFDT_archive)

Tested locally with 3 VPATH configurations (no-, VPATH, VPATH in src subdir),
and with docker-image-fedora, docker-test-debug@fedora that failed before.

Claudio Fontana (2):
  Makefile: libfdt: build only the strict necessary
  Makefile: remove old compatibility gunks

 Makefile  | 32 
 configure |  6 +-
 rules.mak |  2 ++
 3 files changed, 19 insertions(+), 21 deletions(-)

-- 
2.16.4




[PATCH v4 1/2] Makefile: dtc: build the libfdt target

2020-05-14 Thread Claudio Fontana
call the libfdt target from the dtc Makefile, which has been
changed to not require bison, flex, etc.

scripts/ symlink and tests directory creation are not necessary,
and neither is calling the clean rule explicitly.

Signed-off-by: Claudio Fontana 
---
 Makefile  | 10 +-
 configure |  1 -
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/Makefile b/Makefile
index 34275f57c9..36a6454295 100644
--- a/Makefile
+++ b/Makefile
@@ -526,13 +526,14 @@ $(SOFTMMU_FUZZ_RULES): $(edk2-decompressed)
 $(TARGET_DIRS_RULES):
$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $(dir $@) V="$(V)" 
TARGET_DIR="$(dir $@)" $(notdir $@),)
 
-DTC_MAKE_ARGS=-I$(SRC_PATH)/dtc VPATH=$(SRC_PATH)/dtc -C dtc V="$(V)" 
LIBFDT_srcdir=$(SRC_PATH)/dtc/libfdt
+# LIBFDT_lib="": avoid breaking existing trees with objects requiring -fPIC
+DTC_MAKE_ARGS=-I$(SRC_PATH)/dtc VPATH=$(SRC_PATH)/dtc -C dtc V="$(V)" 
LIBFDT_lib=""
 DTC_CFLAGS=$(CFLAGS) $(QEMU_CFLAGS)
-DTC_CPPFLAGS=-I$(BUILD_DIR)/dtc -I$(SRC_PATH)/dtc -I$(SRC_PATH)/dtc/libfdt
+DTC_CPPFLAGS=-I$(SRC_PATH)/dtc/libfdt
 
 .PHONY: dtc/all
-dtc/all: .git-submodule-status dtc/libfdt dtc/tests
-   $(call quiet-command,$(MAKE) $(DTC_MAKE_ARGS) 
CPPFLAGS="$(DTC_CPPFLAGS)" CFLAGS="$(DTC_CFLAGS)" LDFLAGS="$(QEMU_LDFLAGS)" 
ARFLAGS="$(ARFLAGS)" CC="$(CC)" AR="$(AR)" LD="$(LD)" $(SUBDIR_MAKEFLAGS) 
libfdt/libfdt.a,)
+dtc/all: .git-submodule-status dtc/libfdt
+   $(call quiet-command,$(MAKE) $(DTC_MAKE_ARGS) 
CPPFLAGS="$(DTC_CPPFLAGS)" CFLAGS="$(DTC_CFLAGS)" LDFLAGS="$(QEMU_LDFLAGS)" 
ARFLAGS="$(ARFLAGS)" CC="$(CC)" AR="$(AR)" LD="$(LD)" $(SUBDIR_MAKEFLAGS) 
libfdt,)
 
 dtc/%: .git-submodule-status
@mkdir -p $@
@@ -820,7 +821,6 @@ distclean: clean
rm -rf $$d || exit 1 ; \
 done
rm -Rf .sdk
-   if test -f dtc/version_gen.h; then $(MAKE) $(DTC_MAKE_ARGS) clean; fi
 
 KEYMAPS=da en-gb  et  fr fr-ch  is  lt  no  pt-br  sv \
 ar  de en-us  fi  fr-be  hr it  lv  nl pl  ru th \
diff --git a/configure b/configure
index 0d69c360c0..42554792ec 100755
--- a/configure
+++ b/configure
@@ -4281,7 +4281,6 @@ EOF
   mkdir -p dtc
   if [ "$pwd_is_source_path" != "y" ] ; then
   symlink "$source_path/dtc/Makefile" "dtc/Makefile"
-  symlink "$source_path/dtc/scripts" "dtc/scripts"
   fi
   fdt_cflags="-I\$(SRC_PATH)/dtc/libfdt"
   fdt_ldflags="-L\$(BUILD_DIR)/dtc/libfdt"
-- 
2.16.4




[PATCH v4 2/2] Makefile: remove old compatibility gunks

2020-05-14 Thread Claudio Fontana
Signed-off-by: Claudio Fontana 
Reviewed-by: Markus Armbruster 
Reviewed-by: Philippe Mathieu-Daudé 
---
 Makefile | 6 --
 1 file changed, 6 deletions(-)

diff --git a/Makefile b/Makefile
index 36a6454295..2873d59ea2 100644
--- a/Makefile
+++ b/Makefile
@@ -562,12 +562,6 @@ slirp/all: .git-submodule-status
CC="$(CC)" AR="$(AR)"   LD="$(LD)" RANLIB="$(RANLIB)"   \
CFLAGS="$(QEMU_CFLAGS) $(CFLAGS)" LDFLAGS="$(QEMU_LDFLAGS)")
 
-# Compatibility gunk to keep make working across the rename of targets
-# for recursion, to be removed some time after 4.1.
-subdir-dtc: dtc/all
-subdir-capstone: capstone/all
-subdir-slirp: slirp/all
-
 $(filter %/all, $(TARGET_DIRS_RULES)): libqemuutil.a $(common-obj-y) \
$(qom-obj-y)
 
-- 
2.16.4




Re: [PATCH v4 3/3] iotests: modify test 040 to use JobRunner

2020-05-14 Thread John Snow



On 5/14/20 11:53 AM, Kevin Wolf wrote:
> Am 14.05.2020 um 04:25 hat John Snow geschrieben:
>> Instead of having somewhat reproduced it for itself.
>>
>> Signed-off-by: John Snow 
> 
> I think you should pass auto_dismiss=True to the JobRunner, or (probably
> preferable) change prepare_and_start_job() to start the job with
> auto_dismiss=False.
> 
> Kevin
> 

okay, I'll try that out and see if I like it.


Wild tangents, as is my normal:

I also think it would be neat, in some sense, to provide a job creation
abstraction where creating the QMP command in python also creates the
runner with the right parameters based on how you initialized it.

I've not given these even a proper three minutes think, but some
generalized interface for managing the creation of jobs to use in
concert with the job runner would be slick.

(What reminds me of this is needing to remember and understand if I
started something with auto_dismiss or not, which jobs it defaults to
which for, etc. Streamlining the creation and runner could be slick for
faster test-writing in normative cases.)




Re: [PATCH for-5.1 V3 2/7] hw/mips: Implement the kvm_type() hook in MachineClass

2020-05-14 Thread Aleksandar Markovic
нед, 3. мај 2020. у 12:24 Huacai Chen  је написао/ла:
>
> MIPS has two types of KVM: TE & VZ, and TE is the default type. Now we
> can't create a VZ guest in QEMU because it lacks the kvm_type() hook in
> MachineClass. Besides, libvirt uses a null-machine to detect the kvm
> capability, so by default it will return "KVM not supported" on a VZ
> platform. Thus, null-machine also need the kvm_type() hook.
>
> Signed-off-by: Huacai Chen 
> Co-developed-by: Jiaxun Yang 
> ---

Reviewed-by: Aleksandar Markovic 

>  hw/core/Makefile.objs  |  2 +-
>  hw/core/null-machine.c |  4 
>  hw/mips/Makefile.objs  |  2 +-
>  hw/mips/common.c   | 31 +++
>  include/hw/mips/mips.h |  3 +++
>  5 files changed, 40 insertions(+), 2 deletions(-)
>  create mode 100644 hw/mips/common.c
>
> diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
> index 1d540ed..b5672f4 100644
> --- a/hw/core/Makefile.objs
> +++ b/hw/core/Makefile.objs
> @@ -17,11 +17,11 @@ common-obj-$(CONFIG_SOFTMMU) += vm-change-state-handler.o
>  common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
>  common-obj-$(CONFIG_SOFTMMU) += sysbus.o
>  common-obj-$(CONFIG_SOFTMMU) += machine.o
> -common-obj-$(CONFIG_SOFTMMU) += null-machine.o
>  common-obj-$(CONFIG_SOFTMMU) += loader.o
>  common-obj-$(CONFIG_SOFTMMU) += machine-hmp-cmds.o
>  common-obj-$(CONFIG_SOFTMMU) += numa.o
>  common-obj-$(CONFIG_SOFTMMU) += clock-vmstate.o
> +obj-$(CONFIG_SOFTMMU) += null-machine.o
>  obj-$(CONFIG_SOFTMMU) += machine-qmp-cmds.o
>
>  common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
> diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c
> index cb47d9d..94a36f9 100644
> --- a/hw/core/null-machine.c
> +++ b/hw/core/null-machine.c
> @@ -17,6 +17,7 @@
>  #include "sysemu/sysemu.h"
>  #include "exec/address-spaces.h"
>  #include "hw/core/cpu.h"
> +#include "hw/mips/mips.h"
>
>  static void machine_none_init(MachineState *mch)
>  {
> @@ -50,6 +51,9 @@ static void machine_none_machine_init(MachineClass *mc)
>  mc->max_cpus = 1;
>  mc->default_ram_size = 0;
>  mc->default_ram_id = "ram";
> +#ifdef TARGET_MIPS
> +mc->kvm_type = mips_kvm_type;
> +#endif
>  }
>
>  DEFINE_MACHINE("none", machine_none_machine_init)
> diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs
> index 525809a..2f7795b 100644
> --- a/hw/mips/Makefile.objs
> +++ b/hw/mips/Makefile.objs
> @@ -1,4 +1,4 @@
> -obj-y += addr.o mips_int.o
> +obj-y += addr.o common.o mips_int.o
>  obj-$(CONFIG_R4K) += mips_r4k.o
>  obj-$(CONFIG_MALTA) += gt64xxx_pci.o mips_malta.o
>  obj-$(CONFIG_MIPSSIM) += mips_mipssim.o
> diff --git a/hw/mips/common.c b/hw/mips/common.c
> new file mode 100644
> index 000..0e33bd0
> --- /dev/null
> +++ b/hw/mips/common.c
> @@ -0,0 +1,31 @@
> +/*
> + * Common MIPS routines
> + *
> + * Copyright (c) 2020 Huacai Chen (che...@lemote.com)
> + * This code is licensed under the GNU GPL v2.
> + */
> +
> +#include 
> +#include "qemu/osdep.h"
> +#include "qemu-common.h"
> +#include "hw/boards.h"
> +#include "hw/mips/mips.h"
> +#include "sysemu/kvm_int.h"
> +
> +int mips_kvm_type(MachineState *machine, const char *vm_type)
> +{
> +int r;
> +KVMState *s = KVM_STATE(machine->accelerator);
> +
> +r = kvm_check_extension(s, KVM_CAP_MIPS_VZ);
> +if (r > 0) {
> +return KVM_VM_MIPS_VZ;
> +}
> +
> +r = kvm_check_extension(s, KVM_CAP_MIPS_TE);
> +if (r > 0) {
> +return KVM_VM_MIPS_TE;
> +}
> +
> +return -1;
> +}
> diff --git a/include/hw/mips/mips.h b/include/hw/mips/mips.h
> index 0af4c3d..2ac0580 100644
> --- a/include/hw/mips/mips.h
> +++ b/include/hw/mips/mips.h
> @@ -20,4 +20,7 @@ void rc4030_dma_write(void *dma, uint8_t *buf, int len);
>
>  DeviceState *rc4030_init(rc4030_dma **dmas, IOMMUMemoryRegion **dma_mr);
>
> +/* common.c */
> +int mips_kvm_type(MachineState *machine, const char *vm_type);
> +
>  #endif
> --
> 2.7.0
>



Re: [PATCH v4 2/3] iotests: add JobRunner class

2020-05-14 Thread John Snow



On 5/14/20 11:40 AM, Kevin Wolf wrote:
> Am 14.05.2020 um 04:25 hat John Snow geschrieben:
>> The idea is that instead of increasing the arguments to job_run all the
>> time, create a more general-purpose job runner that can be subclassed to
>> do interesting things with.
>>
>> pylint note: the 'callbacks' option guards against unused warning
>> arguments in functions designated as callbacks. It does not currently
>> guard against "no-self-use" though; hence a once-off ignore.
>>
>> mypy note: QapiEvent is only a weak alias; it's fully interchangable
>> with the type it's declared as. In the future, we may wish to tighten
>> these types. For now, this communicates the rough shape of the type and
>> (more importantly) the intent.
>>
>> Signed-off-by: John Snow 
> 
>> +# Listen for these events with these parameters:
>> +self._events = {
>> +'BLOCK_JOB_COMPLETED': match_device,
>> +'BLOCK_JOB_CANCELLED': match_device,
>> +'BLOCK_JOB_ERROR': match_device,
>> +'BLOCK_JOB_READY': match_device,
>> +'BLOCK_JOB_PENDING': match_id,
>> +'JOB_STATUS_CHANGE': match_id
>> +}
> 
> The old code had a trailing comma here in case we need to add more
> events later. Anyway:
> 
> Reviewed-by: Kevin Wolf 
> 

Whoops. I favor those too, so I'll put it back.




[PATCH v2 12/17] target/mips: fpu: Remove now unused FLOAT_CLASS macro

2020-05-14 Thread Aleksandar Markovic
After demacroing CLASS., this macro is not needed anymore.

Signed-off-by: Aleksandar Markovic 
---
 target/mips/fpu_helper.c | 39 ---
 1 file changed, 39 deletions(-)

diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index b3903f5357..e227e53f70 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -1128,45 +1128,6 @@ FLOAT_RINT(rint_d, 64)
 #define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100
 #define FLOAT_CLASS_POSITIVE_ZERO  0x200
 
-#define FLOAT_CLASS(name, bits)  \
-uint ## bits ## _t float_ ## name(uint ## bits ## _t arg,\
-  float_status *status)  \
-{\
-if (float ## bits ## _is_signaling_nan(arg, status)) {   \
-return FLOAT_CLASS_SIGNALING_NAN;\
-} else if (float ## bits ## _is_quiet_nan(arg, status)) {\
-return FLOAT_CLASS_QUIET_NAN;\
-} else if (float ## bits ## _is_neg(arg)) {  \
-if (float ## bits ## _is_infinity(arg)) {\
-return FLOAT_CLASS_NEGATIVE_INFINITY;\
-} else if (float ## bits ## _is_zero(arg)) { \
-return FLOAT_CLASS_NEGATIVE_ZERO;\
-} else if (float ## bits ## _is_zero_or_denormal(arg)) { \
-return FLOAT_CLASS_NEGATIVE_SUBNORMAL;   \
-} else { \
-return FLOAT_CLASS_NEGATIVE_NORMAL;  \
-}\
-} else { \
-if (float ## bits ## _is_infinity(arg)) {\
-return FLOAT_CLASS_POSITIVE_INFINITY;\
-} else if (float ## bits ## _is_zero(arg)) { \
-return FLOAT_CLASS_POSITIVE_ZERO;\
-} else if (float ## bits ## _is_zero_or_denormal(arg)) { \
-return FLOAT_CLASS_POSITIVE_SUBNORMAL;   \
-} else { \
-return FLOAT_CLASS_POSITIVE_NORMAL;  \
-}\
-}\
-}\
- \
-uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env,  \
- uint ## bits ## _t arg) \
-{\
-return float_ ## name(arg, >active_fpu.fp_status);  \
-}
-
-#undef FLOAT_CLASS
-
 uint64_t float_class_d(uint64_t arg, float_status *status)
 {
 if (float64_is_signaling_nan(arg, status)) {
-- 
2.20.1




Re: [PATCH v4 1/3] qmp.py: change event_wait to use a dict

2020-05-14 Thread John Snow



On 5/14/20 11:59 AM, Kevin Wolf wrote:
> Am 14.05.2020 um 17:07 hat John Snow geschrieben:
>>
>>
>> On 5/14/20 10:47 AM, Kevin Wolf wrote:
>>> Am 14.05.2020 um 04:25 hat John Snow geschrieben:
 It's easier to work with than a list of tuples, because we can check the
 keys for membership.

 Signed-off-by: John Snow 
 ---
  python/qemu/machine.py| 10 +-
  tests/qemu-iotests/040| 12 ++--
  tests/qemu-iotests/260|  5 +++--
  tests/qemu-iotests/iotests.py | 16 
  4 files changed, 22 insertions(+), 21 deletions(-)
>>>
>>> I think you need to convert scripts/simplebench/bench_block_job.py, too.
>>
>> Oh, right -- that one is new since I did this. A lot of these scripts
>> need to be moved over into the python/ directory and managed under the
>> same pylint/mypy regime as everything else.
>>
>> A *ton* of our scripts are in various states of disrepair.
> 
> Is python/ actually supposed to have executable files in it? I thought
> it was more for libraries.
> 

Welll. At the moment it's library only. but one of the
things you can do with a library is define executable entry-points into
that library.

If you haven't cast an eye at that 32 patch series yet, it basically
creates a structure like this:

> ./python/qemu/lib/[qmp|machine|qtest|accel].py

qemu/ forms a PEP420 namespace; the idea is to be able to modularly
create and independently package subpackages.

qemu/lib forms a proper python package in which there are no
executables, just a library, as you say.

My idea is that anything under python/*/ ought to form a properly
formatted package. So we could, for instance, have a
python/qemu/devtools namespace which packages and collects a bunch of
our little scripts.

Then we could make sure we hit them with the same
mypy/pylint/flake8/whatever as the core libraries those scripts are
using to keep them in sync better.

And, ideally, if they are all using the same kind of paradigms for
import and dependency management it will be easier to use them and keep
them up to date, etc.

For using them as a developer, you could, say,
cd  ~/src/qemu/python
pip3 install --user -e .

and install the source packages to your local environment and then have
access to e.g.

> qmp-shell

right on your CLI, without having to fuss with PYTHONPATH or anything
else. As you update the source repo, you'll get the new versions of the
package living in your python environment automatically.

Of course, this maybe has downsides too; so you can always use a virtual
environment to adopt a context in which you have these tools. For that,

> pip3 install --user pipenv  # or use dnf, or apt, w/e.
> cd ~/src/qemu/python
> pipenv shell
> pip install -e .

And from here you'll have the dev package installed to a development
venv that you can use.

*cough* anyway, that's wildly off-topic.

Generally, you want to format a library such that you have a callable
entry point, maybe named main(). So you'd have some qmp-shell module and
it has a main() function.

Then, in the setup.py script, you'd define qemu.lib.qmp_shell:main() as
an entry point and give it a name like 'qmp-shell'. When pip/setuptools
processes your package installation, it'll create a shim for you in e.g.
~/.local/bin/qmp-shell that will just load the library and execute that
entrypoint for you.

I was thinking I'd do this for all of our python scripts so I could
spend my energy on a pylint/mypy test infrastructure *once* and *in one
place* and then it would be easier to detect regressions for scripts
that don't actually run as part of the test suite.

>>>
 diff --git a/python/qemu/machine.py b/python/qemu/machine.py
 index b9a98e2c86..eaedc25172 100644
 --- a/python/qemu/machine.py
 +++ b/python/qemu/machine.py
 @@ -478,21 +478,21 @@ def event_wait(self, name, timeout=60.0, match=None):
  timeout: QEMUMonitorProtocol.pull_event timeout parameter.
  match: Optional match criteria. See event_match for details.
  """
 -return self.events_wait([(name, match)], timeout)
 +return self.events_wait({name: match}, timeout)
  
  def events_wait(self, events, timeout=60.0):
  """
  events_wait waits for and returns a named event from QMP with a 
 timeout.
  
 -events: a sequence of (name, match_criteria) tuples.
 +events: a mapping containing {name: match_criteria}.
  The match criteria are optional and may be None.
  See event_match for details.  timeout:
  QEMUMonitorProtocol.pull_event timeout parameter.
  """
  def _match(event):
 -for name, match in events:
 -if event['event'] == name and self.event_match(event, 
 match):
 -return True
 +name = event['event']
 +

[PATCH v2 10/17] target/mips: fpu: Remove now unused UNFUSED_FMA and FLOAT_FMA macros

2020-05-14 Thread Aleksandar Markovic
After demacroing ., these macros
are not needed anymore.

Signed-off-by: Aleksandar Markovic 
---
 target/mips/fpu_helper.c | 50 
 1 file changed, 50 deletions(-)

diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index 927bac24ac..e8e50e4bc0 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -1446,56 +1446,6 @@ FLOAT_MINMAX(mina_d, 64, minnummag)
 #undef FLOAT_MINMAX
 
 /* ternary operations */
-#define UNFUSED_FMA(prefix, a, b, c, flags)  \
-{\
-a = prefix##_mul(a, b, >active_fpu.fp_status);  \
-if ((flags) & float_muladd_negate_c) {   \
-a = prefix##_sub(a, c, >active_fpu.fp_status);  \
-} else { \
-a = prefix##_add(a, c, >active_fpu.fp_status);  \
-}\
-if ((flags) & float_muladd_negate_result) {  \
-a = prefix##_chs(a); \
-}\
-}
-
-/* FMA based operations */
-#define FLOAT_FMA(name, type)\
-uint64_t helper_float_ ## name ## _d(CPUMIPSState *env,  \
- uint64_t fdt0, uint64_t fdt1,   \
- uint64_t fdt2)  \
-{\
-UNFUSED_FMA(float64, fdt0, fdt1, fdt2, type);\
-update_fcr31(env, GETPC());  \
-return fdt0; \
-}\
- \
-uint32_t helper_float_ ## name ## _s(CPUMIPSState *env,  \
- uint32_t fst0, uint32_t fst1,   \
- uint32_t fst2)  \
-{\
-UNFUSED_FMA(float32, fst0, fst1, fst2, type);\
-update_fcr31(env, GETPC());  \
-return fst0; \
-}\
- \
-uint64_t helper_float_ ## name ## _ps(CPUMIPSState *env, \
-  uint64_t fdt0, uint64_t fdt1,  \
-  uint64_t fdt2) \
-{\
-uint32_t fst0 = fdt0 & 0X;   \
-uint32_t fsth0 = fdt0 >> 32; \
-uint32_t fst1 = fdt1 & 0X;   \
-uint32_t fsth1 = fdt1 >> 32; \
-uint32_t fst2 = fdt2 & 0X;   \
-uint32_t fsth2 = fdt2 >> 32; \
- \
-UNFUSED_FMA(float32, fst0, fst1, fst2, type);\
-UNFUSED_FMA(float32, fsth0, fsth1, fsth2, type); \
-update_fcr31(env, GETPC());  \
-return ((uint64_t)fsth0 << 32) | fst0;   \
-}
-#undef FLOAT_FMA
 
 uint64_t helper_float_madd_d(CPUMIPSState *env, uint64_t fst0,
  uint64_t fst1, uint64_t fst2)
-- 
2.20.1




[PATCH v2 16/17] target/mips: fpu: Refactor conversion from ieee to mips exception flags

2020-05-14 Thread Aleksandar Markovic
The original coversion function is used for regular and MSA floating
point instructions handling. Since there are some nuanced differences
between regular and MSA floatin point excetion handling, provide two
instances of the conversion function, rather than just a common one.
Inline both of these function instances for the sake of performance.
Improve variable naming in surrounding code for clarity.

Signed-off-by: Aleksandar Markovic 
---
 target/mips/fpu_helper.c | 55 +++-
 target/mips/internal.h   |  1 -
 target/mips/msa_helper.c | 77 +++-
 3 files changed, 82 insertions(+), 51 deletions(-)

diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index dbb8ca5692..7a3a61cab3 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -189,43 +189,48 @@ void helper_ctc1(CPUMIPSState *env, target_ulong arg1, 
uint32_t fs, uint32_t rt)
 }
 }
 
-int ieee_ex_to_mips(int xcpt)
+static inline int ieee_to_mips_xcpt(int ieee_xcpt)
 {
-int ret = 0;
-if (xcpt) {
-if (xcpt & float_flag_invalid) {
-ret |= FP_INVALID;
-}
-if (xcpt & float_flag_overflow) {
-ret |= FP_OVERFLOW;
-}
-if (xcpt & float_flag_underflow) {
-ret |= FP_UNDERFLOW;
-}
-if (xcpt & float_flag_divbyzero) {
-ret |= FP_DIV0;
-}
-if (xcpt & float_flag_inexact) {
-ret |= FP_INEXACT;
-}
+int mips_xcpt = 0;
+
+if (ieee_xcpt & float_flag_invalid) {
+mips_xcpt |= FP_INVALID;
+}
+if (ieee_xcpt & float_flag_overflow) {
+mips_xcpt |= FP_OVERFLOW;
 }
-return ret;
+if (ieee_xcpt & float_flag_underflow) {
+mips_xcpt |= FP_UNDERFLOW;
+}
+if (ieee_xcpt & float_flag_divbyzero) {
+mips_xcpt |= FP_DIV0;
+}
+if (ieee_xcpt & float_flag_inexact) {
+mips_xcpt |= FP_INEXACT;
+}
+
+return mips_xcpt;
 }
 
 static inline void update_fcr31(CPUMIPSState *env, uintptr_t pc)
 {
-int tmp = ieee_ex_to_mips(get_float_exception_flags(
-  >active_fpu.fp_status));
+int ieee_exception_flags = get_float_exception_flags(
+   >active_fpu.fp_status);
+int mips_exception_flags = 0;
+
+if (ieee_exception_flags) {
+mips_exception_flags = ieee_to_mips_xcpt(ieee_exception_flags);
+}
 
-SET_FP_CAUSE(env->active_fpu.fcr31, tmp);
+SET_FP_CAUSE(env->active_fpu.fcr31, mips_exception_flags);
 
-if (tmp) {
+if (mips_exception_flags)  {
 set_float_exception_flags(0, >active_fpu.fp_status);
 
-if (GET_FP_ENABLE(env->active_fpu.fcr31) & tmp) {
+if (GET_FP_ENABLE(env->active_fpu.fcr31) & mips_exception_flags) {
 do_raise_exception(env, EXCP_FPE, pc);
 } else {
-UPDATE_FP_FLAGS(env->active_fpu.fcr31, tmp);
+UPDATE_FP_FLAGS(env->active_fpu.fcr31, mips_exception_flags);
 }
 }
 }
diff --git a/target/mips/internal.h b/target/mips/internal.h
index 1bf274b3ef..684356e309 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -224,7 +224,6 @@ uint32_t float_class_s(uint32_t arg, float_status *fst);
 uint64_t float_class_d(uint64_t arg, float_status *fst);
 
 extern unsigned int ieee_rm[];
-int ieee_ex_to_mips(int xcpt);
 void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t *pagemask);
 
 static inline void restore_rounding_mode(CPUMIPSState *env)
diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c
index 4065cfe4f7..c520405929 100644
--- a/target/mips/msa_helper.c
+++ b/target/mips/msa_helper.c
@@ -5419,54 +5419,81 @@ static inline void check_msacsr_cause(CPUMIPSState 
*env, uintptr_t retaddr)
 #define CLEAR_IS_INEXACT   2
 #define RECIPROCAL_INEXACT 4
 
-static inline int update_msacsr(CPUMIPSState *env, int action, int denormal)
+
+static inline int ieee_to_mips_xcpt_msa(int ieee_xcpt)
 {
-int ieee_ex;
+int mips_xcpt = 0;
 
-int c;
+if (ieee_xcpt & float_flag_invalid) {
+mips_xcpt |= FP_INVALID;
+}
+if (ieee_xcpt & float_flag_overflow) {
+mips_xcpt |= FP_OVERFLOW;
+}
+if (ieee_xcpt & float_flag_underflow) {
+mips_xcpt |= FP_UNDERFLOW;
+}
+if (ieee_xcpt & float_flag_divbyzero) {
+mips_xcpt |= FP_DIV0;
+}
+if (ieee_xcpt & float_flag_inexact) {
+mips_xcpt |= FP_INEXACT;
+}
+
+return mips_xcpt;
+}
+
+static inline int update_msacsr(CPUMIPSState *env, int action, int denormal)
+{
+int ieee_exception_flags;
+int mips_exception_flags = 0;
 int cause;
 int enable;
 
-ieee_ex = get_float_exception_flags(>active_tc.msa_fp_status);
+ieee_exception_flags = get_float_exception_flags(
+   >active_tc.msa_fp_status);
 
 /* QEMU softfloat does not signal all underflow cases */
 if (denormal) {
-ieee_ex |= 

[PATCH v2 17/17] hw/mips: Convert Malta "ifdef 0"-ed code to comments

2020-05-14 Thread Aleksandar Markovic
The checkpatch complain about "#ifdef 0". Convert corresponding
dead code to comments. In future, these cases could be converted
to some no-nonsense logging/tracing.

Signed-off-by: Aleksandar Markovic 
CC: Philippe Mathieu-Daudé 
---
 hw/mips/mips_malta.c | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index e4c4de1b4e..f91fa34b06 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -427,10 +427,12 @@ static uint64_t malta_fpga_read(void *opaque, hwaddr addr,
 break;
 
 default:
-#if 0
-printf("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx "\n",
-   addr);
-#endif
+/*
+ * Possible logging:
+ *
+ *printf("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx "\n",
+ *   addr);
+ */
 break;
 }
 return val;
@@ -515,10 +517,12 @@ static void malta_fpga_write(void *opaque, hwaddr addr,
 break;
 
 default:
-#if 0
-printf("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx "\n",
-   addr);
-#endif
+/*
+ * Possible logging:
+ *
+ *printf("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx "\n",
+ *   addr);
+ */
 break;
 }
 }
-- 
2.20.1




[PATCH v2 09/17] target/mips: fpu: Demacro NMSUB.

2020-05-14 Thread Aleksandar Markovic
This is just a cosmetic change to enable tools like gcov, gdb,
callgrind, etc. to better display involved source code.

Signed-off-by: Aleksandar Markovic 
---
 target/mips/fpu_helper.c | 44 +++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index d4c065f281..927bac24ac 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -1495,7 +1495,6 @@ uint64_t helper_float_ ## name ## _ps(CPUMIPSState *env,  
   \
 update_fcr31(env, GETPC());  \
 return ((uint64_t)fsth0 << 32) | fst0;   \
 }
-FLOAT_FMA(nmsub, float_muladd_negate_result | float_muladd_negate_c)
 #undef FLOAT_FMA
 
 uint64_t helper_float_madd_d(CPUMIPSState *env, uint64_t fst0,
@@ -1619,6 +1618,49 @@ uint64_t helper_float_nmadd_ps(CPUMIPSState *env, 
uint64_t fdt0,
 return ((uint64_t)fsth0 << 32) | fstl0;
 }
 
+uint64_t helper_float_nmsub_d(CPUMIPSState *env, uint64_t fst0,
+ uint64_t fst1, uint64_t fst2)
+{
+fst0 = float64_mul(fst0, fst1, >active_fpu.fp_status);
+fst0 = float64_sub(fst0, fst2, >active_fpu.fp_status);
+fst0 = float64_chs(fst0);
+
+update_fcr31(env, GETPC());
+return fst0;
+}
+
+uint32_t helper_float_nmsub_s(CPUMIPSState *env, uint32_t fst0,
+ uint32_t fst1, uint32_t fst2)
+{
+fst0 = float32_mul(fst0, fst1, >active_fpu.fp_status);
+fst0 = float32_sub(fst0, fst2, >active_fpu.fp_status);
+fst0 = float32_chs(fst0);
+
+update_fcr31(env, GETPC());
+return fst0;
+}
+
+uint64_t helper_float_nmsub_ps(CPUMIPSState *env, uint64_t fdt0,
+  uint64_t fdt1, uint64_t fdt2)
+{
+uint32_t fstl0 = fdt0 & 0X;
+uint32_t fsth0 = fdt0 >> 32;
+uint32_t fstl1 = fdt1 & 0X;
+uint32_t fsth1 = fdt1 >> 32;
+uint32_t fstl2 = fdt2 & 0X;
+uint32_t fsth2 = fdt2 >> 32;
+
+fstl0 = float32_mul(fstl0, fstl1, >active_fpu.fp_status);
+fstl0 = float32_sub(fstl0, fstl2, >active_fpu.fp_status);
+fstl0 = float32_chs(fstl0);
+fsth0 = float32_mul(fsth0, fsth1, >active_fpu.fp_status);
+fsth0 = float32_sub(fsth0, fsth2, >active_fpu.fp_status);
+fsth0 = float32_chs(fsth0);
+
+update_fcr31(env, GETPC());
+return ((uint64_t)fsth0 << 32) | fstl0;
+}
+
 
 #define FLOAT_FMADDSUB(name, bits, muladd_arg)  \
 uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env, \
-- 
2.20.1




[PATCH v2 14/17] target/mips: fpu: Remove now unused FLOAT_RINT macro

2020-05-14 Thread Aleksandar Markovic
After demacroing RINT., this macro is not needed anymore.

Signed-off-by: Aleksandar Markovic 
---
 target/mips/fpu_helper.c | 13 -
 1 file changed, 13 deletions(-)

diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index dae1331f23..56ba49104e 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -1102,19 +1102,6 @@ uint64_t helper_float_rsqrt1_ps(CPUMIPSState *env, 
uint64_t fdt0)
 return ((uint64_t)fsth2 << 32) | fst2;
 }
 
-#define FLOAT_RINT(name, bits)  \
-uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env, \
- uint ## bits ## _t fs) \
-{   \
-uint ## bits ## _t fdret;   \
-\
-fdret = float ## bits ## _round_to_int(fs, >active_fpu.fp_status); \
-update_fcr31(env, GETPC()); \
-return fdret;   \
-}
-
-#undef FLOAT_RINT
-
 uint64_t helper_float_rint_d(CPUMIPSState *env, uint64_t fs)
 {
 uint64_t fdret;
-- 
2.20.1




[PATCH v2 08/17] target/mips: fpu: Demacro NMADD.

2020-05-14 Thread Aleksandar Markovic
This is just a cosmetic change to enable tools like gcov, gdb,
callgrind, etc. to better display involved source code.

Signed-off-by: Aleksandar Markovic 
---
 target/mips/fpu_helper.c | 44 +++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index e37fc4075d..d4c065f281 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -1495,7 +1495,6 @@ uint64_t helper_float_ ## name ## _ps(CPUMIPSState *env,  
   \
 update_fcr31(env, GETPC());  \
 return ((uint64_t)fsth0 << 32) | fst0;   \
 }
-FLOAT_FMA(nmadd, float_muladd_negate_result)
 FLOAT_FMA(nmsub, float_muladd_negate_result | float_muladd_negate_c)
 #undef FLOAT_FMA
 
@@ -1577,6 +1576,49 @@ uint64_t helper_float_msub_ps(CPUMIPSState *env, 
uint64_t fdt0,
 return ((uint64_t)fsth0 << 32) | fstl0;
 }
 
+uint64_t helper_float_nmadd_d(CPUMIPSState *env, uint64_t fst0,
+ uint64_t fst1, uint64_t fst2)
+{
+fst0 = float64_mul(fst0, fst1, >active_fpu.fp_status);
+fst0 = float64_add(fst0, fst2, >active_fpu.fp_status);
+fst0 = float64_chs(fst0);
+
+update_fcr31(env, GETPC());
+return fst0;
+}
+
+uint32_t helper_float_nmadd_s(CPUMIPSState *env, uint32_t fst0,
+ uint32_t fst1, uint32_t fst2)
+{
+fst0 = float32_mul(fst0, fst1, >active_fpu.fp_status);
+fst0 = float32_add(fst0, fst2, >active_fpu.fp_status);
+fst0 = float32_chs(fst0);
+
+update_fcr31(env, GETPC());
+return fst0;
+}
+
+uint64_t helper_float_nmadd_ps(CPUMIPSState *env, uint64_t fdt0,
+  uint64_t fdt1, uint64_t fdt2)
+{
+uint32_t fstl0 = fdt0 & 0X;
+uint32_t fsth0 = fdt0 >> 32;
+uint32_t fstl1 = fdt1 & 0X;
+uint32_t fsth1 = fdt1 >> 32;
+uint32_t fstl2 = fdt2 & 0X;
+uint32_t fsth2 = fdt2 >> 32;
+
+fstl0 = float32_mul(fstl0, fstl1, >active_fpu.fp_status);
+fstl0 = float32_add(fstl0, fstl2, >active_fpu.fp_status);
+fstl0 = float32_chs(fstl0);
+fsth0 = float32_mul(fsth0, fsth1, >active_fpu.fp_status);
+fsth0 = float32_add(fsth0, fsth2, >active_fpu.fp_status);
+fsth0 = float32_chs(fsth0);
+
+update_fcr31(env, GETPC());
+return ((uint64_t)fsth0 << 32) | fstl0;
+}
+
 
 #define FLOAT_FMADDSUB(name, bits, muladd_arg)  \
 uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env, \
-- 
2.20.1




[PATCH v2 15/17] target/mips: fpu: Name better paired-single variables

2020-05-14 Thread Aleksandar Markovic
Use consistently 'l' and 'h' for low and high halves.

Signed-off-by: Aleksandar Markovic 
---
 target/mips/fpu_helper.c | 62 
 1 file changed, 31 insertions(+), 31 deletions(-)

diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index 56ba49104e..dbb8ca5692 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -1059,14 +1059,14 @@ uint32_t helper_float_recip1_s(CPUMIPSState *env, 
uint32_t fst0)
 
 uint64_t helper_float_recip1_ps(CPUMIPSState *env, uint64_t fdt0)
 {
-uint32_t fst2;
+uint32_t fstl2;
 uint32_t fsth2;
 
-fst2 = float32_div(float32_one, fdt0 & 0X,
-   >active_fpu.fp_status);
+fstl2 = float32_div(float32_one, fdt0 & 0X,
+>active_fpu.fp_status);
 fsth2 = float32_div(float32_one, fdt0 >> 32, >active_fpu.fp_status);
 update_fcr31(env, GETPC());
-return ((uint64_t)fsth2 << 32) | fst2;
+return ((uint64_t)fsth2 << 32) | fstl2;
 }
 
 uint64_t helper_float_rsqrt1_d(CPUMIPSState *env, uint64_t fdt0)
@@ -1091,15 +1091,15 @@ uint32_t helper_float_rsqrt1_s(CPUMIPSState *env, 
uint32_t fst0)
 
 uint64_t helper_float_rsqrt1_ps(CPUMIPSState *env, uint64_t fdt0)
 {
-uint32_t fst2;
+uint32_t fstl2;
 uint32_t fsth2;
 
-fst2 = float32_sqrt(fdt0 & 0X, >active_fpu.fp_status);
+fstl2 = float32_sqrt(fdt0 & 0X, >active_fpu.fp_status);
 fsth2 = float32_sqrt(fdt0 >> 32, >active_fpu.fp_status);
-fst2 = float32_div(float32_one, fst2, >active_fpu.fp_status);
+fstl2 = float32_div(float32_one, fstl2, >active_fpu.fp_status);
 fsth2 = float32_div(float32_one, fsth2, >active_fpu.fp_status);
 update_fcr31(env, GETPC());
-return ((uint64_t)fsth2 << 32) | fst2;
+return ((uint64_t)fsth2 << 32) | fstl2;
 }
 
 uint64_t helper_float_rint_d(CPUMIPSState *env, uint64_t fs)
@@ -1367,19 +1367,19 @@ uint32_t helper_float_recip2_s(CPUMIPSState *env, 
uint32_t fst0, uint32_t fst2)
 
 uint64_t helper_float_recip2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t 
fdt2)
 {
-uint32_t fst0 = fdt0 & 0X;
+uint32_t fstl0 = fdt0 & 0X;
 uint32_t fsth0 = fdt0 >> 32;
-uint32_t fst2 = fdt2 & 0X;
+uint32_t fstl2 = fdt2 & 0X;
 uint32_t fsth2 = fdt2 >> 32;
 
-fst2 = float32_mul(fst0, fst2, >active_fpu.fp_status);
+fstl2 = float32_mul(fstl0, fstl2, >active_fpu.fp_status);
 fsth2 = float32_mul(fsth0, fsth2, >active_fpu.fp_status);
-fst2 = float32_chs(float32_sub(fst2, float32_one,
+fstl2 = float32_chs(float32_sub(fstl2, float32_one,
>active_fpu.fp_status));
 fsth2 = float32_chs(float32_sub(fsth2, float32_one,
>active_fpu.fp_status));
 update_fcr31(env, GETPC());
-return ((uint64_t)fsth2 << 32) | fst2;
+return ((uint64_t)fsth2 << 32) | fstl2;
 }
 
 uint64_t helper_float_rsqrt2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
@@ -1404,51 +1404,51 @@ uint32_t helper_float_rsqrt2_s(CPUMIPSState *env, 
uint32_t fst0, uint32_t fst2)
 
 uint64_t helper_float_rsqrt2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t 
fdt2)
 {
-uint32_t fst0 = fdt0 & 0X;
+uint32_t fstl0 = fdt0 & 0X;
 uint32_t fsth0 = fdt0 >> 32;
-uint32_t fst2 = fdt2 & 0X;
+uint32_t fstl2 = fdt2 & 0X;
 uint32_t fsth2 = fdt2 >> 32;
 
-fst2 = float32_mul(fst0, fst2, >active_fpu.fp_status);
+fstl2 = float32_mul(fstl0, fstl2, >active_fpu.fp_status);
 fsth2 = float32_mul(fsth0, fsth2, >active_fpu.fp_status);
-fst2 = float32_sub(fst2, float32_one, >active_fpu.fp_status);
+fstl2 = float32_sub(fstl2, float32_one, >active_fpu.fp_status);
 fsth2 = float32_sub(fsth2, float32_one, >active_fpu.fp_status);
-fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32,
+fstl2 = float32_chs(float32_div(fstl2, FLOAT_TWO32,
>active_fpu.fp_status));
 fsth2 = float32_chs(float32_div(fsth2, FLOAT_TWO32,
>active_fpu.fp_status));
 update_fcr31(env, GETPC());
-return ((uint64_t)fsth2 << 32) | fst2;
+return ((uint64_t)fsth2 << 32) | fstl2;
 }
 
 uint64_t helper_float_addr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
 {
-uint32_t fst0 = fdt0 & 0X;
+uint32_t fstl0 = fdt0 & 0X;
 uint32_t fsth0 = fdt0 >> 32;
-uint32_t fst1 = fdt1 & 0X;
+uint32_t fstl1 = fdt1 & 0X;
 uint32_t fsth1 = fdt1 >> 32;
-uint32_t fst2;
+uint32_t fstl2;
 uint32_t fsth2;
 
-fst2 = float32_add(fst0, fsth0, >active_fpu.fp_status);
-fsth2 = float32_add(fst1, fsth1, >active_fpu.fp_status);
+fstl2 = float32_add(fstl0, fsth0, >active_fpu.fp_status);
+fsth2 = float32_add(fstl1, fsth1, >active_fpu.fp_status);
 update_fcr31(env, GETPC());
-return ((uint64_t)fsth2 << 32) | fst2;
+return ((uint64_t)fsth2 << 

[PATCH v2 13/17] target/mips: fpu: Demacro RINT.

2020-05-14 Thread Aleksandar Markovic
This is just a cosmetic change to enable tools like gcov, gdb,
callgrind, etc. to better display involved source code.

Signed-off-by: Aleksandar Markovic 
---
 target/mips/fpu_helper.c | 20 ++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index e227e53f70..dae1331f23 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -1113,10 +1113,26 @@ uint ## bits ## _t helper_float_ ## name(CPUMIPSState 
*env, \
 return fdret;   \
 }
 
-FLOAT_RINT(rint_s, 32)
-FLOAT_RINT(rint_d, 64)
 #undef FLOAT_RINT
 
+uint64_t helper_float_rint_d(CPUMIPSState *env, uint64_t fs)
+{
+uint64_t fdret;
+
+fdret = float64_round_to_int(fs, >active_fpu.fp_status);
+update_fcr31(env, GETPC());
+return fdret;
+}
+
+uint32_t helper_float_rint_s(CPUMIPSState *env, uint32_t fs)
+{
+uint32_t fdret;
+
+fdret = float32_round_to_int(fs, >active_fpu.fp_status);
+update_fcr31(env, GETPC());
+return fdret;
+}
+
 #define FLOAT_CLASS_SIGNALING_NAN  0x001
 #define FLOAT_CLASS_QUIET_NAN  0x002
 #define FLOAT_CLASS_NEGATIVE_INFINITY  0x004
-- 
2.20.1




[PATCH v2 11/17] target/mips: fpu: Demacro CLASS.

2020-05-14 Thread Aleksandar Markovic
This is just a cosmetic change to enable tools like gcov, gdb,
callgrind, etc. to better display involved source code.

Signed-off-by: Aleksandar Markovic 
---
 target/mips/fpu_helper.c | 70 ++--
 1 file changed, 68 insertions(+), 2 deletions(-)

diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index e8e50e4bc0..b3903f5357 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -1165,10 +1165,76 @@ uint ## bits ## _t helper_float_ ## name(CPUMIPSState 
*env,  \
 return float_ ## name(arg, >active_fpu.fp_status);  \
 }
 
-FLOAT_CLASS(class_s, 32)
-FLOAT_CLASS(class_d, 64)
 #undef FLOAT_CLASS
 
+uint64_t float_class_d(uint64_t arg, float_status *status)
+{
+if (float64_is_signaling_nan(arg, status)) {
+return FLOAT_CLASS_SIGNALING_NAN;
+} else if (float64_is_quiet_nan(arg, status)) {
+return FLOAT_CLASS_QUIET_NAN;
+} else if (float64_is_neg(arg)) {
+if (float64_is_infinity(arg)) {
+return FLOAT_CLASS_NEGATIVE_INFINITY;
+} else if (float64_is_zero(arg)) {
+return FLOAT_CLASS_NEGATIVE_ZERO;
+} else if (float64_is_zero_or_denormal(arg)) {
+return FLOAT_CLASS_NEGATIVE_SUBNORMAL;
+} else {
+return FLOAT_CLASS_NEGATIVE_NORMAL;
+}
+} else {
+if (float64_is_infinity(arg)) {
+return FLOAT_CLASS_POSITIVE_INFINITY;
+} else if (float64_is_zero(arg)) {
+return FLOAT_CLASS_POSITIVE_ZERO;
+} else if (float64_is_zero_or_denormal(arg)) {
+return FLOAT_CLASS_POSITIVE_SUBNORMAL;
+} else {
+return FLOAT_CLASS_POSITIVE_NORMAL;
+}
+}
+}
+
+uint64_t helper_float_class_d(CPUMIPSState *env, uint64_t arg)
+{
+return float_class_d(arg, >active_fpu.fp_status);
+}
+
+uint32_t float_class_s(uint32_t arg, float_status *status)
+{
+if (float32_is_signaling_nan(arg, status)) {
+return FLOAT_CLASS_SIGNALING_NAN;
+} else if (float32_is_quiet_nan(arg, status)) {
+return FLOAT_CLASS_QUIET_NAN;
+} else if (float32_is_neg(arg)) {
+if (float32_is_infinity(arg)) {
+return FLOAT_CLASS_NEGATIVE_INFINITY;
+} else if (float32_is_zero(arg)) {
+return FLOAT_CLASS_NEGATIVE_ZERO;
+} else if (float32_is_zero_or_denormal(arg)) {
+return FLOAT_CLASS_NEGATIVE_SUBNORMAL;
+} else {
+return FLOAT_CLASS_NEGATIVE_NORMAL;
+}
+} else {
+if (float32_is_infinity(arg)) {
+return FLOAT_CLASS_POSITIVE_INFINITY;
+} else if (float32_is_zero(arg)) {
+return FLOAT_CLASS_POSITIVE_ZERO;
+} else if (float32_is_zero_or_denormal(arg)) {
+return FLOAT_CLASS_POSITIVE_SUBNORMAL;
+} else {
+return FLOAT_CLASS_POSITIVE_NORMAL;
+}
+}
+}
+
+uint32_t helper_float_class_s(CPUMIPSState *env, uint32_t arg)
+{
+return float_class_s(arg, >active_fpu.fp_status);
+}
+
 /* binary operations */
 
 uint64_t helper_float_add_d(CPUMIPSState *env,
-- 
2.20.1




[PATCH v2 02/17] target/mips: fpu: Demacro SUB.

2020-05-14 Thread Aleksandar Markovic
This is just a cosmetic change to enable tools like gcov, gdb,
callgrind, etc. to better display involved source code.

Signed-off-by: Aleksandar Markovic 
---
 target/mips/fpu_helper.c | 37 -
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index 984f3f4dfb..715a872cae 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -1208,7 +1208,6 @@ uint64_t helper_float_ ## name ## _ps(CPUMIPSState *env,  
 \
 return ((uint64_t)wth2 << 32) | wt2;   \
 }
 
-FLOAT_BINOP(sub)
 FLOAT_BINOP(mul)
 FLOAT_BINOP(div)
 #undef FLOAT_BINOP
@@ -1249,6 +1248,42 @@ uint64_t helper_float_add_ps(CPUMIPSState *env,
 return ((uint64_t)wth2 << 32) | wtl2;
 }
 
+uint64_t helper_float_sub_d(CPUMIPSState *env,
+uint64_t fdt0, uint64_t fdt1)
+{
+uint64_t dt2;
+
+dt2 = float64_sub(fdt0, fdt1, >active_fpu.fp_status);
+update_fcr31(env, GETPC());
+return dt2;
+}
+
+uint32_t helper_float_sub_s(CPUMIPSState *env,
+uint32_t fst0, uint32_t fst1)
+{
+uint32_t wt2;
+
+wt2 = float32_sub(fst0, fst1, >active_fpu.fp_status);
+update_fcr31(env, GETPC());
+return wt2;
+}
+
+uint64_t helper_float_sub_ps(CPUMIPSState *env,
+ uint64_t fdt0, uint64_t fdt1)
+{
+uint32_t fstl0 = fdt0 & 0X;
+uint32_t fsth0 = fdt0 >> 32;
+uint32_t fstl1 = fdt1 & 0X;
+uint32_t fsth1 = fdt1 >> 32;
+uint32_t wtl2;
+uint32_t wth2;
+
+wtl2 = float32_sub(fstl0, fstl1, >active_fpu.fp_status);
+wth2 = float32_sub(fsth0, fsth1, >active_fpu.fp_status);
+update_fcr31(env, GETPC());
+return ((uint64_t)wth2 << 32) | wtl2;
+}
+
 
 /* MIPS specific binary operations */
 uint64_t helper_float_recip2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
-- 
2.20.1




[PATCH v2 05/17] target/mips: fpu: Remove now unused macro FLOAT_BINOP

2020-05-14 Thread Aleksandar Markovic
After demacroing ., this macro is not
needed anymore.

Signed-off-by: Aleksandar Markovic 
---
 target/mips/fpu_helper.c | 39 ---
 1 file changed, 39 deletions(-)

diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index 2759c9989d..a3a39681f8 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -1170,45 +1170,6 @@ FLOAT_CLASS(class_d, 64)
 #undef FLOAT_CLASS
 
 /* binary operations */
-#define FLOAT_BINOP(name)  \
-uint64_t helper_float_ ## name ## _d(CPUMIPSState *env,\
- uint64_t fdt0, uint64_t fdt1) \
-{  \
-uint64_t dt2;  \
-   \
-dt2 = float64_ ## name(fdt0, fdt1, >active_fpu.fp_status);\
-update_fcr31(env, GETPC());\
-return dt2;\
-}  \
-   \
-uint32_t helper_float_ ## name ## _s(CPUMIPSState *env,\
- uint32_t fst0, uint32_t fst1) \
-{  \
-uint32_t wt2;  \
-   \
-wt2 = float32_ ## name(fst0, fst1, >active_fpu.fp_status);\
-update_fcr31(env, GETPC());\
-return wt2;\
-}  \
-   \
-uint64_t helper_float_ ## name ## _ps(CPUMIPSState *env,   \
-  uint64_t fdt0,   \
-  uint64_t fdt1)   \
-{  \
-uint32_t fst0 = fdt0 & 0X; \
-uint32_t fsth0 = fdt0 >> 32;   \
-uint32_t fst1 = fdt1 & 0X; \
-uint32_t fsth1 = fdt1 >> 32;   \
-uint32_t wt2;  \
-uint32_t wth2; \
-   \
-wt2 = float32_ ## name(fst0, fst1, >active_fpu.fp_status); \
-wth2 = float32_ ## name(fsth0, fsth1, >active_fpu.fp_status);  \
-update_fcr31(env, GETPC());\
-return ((uint64_t)wth2 << 32) | wt2;   \
-}
-
-#undef FLOAT_BINOP
 
 uint64_t helper_float_add_d(CPUMIPSState *env,
 uint64_t fdt0, uint64_t fdt1)
-- 
2.20.1




[PATCH v2 04/17] target/mips: fpu: Demacro DIV.

2020-05-14 Thread Aleksandar Markovic
This is just a cosmetic change to enable tools like gcov, gdb,
callgrind, etc. to better display involved source code.

Signed-off-by: Aleksandar Markovic 
---
 target/mips/fpu_helper.c | 37 -
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index 449e945166..2759c9989d 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -1208,7 +1208,6 @@ uint64_t helper_float_ ## name ## _ps(CPUMIPSState *env,  
 \
 return ((uint64_t)wth2 << 32) | wt2;   \
 }
 
-FLOAT_BINOP(div)
 #undef FLOAT_BINOP
 
 uint64_t helper_float_add_d(CPUMIPSState *env,
@@ -1319,6 +1318,42 @@ uint64_t helper_float_mul_ps(CPUMIPSState *env,
 return ((uint64_t)wth2 << 32) | wtl2;
 }
 
+uint64_t helper_float_div_d(CPUMIPSState *env,
+uint64_t fdt0, uint64_t fdt1)
+{
+uint64_t dt2;
+
+dt2 = float64_div(fdt0, fdt1, >active_fpu.fp_status);
+update_fcr31(env, GETPC());
+return dt2;
+}
+
+uint32_t helper_float_div_s(CPUMIPSState *env,
+uint32_t fst0, uint32_t fst1)
+{
+uint32_t wt2;
+
+wt2 = float32_div(fst0, fst1, >active_fpu.fp_status);
+update_fcr31(env, GETPC());
+return wt2;
+}
+
+uint64_t helper_float_div_ps(CPUMIPSState *env,
+ uint64_t fdt0, uint64_t fdt1)
+{
+uint32_t fstl0 = fdt0 & 0X;
+uint32_t fsth0 = fdt0 >> 32;
+uint32_t fstl1 = fdt1 & 0X;
+uint32_t fsth1 = fdt1 >> 32;
+uint32_t wtl2;
+uint32_t wth2;
+
+wtl2 = float32_div(fstl0, fstl1, >active_fpu.fp_status);
+wth2 = float32_div(fsth0, fsth1, >active_fpu.fp_status);
+update_fcr31(env, GETPC());
+return ((uint64_t)wth2 << 32) | wtl2;
+}
+
 
 /* MIPS specific binary operations */
 uint64_t helper_float_recip2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
-- 
2.20.1




[PATCH v2 07/17] target/mips: fpu: Demacro MSUB.

2020-05-14 Thread Aleksandar Markovic
This is just a cosmetic change to enable tools like gcov, gdb,
callgrind, etc. to better display involved source code.

Signed-off-by: Aleksandar Markovic 
---
 target/mips/fpu_helper.c | 40 +++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index c070081cbc..e37fc4075d 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -1495,7 +1495,6 @@ uint64_t helper_float_ ## name ## _ps(CPUMIPSState *env,  
   \
 update_fcr31(env, GETPC());  \
 return ((uint64_t)fsth0 << 32) | fst0;   \
 }
-FLOAT_FMA(msub, float_muladd_negate_c)
 FLOAT_FMA(nmadd, float_muladd_negate_result)
 FLOAT_FMA(nmsub, float_muladd_negate_result | float_muladd_negate_c)
 #undef FLOAT_FMA
@@ -1539,6 +1538,45 @@ uint64_t helper_float_madd_ps(CPUMIPSState *env, 
uint64_t fdt0,
 return ((uint64_t)fsth0 << 32) | fstl0;
 }
 
+uint64_t helper_float_msub_d(CPUMIPSState *env, uint64_t fst0,
+ uint64_t fst1, uint64_t fst2)
+{
+fst0 = float64_mul(fst0, fst1, >active_fpu.fp_status);
+fst0 = float64_sub(fst0, fst2, >active_fpu.fp_status);
+
+update_fcr31(env, GETPC());
+return fst0;
+}
+
+uint32_t helper_float_msub_s(CPUMIPSState *env, uint32_t fst0,
+ uint32_t fst1, uint32_t fst2)
+{
+fst0 = float32_mul(fst0, fst1, >active_fpu.fp_status);
+fst0 = float32_sub(fst0, fst2, >active_fpu.fp_status);
+
+update_fcr31(env, GETPC());
+return fst0;
+}
+
+uint64_t helper_float_msub_ps(CPUMIPSState *env, uint64_t fdt0,
+  uint64_t fdt1, uint64_t fdt2)
+{
+uint32_t fstl0 = fdt0 & 0X;
+uint32_t fsth0 = fdt0 >> 32;
+uint32_t fstl1 = fdt1 & 0X;
+uint32_t fsth1 = fdt1 >> 32;
+uint32_t fstl2 = fdt2 & 0X;
+uint32_t fsth2 = fdt2 >> 32;
+
+fstl0 = float32_mul(fstl0, fstl1, >active_fpu.fp_status);
+fstl0 = float32_sub(fstl0, fstl2, >active_fpu.fp_status);
+fsth0 = float32_mul(fsth0, fsth1, >active_fpu.fp_status);
+fsth0 = float32_sub(fsth0, fsth2, >active_fpu.fp_status);
+
+update_fcr31(env, GETPC());
+return ((uint64_t)fsth0 << 32) | fstl0;
+}
+
 
 #define FLOAT_FMADDSUB(name, bits, muladd_arg)  \
 uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env, \
-- 
2.20.1




[PATCH v2 03/17] target/mips: fpu: Demacro MUL.

2020-05-14 Thread Aleksandar Markovic
This is just a cosmetic change to enable tools like gcov, gdb,
callgrind, etc. to better display involved source code.

Signed-off-by: Aleksandar Markovic 
---
 target/mips/fpu_helper.c | 37 -
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index 715a872cae..449e945166 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -1208,7 +1208,6 @@ uint64_t helper_float_ ## name ## _ps(CPUMIPSState *env,  
 \
 return ((uint64_t)wth2 << 32) | wt2;   \
 }
 
-FLOAT_BINOP(mul)
 FLOAT_BINOP(div)
 #undef FLOAT_BINOP
 
@@ -1284,6 +1283,42 @@ uint64_t helper_float_sub_ps(CPUMIPSState *env,
 return ((uint64_t)wth2 << 32) | wtl2;
 }
 
+uint64_t helper_float_mul_d(CPUMIPSState *env,
+uint64_t fdt0, uint64_t fdt1)
+{
+uint64_t dt2;
+
+dt2 = float64_mul(fdt0, fdt1, >active_fpu.fp_status);
+update_fcr31(env, GETPC());
+return dt2;
+}
+
+uint32_t helper_float_mul_s(CPUMIPSState *env,
+uint32_t fst0, uint32_t fst1)
+{
+uint32_t wt2;
+
+wt2 = float32_mul(fst0, fst1, >active_fpu.fp_status);
+update_fcr31(env, GETPC());
+return wt2;
+}
+
+uint64_t helper_float_mul_ps(CPUMIPSState *env,
+ uint64_t fdt0, uint64_t fdt1)
+{
+uint32_t fstl0 = fdt0 & 0X;
+uint32_t fsth0 = fdt0 >> 32;
+uint32_t fstl1 = fdt1 & 0X;
+uint32_t fsth1 = fdt1 >> 32;
+uint32_t wtl2;
+uint32_t wth2;
+
+wtl2 = float32_mul(fstl0, fstl1, >active_fpu.fp_status);
+wth2 = float32_mul(fsth0, fsth1, >active_fpu.fp_status);
+update_fcr31(env, GETPC());
+return ((uint64_t)wth2 << 32) | wtl2;
+}
+
 
 /* MIPS specific binary operations */
 uint64_t helper_float_recip2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
-- 
2.20.1




Re: [PATCH 0/1] virtio-9pfs: don't truncate response

2020-05-14 Thread Stefano Stabellini
On Thu, 14 May 2020, Christian Schoenebeck wrote:
> The following patch reverts
> SHA-1 16724a173049ac29c7b5ade741da93a0f46edff for the virtio backend.
> 
> Greg, it is intended as a quick fix for
> https://bugs.launchpad.net/bugs/1877688 at least for virtio, for the
> case the appropriate fix on Xen side might still take a while. Because
> this bug is too serious to let it rest for too long.
> 
> In case Stefano comes up with a fix for Xen soon, you might just ignore
> this patch and just revert SHA-1 16724a173049ac29c7b5ade741da93a0f46edff
> entirely instead of course.

I am aiming at getting this fixed within a few days.  Up to you as you
want to proceed with the patches. I am happy either way.



  1   2   3   4   5   >