Re: [PATCH v3 04/10] vfio: Query and store the maximum number of DMA mappings

2020-12-16 Thread Pankaj Gupta
> Let's query the maximum number of DMA mappings by querying the available
> mappings when creating the container.
>
> In addition, count the number of DMA mappings and warn when we would
> exceed it. This is a preparation for RamDiscardMgr which might
> create quite some DMA mappings over time, and we at least want to warn
> early that the QEMU setup might be problematic. Use "reserved"
> terminology, so we can use this to reserve mappings before they are
> actually created.
>
> Note: don't reserve vIOMMU DMA mappings - using the vIOMMU region size
> divided by the mapping page size might be a bad indication of what will
> happen in practice - we might end up warning all the time.
>
> Cc: Paolo Bonzini 
> Cc: "Michael S. Tsirkin" 
> Cc: Alex Williamson 
> Cc: Dr. David Alan Gilbert 
> Cc: Igor Mammedov 
> Cc: Pankaj Gupta 
> Cc: Peter Xu 
> Cc: Auger Eric 
> Cc: Wei Yang 
> Cc: teawater 
> Cc: Marek Kedzierski 
> Signed-off-by: David Hildenbrand 
> ---
>  hw/vfio/common.c  | 34 ++
>  include/hw/vfio/vfio-common.h |  2 ++
>  2 files changed, 36 insertions(+)
>
> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> index 6ff1daa763..5ad88d476f 100644
> --- a/hw/vfio/common.c
> +++ b/hw/vfio/common.c
> @@ -288,6 +288,26 @@ const MemoryRegionOps vfio_region_ops = {
>  },
>  };
>
> +static void vfio_container_dma_reserve(VFIOContainer *container,
> +   unsigned long dma_mappings)
> +{
> +bool warned = container->dma_reserved > container->dma_max;
> +
> +container->dma_reserved += dma_mappings;
> +if (!warned && container->dma_max &&
> +container->dma_reserved > container->dma_max) {
> +warn_report("%s: possibly running out of DMA mappings. "
> +" Maximum number of DMA mappings: %d", __func__,
> +container->dma_max);
> +}
> +}
> +
> +static void vfio_container_dma_unreserve(VFIOContainer *container,
> + unsigned long dma_mappings)
> +{
> +container->dma_reserved -= dma_mappings;
> +}
> +
>  /*
>   * Device state interfaces
>   */
> @@ -835,6 +855,9 @@ static void vfio_listener_region_add(MemoryListener 
> *listener,
>  }
>  }
>
> +/* We'll need one DMA mapping. */
> +vfio_container_dma_reserve(container, 1);
> +
>  ret = vfio_dma_map(container, iova, int128_get64(llsize),
> vaddr, section->readonly);
>  if (ret) {
> @@ -879,6 +902,7 @@ static void vfio_listener_region_del(MemoryListener 
> *listener,
>   MemoryRegionSection *section)
>  {
>  VFIOContainer *container = container_of(listener, VFIOContainer, 
> listener);
> +bool unreserve_on_unmap = true;
>  hwaddr iova, end;
>  Int128 llend, llsize;
>  int ret;
> @@ -919,6 +943,7 @@ static void vfio_listener_region_del(MemoryListener 
> *listener,
>   * based IOMMU where a big unmap flattens a large range of IO-PTEs.
>   * That may not be true for all IOMMU types.
>   */
> +unreserve_on_unmap = false;
>  }
>
>  iova = TARGET_PAGE_ALIGN(section->offset_within_address_space);
> @@ -970,6 +995,11 @@ static void vfio_listener_region_del(MemoryListener 
> *listener,
>   "0x%"HWADDR_PRIx") = %d (%m)",
>   container, iova, int128_get64(llsize), ret);
>  }
> +
> +/* We previously reserved one DMA mapping. */
> +if (unreserve_on_unmap) {
> +vfio_container_dma_unreserve(container, 1);
> +}
>  }
>
>  memory_region_unref(section->mr);
> @@ -1735,6 +1765,7 @@ static int vfio_connect_container(VFIOGroup *group, 
> AddressSpace *as,
>  container->fd = fd;
>  container->error = NULL;
>  container->dirty_pages_supported = false;
> +container->dma_max = 0;
>  QLIST_INIT(>giommu_list);
>  QLIST_INIT(>hostwin_list);
>
> @@ -1765,7 +1796,10 @@ static int vfio_connect_container(VFIOGroup *group, 
> AddressSpace *as,
>  vfio_host_win_add(container, 0, (hwaddr)-1, info->iova_pgsizes);
>  container->pgsizes = info->iova_pgsizes;
>
> +/* The default in the kernel ("dma_entry_limit") is 65535. */
> +container->dma_max = 65535;
>  if (!ret) {
> +vfio_get_info_dma_avail(info, >dma_max);
>  vfio_get_iommu_info_migration(container, info);
>  }
>  g_free(info);
> diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
> index 6141162d7a..fed0e85f66 100644
> --- a/include/hw/vfio/vfio-common.h
> +++ b/include/hw/vfio/vfio-common.h
> @@ -88,6 +88,8 @@ typedef struct VFIOContainer {
>  uint64_t dirty_pgsizes;
>  uint64_t max_dirty_bitmap_size;
>  unsigned long pgsizes;
> +unsigned int dma_max;
> +unsigned long dma_reserved;
>  QLIST_HEAD(, VFIOGuestIOMMU) giommu_list;
>  QLIST_HEAD(, VFIOHostDMAWindow) 

[Bug 1907776] Re: Mounting VFat drive yields error messages.

2020-12-16 Thread John Doe
I have just noticed that the error does not appear when mounting the
VFat drive in the installed instance of Arch Linux. The reported error
messages occurred when using the "LiveUSB".

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

Title:
  Mounting VFat drive yields error messages.

Status in QEMU:
  New

Bug description:
  Mounting a virtual Fat drive results in error messages (see attached
  image).

  * https://www.qemu.org/docs/master/system/images.html#virtual-fat-
  disk-images

  The "drive" is however mounted, and as a test, saving a text file to
  the drive is successfully stored in the directory `/tmp`, which can be
  read after shutdown of Qemu.

  Archlinux 5.9.11-arch2-1 (64-bit)
  qemu-headless 5.1.0-3

  qemu-system-x86_64 -boot order=d -name test \
-enable-kvm -m 2G -cpu host -k sv \
-daemonize \
-drive 
if=pflash,format=raw,readonly,file=/usr/share/edk2-ovmf/x64/OVMF_CODE.fd \
-drive if=pflash,format=raw,file=~/vm/OVMF_VARS.local.fd \
-drive if=ide,format=raw,media=disk,index=1,file=fat:rw:/tmp \
-vnc :1 \
-cdrom /obj/archlinux/release/2020.10.01-x86_64.iso \
-drive format=raw,index=0,media=disk,file=~/vm/qemu.raw

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



RE: [PATCH v3] migration: Don't allow migration if vm is in POSTMIGRATE

2020-12-16 Thread Tuguoyi
Ping. 
It seems no one handle this patch. 


> -Original Message-
> From: Pankaj Gupta [mailto:pankaj.gupta.li...@gmail.com]
> Sent: Wednesday, December 09, 2020 10:21 PM
> To: tuguoyi (Cloud) 
> Cc: Juan Quintela ; Dr. David Alan Gilbert
> ; vsement...@virtuozzo.com;
> qemu-devel@nongnu.org; Li Zhang 
> Subject: Re: [PATCH v3] migration: Don't allow migration if vm is in
> POSTMIGRATE
> 
> > The following steps will cause qemu assertion failure:
> > - pause vm by executing 'virsh suspend'
> > - create external snapshot of memory and disk using 'virsh
> snapshot-create-as'
> > - doing the above operation again will cause qemu crash
> >
> > The backtrace looks like:
> > #0  0x7fbf958c5c37 in raise () from /lib/x86_64-linux-gnu/libc.so.6
> > #1  0x7fbf958c9028 in abort () from /lib/x86_64-linux-gnu/libc.so.6
> > #2  0x7fbf958bebf6 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
> > #3  0x7fbf958beca2 in __assert_fail () from
> /lib/x86_64-linux-gnu/libc.so.6
> > #4  0x55ca8decd39d in bdrv_inactivate_recurse (bs=0x55ca90c80400)
> at /build/qemu-5.0/block.c:5724
> > #5  0x55ca8dece967 in bdrv_inactivate_all () at
> /build//qemu-5.0/block.c:5792
> > #6  0x55ca8de5539d in
> qemu_savevm_state_complete_precopy_non_iterable (inactivate_disks=true,
> in_postcopy=false, f=0x55ca907044b0)
> > at /build/qemu-5.0/migration/savevm.c:1401
> > #7  qemu_savevm_state_complete_precopy (f=0x55ca907044b0,
> iterable_only=iterable_only@entry=false,
> inactivate_disks=inactivate_disks@entry=true)
> > at /build/qemu-5.0/migration/savevm.c:1453
> > #8  0x55ca8de4f581 in migration_completion (s=0x55ca8f64d9f0) at
> /build/qemu-5.0/migration/migration.c:2941
> > #9  migration_iteration_run (s=0x55ca8f64d9f0) at
> /build/qemu-5.0/migration/migration.c:3295
> > #10 migration_thread (opaque=opaque@entry=0x55ca8f64d9f0) at
> /build/qemu-5.0/migration/migration.c:3459
> > #11 0x55ca8dfc6716 in qemu_thread_start (args=) at
> /build/qemu-5.0/util/qemu-thread-posix.c:519
> > #12 0x7fbf95c5f184 in start_thread () from
> /lib/x86_64-linux-gnu/libpthread.so.0
> > #13 0x7fbf9598cbed in clone () from /lib/x86_64-linux-gnu/libc.so.6
> >
> > When the first migration completes, bs->open_flags will set
> BDRV_O_INACTIVE
> > flag by bdrv_inactivate_all(), and during the second migration the
> > bdrv_inactivate_recurse assert that the bs->open_flags is already
> > BDRV_O_INACTIVE enabled which cause crash.
> >
> > As Vladimir suggested, this patch makes migrate_prepare check the state of
> vm and
> > return error if it is in RUN_STATE_POSTMIGRATE state.
> >
> > Signed-off-by: Tuguoyi 
> Similar issue is reported by Li Zhang(+CC) with almost same patch[3]
> to fix this.
> 
> Reported-by: Li Zhang 
> Reviewed-by: Pankaj Gupta 
> 
> [3] https://marc.info/?l=qemu-devel=160749859831357=2
> > ---
> >  migration/migration.c | 6 ++
> >  1 file changed, 6 insertions(+)
> >
> > diff --git a/migration/migration.c b/migration/migration.c
> > index 87a9b59..5e33962 100644
> > --- a/migration/migration.c
> > +++ b/migration/migration.c
> > @@ -2115,6 +2115,12 @@ static bool migrate_prepare(MigrationState *s,
> bool blk, bool blk_inc,
> >  return false;
> >  }
> >
> > +if (runstate_check(RUN_STATE_POSTMIGRATE)) {
> > +error_setg(errp, "Can't migrate the vm that was paused due to "
> > +   "previous migration");
> > +return false;
> > +}
> > +
> >  if (migration_is_blocked(errp)) {
> >  return false;
> >  }
> > --
> > 2.7.4
> >
> > [Patch v2]:
> https://lists.gnu.org/archive/html/qemu-devel/2020-12/msg01318.html
> > [Patch v1]:
> https://lists.gnu.org/archive/html/qemu-devel/2020-11/msg05950.html


Re: [PATCH v2 1/3] net: checksum: Skip fragmented IP packets

2020-12-16 Thread Jason Wang



On 2020/12/17 下午1:41, Bin Meng wrote:

Hi Jason,

On Fri, Dec 11, 2020 at 5:35 PM Bin Meng  wrote:

From: Markus Carlstedt 

To calculate the TCP/UDP checksum we need the whole datagram. Unless
the hardware has some logic to collect all fragments before sending
the whole datagram first, it can only be done by the network stack,
which is normally the case for the NICs we have seen so far.

Skip these fragmented IP packets to avoid checksum corruption.

Signed-off-by: Markus Carlstedt 
Signed-off-by: Bin Meng 
---

(no changes since v1)

  net/checksum.c | 4 
  1 file changed, 4 insertions(+)


Ping?

Regards,
Bin



Queued.

Thanks









Re: [PATCH 04/12] qapi/gen: assert that _start_if is not None in _wrap_ifcond

2020-12-16 Thread Markus Armbruster
John Snow  writes:

> On 12/16/20 3:26 AM, Markus Armbruster wrote:
>> John Snow  writes:
>> 
>>> We already assert this in end_if, but that's opaque to mypy. Do it in
>>> _wrap_ifcond instead. Same effect at runtime, but mypy can now infer
>>> the type in _wrap_ifcond's body.
>>>
>>> Signed-off-by: John Snow 
>>> ---
>>>   scripts/qapi/gen.py | 2 +-
>>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
>>> index b40f18eee3cd..a6dc991b1d03 100644
>>> --- a/scripts/qapi/gen.py
>>> +++ b/scripts/qapi/gen.py
>>> @@ -130,11 +130,11 @@ def start_if(self, ifcond: List[str]) -> None:
>>>   self._start_if = (ifcond, self._body, self._preamble)
>>>   
>>>   def end_if(self) -> None:
>>> -assert self._start_if
>>>   self._wrap_ifcond()
>>>   self._start_if = None
>>>   
>>>   def _wrap_ifcond(self) -> None:
>>> +assert self._start_if
>>>   self._body = _wrap_ifcond(self._start_if[0],
>>> self._start_if[1], self._body)
>>>   self._preamble = _wrap_ifcond(self._start_if[0],
>> 
>> Drawback: the public method's precondition is now more opaque.  Do we
>> care?
>> 
>
> Ish. If you call end_if before start_if, what did you want to have happen?

Point.

> Or more to the point: do you want the assertion in both places?

What about inlining QAPIGenCCode._wrap_ifcond() into .end_if()?




[PATCH] docs/devel/migration: Improve debugging section a bit

2020-12-16 Thread Markus Armbruster
Fix typos, and make the example work out of the box.

Signed-off-by: Markus Armbruster 
---
 docs/devel/migration.rst | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst
index 49112bb27a..ad381b89b2 100644
--- a/docs/devel/migration.rst
+++ b/docs/devel/migration.rst
@@ -53,22 +53,23 @@ savevm/loadvm functionality.
 Debugging
 =
 
-The migration stream can be analyzed thanks to `scripts/analyze_migration.py`.
+The migration stream can be analyzed thanks to `scripts/analyze-migration.py`.
 
 Example usage:
 
 .. code-block:: shell
 
-  $ qemu-system-x86_64
-   (qemu) migrate "exec:cat > mig"
-  $ ./scripts/analyze_migration.py -f mig
+  $ qemu-system-x86_64 -display none -monitor stdio
+  (qemu) migrate "exec:cat > mig"
+  (qemu) q
+  $ ./scripts/analyze-migration.py -f mig
   {
 "ram (3)": {
 "section sizes": {
 "pc.ram": "0x0800",
   ...
 
-See also ``analyze_migration.py -h`` help for more options.
+See also ``analyze-migration.py -h`` help for more options.
 
 Common infrastructure
 =
-- 
2.26.2




Re: [PATCH 16/20] migration: Replace migration's JSON writer by the general one

2020-12-16 Thread Markus Armbruster
"Dr. David Alan Gilbert"  writes:

> * Markus Armbruster (arm...@redhat.com) wrote:
>> Commit 8118f0950f "migration: Append JSON description of migration
>> stream" needs a JSON writer.  The existing qobject_to_json() wasn't a
>> good fit, because it requires building a QObject to convert.  Instead,
>> migration got its very own JSON writer, in commit 190c882ce2 "QJSON:
>> Add JSON writer".  It tacitly limits numbers to int64_t, and strings
>> contents to characters that don't need escaping, unlike
>> qobject_to_json().
>> 
>> The previous commit factored the JSON writer out of qobject_to_json().
>> Replace migration's JSON writer by it.
>> 
>> Cc: Juan Quintela 
>> Cc: Dr. David Alan Gilbert 
>> Signed-off-by: Markus Armbruster 
>
> (Copying in Alex)
>
> This looks OK to me, so:
>
> Reviewed-by: Dr. David Alan Gilbert 
>
> but, can I just check, have you checked scripts/analyze-migration.py is
> still happy with the output?

Good point.  I just did, following instructions in
docs/devel/migration.rst.  It prints stuff and succeeds.  Anything else
you'd like me to try?




Re: [PATCH v2 05/11] qapi/introspect.py: add preliminary type hint annotations

2020-12-16 Thread Markus Armbruster
John Snow  writes:

> On 12/16/20 2:51 AM, Markus Armbruster wrote:
>> Is it too late to delay the introduction of type hints until after
>> the
>> data structure cleanups?
>> If yes, I have to spend more time replying below.
>> 
>
> No, I re-ordered the series again to delay typing until the end, or
> close to it.

Thanks!

> Though I abandoned plans to slacken List[...] inputs to Iterable[...]
> or Sequence[...] like I had mentioned; I think it could still be done,
> but it's fine to just use List[...] for the inputs for now. We can
> worry about optimizing type flexibility later, I think.

Shouldn't be a problem now I know what to expect.

> Let's just get the dog hunting at all first.

Yes.




Re: [PATCH v2 05/11] qapi/introspect.py: add preliminary type hint annotations

2020-12-16 Thread Markus Armbruster
Eduardo Habkost  writes:

> On Wed, Dec 16, 2020 at 08:51:10AM +0100, Markus Armbruster wrote:
> [...]
>> You guys clearly struggled with the tree data structure.  Documentation
>> would have helped[*].  Since you're going to replace it (PATCH 09),
>> adding it now makes little sense.
>> 
>> *My* struggle is with the type annotations.
>> 
>> The initial state is messy to type, in part due to mypy's surprising
>> inability to deal with recursive types, in part because the tree data
>> structure is messier than it could be.
>> 
>> Much of the series is cleanup that benefits the typing.  Makes sense.
>> 
>> What makes review hard for me: you add (fairly complicated) typing
>> first, then evolve it along with the cleanups.  I have to first grok the
>> complicated typing (a struggle), then for each cleanup grok the type
>> changes in addition to the code changes.
>> 
>> I believe adding the typing before the cleanups is a mistake.
>
> Possibly my fault, as I remember asking John to do that (in
> earlier versions of these patches, type annotations were added
> after cleanup).
>
>> 
>> I share the desire to have type annotations that help with understanding
>> the code.  I understand the desire to have them sooner rather than
>> later.  I just think they're a costly distraction at this stage for this
>> code.  Once you understand the data structure, the cleanups are fairly
>> straightforward.
>> 
>
> I expected the type annotations to be a simple and helpful tool
> for understanding the data structure before refactoring.  In the
> case of introspect.py, I was completely wrong about "simple", and
> I'm not entirely sure about "helpful".

Quite excusable.  We lack the mypy experience to predict such outcomes.

> I wasn't expecting them to be an obstacle for patch review,
> though.  If the type annotations look good at the end of the
> series, do we care about the intermediate state?  Bisectability
> isn't an issue because type annotations are ignored by the Python
> interpreter.

I don't worry about bisectability.  The issue is reviewability.

Here's the best case for me reviewing a single patch.  First, the commit
message convinces me this makes sense.  Then I read the patch mostly in
order.  It does what the commit message made me expect, I think I
understand how it does it, and it doesn't touch anything I know to be
subtle.

Here's the best case for me reviewing a patch series: every patch in
order is a best case review.

As soon as review deviates from this best case, I slow down.  A lot.  If
there is something I didn't expect, maybe I'm misunderstanding the
patch's purpose.  If I feel confused about how the patch achieves its
purpose, I better figure it out.  If something subtle is being touched,
I better recall its subtleties and carefully check the patch.  Slow and
exhausting work.

This way of review can be overly careful.  But even deciding "this isn't
important, let it go" is slow, unless I do it wholesale.  All we get
then is "looks good at a glance".  But that's maybe an Acked-by,
certainly not a Reviewed-by.

Me finding the patch where the type hints start to be "serious" is slow.
Me mentally separating changes to type hints from other changes in
patches before that point is slow.  Me examining the type hints at that
point (which need not be entirely visible in the patch) is slow.

If the annotations in the intermediate state don't have to be good, do
they have to be there?  If John can take them out, review will be easier
and faster.




Re: [PATCH v4 12/16] target/riscv: cpu: Remove compile time XLEN checks

2020-12-16 Thread Bin Meng
On Thu, Dec 17, 2020 at 2:22 AM Alistair Francis
 wrote:
>
> Signed-off-by: Alistair Francis 
> Reviewed-by: Bin Meng 
> Reviewed-by: Richard Henderson 
> Reviewed-by: Palmer Dabbelt 
> Acked-by: Palmer Dabbelt 
> ---
>  target/riscv/cpu.c | 19 ++-
>  1 file changed, 10 insertions(+), 9 deletions(-)
>

Tested-by: Bin Meng 



Re: [PATCH v4 16/16] hw/riscv: Use the CPU to determine if 32-bit

2020-12-16 Thread Bin Meng
On Thu, Dec 17, 2020 at 2:23 AM Alistair Francis
 wrote:
>
> Instead of using string compares to determine if a RISC-V machine is
> using 32-bit or 64-bit CPUs we can use the initalised CPUs. This avoids
> us having to maintain a list of CPU names to compare against.
>
> This commit also fixes the name of the function to match the
> riscv_cpu_is_32bit() function.
>
> Signed-off-by: Alistair Francis 
> ---
>  include/hw/riscv/boot.h |  8 +---
>  hw/riscv/boot.c | 31 ++-
>  hw/riscv/sifive_u.c | 10 +-
>  hw/riscv/spike.c|  8 
>  hw/riscv/virt.c |  9 +
>  5 files changed, 29 insertions(+), 37 deletions(-)
>
> diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
> index b6d37a91d6..20ff5fe5e5 100644
> --- a/include/hw/riscv/boot.h
> +++ b/include/hw/riscv/boot.h
> @@ -22,10 +22,11 @@
>
>  #include "exec/cpu-defs.h"
>  #include "hw/loader.h"
> +#include "hw/riscv/riscv_hart.h"
>
> -bool riscv_is_32_bit(MachineState *machine);
> +bool riscv_is_32bit(RISCVHartArrayState harts);
>
> -target_ulong riscv_calc_kernel_start_addr(MachineState *machine,
> +target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState harts,
>target_ulong firmware_end_addr);
>  target_ulong riscv_find_and_load_firmware(MachineState *machine,
>const char 
> *default_machine_firmware,
> @@ -41,7 +42,8 @@ target_ulong riscv_load_kernel(const char *kernel_filename,
>  hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
>   uint64_t kernel_entry, hwaddr *start);
>  uint32_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt);
> -void riscv_setup_rom_reset_vec(MachineState *machine, hwaddr saddr,
> +void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState 
> harts,
> +   hwaddr saddr,
> hwaddr rom_base, hwaddr rom_size,
> uint64_t kernel_entry,
> uint32_t fdt_load_addr, void *fdt);
> diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
> index 6bce6fb485..83586aef41 100644
> --- a/hw/riscv/boot.c
> +++ b/hw/riscv/boot.c
> @@ -33,28 +33,16 @@
>
>  #include 
>
> -bool riscv_is_32_bit(MachineState *machine)
> +bool riscv_is_32bit(RISCVHartArrayState harts)
>  {
> -/*
> - * To determine if the CPU is 32-bit we need to check a few different 
> CPUs.
> - *
> - * If the CPU starts with rv32
> - * If the CPU is a sifive 3 seriries CPU (E31, U34)
> - * If it's the Ibex CPU
> - */
> -if (!strncmp(machine->cpu_type, "rv32", 4) ||
> -(!strncmp(machine->cpu_type, "sifive", 6) &&
> -machine->cpu_type[8] == '3') ||
> -!strncmp(machine->cpu_type, "lowrisc-ibex", 12)) {
> -return true;
> -} else {
> -return false;
> -}
> +RISCVCPU hart = harts.harts[0];

What happens if something like ARM big.LITTLE needs to be supported on RISC-V?

> +
> +return riscv_cpu_is_32bit();
>  }
>

[snip]

Regards,
Bin



Re: [PATCH v4 14/16] target/riscv: csr: Remove compile time XLEN checks

2020-12-16 Thread Bin Meng
On Thu, Dec 17, 2020 at 2:23 AM Alistair Francis
 wrote:
>
> Signed-off-by: Alistair Francis 
> Reviewed-by: Bin Meng 
> Reviewed-by: Palmer Dabbelt 
> Acked-by: Palmer Dabbelt 
> ---
>  target/riscv/cpu_bits.h |   4 +-
>  target/riscv/csr.c  | 176 +---
>  2 files changed, 92 insertions(+), 88 deletions(-)
>

Tested-by: Bin Meng 



Re: [PATCH v4 13/16] target/riscv: cpu_helper: Remove compile time XLEN checks

2020-12-16 Thread Bin Meng
On Thu, Dec 17, 2020 at 2:23 AM Alistair Francis
 wrote:
>
> Signed-off-by: Alistair Francis 
> Reviewed-by: Richard Henderson 
> Reviewed-by: Palmer Dabbelt 
> Acked-by: Palmer Dabbelt 
> ---
>  target/riscv/cpu_helper.c | 12 +++-
>  1 file changed, 7 insertions(+), 5 deletions(-)
>

Reviewed-by: Bin Meng 
Tested-by: Bin Meng 



Re: [PATCH v4 08/16] hw/riscv: sifive_u: Remove compile time XLEN checks

2020-12-16 Thread Bin Meng
On Thu, Dec 17, 2020 at 2:22 AM Alistair Francis
 wrote:
>
> Signed-off-by: Alistair Francis 
> Reviewed-by: Palmer Dabbelt 
> Acked-by: Palmer Dabbelt 
> ---
>  hw/riscv/sifive_u.c | 55 -
>  1 file changed, 30 insertions(+), 25 deletions(-)
>

Tested with 64-bit sifive_u
Reviewed-by: Bin Meng 
Tested-by: Bin Meng 

32-bit is blocked by:
http://lists.infradead.org/pipermail/linux-riscv/2020-December/003927.html

Regards,
Bin



[Bug 1908489] [NEW] qemu 4.2 bootloops with -cpu host and nested hypervisor

2020-12-16 Thread Luqman
Public bug reported:

I've noticed that after upgrading from Ubuntu 18.04 to 20.04 that nested
virtualization isn't working anymore.

I have a simple repro where I create a Windows 10 2004 guest and enable
Hyper-V in it. This worked fine in 18.04 and specifically qemu <4.2 (I
specifically tested Qemu 2.11-4.1 which work fine).

The -cpu arg I'm passing is simply:
-cpu host,l3-cache=on,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time

Using that Windows won't boot because the nested hypervisor (Hyper-V) is
unable to be initialize and so it just boot loops. Using the exact same
qemu command works fine with 4.1 and lower.

Switching to a named CPU model like Skylake-Client-noTSX-IBRS instead of
host lets the VM boot but causes some weird behaviour later trying to
use nested VMs.

If I had to guess I think it would probably be related to this change
https://github.com/qemu/qemu/commit/20a78b02d31534ae478779c2f2816c273601e869
which would line up with 4.2 being the first bad version but unsure.

For now I just have to keep an older build of QEMU to work around this.
Let me know if there's anything else needed. I can also try out any
patches. I already have at least a dozen copies of qemu lying around
now.

** Affects: qemu
 Importance: Undecided
 Status: New

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

Title:
  qemu 4.2 bootloops with -cpu host and nested hypervisor

Status in QEMU:
  New

Bug description:
  I've noticed that after upgrading from Ubuntu 18.04 to 20.04 that
  nested virtualization isn't working anymore.

  I have a simple repro where I create a Windows 10 2004 guest and
  enable Hyper-V in it. This worked fine in 18.04 and specifically qemu
  <4.2 (I specifically tested Qemu 2.11-4.1 which work fine).

  The -cpu arg I'm passing is simply:
  -cpu host,l3-cache=on,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time

  Using that Windows won't boot because the nested hypervisor (Hyper-V)
  is unable to be initialize and so it just boot loops. Using the exact
  same qemu command works fine with 4.1 and lower.

  Switching to a named CPU model like Skylake-Client-noTSX-IBRS instead
  of host lets the VM boot but causes some weird behaviour later trying
  to use nested VMs.

  If I had to guess I think it would probably be related to this change
  https://github.com/qemu/qemu/commit/20a78b02d31534ae478779c2f2816c273601e869
  which would line up with 4.2 being the first bad version but unsure.

  For now I just have to keep an older build of QEMU to work around
  this. Let me know if there's anything else needed. I can also try out
  any patches. I already have at least a dozen copies of qemu lying
  around now.

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



Re: [for-6.0 v5 00/13] Generalize memory encryption models

2020-12-16 Thread David Gibson
On Tue, Dec 08, 2020 at 01:43:08PM +0100, Cornelia Huck wrote:
> On Tue, 8 Dec 2020 13:57:28 +1100
> David Gibson  wrote:
> 
> > On Fri, Dec 04, 2020 at 02:12:29PM +0100, Cornelia Huck wrote:
> > > On Fri, 4 Dec 2020 13:07:27 +
> > > "Dr. David Alan Gilbert"  wrote:
> > >   
> > > > * Cornelia Huck (coh...@redhat.com) wrote:  
> > > > > On Fri, 4 Dec 2020 09:06:50 +0100
> > > > > Christian Borntraeger  wrote:
> > > > > 
> > > > > > On 04.12.20 06:44, David Gibson wrote:
> > > > > > > A number of hardware platforms are implementing mechanisms 
> > > > > > > whereby the
> > > > > > > hypervisor does not have unfettered access to guest memory, in 
> > > > > > > order
> > > > > > > to mitigate the security impact of a compromised hypervisor.
> > > > > > > 
> > > > > > > AMD's SEV implements this with in-cpu memory encryption, and 
> > > > > > > Intel has
> > > > > > > its own memory encryption mechanism.  POWER has an upcoming 
> > > > > > > mechanism
> > > > > > > to accomplish this in a different way, using a new memory 
> > > > > > > protection
> > > > > > > level plus a small trusted ultravisor.  s390 also has a protected
> > > > > > > execution environment.
> > > > > > > 
> > > > > > > The current code (committed or draft) for these features has each
> > > > > > > platform's version configured entirely differently.  That doesn't 
> > > > > > > seem
> > > > > > > ideal for users, or particularly for management layers.
> > > > > > > 
> > > > > > > AMD SEV introduces a notionally generic machine option
> > > > > > > "machine-encryption", but it doesn't actually cover any cases 
> > > > > > > other
> > > > > > > than SEV.
> > > > > > > 
> > > > > > > This series is a proposal to at least partially unify 
> > > > > > > configuration
> > > > > > > for these mechanisms, by renaming and generalizing AMD's
> > > > > > > "memory-encryption" property.  It is replaced by a
> > > > > > > "securable-guest-memory" property pointing to a platform specific 
> > > > > > >  
> > > > > > 
> > > > > > Can we do "securable-guest" ?
> > > > > > s390x also protects registers and integrity. memory is only one 
> > > > > > piece
> > > > > > of the puzzle and what we protect might differ from platform to 
> > > > > > platform.
> > > > > > 
> > > > > 
> > > > > I agree. Even technologies that currently only do memory encryption 
> > > > > may
> > > > > be enhanced with more protections later.
> > > > 
> > > > There's already SEV-ES patches onlist for this on the SEV side.
> > > > 
> > > > 
> > > > 
> > > > Perhaps 'confidential guest' is actually what we need, since the
> > > > marketing folks seem to have started labelling this whole idea
> > > > 'confidential computing'.  
> > 
> > That's not a bad idea, much as I usually hate marketing terms.  But it
> > does seem to be becoming a general term for this style of thing, and
> > it doesn't overlap too badly with other terms ("secure" and
> > "protected" are also used for hypervisor-from-guest and
> > guest-from-guest protection).
> > 
> > > It's more like a 'possibly confidential guest', though.  
> > 
> > Hmm.  What about "Confidential Guest Facility" or "Confidential Guest
> > Mechanism"?  The implication being that the facility is there, whether
> > or not the guest actually uses it.
> > 
> 
> "Confidential Guest Enablement"? The others generally sound fine to me
> as well, though; not sure if "Facility" might be a bit confusing, as
> that term is already a bit overloaded.

Well, "facility" is a bit overloaded, but IMO "enablement" is even
more so.  I think I'll go with "confidential guest support" in the
next spin.

-- 
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: [PULL 00/12] Compile QEMU with -Wimplicit-fallthrough

2020-12-16 Thread Thomas Huth
On 17/12/2020 00.01, no-re...@patchew.org wrote:
> Patchew URL: https://patchew.org/QEMU/20201216172949.57380-1-th...@redhat.com/
> 
> 
> 
> Hi,
> 
> This series seems to have some coding style problems. See output below for
> more information:
> 
> Type: series
> Message-id: 20201216172949.57380-1-th...@redhat.com
> Subject: [PULL 00/12] Compile QEMU with -Wimplicit-fallthrough
> 
> === TEST SCRIPT BEGIN ===
> #!/bin/bash
> git rev-parse base > /dev/null || exit 0
> git config --local diff.renamelimit 0
> git config --local diff.renames True
> git config --local diff.algorithm histogram
> ./scripts/checkpatch.pl --mailback base..
> === TEST SCRIPT END ===
> 
> Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
> From https://github.com/patchew-project/qemu
>  * [new tag] patchew/20201216172949.57380-1-th...@redhat.com -> 
> patchew/20201216172949.57380-1-th...@redhat.com
> Switched to a new branch 'test'
> 7bedbc8 configure: Compile with -Wimplicit-fallthrough=2
> e14bb9d tests/fp: Do not emit implicit-fallthrough warnings in the softfloat 
> tests
> ebd3c45 tcg/optimize: Add fallthrough annotations
> cfe5662 target/sparc/win_helper: silence the compiler warnings
> 8ef9335 target/sparc/translate: silence the compiler warnings
> 4588bf9 accel/tcg/user-exec: silence the compiler warnings
> be2108e hw/intc/arm_gicv3_kvm: silence the compiler warnings
> 7d033d0 target/i386: silence the compiler warnings in gen_shiftd_rm_T1
> 284b00a hw/timer/renesas_tmr: silence the compiler warnings
> c3d2957 hw/rtc/twl92230: Silence warnings about missing fallthrough statements
> 1b1609c target/unicore32/translate: Add missing fallthrough annotations
> 99bc0f0 disas/libvixl: Fix fall-through annotation for GCC >= 7
> 
> === OUTPUT BEGIN ===
> 1/12 Checking commit 99bc0f0e92b7 (disas/libvixl: Fix fall-through annotation 
> for GCC >= 7)
> ERROR: do not use C99 // comments
> #49: FILE: disas/libvixl/vixl/globals.h:111:
> +// Fallthrough annotation for Clang and C++11(201103L).
> 
> ERROR: do not use C99 // comments
> #52: FILE: disas/libvixl/vixl/globals.h:114:
> +// Fallthrough annotation for GCC >= 7.

Well, libvixl is C++ code and the upstream patch used these comments, too,
so this error can be ignored.

> total: 2 errors, 0 warnings, 24 lines checked
> 
> Patch 1/12 has style problems, please review.  If any of these errors
> are false positives report them to the maintainer, see
> CHECKPATCH in MAINTAINERS.
> 
> 2/12 Checking commit 1b1609c7573a (target/unicore32/translate: Add missing 
> fallthrough annotations)
> 3/12 Checking commit c3d2957383b8 (hw/rtc/twl92230: Silence warnings about 
> missing fallthrough statements)
> 4/12 Checking commit 284b00aef566 (hw/timer/renesas_tmr: silence the compiler 
> warnings)
> 5/12 Checking commit 7d033d02b90d (target/i386: silence the compiler warnings 
> in gen_shiftd_rm_T1)
> 6/12 Checking commit be2108e641c9 (hw/intc/arm_gicv3_kvm: silence the 
> compiler warnings)
> 7/12 Checking commit 4588bf97482b (accel/tcg/user-exec: silence the compiler 
> warnings)
> 8/12 Checking commit 8ef9335f2838 (target/sparc/translate: silence the 
> compiler warnings)
> 9/12 Checking commit cfe56623ece8 (target/sparc/win_helper: silence the 
> compiler warnings)
> 10/12 Checking commit ebd3c45fd052 (tcg/optimize: Add fallthrough annotations)
> WARNING: architecture specific defines should be avoided
> #35: FILE: include/qemu/compiler.h:230:
> +#if __has_attribute(fallthrough)

Maybe we should teach checkpatch.pl to allow these in compiler.h?

 Thomas




Re: [for-6.0 v5 11/13] spapr: PEF: prevent migration

2020-12-16 Thread David Gibson
On Mon, Dec 14, 2020 at 06:22:40PM +0100, Cornelia Huck wrote:
> On Fri,  4 Dec 2020 16:44:13 +1100
> David Gibson  wrote:
> 
> > We haven't yet implemented the fairly involved handshaking that will be
> > needed to migrate PEF protected guests.  For now, just use a migration
> > blocker so we get a meaningful error if someone attempts this (this is the
> > same approach used by AMD SEV).
> > 
> > Signed-off-by: David Gibson 
> > Reviewed-by: Dr. David Alan Gilbert 
> > ---
> >  hw/ppc/pef.c | 9 +
> >  1 file changed, 9 insertions(+)
> > 
> > diff --git a/hw/ppc/pef.c b/hw/ppc/pef.c
> > index 3ae3059cfe..edc3e744ba 100644
> > --- a/hw/ppc/pef.c
> > +++ b/hw/ppc/pef.c
> > @@ -38,7 +38,11 @@ struct PefGuestState {
> >  };
> >  
> >  #ifdef CONFIG_KVM
> > +static Error *pef_mig_blocker;
> > +
> >  static int kvmppc_svm_init(Error **errp)
> 
> This looks weird?

Oops.  Not sure how that made it past even my rudimentary compile
testing.

> > +
> > +int kvmppc_svm_init(SecurableGuestMemory *sgm, Error **errp)
> >  {
> >  if (!kvm_check_extension(kvm_state, KVM_CAP_PPC_SECURABLE_GUEST)) {
> >  error_setg(errp,
> > @@ -54,6 +58,11 @@ static int kvmppc_svm_init(Error **errp)
> >  }
> >  }
> >  
> > +/* add migration blocker */
> > +error_setg(_mig_blocker, "PEF: Migration is not implemented");
> > +/* NB: This can fail if --only-migratable is used */
> > +migrate_add_blocker(pef_mig_blocker, _fatal);
> 
> Just so that I understand: is PEF something that is enabled by the host
> (and the guest is either secured or doesn't start), or is it using a
> model like s390x PV where the guest initiates the transition into
> secured mode?

Like s390x PV it's initiated by the guest.

> Asking because s390x adds the migration blocker only when the
> transition is actually happening (i.e. guests that do not transition
> into secure mode remain migratable.) This has the side effect that you
> might be able to start a machine with --only-migratable that
> transitions into a non-migratable machine via a guest action, if I'm
> not mistaken. Without the new object, I don't see a way to block with
> --only-migratable; with it, we should be able to do that. Not sure what
> the desirable behaviour is here.

Hm, I'm not sure what the best option is here either.

> 
> > +
> >  return 0;
> >  }
> >  
> 

-- 
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: [for-6.0 v5 13/13] s390: Recognize securable-guest-memory option

2020-12-16 Thread David Gibson
On Tue, Dec 15, 2020 at 12:45:26PM +0100, Cornelia Huck wrote:
> On Fri,  4 Dec 2020 16:44:15 +1100
> David Gibson  wrote:
> 
> > At least some s390 cpu models support "Protected Virtualization" (PV),
> > a mechanism to protect guests from eavesdropping by a compromised
> > hypervisor.
> > 
> > This is similar in function to other mechanisms like AMD's SEV and
> > POWER's PEF, which are controlled bythe "securable-guest-memory" machine
> 
> s/bythe/by the/
> 
> > option.  s390 is a slightly special case, because we already supported
> > PV, simply by using a CPU model with the required feature
> > (S390_FEAT_UNPACK).
> > 
> > To integrate this with the option used by other platforms, we
> > implement the following compromise:
> > 
> >  - When the securable-guest-memory option is set, s390 will recognize it,
> >verify that the CPU can support PV (failing if not) and set virtio
> >default options necessary for encrypted or protected guests, as on
> >other platforms.  i.e. if securable-guest-memory is set, we will
> >either create a guest capable of entering PV mode, or fail outright
> 
> s/outright/outright./
> 
> > 
> >  - If securable-guest-memory is not set, guest's might still be able to
> 
> s/guest's/guests/

All those corrected, thanks.

> >enter PV mode, if the CPU has the right model.  This may be a
> >little surprising, but shouldn't actually be harmful.
> > 
> > To start a guest supporting Protected Virtualization using the new
> > option use the command line arguments:
> > -object s390-pv-guest,id=pv0 -machine securable-guest-memory=pv0
> > 
> > Signed-off-by: David Gibson 
> > ---
> >  hw/s390x/pv.c | 58 +++
> >  include/hw/s390x/pv.h |  1 +
> >  target/s390x/kvm.c|  3 +++
> >  3 files changed, 62 insertions(+)
> > 
> 
> Modulo any naming changes etc., I think this should work for s390. I
> don't have the hardware to test this, however, and would appreciate
> someone with a PV setup giving this a go.

Makes sense.

-- 
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: [for-6.0 v5 08/13] securable guest memory: Introduce sgm "ready" flag

2020-12-16 Thread David Gibson
On Mon, Dec 14, 2020 at 06:00:36PM +0100, Cornelia Huck wrote:
> On Fri,  4 Dec 2020 16:44:10 +1100
> David Gibson  wrote:
> 
> > The platform specific details of mechanisms for implementing securable
> > guest memory may require setup at various points during initialization.
> > Thus, it's not really feasible to have a single sgm initialization hook,
> > but instead each mechanism needs its own initialization calls in arch or
> > machine specific code.
> > 
> > However, to make it harder to have a bug where a mechanism isn't properly
> > initialized under some circumstances, we want to have a common place,
> > relatively late in boot, where we verify that sgm has been initialized if
> > it was requested.
> > 
> > This patch introduces a ready flag to the SecurableGuestMemory base type
> > to accomplish this, which we verify just before the machine specific
> > initialization function.
> > 
> > Signed-off-by: David Gibson 
> > ---
> >  hw/core/machine.c | 8 
> >  include/exec/securable-guest-memory.h | 2 ++
> >  target/i386/sev.c | 2 ++
> >  3 files changed, 12 insertions(+)
> > 
> > diff --git a/hw/core/machine.c b/hw/core/machine.c
> > index 816ea3ae3e..a67a27d03c 100644
> > --- a/hw/core/machine.c
> > +++ b/hw/core/machine.c
> > @@ -1155,6 +1155,14 @@ void machine_run_board_init(MachineState *machine)
> >  }
> >  
> >  if (machine->sgm) {
> > +/*
> > + * Where securable guest memory is initialized depends on the
> > + * specific mechanism in use.  But, we need to make sure it's
> > + * ready by now.  If it isn't, that's a bug in the
> > + * implementation of that sgm mechanism.
> > + */
> > +assert(machine->sgm->ready);
> 
> Under which circumstances might we arrive here with 'ready' not set?
> 
> - programming error, setup is happening too late -> assert() seems
>   appropriate

Yes, this is designed to catch programming errors.  In particular I'm
concerned about:
  * Re-arranging the init code, and either entirely forgetting the sgm
setup, or accidentally moving it too late
  * The sgm setup is buried in the machine setup code, conditional on
various things, and changes mean we no longer either call it or
(correctly) fail
  * User has specified an sgm scheme designed for a machine type other
than the one they selected.  The arch/machine init code hasn't
correctly accounted for that possibility and ignores it, instead
of correctly throwing an error
 
> - we tried to set it up, but some error happened -> should we rely on
>   the setup code to error out first? (i.e. we won't end up here, unless
>   there's a programming error, in which case the assert() looks
>   fine)

Yes, that's my intention.

>   Is there a possible use case for "we could not set it up, but we
>   support an unsecured guest (as long as it is clear what happens)"?

I don't think so.  My feeling is that if you specify that you want the
feature, qemu needs to either give it to you, or fail, not silently
degrade the features presented to the guest.

>   Likely only for guests that transition themselves, but one could
>   argue that QEMU should simply be invoked a second time without the
>   sgm stuff being specified in the error case.

Right - I think whatever error we give here is likely to be easier to
diagnose than the guest itself throwing an error when it fails to
transition to secure mode (plus we should catch it always, rather than
only if we run a guest which tries to go secure).

-- 
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: [for-6.0 v5 12/13] securable guest memory: Alter virtio default properties for protected guests

2020-12-16 Thread David Gibson
On Tue, Dec 08, 2020 at 01:50:05PM +0100, Cornelia Huck wrote:
> On Tue, 8 Dec 2020 11:28:29 +0100
> Halil Pasic  wrote:
> 
> > On Tue, 8 Dec 2020 12:54:03 +1100
> > David Gibson  wrote:
> > 
> > > > > >>> + * Virtio devices can't count on directly accessing guest
> > > > > >>> + * memory, so they need iommu_platform=on to use normal 
> > > > > >>> DMA
> > > > > >>> + * mechanisms.  That requires also disabling legacy 
> > > > > >>> virtio
> > > > > >>> + * support for those virtio pci devices which allow it.
> > > > > >>> + */
> > > > > >>> +object_register_sugar_prop(TYPE_VIRTIO_PCI, 
> > > > > >>> "disable-legacy",
> > > > > >>> +   "on", true);
> > > > > >>> +object_register_sugar_prop(TYPE_VIRTIO_DEVICE, 
> > > > > >>> "iommu_platform",
> > > > > >>> +   "on", false);  
> > > > > >>
> > > > > >> I have not followed all the history (sorry). Should we also set 
> > > > > >> iommu_platform
> > > > > >> for virtio-ccw? Halil?
> > > > > >>
> > > > > > 
> > > > > > That line should add iommu_platform for all virtio devices, 
> > > > > > shouldn't
> > > > > > it?
> > > > > 
> > > > > Yes, sorry. Was misreading that with the line above. 
> > > > > 
> > > > 
> > > > I believe this is the best we can get. In a sense it is still a
> > > > pessimization,
> > > 
> > > I'm not really clear on what you're getting at here.  
> > 
> > By pessimiziation, I mean that we are going to indicate
> > _F_PLATFORM_ACCESS even if it isn't necessary, because the guest never
> > opted in for confidential/memory protection/memory encryption. We have
> > discussed this before, and I don't see a better solution that works for
> > everybody.
> 
> If you consider specifying the secure guest option as a way to tell
> QEMU to make everything ready for running a secure guest, I'd certainly
> consider it necessary. If you do not want to force it, you should not
> do the secure guest preparation setup.

Right, that's my feeling as well.

I'm also of the opinion that !F_PLATFORM_ACCESS is kind of a nasty
hack that has some other problems (e.g. it means an L1 can't safely
pass the device into an L2).

-- 
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 v2 1/3] net: checksum: Skip fragmented IP packets

2020-12-16 Thread Bin Meng
Hi Jason,

On Fri, Dec 11, 2020 at 5:35 PM Bin Meng  wrote:
>
> From: Markus Carlstedt 
>
> To calculate the TCP/UDP checksum we need the whole datagram. Unless
> the hardware has some logic to collect all fragments before sending
> the whole datagram first, it can only be done by the network stack,
> which is normally the case for the NICs we have seen so far.
>
> Skip these fragmented IP packets to avoid checksum corruption.
>
> Signed-off-by: Markus Carlstedt 
> Signed-off-by: Bin Meng 
> ---
>
> (no changes since v1)
>
>  net/checksum.c | 4 
>  1 file changed, 4 insertions(+)
>

Ping?

Regards,
Bin



[PATCH 1/2] hw/ssi: imx_spi: Correct the burst length > 32 bit transfer logic

2020-12-16 Thread Bin Meng
From: Bin Meng 

For the ECSPIx_CONREG register BURST_LENGTH field, the manual says:

0x020 A SPI burst contains the 1 LSB in first word and all 32 bits in second 
word.
0x021 A SPI burst contains the 2 LSB in first word and all 32 bits in second 
word.

Current logic uses either s->burst_length or 32, whichever smaller,
to determine how many bits it should read from the tx fifo each time.
For example, for a 48 bit burst length, current logic transfers the
first 32 bit from the first word in the tx fifo, followed by a 16
bit from the second word in the tx fifo, which is wrong. The correct
logic should be: transfer the first 16 bit from the first word in
the tx fifo, followed by a 32 bit from the second word in the tx fifo.

With this change, SPI flash can be successfully probed by U-Boot on
imx6 sabrelite board.

  => sf probe
  SF: Detected sst25vf016b with page size 256 Bytes, erase size 4 KiB, total 2 
MiB

Fixes: c906a3a01582 ("i.MX: Add the Freescale SPI Controller")
Signed-off-by: Bin Meng 
---

 hw/ssi/imx_spi.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
index 85c172e..509fb9f 100644
--- a/hw/ssi/imx_spi.c
+++ b/hw/ssi/imx_spi.c
@@ -178,7 +178,10 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
 
 DPRINTF("data tx:0x%08x\n", tx);
 
-tx_burst = MIN(s->burst_length, 32);
+tx_burst = s->burst_length % 32;
+if (tx_burst == 0) {
+tx_burst = 32;
+}
 
 rx = 0;
 
-- 
2.7.4




[PATCH 2/2] hw/ssi: imx_spi: Correct tx and rx fifo endianness

2020-12-16 Thread Bin Meng
From: Bin Meng 

The endianness of data exchange between tx and rx fifo is incorrect.
Earlier bytes are supposed to show up on MSB and later bytes on LSB,
ie: in big endian. The manual does not explicitly say this, but the
U-Boot and Linux driver codes have a swap on the data transferred
to tx fifo and from rx fifo.

With this change, U-Boot read from / write to SPI flash tests pass.

  => sf test 1ff000 1000
  SPI flash test:
  0 erase: 0 ticks, 4096000 KiB/s 32768.000 Mbps
  1 check: 3 ticks, 1333 KiB/s 10.664 Mbps
  2 write: 235 ticks, 17 KiB/s 0.136 Mbps
  3 read: 2 ticks, 2000 KiB/s 16.000 Mbps
  Test passed
  0 erase: 0 ticks, 4096000 KiB/s 32768.000 Mbps
  1 check: 3 ticks, 1333 KiB/s 10.664 Mbps
  2 write: 235 ticks, 17 KiB/s 0.136 Mbps
  3 read: 2 ticks, 2000 KiB/s 16.000 Mbps

Fixes: c906a3a01582 ("i.MX: Add the Freescale SPI Controller")
Signed-off-by: Bin Meng 

---

 hw/ssi/imx_spi.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
index 509fb9f..71f0902 100644
--- a/hw/ssi/imx_spi.c
+++ b/hw/ssi/imx_spi.c
@@ -156,13 +156,14 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
 {
 uint32_t tx;
 uint32_t rx;
+uint32_t data;
+uint8_t byte;
 
 DPRINTF("Begin: TX Fifo Size = %d, RX Fifo Size = %d\n",
 fifo32_num_used(>tx_fifo), fifo32_num_used(>rx_fifo));
 
 while (!fifo32_is_empty(>tx_fifo)) {
 int tx_burst = 0;
-int index = 0;
 
 if (s->burst_length <= 0) {
 s->burst_length = imx_spi_burst_length(s);
@@ -183,10 +184,18 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
 tx_burst = 32;
 }
 
+data = 0;
+for (int i = 0; i < tx_burst / 8; i++) {
+byte = tx & 0xff;
+tx = tx >> 8;
+data = (data << 8) | byte;
+}
+tx = data;
+
 rx = 0;
 
 while (tx_burst > 0) {
-uint8_t byte = tx & 0xff;
+byte = tx & 0xff;
 
 DPRINTF("writing 0x%02x\n", (uint32_t)byte);
 
@@ -196,12 +205,11 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
 DPRINTF("0x%02x read\n", (uint32_t)byte);
 
 tx = tx >> 8;
-rx |= (byte << (index * 8));
+rx = (rx << 8) | byte;
 
 /* Remove 8 bits from the actual burst */
 tx_burst -= 8;
 s->burst_length -= 8;
-index++;
 }
 
 DPRINTF("data rx:0x%08x\n", rx);
-- 
2.7.4




hexagon sysemu - library loading path feature

2020-12-16 Thread Brian Cain
My team is working on sysemu support for Hexagon.  We've made some good 
progress so far and we'll work on upstreaming after Taylor’s hexagon linux-user 
patch series lands.

The only use case we have focused on with sysemu is booting/running elf 
programs.  Both "-device loader,file=..." or "-kernel" are effective and work 
similarly.  We have implemented "angel calls" (semihosting) to do host I/O.  We 
have not yet tried using the QEMU semihosting features/cmdline args, but may 
explore that option.

One feature we'd like to integrate is a guest library search path feature.  The 
existing hexagon simulator program distributed in the Hexagon SDK has a command 
line option, “--usefs".  The manual states that it “Cause[s] the simulator to 
search for files in the directory with the specified path. It is used for 
accessing shared object files that are loaded during program execution.”  If 
the guest OS has a loader that tries to resolve an executable or library's 
DT_NEEDED shared object libraries, we would want QEMU angel calls to be able to 
search a user specified host-path for the toolchain language support libraries.

This feature is like the functionality in QEMU’s “QEMU_LD_PREFIX” environment 
variable used by linux-userspace.  So, one idea was to just (ab)use this 
interface to mean the same thing for sysemu.  We could make it a 
target-specific hexagon feature, if it doesn’t make sense to have it as 
target-independent.  And if it makes sense we could qualify it like 
HEXAGON_QEMU_LD_PREFIX.

If not this environment variable, is there an existing QEMU feature that maps 
well here?  Or is there a better interface that we should consider instead?

-Brian



Re:[PATCH v2 0/5] Fix some style problems in contrib

2020-12-16 Thread zhouyang (T)
kindly ping

>v1 -> v2:
>Changed the "From:" and "Signed-off-by:" lines from "zhouyang (T)"
>to my real name "zhouyang".
>
>I found some style problems while check the code using checkpatch.pl
>and fixed them, please review.
>
>zhouyang (5):
>  contrib: Don't use '#' flag of printf format
>  contrib: Fix some code style problems, ERROR: "foo * bar" should be
>"foo *bar"
>  contrib: Add spaces around operator
>  contrib: space required after that ','
>  contrib: Open brace '{' following struct go on the same line
>
> contrib/ivshmem-server/main.c |  2 +-
> contrib/plugins/hotblocks.c   |  2 +-
> contrib/plugins/hotpages.c|  2 +-
> contrib/plugins/howvec.c  | 19 +--
> contrib/plugins/lockstep.c|  6 +++---
> 5 files changed, 15 insertions(+), 16 deletions(-)
>
>--
>2.23.0




Re: [PATCH] tests/acceptance: Test PMON with Loongson-3A1000 CPU

2020-12-16 Thread Jiaxun Yang




在 2020/12/17 上午2:17, Philippe Mathieu-Daudé 写道:

Test the PMON firmware. As the firmware is not redistributable,
it has to be downloaded manually first. Then it can be used by
providing its path via the PMON_PATH environment variable:


We have a PMON port for loongson3-virt machine[1] and it's redistributable.

You can also fetch prebuilt binary from GitHub action artifacts, I can 
also make

a release on GitHub to make it easier.

Thanks.

[1] https://github.com/loongson-community/pmon

- Jiaxun


   $ AVOCADO_ALLOW_UNTRUSTED_CODE=1 \
 PMON_PATH=/images/pmon \
 avocado --show=app,console \
   run -t machine:loongson3-virt tests/acceptance
   JOB ID : 363e66a2d20b1c0e3f515653f9137483b83b2984
   JOB LOG: 
/home/phil/avocado/job-results/job-2020-12-16T19.02-363e66a/job.log
(1/2) 
tests/acceptance/machine_mips_fuloong3.py:MipsFuloong3.test_pmon_BLD_serial_console:
   console: PMON2000 MIPS Initializing. Standby...
   console: 
   console: Shut down other cores
   console: 0xbfe00190  : 
   console: CPU CLK SEL : 
   console: MEM CLK SEL : 
   console: Change the driver
   console: Soft CLK SEL adjust begin
   console: HT :
   console: DDR_DIV:0002
   console: BBGEN start  :
   console: BBGEN config value  :
   console: MC RESET
   console: Fix L1xbar illegal access at NODE 0
   console: Fix L2xbar in NODE 0
   console: 32 bit PCI space translate to 64 bit HT space
   console: Waiting HyperTransport bus to be up.
   PASS (0.10 s)
(2/2) 
tests/acceptance/machine_mips_fuloong3.py:MipsFuloong3.test_pmon_A1101_serial_console:
   console: PMON2000 MIPS Initializing. Standby...
   console: 0xbfe00190  : 
   console: CPU CLK SEL : 
   console: CPU clk frequency = SYSCLK x 0x001e /  1
   console: MEM CLK SEL : 
   console: DDR clk frequency = MEMCLK x 0x001e /  3
   console: Fix L1xbar illegal access
   console: Fix L2xbar illegal access
   console: Init tlb...
   console: godson2 caches found
   PASS (0.12 s)
   RESULTS: PASS 2 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | 
CANCEL 0
   JOB TIME   : 0.58 s

Signed-off-by: Philippe Mathieu-Daudé 
---
Based-on: <20201215125716.477023-1-chenhua...@kernel.org>
---
  MAINTAINERS |  1 +
  tests/acceptance/machine_mips_loongson3v.py | 66 +
  2 files changed, 67 insertions(+)
  create mode 100644 tests/acceptance/machine_mips_loongson3v.py

diff --git a/MAINTAINERS b/MAINTAINERS
index f75fa2a7142..9a02d44f997 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1166,6 +1166,7 @@ M: Huacai Chen 
  R: Jiaxun Yang 
  S: Maintained
  F: hw/intc/loongson_liointc.c
+F: tests/acceptance/machine_mips_loongson3v.py
  
  Boston

  M: Paul Burton 
diff --git a/tests/acceptance/machine_mips_loongson3v.py 
b/tests/acceptance/machine_mips_loongson3v.py
new file mode 100644
index 000..8e698bbc99b
--- /dev/null
+++ b/tests/acceptance/machine_mips_loongson3v.py
@@ -0,0 +1,66 @@
+# Functional tests for the Generic Loongson-3 Platform.
+#
+# Copyright (c) 2020 Philippe Mathieu-Daudé 
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import os
+import time
+
+from avocado import skipUnless
+from avocado_qemu import Test
+from avocado_qemu import wait_for_console_pattern
+
+class MipsFuloong3(Test):
+
+timeout = 60
+
+@skipUnless(os.getenv('PMON_PATH'), 'PMON_PATH not available')
+@skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
+def test_pmon_BLD_serial_console(self):
+"""
+:avocado: tags=arch:mips64el
+:avocado: tags=endian:little
+:avocado: tags=machine:loongson3-virt
+:avocado: tags=cpu:Loongson-3A1000
+:avocado: tags=device:liointc
+:avocado: tags=device:goldfish_rtc
+"""
+pmon_name = 'pmon_BLD-3A3000-780EMATX-1w-V1.10.bin'
+pmon_hash = '38916ee03ed09a86997b40c687c83e92'
+pmon_path = self.fetch_asset('file://' + os.path.join(
+os.getenv('PMON_PATH'), pmon_name),
+ asset_hash=pmon_hash, algorithm='md5')
+
+self.vm.set_console()
+self.vm.add_args('-bios', pmon_path)
+self.vm.launch()
+wait_for_console_pattern(self, 'PMON2000 MIPS Initializing. 
Standby...')
+wait_for_console_pattern(self, 'Shut down other cores')
+wait_for_console_pattern(self, 'Waiting HyperTransport bus to be up.')
+
+@skipUnless(os.getenv('PMON_PATH'), 'PMON_PATH not available')
+@skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
+def test_pmon_A1101_serial_console(self):
+"""
+:avocado: tags=arch:mips64el
+:avocado: tags=endian:little
+:avocado: tags=machine:loongson3-virt
+

[PATCH v2 09/12] qapi/gen: move write method to QAPIGenC, make fname a str

2020-12-16 Thread John Snow
QAPIGenC and QAPIGenH in particular depend on fname being defined, but
we have a usage of QAPIGenCCode that isn't intended to be associated
with a particular file.

No problem, move the write method down to the class that actually needs
it, and keep QAPIGenCCode more abstract.

Signed-off-by: John Snow 

---

Possibly un-needed in concert with a forthcoming patch by Markus, but I
didn't have it in my hands at time of publishing.

Signed-off-by: John Snow 
---
 scripts/qapi/commands.py |  2 +-
 scripts/qapi/gen.py  | 54 
 2 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
index 71744f48a35..b346676d15a 100644
--- a/scripts/qapi/commands.py
+++ b/scripts/qapi/commands.py
@@ -258,7 +258,7 @@ def __init__(self, prefix: str):
 super().__init__(
 prefix, 'qapi-commands',
 ' * Schema-defined QAPI/QMP commands', None, __doc__)
-self._regy = QAPIGenCCode(None)
+self._regy = QAPIGenCCode()
 self._visited_ret_types: Dict[QAPIGenC, Set[QAPISchemaType]] = {}
 
 def _begin_user_module(self, name: str) -> None:
diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
index 12ea98fb61e..2dd99635e74 100644
--- a/scripts/qapi/gen.py
+++ b/scripts/qapi/gen.py
@@ -36,8 +36,7 @@
 
 
 class QAPIGen:
-def __init__(self, fname: Optional[str]):
-self.fname = fname
+def __init__(self) -> None:
 self._preamble = ''
 self._body = ''
 
@@ -58,28 +57,6 @@ def _bottom(self) -> str:
 # pylint: disable=no-self-use
 return ''
 
-def write(self, output_dir: str) -> None:
-# Include paths starting with ../ are used to reuse modules of the main
-# schema in specialised schemas. Don't overwrite the files that are
-# already generated for the main schema.
-if self.fname.startswith('../'):
-return
-pathname = os.path.join(output_dir, self.fname)
-odir = os.path.dirname(pathname)
-
-if odir:
-os.makedirs(odir, exist_ok=True)
-
-# use os.open for O_CREAT to create and read a non-existant file
-fd = os.open(pathname, os.O_RDWR | os.O_CREAT, 0o666)
-with os.fdopen(fd, 'r+', encoding='utf-8') as fp:
-text = self.get_content()
-oldtext = fp.read(len(text) + 1)
-if text != oldtext:
-fp.seek(0)
-fp.truncate(0)
-fp.write(text)
-
 
 def _wrap_ifcond(ifcond: List[str], before: str, after: str) -> str:
 if before == after:
@@ -121,8 +98,8 @@ def build_params(arg_type: Optional[QAPISchemaObjectType],
 
 
 class QAPIGenCCode(QAPIGen):
-def __init__(self, fname: Optional[str]):
-super().__init__(fname)
+def __init__(self) -> None:
+super().__init__()
 self._start_if: Optional[Tuple[List[str], str, str]] = None
 
 def start_if(self, ifcond: List[str]) -> None:
@@ -147,11 +124,34 @@ def get_content(self) -> str:
 
 class QAPIGenC(QAPIGenCCode):
 def __init__(self, fname: str, blurb: str, pydoc: str):
-super().__init__(fname)
+super().__init__()
+self.fname = fname
 self._blurb = blurb
 self._copyright = '\n * '.join(re.findall(r'^Copyright .*', pydoc,
   re.MULTILINE))
 
+def write(self, output_dir: str) -> None:
+# Include paths starting with ../ are used to reuse modules of the main
+# schema in specialised schemas. Don't overwrite the files that are
+# already generated for the main schema.
+if self.fname.startswith('../'):
+return
+pathname = os.path.join(output_dir, self.fname)
+odir = os.path.dirname(pathname)
+
+if odir:
+os.makedirs(odir, exist_ok=True)
+
+# use os.open for O_CREAT to create and read a non-existant file
+fd = os.open(pathname, os.O_RDWR | os.O_CREAT, 0o666)
+with os.fdopen(fd, 'r+', encoding='utf-8') as fp:
+text = self.get_content()
+oldtext = fp.read(len(text) + 1)
+if text != oldtext:
+fp.seek(0)
+fp.truncate(0)
+fp.write(text)
+
 def _top(self) -> str:
 return mcgen('''
 /* AUTOMATICALLY GENERATED, DO NOT MODIFY */
-- 
2.26.2




[PATCH v2 06/12] qapi/source: Add builtin null-object sentinel

2020-12-16 Thread John Snow
We use None to represent an object that has no source information
because it's a builtin. This complicates interface typing, since many
interfaces expect that there is an info object available to print errors
with.

Introduce a special QAPISourceInfo that represents these built-ins so
that if an error should so happen to occur relating to one of these
builtins that we will be able to print its information, and interface
typing becomes simpler: you will always have a source info object.

This object will evaluate as False, so "if info" remains a valid
idiomatic construct.

NB: It was intentional to not allow empty constructors or similar to
create "empty" source info objects; callers must explicitly invoke
'builtin()' to pro-actively opt into using the sentinel. This should
prevent use-by-accident.

Signed-off-by: John Snow 
---
 scripts/qapi/source.py | 20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/scripts/qapi/source.py b/scripts/qapi/source.py
index d7a79a9b8ae..a049b73b57b 100644
--- a/scripts/qapi/source.py
+++ b/scripts/qapi/source.py
@@ -11,7 +11,12 @@
 
 import copy
 import sys
-from typing import List, Optional, TypeVar
+from typing import (
+List,
+Optional,
+Type,
+TypeVar,
+)
 
 
 class QAPISchemaPragma:
@@ -41,6 +46,17 @@ def __init__(self, fname: str, line: int,
 self.defn_meta: Optional[str] = None
 self.defn_name: Optional[str] = None
 
+@classmethod
+def builtin(cls: Type[T]) -> T:
+"""
+Create an instance corresponding to a built-in definition.
+"""
+return cls('', -1, None)
+
+def __bool__(self) -> bool:
+# "if info" is false if @info corresponds to a built-in definition.
+return bool(self.fname)
+
 def set_defn(self, meta: str, name: str) -> None:
 self.defn_meta = meta
 self.defn_name = name
@@ -73,4 +89,6 @@ def include_path(self) -> str:
 return ret
 
 def __str__(self) -> str:
+if not bool(self):
+return '[builtin]'
 return self.include_path() + self.in_defn() + self.loc()
-- 
2.26.2




[PATCH v2 10/12] tests/qapi-schema: Add quotes to module name in test output

2020-12-16 Thread John Snow
A forthcoming patch is going to allow the empty string as a name for the
builtin module, and quotes will help us see that in test output. Without
this, git will be upset about trailing empty spaces in test output, so
the quotes are necessary.

Signed-off-by: John Snow 
---
 tests/qapi-schema/comments.out   | 4 ++--
 tests/qapi-schema/doc-good.out   | 4 ++--
 tests/qapi-schema/empty.out  | 4 ++--
 tests/qapi-schema/event-case.out | 4 ++--
 tests/qapi-schema/include-repetition.out | 8 
 tests/qapi-schema/include-simple.out | 6 +++---
 tests/qapi-schema/indented-expr.out  | 4 ++--
 tests/qapi-schema/qapi-schema-test.out   | 8 
 tests/qapi-schema/test-qapi.py   | 2 +-
 9 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/tests/qapi-schema/comments.out b/tests/qapi-schema/comments.out
index 273f0f54e16..08aba8354e2 100644
--- a/tests/qapi-schema/comments.out
+++ b/tests/qapi-schema/comments.out
@@ -1,4 +1,4 @@
-module None
+module "None"
 object q_empty
 enum QType
 prefix QTYPE
@@ -9,7 +9,7 @@ enum QType
 member qdict
 member qlist
 member qbool
-module comments.json
+module "comments.json"
 enum Status
 member good
 member bad
diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
index 419284dae29..83a3d9bd69b 100644
--- a/tests/qapi-schema/doc-good.out
+++ b/tests/qapi-schema/doc-good.out
@@ -1,4 +1,4 @@
-module None
+module "None"
 object q_empty
 enum QType
 prefix QTYPE
@@ -9,7 +9,7 @@ enum QType
 member qdict
 member qlist
 member qbool
-module doc-good.json
+module "doc-good.json"
 enum Enum
 member one
 if ['defined(IFONE)']
diff --git a/tests/qapi-schema/empty.out b/tests/qapi-schema/empty.out
index 69666c39ad2..0dac23c80c1 100644
--- a/tests/qapi-schema/empty.out
+++ b/tests/qapi-schema/empty.out
@@ -1,4 +1,4 @@
-module None
+module "None"
 object q_empty
 enum QType
 prefix QTYPE
@@ -9,4 +9,4 @@ enum QType
 member qdict
 member qlist
 member qbool
-module empty.json
+module "empty.json"
diff --git a/tests/qapi-schema/event-case.out b/tests/qapi-schema/event-case.out
index 42ae519656d..ace511ba5a9 100644
--- a/tests/qapi-schema/event-case.out
+++ b/tests/qapi-schema/event-case.out
@@ -1,4 +1,4 @@
-module None
+module "None"
 object q_empty
 enum QType
 prefix QTYPE
@@ -9,6 +9,6 @@ enum QType
 member qdict
 member qlist
 member qbool
-module event-case.json
+module "event-case.json"
 event oops None
 boxed=False
diff --git a/tests/qapi-schema/include-repetition.out 
b/tests/qapi-schema/include-repetition.out
index 0b654ddebb6..f7ab4987943 100644
--- a/tests/qapi-schema/include-repetition.out
+++ b/tests/qapi-schema/include-repetition.out
@@ -1,4 +1,4 @@
-module None
+module "None"
 object q_empty
 enum QType
 prefix QTYPE
@@ -9,15 +9,15 @@ enum QType
 member qdict
 member qlist
 member qbool
-module include-repetition.json
+module "include-repetition.json"
 include comments.json
 include include-repetition-sub.json
 include comments.json
-module comments.json
+module "comments.json"
 enum Status
 member good
 member bad
 member ugly
-module include-repetition-sub.json
+module "include-repetition-sub.json"
 include comments.json
 include comments.json
diff --git a/tests/qapi-schema/include-simple.out 
b/tests/qapi-schema/include-simple.out
index 061f81e5090..81bdeb887b6 100644
--- a/tests/qapi-schema/include-simple.out
+++ b/tests/qapi-schema/include-simple.out
@@ -1,4 +1,4 @@
-module None
+module "None"
 object q_empty
 enum QType
 prefix QTYPE
@@ -9,9 +9,9 @@ enum QType
 member qdict
 member qlist
 member qbool
-module include-simple.json
+module "include-simple.json"
 include include-simple-sub.json
-module include-simple-sub.json
+module "include-simple-sub.json"
 enum Status
 member good
 member bad
diff --git a/tests/qapi-schema/indented-expr.out 
b/tests/qapi-schema/indented-expr.out
index 04356775cd1..361a58185e6 100644
--- a/tests/qapi-schema/indented-expr.out
+++ b/tests/qapi-schema/indented-expr.out
@@ -1,4 +1,4 @@
-module None
+module "None"
 object q_empty
 enum QType
 prefix QTYPE
@@ -9,7 +9,7 @@ enum QType
 member qdict
 member qlist
 member qbool
-module indented-expr.json
+module "indented-expr.json"
 command eins None -> None
 gen=True success_response=True boxed=False oob=False preconfig=False
 command zwei None -> None
diff --git a/tests/qapi-schema/qapi-schema-test.out 
b/tests/qapi-schema/qapi-schema-test.out
index 8868ca0dca9..4f5ab9fd596 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -1,4 +1,4 @@
-module None
+module "None"
 object q_empty
 enum QType
 prefix QTYPE
@@ -9,7 +9,7 @@ enum QType
 member qdict
 member qlist
 member qbool
-module qapi-schema-test.json
+module "qapi-schema-test.json"
 object TestStruct
 member integer: int optional=False
 

[PATCH v2 11/12] qapi/schema: Name the builtin module "" instead of None

2020-12-16 Thread John Snow
Instead of using None as the built-in module filename, use an empty
string instead. This allows us to clarify the type of various interfaces
dealing with module names as always taking a string, which saves us from
having to use Optional[str] everywhere.

Signed-off-by: John Snow 
---
 scripts/qapi/gen.py  |  6 +++---
 scripts/qapi/schema.py   | 12 ++--
 scripts/qapi/types.py|  2 +-
 scripts/qapi/visit.py|  2 +-
 tests/qapi-schema/comments.out   |  2 +-
 tests/qapi-schema/doc-good.out   |  2 +-
 tests/qapi-schema/empty.out  |  2 +-
 tests/qapi-schema/event-case.out |  2 +-
 tests/qapi-schema/include-repetition.out |  2 +-
 tests/qapi-schema/include-simple.out |  2 +-
 tests/qapi-schema/indented-expr.out  |  2 +-
 tests/qapi-schema/qapi-schema-test.out   |  2 +-
 12 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
index 2dd99635e74..1933090a2a0 100644
--- a/scripts/qapi/gen.py
+++ b/scripts/qapi/gen.py
@@ -310,14 +310,14 @@ def write(self, output_dir: str, opt_builtins: bool = 
False) -> None:
 genc.write(output_dir)
 genh.write(output_dir)
 
-def _begin_system_module(self, name: None) -> None:
+def _begin_system_module(self, name: str) -> None:
 pass
 
 def _begin_user_module(self, name: str) -> None:
 pass
 
-def visit_module(self, name: Optional[str]) -> None:
-if name is None:
+def visit_module(self, name: str) -> None:
+if not name:
 if self._builtin_blurb:
 self._add_system_module('builtin', self._builtin_blurb)
 self._begin_system_module(name)
diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
index 0449771dfe5..0235208966a 100644
--- a/scripts/qapi/schema.py
+++ b/scripts/qapi/schema.py
@@ -69,7 +69,7 @@ def check_doc(self):
 
 def _set_module(self, schema, info):
 assert self._checked
-self._module = schema.module_by_fname(info.fname if info else None)
+self._module = schema.module_by_fname(info.fname)
 self._module.add_entity(self)
 
 def set_module(self, schema):
@@ -826,7 +826,7 @@ def __init__(self, fname):
 self._entity_dict = {}
 self._module_dict = OrderedDict()
 self._schema_dir = os.path.dirname(fname)
-self._make_module(None)  # built-ins
+self._make_module(QAPISourceInfo.builtin().fname)  # built-ins
 self._make_module(fname)
 self._predefining = True
 self._def_predefineds()
@@ -871,10 +871,10 @@ def resolve_type(self, name, info, what):
 info, "%s uses unknown type '%s'" % (what, name))
 return typ
 
-def _module_name(self, fname):
-if fname is None:
-return None
-return os.path.relpath(fname, self._schema_dir)
+def _module_name(self, fname: str) -> str:
+if fname:
+return os.path.relpath(fname, self._schema_dir)
+return fname
 
 def _make_module(self, fname):
 name = self._module_name(fname)
diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py
index a3a16284006..12eeea3aaff 100644
--- a/scripts/qapi/types.py
+++ b/scripts/qapi/types.py
@@ -272,7 +272,7 @@ def __init__(self, prefix: str):
 prefix, 'qapi-types', ' * Schema-defined QAPI types',
 ' * Built-in QAPI types', __doc__)
 
-def _begin_system_module(self, name: None) -> None:
+def _begin_system_module(self, name: str) -> None:
 self._genc.preamble_add(mcgen('''
 #include "qemu/osdep.h"
 #include "qapi/dealloc-visitor.h"
diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py
index 3f49c307c56..76e34ee7f02 100644
--- a/scripts/qapi/visit.py
+++ b/scripts/qapi/visit.py
@@ -305,7 +305,7 @@ def __init__(self, prefix: str):
 prefix, 'qapi-visit', ' * Schema-defined QAPI visitors',
 ' * Built-in QAPI visitors', __doc__)
 
-def _begin_system_module(self, name: None) -> None:
+def _begin_system_module(self, name: str) -> None:
 self._genc.preamble_add(mcgen('''
 #include "qemu/osdep.h"
 #include "qapi/error.h"
diff --git a/tests/qapi-schema/comments.out b/tests/qapi-schema/comments.out
index 08aba8354e2..02000c06e5e 100644
--- a/tests/qapi-schema/comments.out
+++ b/tests/qapi-schema/comments.out
@@ -1,4 +1,4 @@
-module "None"
+module ""
 object q_empty
 enum QType
 prefix QTYPE
diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
index 83a3d9bd69b..494533d7479 100644
--- a/tests/qapi-schema/doc-good.out
+++ b/tests/qapi-schema/doc-good.out
@@ -1,4 +1,4 @@
-module "None"
+module ""
 object q_empty
 enum QType
 prefix QTYPE
diff --git a/tests/qapi-schema/empty.out b/tests/qapi-schema/empty.out
index 0dac23c80c1..059caa4e1d2 100644
--- a/tests/qapi-schema/empty.out
+++ b/tests/qapi-schema/empty.out
@@ -1,4 +1,4 @@

[PATCH v2 08/12] qapi/gen: write _genc/_genh access shims

2020-12-16 Thread John Snow
Many places assume they can access these fields without checking them
first to ensure they are defined. Eliminating the _genc and _genh fields
and replacing them with functional properties that check for correct
state can ease the typing overhead by eliminating the Optional[T] return
type.

Signed-off-by: John Snow 
---
 scripts/qapi/gen.py | 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
index 476d0adac4e..12ea98fb61e 100644
--- a/scripts/qapi/gen.py
+++ b/scripts/qapi/gen.py
@@ -243,11 +243,20 @@ def __init__(self,
 self._user_blurb = user_blurb
 self._builtin_blurb = builtin_blurb
 self._pydoc = pydoc
-self._genc: Optional[QAPIGenC] = None
-self._genh: Optional[QAPIGenH] = None
+self._current_module: Optional[str] = None
 self._module: Dict[str, Tuple[QAPIGenC, QAPIGenH]] = {}
 self._main_module: Optional[str] = None
 
+@property
+def _genc(self) -> QAPIGenC:
+assert self._current_module is not None
+return self._module[self._current_module][0]
+
+@property
+def _genh(self) -> QAPIGenH:
+assert self._current_module is not None
+return self._module[self._current_module][1]
+
 @staticmethod
 def _is_user_module(name: str) -> bool:
 return not name.startswith('./')
@@ -282,7 +291,7 @@ def _add_module(self, name: str, blurb: str) -> None:
 genc = QAPIGenC(basename + '.c', blurb, self._pydoc)
 genh = QAPIGenH(basename + '.h', blurb, self._pydoc)
 self._module[name] = (genc, genh)
-self._genc, self._genh = self._module[name]
+self._current_module = name
 
 def _add_user_module(self, name: str, blurb: str) -> None:
 assert self._is_user_module(name)
@@ -315,8 +324,7 @@ def visit_module(self, name: Optional[str]) -> None:
 else:
 # The built-in module has not been created.  No code may
 # be generated.
-self._genc = None
-self._genh = None
+self._current_module = None
 else:
 self._add_user_module(name, self._user_blurb)
 self._begin_user_module(name)
-- 
2.26.2




[PATCH v2 05/12] qapi/gen: use './builtin' for the built-in module name

2020-12-16 Thread John Snow
Use this in preference to 'None', which helps remove some edge cases in
the typing.

Signed-off-by: John Snow 
---
 scripts/qapi/gen.py | 28 ++--
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
index a6dc991b1d0..476d0adac4e 100644
--- a/scripts/qapi/gen.py
+++ b/scripts/qapi/gen.py
@@ -245,23 +245,23 @@ def __init__(self,
 self._pydoc = pydoc
 self._genc: Optional[QAPIGenC] = None
 self._genh: Optional[QAPIGenH] = None
-self._module: Dict[Optional[str], Tuple[QAPIGenC, QAPIGenH]] = {}
+self._module: Dict[str, Tuple[QAPIGenC, QAPIGenH]] = {}
 self._main_module: Optional[str] = None
 
 @staticmethod
-def _is_user_module(name: Optional[str]) -> bool:
-return bool(name and not name.startswith('./'))
+def _is_user_module(name: str) -> bool:
+return not name.startswith('./')
 
 @staticmethod
-def _is_builtin_module(name: Optional[str]) -> bool:
-return not name
+def _is_builtin_module(name: str) -> bool:
+return name == './builtin'
 
-def _module_dirname(self, name: Optional[str]) -> str:
+def _module_dirname(self, name: str) -> str:
 if self._is_user_module(name):
 return os.path.dirname(name)
 return ''
 
-def _module_basename(self, what: str, name: Optional[str]) -> str:
+def _module_basename(self, what: str, name: str) -> str:
 ret = '' if self._is_builtin_module(name) else self._prefix
 if self._is_user_module(name):
 basename = os.path.basename(name)
@@ -269,15 +269,15 @@ def _module_basename(self, what: str, name: 
Optional[str]) -> str:
 if name != self._main_module:
 ret += '-' + os.path.splitext(basename)[0]
 else:
-name = name[2:] if name else 'builtin'
-ret += re.sub(r'-', '-' + name + '-', what)
+assert name.startswith('./')
+ret += re.sub(r'-', '-' + name[2:] + '-', what)
 return ret
 
-def _module_filename(self, what: str, name: Optional[str]) -> str:
+def _module_filename(self, what: str, name: str) -> str:
 return os.path.join(self._module_dirname(name),
 self._module_basename(what, name))
 
-def _add_module(self, name: Optional[str], blurb: str) -> None:
+def _add_module(self, name: str, blurb: str) -> None:
 basename = self._module_filename(self._what, name)
 genc = QAPIGenC(basename + '.c', blurb, self._pydoc)
 genh = QAPIGenH(basename + '.h', blurb, self._pydoc)
@@ -290,8 +290,8 @@ def _add_user_module(self, name: str, blurb: str) -> None:
 self._main_module = name
 self._add_module(name, blurb)
 
-def _add_system_module(self, name: Optional[str], blurb: str) -> None:
-self._add_module(name and './' + name, blurb)
+def _add_system_module(self, name: str, blurb: str) -> None:
+self._add_module('./' + name, blurb)
 
 def write(self, output_dir: str, opt_builtins: bool = False) -> None:
 for name in self._module:
@@ -310,7 +310,7 @@ def _begin_user_module(self, name: str) -> None:
 def visit_module(self, name: Optional[str]) -> None:
 if name is None:
 if self._builtin_blurb:
-self._add_system_module(None, self._builtin_blurb)
+self._add_system_module('builtin', self._builtin_blurb)
 self._begin_system_module(name)
 else:
 # The built-in module has not been created.  No code may
-- 
2.26.2




[PATCH v2 07/12] qapi/schema: make QAPISourceInfo mandatory

2020-12-16 Thread John Snow
Signed-off-by: John Snow 

---

The event_enum_members change might become irrelevant after a
forthcoming (?) patch by Markus, but didn't have it in-hand at time of
publishing.

Signed-off-by: John Snow 
---
 scripts/qapi/events.py |  2 +-
 scripts/qapi/schema.py | 25 ++---
 scripts/qapi/types.py  |  9 +
 scripts/qapi/visit.py  |  6 +++---
 4 files changed, 23 insertions(+), 19 deletions(-)

diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py
index 9851653b9d1..9ba4f109028 100644
--- a/scripts/qapi/events.py
+++ b/scripts/qapi/events.py
@@ -225,7 +225,7 @@ def visit_event(self,
   self._event_emit_name))
 # Note: we generate the enum member regardless of @ifcond, to
 # keep the enumeration usable in target-independent code.
-self._event_enum_members.append(QAPISchemaEnumMember(name, None))
+self._event_enum_members.append(QAPISchemaEnumMember(name, info))
 
 
 def gen_events(schema: QAPISchema,
diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
index 720449feee4..0449771dfe5 100644
--- a/scripts/qapi/schema.py
+++ b/scripts/qapi/schema.py
@@ -23,6 +23,7 @@
 from .error import QAPIError, QAPISemError
 from .expr import check_exprs
 from .parser import QAPISchemaParser
+from .source import QAPISourceInfo
 
 
 class QAPISchemaEntity:
@@ -36,10 +37,10 @@ def __init__(self, name, info, doc, ifcond=None, 
features=None):
 self.name = name
 self._module = None
 # For explicitly defined entities, info points to the (explicit)
-# definition.  For builtins (and their arrays), info is None.
-# For implicitly defined entities, info points to a place that
-# triggered the implicit definition (there may be more than one
-# such place).
+# definition. For built-in types (and their arrays), info is a
+# special object that evaluates to False. For implicitly defined
+# entities, info points to a place that triggered the implicit
+# definition (there may be more than one such place).
 self.info = info
 self.doc = doc
 self._ifcond = ifcond or []
@@ -68,7 +69,7 @@ def check_doc(self):
 
 def _set_module(self, schema, info):
 assert self._checked
-self._module = schema.module_by_fname(info and info.fname)
+self._module = schema.module_by_fname(info.fname if info else None)
 self._module.add_entity(self)
 
 def set_module(self, schema):
@@ -209,7 +210,7 @@ class QAPISchemaBuiltinType(QAPISchemaType):
 meta = 'built-in'
 
 def __init__(self, name, json_type, c_type):
-super().__init__(name, None, None)
+super().__init__(name, QAPISourceInfo.builtin(), None)
 assert not c_type or isinstance(c_type, str)
 assert json_type in ('string', 'number', 'int', 'boolean', 'null',
  'value')
@@ -897,7 +898,7 @@ def _def_builtin_type(self, name, json_type, c_type):
 # be nice, but we can't as long as their generated code
 # (qapi-builtin-types.[ch]) may be shared by some other
 # schema.
-self._make_array_type(name, None)
+self._make_array_type(name, QAPISourceInfo.builtin())
 
 def _def_predefineds(self):
 for t in [('str','string',  'char' + POINTER_SUFFIX),
@@ -917,16 +918,18 @@ def _def_predefineds(self):
   ('null',   'null','QNull' + POINTER_SUFFIX)]:
 self._def_builtin_type(*t)
 self.the_empty_object_type = QAPISchemaObjectType(
-'q_empty', None, None, None, None, None, [], None)
+'q_empty', QAPISourceInfo.builtin(),
+None, None, None, None, [], None)
 self._def_entity(self.the_empty_object_type)
 
 qtypes = ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist',
   'qbool']
 qtype_values = self._make_enum_members(
-[{'name': n} for n in qtypes], None)
+[{'name': n} for n in qtypes], QAPISourceInfo.builtin())
 
-self._def_entity(QAPISchemaEnumType('QType', None, None, None, None,
-qtype_values, 'QTYPE'))
+self._def_entity(QAPISchemaEnumType(
+'QType', QAPISourceInfo.builtin(), None,
+None, None, qtype_values, 'QTYPE'))
 
 def _make_features(self, features, info):
 if features is None:
diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py
index 2b4916cdaa1..a3a16284006 100644
--- a/scripts/qapi/types.py
+++ b/scripts/qapi/types.py
@@ -71,7 +71,8 @@ def gen_enum(name: str,
  members: List[QAPISchemaEnumMember],
  prefix: Optional[str] = None) -> str:
 # append automatically generated _MAX value
-enum_members = members + [QAPISchemaEnumMember('_MAX', None)]
+enum_members = members + [
+QAPISchemaEnumMember('_MAX', QAPISourceInfo.builtin())]
 
 ret = mcgen('''
 
@@ 

[PATCH v2 04/12] qapi/gen: assert that _start_if is not None in _wrap_ifcond

2020-12-16 Thread John Snow
We already assert this in end_if, but that's opaque to mypy. Do it in
_wrap_ifcond instead. Same effect at runtime, but mypy can now infer
the type in _wrap_ifcond's body.

Signed-off-by: John Snow 
---
 scripts/qapi/gen.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
index b40f18eee3c..a6dc991b1d0 100644
--- a/scripts/qapi/gen.py
+++ b/scripts/qapi/gen.py
@@ -130,11 +130,11 @@ def start_if(self, ifcond: List[str]) -> None:
 self._start_if = (ifcond, self._body, self._preamble)
 
 def end_if(self) -> None:
-assert self._start_if
 self._wrap_ifcond()
 self._start_if = None
 
 def _wrap_ifcond(self) -> None:
+assert self._start_if
 self._body = _wrap_ifcond(self._start_if[0],
   self._start_if[1], self._body)
 self._preamble = _wrap_ifcond(self._start_if[0],
-- 
2.26.2




[PATCH v2 00/12] qapi: static typing conversion, pt1.5

2020-12-16 Thread John Snow
Hi, this patchset enables strict optional checking in mypy for
everything we have typed so far.

In general, this patchset seeks to eliminate Optional[T] in favor of T
wherever possible. Optional types used for object properties,
function/method parameters and return values where we expect, in most
cases, to be non-None is troublesome as it requires peppering the code
with assertions about state. If and whenever possible, prefer using
non-Optional types.

Ironing out these issues allows us to be even stricter with our type
checking, which improves consistency in subclass interface types and
should make review a little nicer.

This series is based on (but does not require) the 'qapi: sphinx-autodoc
for qapi module' series.

V2:

001/12:[] [--] 'qapi/commands: assert arg_type is not None'
002/12:[] [--] 'qapi/events: fix visit_event typing'
003/12:[0003] [FC] 'qapi/main: handle theoretical None-return from re.match()'
004/12:[] [--] 'qapi/gen: assert that _start_if is not None in _wrap_ifcond'
005/12:[0003] [FC] 'qapi/gen: use './builtin' for the built-in module name'
006/12:[0004] [FC] 'qapi/source: Add builtin null-object sentinel'
007/12:[0024] [FC] 'qapi/schema: make QAPISourceInfo mandatory'
008/12:[] [--] 'qapi/gen: write _genc/_genh access shims'
009/12:[] [--] 'qapi/gen: move write method to QAPIGenC, make fname a str'
010/12:[] [--] 'tests/qapi-schema: Add quotes to module name in test output'
011/12:[0004] [FC] 'qapi/schema: Name the builtin module "" instead of None'
012/12:[] [--] 'qapi: enable strict-optional checks'

- This revision isn't quite complete, but due to deadlines and
  timezones, opted to send the "revision so far". It keeps some
  imperfect fixes that Markus is devising better alternatives for.

John Snow (12):
  qapi/commands: assert arg_type is not None
  qapi/events: fix visit_event typing
  qapi/main: handle theoretical None-return from re.match()
  qapi/gen: assert that _start_if is not None in _wrap_ifcond
  qapi/gen: use './builtin' for the built-in module name
  qapi/source: Add builtin null-object sentinel
  qapi/schema: make QAPISourceInfo mandatory
  qapi/gen: write _genc/_genh access shims
  qapi/gen: move write method to QAPIGenC, make fname a str
  tests/qapi-schema: Add quotes to module name in test output
  qapi/schema: Name the builtin module "" instead of None
  qapi: enable strict-optional checks

 scripts/qapi/commands.py |  11 ++-
 scripts/qapi/events.py   |  14 +--
 scripts/qapi/gen.py  | 108 ---
 scripts/qapi/main.py |   2 +
 scripts/qapi/mypy.ini|   1 -
 scripts/qapi/schema.py   |  35 
 scripts/qapi/source.py   |  20 -
 scripts/qapi/types.py|  11 +--
 scripts/qapi/visit.py|   8 +-
 tests/qapi-schema/comments.out   |   4 +-
 tests/qapi-schema/doc-good.out   |   4 +-
 tests/qapi-schema/empty.out  |   4 +-
 tests/qapi-schema/event-case.out |   4 +-
 tests/qapi-schema/include-repetition.out |   8 +-
 tests/qapi-schema/include-simple.out |   6 +-
 tests/qapi-schema/indented-expr.out  |   4 +-
 tests/qapi-schema/qapi-schema-test.out   |   8 +-
 tests/qapi-schema/test-qapi.py   |   2 +-
 18 files changed, 145 insertions(+), 109 deletions(-)

-- 
2.26.2





[PATCH v2 03/12] qapi/main: handle theoretical None-return from re.match()

2020-12-16 Thread John Snow
Mypy cannot understand that this match can never be None, so help it
along.

Signed-off-by: John Snow 
---
 scripts/qapi/main.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/scripts/qapi/main.py b/scripts/qapi/main.py
index 42517210b80..703e7ed1ed5 100644
--- a/scripts/qapi/main.py
+++ b/scripts/qapi/main.py
@@ -23,6 +23,8 @@
 
 def invalid_prefix_char(prefix: str) -> Optional[str]:
 match = re.match(r'([A-Za-z_.-][A-Za-z0-9_.-]*)?', prefix)
+# match cannot be None, but mypy cannot infer that.
+assert match is not None
 if match.end() != len(prefix):
 return prefix[match.end()]
 return None
-- 
2.26.2




[PATCH v2 02/12] qapi/events: fix visit_event typing

2020-12-16 Thread John Snow
Actually, the arg_type can indeed be Optional.

Signed-off-by: John Snow 
---
 scripts/qapi/events.py | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py
index 599f3d1f564..9851653b9d1 100644
--- a/scripts/qapi/events.py
+++ b/scripts/qapi/events.py
@@ -12,7 +12,7 @@
 See the COPYING file in the top-level directory.
 """
 
-from typing import List
+from typing import List, Optional
 
 from .common import c_enum_const, c_name, mcgen
 from .gen import QAPISchemaModularCVisitor, build_params, ifcontext
@@ -27,7 +27,7 @@
 
 
 def build_event_send_proto(name: str,
-   arg_type: QAPISchemaObjectType,
+   arg_type: Optional[QAPISchemaObjectType],
boxed: bool) -> str:
 return 'void qapi_event_send_%(c_name)s(%(param)s)' % {
 'c_name': c_name(name.lower()),
@@ -35,7 +35,7 @@ def build_event_send_proto(name: str,
 
 
 def gen_event_send_decl(name: str,
-arg_type: QAPISchemaObjectType,
+arg_type: Optional[QAPISchemaObjectType],
 boxed: bool) -> str:
 return mcgen('''
 
@@ -78,7 +78,7 @@ def gen_param_var(typ: QAPISchemaObjectType) -> str:
 
 
 def gen_event_send(name: str,
-   arg_type: QAPISchemaObjectType,
+   arg_type: Optional[QAPISchemaObjectType],
boxed: bool,
event_enum_name: str,
event_emit: str) -> str:
@@ -99,6 +99,7 @@ def gen_event_send(name: str,
 proto=build_event_send_proto(name, arg_type, boxed))
 
 if have_args:
+assert arg_type is not None
 ret += mcgen('''
 QObject *obj;
 Visitor *v;
@@ -114,6 +115,7 @@ def gen_event_send(name: str,
  name=name)
 
 if have_args:
+assert arg_type is not None
 ret += mcgen('''
 v = qobject_output_visitor_new();
 ''')
@@ -214,7 +216,7 @@ def visit_event(self,
 info: QAPISourceInfo,
 ifcond: List[str],
 features: List[QAPISchemaFeature],
-arg_type: QAPISchemaObjectType,
+arg_type: Optional[QAPISchemaObjectType],
 boxed: bool) -> None:
 with ifcontext(ifcond, self._genh, self._genc):
 self._genh.add(gen_event_send_decl(name, arg_type, boxed))
-- 
2.26.2




[PATCH v2 01/12] qapi/commands: assert arg_type is not None

2020-12-16 Thread John Snow
when boxed is true, expr.py asserts that we must have
arguments. Ultimately, this should mean that if boxed is True, that
arg_type should be defined. Mypy cannot infer this, and does not support
'stateful' type inference, e.g.:

```
if x:
assert y is not None

...

if x:
y.etc()
```

does not work, because mypy does not statefully remember the conditional
assertion in the second block. Help mypy out by creating a new local
that it can track more easily.

Signed-off-by: John Snow 
---
 scripts/qapi/commands.py | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
index 50978090b44..71744f48a35 100644
--- a/scripts/qapi/commands.py
+++ b/scripts/qapi/commands.py
@@ -126,6 +126,9 @@ def gen_marshal(name: str,
 boxed: bool,
 ret_type: Optional[QAPISchemaType]) -> str:
 have_args = boxed or (arg_type and not arg_type.is_empty())
+if have_args:
+assert arg_type is not None
+arg_type_c_name = arg_type.c_name()
 
 ret = mcgen('''
 
@@ -147,7 +150,7 @@ def gen_marshal(name: str,
 ret += mcgen('''
 %(c_name)s arg = {0};
 ''',
- c_name=arg_type.c_name())
+ c_name=arg_type_c_name)
 
 ret += mcgen('''
 
@@ -163,7 +166,7 @@ def gen_marshal(name: str,
 ok = visit_check_struct(v, errp);
 }
 ''',
- c_arg_type=arg_type.c_name())
+ c_arg_type=arg_type_c_name)
 else:
 ret += mcgen('''
 ok = visit_check_struct(v, errp);
@@ -193,7 +196,7 @@ def gen_marshal(name: str,
 ret += mcgen('''
 visit_type_%(c_arg_type)s_members(v, , NULL);
 ''',
- c_arg_type=arg_type.c_name())
+ c_arg_type=arg_type_c_name)
 
 ret += mcgen('''
 visit_end_struct(v, NULL);
-- 
2.26.2




[PATCH v3 10/13] qapi/introspect.py: improve readability of _tree_to_qlit

2020-12-16 Thread John Snow
Subjective, but I find getting rid of the comprehensions helps. Also,
divide the sections into scalar and non-scalar sections, and remove
old-style string formatting.

Signed-off-by: John Snow 
---
 scripts/qapi/introspect.py | 33 ++---
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index c72bd27..60ec326d2c7 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -89,7 +89,7 @@ def indent(level):
 
 ret = ''
 if obj.comment:
-ret += indent(level) + '/* %s */\n' % obj.comment
+ret += indent(level) + f"/* {obj.comment} */\n"
 if obj.ifcond:
 ret += gen_if(obj.ifcond)
 ret += _tree_to_qlit(obj.value, level, suppress_first_indent)
@@ -100,33 +100,36 @@ def indent(level):
 ret = ''
 if not suppress_first_indent:
 ret += indent(level)
+
+# Scalars:
 if obj is None:
 ret += 'QLIT_QNULL'
 elif isinstance(obj, str):
-ret += 'QLIT_QSTR(' + to_c_string(obj) + ')'
+ret += f"QLIT_QSTR({to_c_string(obj)})"
+elif isinstance(obj, bool):
+ret += f"QLIT_QBOOL({str(obj).lower()})"
+
+# Non-scalars:
 elif isinstance(obj, list):
-elts = [_tree_to_qlit(elt, level + 1).strip('\n')
-for elt in obj]
-elts.append(indent(level + 1) + "{}")
 ret += 'QLIT_QLIST(((QLitObject[]) {\n'
-ret += '\n'.join(elts) + '\n'
+for value in obj:
+ret += _tree_to_qlit(value, level + 1).strip('\n') + '\n'
+ret += indent(level + 1) + '{}\n'
 ret += indent(level) + '}))'
 elif isinstance(obj, dict):
-elts = []
-for key, value in sorted(obj.items()):
-elts.append(indent(level + 1) + '{ %s, %s }' %
-(to_c_string(key),
- _tree_to_qlit(value, level + 1, True)))
-elts.append(indent(level + 1) + '{}')
 ret += 'QLIT_QDICT(((QLitDictEntry[]) {\n'
-ret += ',\n'.join(elts) + '\n'
+for key, value in sorted(obj.items()):
+ret += indent(level + 1) + "{{ {:s}, {:s} }},\n".format(
+to_c_string(key),
+_tree_to_qlit(value, level + 1, suppress_first_indent=True)
+)
+ret += indent(level + 1) + '{}\n'
 ret += indent(level) + '}))'
-elif isinstance(obj, bool):
-ret += 'QLIT_QBOOL(%s)' % ('true' if obj else 'false')
 else:
 raise NotImplementedError(
 f"type '{type(obj).__name__}' not implemented"
 )
+
 if level > 0:
 ret += ','
 return ret
-- 
2.26.2




[PATCH v3 13/13] qapi/introspect.py: Add docstring to _tree_to_qlit

2020-12-16 Thread John Snow
Signed-off-by: John Snow 
Reviewed-by: Cleber Rosa 
Signed-off-by: John Snow 
---
 scripts/qapi/introspect.py | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index 428397a6954..8d5b8513fc8 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -1,10 +1,11 @@
 """
 QAPI introspection generator
 
-Copyright (C) 2015-2018 Red Hat, Inc.
+Copyright (C) 2015-2020 Red Hat, Inc.
 
 Authors:
  Markus Armbruster 
+ John Snow 
 
 This work is licensed under the terms of the GNU GPL, version 2.
 See the COPYING file in the top-level directory.
@@ -96,6 +97,13 @@ def __init__(self, value: _NodeT, ifcond: Iterable[str],
 def _tree_to_qlit(obj: TreeValue,
   level: int = 0,
   suppress_first_indent: bool = False) -> str:
+"""
+Convert the type tree into a QLIT C string, recursively.
+
+:param obj: The value to convert.
+:param level: The indentation level for this particular value.
+:param suppress_first_indent: True for dict value children.
+"""
 
 def indent(level: int) -> str:
 return level * 4 * ' '
-- 
2.26.2




[PATCH v3 07/13] qapi/introspect.py: Introduce preliminary tree typing

2020-12-16 Thread John Snow
The types will be used in forthcoming patches to add typing. These types
describe the layout and structure of the objects passed to
_tree_to_qlit, but lack the power to describe annotations until the next
commit.

Signed-off-by: John Snow 
---
 scripts/qapi/introspect.py | 30 +-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index 0aa3b77109f..b82efe16f6e 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -10,7 +10,13 @@
 See the COPYING file in the top-level directory.
 """
 
-from typing import Optional
+from typing import (
+Any,
+Dict,
+List,
+Optional,
+Union,
+)
 
 from .common import (
 c_name,
@@ -26,6 +32,28 @@
 )
 
 
+# This module constructs a tree data structure that is used to
+# generate the introspection information for QEMU. It behaves similarly
+# to a JSON value.
+#
+# A complexity over JSON is that our values may or may not be annotated.
+#
+# Un-annotated values may be:
+# Scalar: str, bool, None.
+# Non-scalar: List, Dict
+# _value = Union[str, bool, None, Dict[str, TreeValue], List[TreeValue]]
+#
+# With optional annotations, the type of all values is:
+# TreeValue = Union[_value, Annotated[_value]]
+#
+# Sadly, mypy does not support recursive types, so we must approximate this.
+_stub = Any
+_scalar = Union[str, bool, None]
+_nonscalar = Union[Dict[str, _stub], List[_stub]]
+_value = Union[_scalar, _nonscalar]
+# TreeValue = Union[_value, 'Annotated[_value]']
+
+
 def _make_tree(obj, ifcond, comment=None):
 extra = {
 'if': ifcond,
-- 
2.26.2




[PATCH v3 08/13] qapi/introspect.py: create a typed 'Annotated' data strutcure

2020-12-16 Thread John Snow
Presently, we use a tuple to attach a dict containing annotations
(comments and compile-time conditionals) to a tree node. This is
undesirable because dicts are difficult to strongly type; promoting it
to a real class allows us to name the values and types of the
annotations we are expecting.

In terms of typing, the Annotated type serves as a generic container
where the annotated node's type is preserved, allowing for greater
specificity than we'd be able to provide without a generic.

Signed-off-by: John Snow 
---
 scripts/qapi/introspect.py | 77 ++
 1 file changed, 44 insertions(+), 33 deletions(-)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index b82efe16f6e..2b90a52f016 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -13,8 +13,12 @@
 from typing import (
 Any,
 Dict,
+Generic,
+Iterable,
 List,
 Optional,
+Tuple,
+TypeVar,
 Union,
 )
 
@@ -51,15 +55,25 @@
 _scalar = Union[str, bool, None]
 _nonscalar = Union[Dict[str, _stub], List[_stub]]
 _value = Union[_scalar, _nonscalar]
-# TreeValue = Union[_value, 'Annotated[_value]']
+TreeValue = Union[_value, 'Annotated[_value]']
 
 
-def _make_tree(obj, ifcond, comment=None):
-extra = {
-'if': ifcond,
-'comment': comment,
-}
-return (obj, extra)
+_NodeT = TypeVar('_NodeT', bound=TreeValue)
+
+
+class Annotated(Generic[_NodeT]):
+"""
+Annotated generally contains a SchemaInfo-like type (as a dict),
+But it also used to wrap comments/ifconds around scalar leaf values,
+for the benefit of features and enums.
+"""
+# Remove after 3.7 adds @dataclass:
+# pylint: disable=too-few-public-methods
+def __init__(self, value: _NodeT, ifcond: Iterable[str],
+ comment: Optional[str] = None):
+self.value = value
+self.comment: Optional[str] = comment
+self.ifcond: Tuple[str, ...] = tuple(ifcond)
 
 
 def _tree_to_qlit(obj, level=0, suppress_first_indent=False):
@@ -67,24 +81,20 @@ def _tree_to_qlit(obj, level=0, 
suppress_first_indent=False):
 def indent(level):
 return level * 4 * ' '
 
-if isinstance(obj, tuple):
-ifobj, extra = obj
-ifcond = extra.get('if')
-comment = extra.get('comment')
-
+if isinstance(obj, Annotated):
 # NB: _tree_to_qlit is called recursively on the values of a key:value
 # pair; those values can't be decorated with comments or conditionals.
 msg = "dict values cannot have attached comments or if-conditionals."
 assert not suppress_first_indent, msg
 
 ret = ''
-if comment:
-ret += indent(level) + '/* %s */\n' % comment
-if ifcond:
-ret += gen_if(ifcond)
-ret += _tree_to_qlit(ifobj, level)
-if ifcond:
-ret += '\n' + gen_endif(ifcond)
+if obj.comment:
+ret += indent(level) + '/* %s */\n' % obj.comment
+if obj.ifcond:
+ret += gen_if(obj.ifcond)
+ret += _tree_to_qlit(obj.value, level, suppress_first_indent)
+if obj.ifcond:
+ret += '\n' + gen_endif(obj.ifcond)
 return ret
 
 ret = ''
@@ -201,7 +211,7 @@ def _use_type(self, typ):
 
 @staticmethod
 def _gen_features(features):
-return [_make_tree(f.name, f.ifcond) for f in features]
+return [Annotated(f.name, f.ifcond) for f in features]
 
 def _gen_tree(self, name, mtype, obj, ifcond, features):
 comment: Optional[str] = None
@@ -215,7 +225,7 @@ def _gen_tree(self, name, mtype, obj, ifcond, features):
 obj['meta-type'] = mtype
 if features:
 obj['features'] = self._gen_features(features)
-self._trees.append(_make_tree(obj, ifcond, comment))
+self._trees.append(Annotated(obj, ifcond, comment))
 
 def _gen_member(self, member):
 obj = {'name': member.name, 'type': self._use_type(member.type)}
@@ -223,7 +233,7 @@ def _gen_member(self, member):
 obj['default'] = None
 if member.features:
 obj['features'] = self._gen_features(member.features)
-return _make_tree(obj, member.ifcond)
+return Annotated(obj, member.ifcond)
 
 def _gen_variants(self, tag_name, variants):
 return {'tag': tag_name,
@@ -231,16 +241,17 @@ def _gen_variants(self, tag_name, variants):
 
 def _gen_variant(self, variant):
 obj = {'case': variant.name, 'type': self._use_type(variant.type)}
-return _make_tree(obj, variant.ifcond)
+return Annotated(obj, variant.ifcond)
 
 def visit_builtin_type(self, name, info, json_type):
 self._gen_tree(name, 'builtin', {'json-type': json_type}, [], None)
 
 def visit_enum_type(self, name, info, ifcond, features, members, prefix):
-self._gen_tree(name, 'enum',
-   {'values': [_make_tree(m.name, m.ifcond, None)
-  

[PATCH v3 12/13] qapi/instrospect.py: add introspect.json dummy types

2020-12-16 Thread John Snow
Add some aliases that declare intent for some of the "dictly-typed"
objects we pass around in introspect.py.

Signed-off-by: John Snow 

---

This patch is optional, it can be dropped if desired.

Signed-off-by: John Snow 
---
 scripts/qapi/introspect.py | 48 --
 1 file changed, 30 insertions(+), 18 deletions(-)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index 590898baf93..428397a6954 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -66,8 +66,14 @@
 _value = Union[_scalar, _nonscalar]
 TreeValue = Union[_value, 'Annotated[_value]']
 
-# This is a (strict) alias for an arbitrary object non-scalar, as above:
-_DObject = Dict[str, object]
+# We lack precise object types, so SchemaInfo, children, and related types are
+# typed here loosely as simply python Dicts.
+SchemaInfo = Dict[str, object]
+SchemaInfoObject = Dict[str, object]
+SchemaInfoObjectVariant = Dict[str, object]
+SchemaInfoObjectMember = Dict[str, object]
+SchemaInfoCommand = Dict[str, object]
+
 
 _NodeT = TypeVar('_NodeT', bound=TreeValue)
 
@@ -160,7 +166,7 @@ def __init__(self, prefix: str, unmask: bool):
 ' * QAPI/QMP schema introspection', __doc__)
 self._unmask = unmask
 self._schema: Optional[QAPISchema] = None
-self._trees: List[Annotated[_DObject]] = []
+self._trees: List[Annotated[SchemaInfo]] = []
 self._used_types: List[QAPISchemaType] = []
 self._name_map: Dict[str, str] = {}
 self._genc.add(mcgen('''
@@ -232,9 +238,18 @@ def _gen_features(features: List[QAPISchemaFeature]
   ) -> List[Annotated[str]]:
 return [Annotated(f.name, f.ifcond) for f in features]
 
-def _gen_tree(self, name: str, mtype: str, obj: _DObject,
+def _gen_tree(self, name: str, mtype: str, obj: Dict[str, object],
   ifcond: List[str],
   features: Optional[List[QAPISchemaFeature]]) -> None:
+"""
+Build and append a SchemaInfo object to self._trees.
+
+:param name: The entity's name.
+:param mtype: The entity's meta-type.
+:param obj: Additional entity fields, as appropriate for the meta-type.
+:param ifcond: List of conditionals that apply to this entire entity.
+:param features: Optional features field for SchemaInfo.
+"""
 comment: Optional[str] = None
 if mtype not in ('command', 'event', 'builtin', 'array'):
 if not self._unmask:
@@ -249,8 +264,8 @@ def _gen_tree(self, name: str, mtype: str, obj: _DObject,
 self._trees.append(Annotated(obj, ifcond, comment))
 
 def _gen_member(self, member: QAPISchemaObjectTypeMember
-) -> Annotated[_DObject]:
-obj: _DObject = {
+) -> Annotated[SchemaInfoObjectMember]:
+obj: SchemaInfoObjectMember = {
 'name': member.name,
 'type': self._use_type(member.type)
 }
@@ -260,13 +275,9 @@ def _gen_member(self, member: QAPISchemaObjectTypeMember
 obj['features'] = self._gen_features(member.features)
 return Annotated(obj, member.ifcond)
 
-def _gen_variants(self, tag_name: str,
-  variants: List[QAPISchemaVariant]) -> _DObject:
-return {'tag': tag_name,
-'variants': [self._gen_variant(v) for v in variants]}
-
-def _gen_variant(self, variant: QAPISchemaVariant) -> Annotated[_DObject]:
-obj: _DObject = {
+def _gen_variant(self, variant: QAPISchemaVariant
+ ) -> Annotated[SchemaInfoObjectVariant]:
+obj: SchemaInfoObjectVariant = {
 'case': variant.name,
 'type': self._use_type(variant.type)
 }
@@ -298,11 +309,12 @@ def visit_object_type_flat(self, name: str, info: 
QAPISourceInfo,
features: List[QAPISchemaFeature],
members: List[QAPISchemaObjectTypeMember],
variants: Optional[QAPISchemaVariants]) -> None:
-obj: _DObject = {'members': [self._gen_member(m) for m in members]}
+obj: SchemaInfoObject = {
+'members': [self._gen_member(m) for m in members]
+}
 if variants:
-obj.update(self._gen_variants(variants.tag_member.name,
-  variants.variants))
-
+obj['tag'] = variants.tag_member.name
+obj['variants'] = [self._gen_variant(v) for v in variants.variants]
 self._gen_tree(name, 'object', obj, ifcond, features)
 
 def visit_alternate_type(self, name: str, info: QAPISourceInfo,
@@ -326,7 +338,7 @@ def visit_command(self, name: str, info: QAPISourceInfo, 
ifcond: List[str],
 
 arg_type = arg_type or self._schema.the_empty_object_type
 ret_type = ret_type or self._schema.the_empty_object_type
-obj: _DObject = {
+obj: SchemaInfoCommand 

[PATCH v3 09/13] qapi/introspect.py: improve _tree_to_qlit error message

2020-12-16 Thread John Snow
Trivial; make the error message just a pinch more explicit in case we
trip this by accident in the future.

Signed-off-by: John Snow 
---
 scripts/qapi/introspect.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index 2b90a52f016..c72bd27 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -124,7 +124,9 @@ def indent(level):
 elif isinstance(obj, bool):
 ret += 'QLIT_QBOOL(%s)' % ('true' if obj else 'false')
 else:
-assert False# not implemented
+raise NotImplementedError(
+f"type '{type(obj).__name__}' not implemented"
+)
 if level > 0:
 ret += ','
 return ret
-- 
2.26.2




[PATCH v3 05/13] qapi/introspect.py: Unify return type of _make_tree()

2020-12-16 Thread John Snow
Returning two different types conditionally can be complicated to
type. Return one type for consistency.

Signed-off-by: John Snow 
---
 scripts/qapi/introspect.py | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index ccdf4f1c0d0..d3fbf694ad2 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -29,9 +29,7 @@ def _make_tree(obj, ifcond, extra=None):
 extra = {}
 if ifcond:
 extra['if'] = ifcond
-if extra:
-return (obj, extra)
-return obj
+return (obj, extra)
 
 
 def _tree_to_qlit(obj, level=0, suppress_first_indent=False):
-- 
2.26.2




[PATCH v2 12/12] qapi: enable strict-optional checks

2020-12-16 Thread John Snow
In the modules that we are checking so far, we can be stricter about the
difference between Optional[T] and T types. Enable that check.

Enabling it now will assist review on further typing and cleanup work.

Signed-off-by: John Snow 
---
 scripts/qapi/mypy.ini | 1 -
 1 file changed, 1 deletion(-)

diff --git a/scripts/qapi/mypy.ini b/scripts/qapi/mypy.ini
index 74fc6c82153..04bd5db5278 100644
--- a/scripts/qapi/mypy.ini
+++ b/scripts/qapi/mypy.ini
@@ -1,6 +1,5 @@
 [mypy]
 strict = True
-strict_optional = False
 disallow_untyped_calls = False
 python_version = 3.6
 
-- 
2.26.2




[PATCH v3 06/13] qapi/introspect.py: replace 'extra' dict with 'comment' argument

2020-12-16 Thread John Snow
This is only used to pass in a dictionary with a comment already set, so
skip the runaround and just accept the comment.

This works because _tree_to_qlit() treats 'if': None; 'comment': None
exactly like absent 'if'; 'comment'.

Signed-off-by: John Snow 
---
 scripts/qapi/introspect.py | 18 ++
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index d3fbf694ad2..0aa3b77109f 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -10,6 +10,8 @@
 See the COPYING file in the top-level directory.
 """
 
+from typing import Optional
+
 from .common import (
 c_name,
 gen_endif,
@@ -24,11 +26,11 @@
 )
 
 
-def _make_tree(obj, ifcond, extra=None):
-if extra is None:
-extra = {}
-if ifcond:
-extra['if'] = ifcond
+def _make_tree(obj, ifcond, comment=None):
+extra = {
+'if': ifcond,
+'comment': comment,
+}
 return (obj, extra)
 
 
@@ -174,18 +176,18 @@ def _gen_features(features):
 return [_make_tree(f.name, f.ifcond) for f in features]
 
 def _gen_tree(self, name, mtype, obj, ifcond, features):
-extra = None
+comment: Optional[str] = None
 if mtype not in ('command', 'event', 'builtin', 'array'):
 if not self._unmask:
 # Output a comment to make it easy to map masked names
 # back to the source when reading the generated output.
-extra = {'comment': '"%s" = %s' % (self._name(name), name)}
+comment = f'"{self._name(name)}" = {name}'
 name = self._name(name)
 obj['name'] = name
 obj['meta-type'] = mtype
 if features:
 obj['features'] = self._gen_features(features)
-self._trees.append(_make_tree(obj, ifcond, extra))
+self._trees.append(_make_tree(obj, ifcond, comment))
 
 def _gen_member(self, member):
 obj = {'name': member.name, 'type': self._use_type(member.type)}
-- 
2.26.2




[PATCH v3 03/13] qapi/introspect.py: add _gen_features helper

2020-12-16 Thread John Snow
_make_tree might receive a dict (a SchemaInfo object) or some other type
(usually, a string) for its obj parameter. Adding features information
should arguably be performed by the caller at such a time when we know
the type of the object and don't have to re-interrogate it.

Signed-off-by: John Snow 
---
 scripts/qapi/introspect.py | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index 3295a15c98e..4749f65ea3c 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -24,15 +24,11 @@
 )
 
 
-def _make_tree(obj, ifcond, features, extra=None):
+def _make_tree(obj, ifcond, extra=None):
 if extra is None:
 extra = {}
 if ifcond:
 extra['if'] = ifcond
-if features:
-obj['features'] = [
-_make_tree(f.name, f.ifcond, None) for f in features
-]
 if extra:
 return (obj, extra)
 return obj
@@ -169,6 +165,10 @@ def _use_type(self, typ):
 return '[' + self._use_type(typ.element_type) + ']'
 return self._name(typ.name)
 
+@staticmethod
+def _gen_features(features):
+return [_make_tree(f.name, f.ifcond) for f in features]
+
 def _gen_tree(self, name, mtype, obj, ifcond, features):
 extra = None
 if mtype not in ('command', 'event', 'builtin', 'array'):
@@ -179,13 +179,17 @@ def _gen_tree(self, name, mtype, obj, ifcond, features):
 name = self._name(name)
 obj['name'] = name
 obj['meta-type'] = mtype
-self._trees.append(_make_tree(obj, ifcond, features, extra))
+if features:
+obj['features'] = self._gen_features(features)
+self._trees.append(_make_tree(obj, ifcond, extra))
 
 def _gen_member(self, member):
 obj = {'name': member.name, 'type': self._use_type(member.type)}
 if member.optional:
 obj['default'] = None
-return _make_tree(obj, member.ifcond, member.features)
+if member.features:
+obj['features'] = self._gen_features(member.features)
+return _make_tree(obj, member.ifcond)
 
 def _gen_variants(self, tag_name, variants):
 return {'tag': tag_name,
@@ -193,7 +197,7 @@ def _gen_variants(self, tag_name, variants):
 
 def _gen_variant(self, variant):
 obj = {'case': variant.name, 'type': self._use_type(variant.type)}
-return _make_tree(obj, variant.ifcond, None)
+return _make_tree(obj, variant.ifcond)
 
 def visit_builtin_type(self, name, info, json_type):
 self._gen_tree(name, 'builtin', {'json-type': json_type}, [], None)
-- 
2.26.2




[PATCH v3 04/13] qapi/introspect.py: guard against ifcond/comment misuse

2020-12-16 Thread John Snow
_tree_to_qlit is called recursively on dict values alone; at such a
point in generating output it is too late to apply an ifcond. Similarly,
comments do not necessarily have a "tidy" place they can be printed in
such a circumstance.

Forbid this usage.

Signed-off-by: John Snow 
---
 scripts/qapi/introspect.py | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index 4749f65ea3c..ccdf4f1c0d0 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -43,6 +43,12 @@ def indent(level):
 ifobj, extra = obj
 ifcond = extra.get('if')
 comment = extra.get('comment')
+
+# NB: _tree_to_qlit is called recursively on the values of a key:value
+# pair; those values can't be decorated with comments or conditionals.
+msg = "dict values cannot have attached comments or if-conditionals."
+assert not suppress_first_indent, msg
+
 ret = ''
 if comment:
 ret += indent(level) + '/* %s */\n' % comment
-- 
2.26.2




[PATCH v3 02/13] qapi/introspect.py: use _make_tree for features nodes

2020-12-16 Thread John Snow
At present, we open-code this in _make_tree itself; but if the structure
of the tree changes, this is brittle. Use an explicit recursive call to
_make_tree when appropriate to help keep the interior node typing
consistent.

Signed-off-by: John Snow 
---
 scripts/qapi/introspect.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index 43ab4be1f77..3295a15c98e 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -30,7 +30,9 @@ def _make_tree(obj, ifcond, features, extra=None):
 if ifcond:
 extra['if'] = ifcond
 if features:
-obj['features'] = [(f.name, {'if': f.ifcond}) for f in features]
+obj['features'] = [
+_make_tree(f.name, f.ifcond, None) for f in features
+]
 if extra:
 return (obj, extra)
 return obj
-- 
2.26.2




[PATCH v3 11/13] qapi/introspect.py: add type hint annotations

2020-12-16 Thread John Snow
Signed-off-by: John Snow 
---
 scripts/qapi/introspect.py | 114 ++---
 scripts/qapi/mypy.ini  |   5 --
 scripts/qapi/schema.py |   2 +-
 3 files changed, 81 insertions(+), 40 deletions(-)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index 60ec326d2c7..590898baf93 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -30,10 +30,19 @@
 )
 from .gen import QAPISchemaMonolithicCVisitor
 from .schema import (
+QAPISchema,
 QAPISchemaArrayType,
 QAPISchemaBuiltinType,
+QAPISchemaEntity,
+QAPISchemaEnumMember,
+QAPISchemaFeature,
+QAPISchemaObjectType,
+QAPISchemaObjectTypeMember,
 QAPISchemaType,
+QAPISchemaVariant,
+QAPISchemaVariants,
 )
+from .source import QAPISourceInfo
 
 
 # This module constructs a tree data structure that is used to
@@ -57,6 +66,8 @@
 _value = Union[_scalar, _nonscalar]
 TreeValue = Union[_value, 'Annotated[_value]']
 
+# This is a (strict) alias for an arbitrary object non-scalar, as above:
+_DObject = Dict[str, object]
 
 _NodeT = TypeVar('_NodeT', bound=TreeValue)
 
@@ -76,9 +87,11 @@ def __init__(self, value: _NodeT, ifcond: Iterable[str],
 self.ifcond: Tuple[str, ...] = tuple(ifcond)
 
 
-def _tree_to_qlit(obj, level=0, suppress_first_indent=False):
+def _tree_to_qlit(obj: TreeValue,
+  level: int = 0,
+  suppress_first_indent: bool = False) -> str:
 
-def indent(level):
+def indent(level: int) -> str:
 return level * 4 * ' '
 
 if isinstance(obj, Annotated):
@@ -135,21 +148,21 @@ def indent(level):
 return ret
 
 
-def to_c_string(string):
+def to_c_string(string: str) -> str:
 return '"' + string.replace('\\', r'\\').replace('"', r'\"') + '"'
 
 
 class QAPISchemaGenIntrospectVisitor(QAPISchemaMonolithicCVisitor):
 
-def __init__(self, prefix, unmask):
+def __init__(self, prefix: str, unmask: bool):
 super().__init__(
 prefix, 'qapi-introspect',
 ' * QAPI/QMP schema introspection', __doc__)
 self._unmask = unmask
-self._schema = None
-self._trees = []
-self._used_types = []
-self._name_map = {}
+self._schema: Optional[QAPISchema] = None
+self._trees: List[Annotated[_DObject]] = []
+self._used_types: List[QAPISchemaType] = []
+self._name_map: Dict[str, str] = {}
 self._genc.add(mcgen('''
 #include "qemu/osdep.h"
 #include "%(prefix)sqapi-introspect.h"
@@ -157,10 +170,10 @@ def __init__(self, prefix, unmask):
 ''',
  prefix=prefix))
 
-def visit_begin(self, schema):
+def visit_begin(self, schema: QAPISchema) -> None:
 self._schema = schema
 
-def visit_end(self):
+def visit_end(self) -> None:
 # visit the types that are actually used
 for typ in self._used_types:
 typ.visit(self)
@@ -182,18 +195,18 @@ def visit_end(self):
 self._used_types = []
 self._name_map = {}
 
-def visit_needed(self, entity):
+def visit_needed(self, entity: QAPISchemaEntity) -> bool:
 # Ignore types on first pass; visit_end() will pick up used types
 return not isinstance(entity, QAPISchemaType)
 
-def _name(self, name):
+def _name(self, name: str) -> str:
 if self._unmask:
 return name
 if name not in self._name_map:
 self._name_map[name] = '%d' % len(self._name_map)
 return self._name_map[name]
 
-def _use_type(self, typ):
+def _use_type(self, typ: QAPISchemaType) -> str:
 assert self._schema is not None
 
 # Map the various integer types to plain int
@@ -215,10 +228,13 @@ def _use_type(self, typ):
 return self._name(typ.name)
 
 @staticmethod
-def _gen_features(features):
+def _gen_features(features: List[QAPISchemaFeature]
+  ) -> List[Annotated[str]]:
 return [Annotated(f.name, f.ifcond) for f in features]
 
-def _gen_tree(self, name, mtype, obj, ifcond, features):
+def _gen_tree(self, name: str, mtype: str, obj: _DObject,
+  ifcond: List[str],
+  features: Optional[List[QAPISchemaFeature]]) -> None:
 comment: Optional[str] = None
 if mtype not in ('command', 'event', 'builtin', 'array'):
 if not self._unmask:
@@ -232,47 +248,67 @@ def _gen_tree(self, name, mtype, obj, ifcond, features):
 obj['features'] = self._gen_features(features)
 self._trees.append(Annotated(obj, ifcond, comment))
 
-def _gen_member(self, member):
-obj = {'name': member.name, 'type': self._use_type(member.type)}
+def _gen_member(self, member: QAPISchemaObjectTypeMember
+) -> Annotated[_DObject]:
+obj: _DObject = {
+'name': member.name,
+'type': self._use_type(member.type)
+}
 if member.optional:
  

[PATCH v3 00/13] qapi: static typing conversion, pt2

2020-12-16 Thread John Snow
Hi, this series adds static type hints to the QAPI module.
This is part two, and covers introspect.py.

Part 2: https://gitlab.com/jsnow/qemu/-/tree/python-qapi-cleanup-pt2
Everything: https://gitlab.com/jsnow/qemu/-/tree/python-qapi-cleanup-pt6

- Requires Python 3.6+
- Requires mypy 0.770 or newer (for type analysis only)
- Requires pylint 2.6.0 or newer (for lint checking only)

Type hints are added in patches that add *only* type hints and change no
other behavior. Any necessary changes to behavior to accommodate typing
are split out into their own tiny patches.

Every commit should pass with:
 - flake8 qapi/
 - pylint --rcfile=qapi/pylintrc qapi/
 - mypy --config-file=qapi/mypy.ini qapi/

V3:
 - Dropped all the R-Bs again...
 - Re-re-ordered to put type annotations last again.
 - Rebased on top of "pt1.5".
 - Ensured compliance with strict-optional typing.
 - Forgive me if I missed a specific critique;
   I probably just lost it in the shuffle.

V2:
 - Dropped all R-B from previous series; enough has changed.
 - pt2 is now introspect.py, expr.py is pushed to pt3.
 - Reworked again to have less confusing (?) type names
 - Added an assertion to prevent future accidental breakage

John Snow (13):
  qapi/introspect.py: assert schema is not None
  qapi/introspect.py: use _make_tree for features nodes
  qapi/introspect.py: add _gen_features helper
  qapi/introspect.py: guard against ifcond/comment misuse
  qapi/introspect.py: Unify return type of _make_tree()
  qapi/introspect.py: replace 'extra' dict with 'comment' argument
  qapi/introspect.py: Introduce preliminary tree typing
  qapi/introspect.py: create a typed 'Annotated' data strutcure
  qapi/introspect.py: improve _tree_to_qlit error message
  qapi/introspect.py: improve readability of _tree_to_qlit
  qapi/introspect.py: add type hint annotations
  qapi/instrospect.py: add introspect.json dummy types
  qapi/introspect.py: Add docstring to _tree_to_qlit

 scripts/qapi/introspect.py | 309 ++---
 scripts/qapi/mypy.ini  |   5 -
 scripts/qapi/schema.py |   2 +-
 3 files changed, 219 insertions(+), 97 deletions(-)

-- 
2.26.2





[PATCH v3 01/13] qapi/introspect.py: assert schema is not None

2020-12-16 Thread John Snow
The introspect visitor is stateful, but expects that it will have a
schema to refer to. Add assertions that state this.

Signed-off-by: John Snow 
---
 scripts/qapi/introspect.py | 5 +
 1 file changed, 5 insertions(+)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index fafec94e022..43ab4be1f77 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -147,6 +147,8 @@ def _name(self, name):
 return self._name_map[name]
 
 def _use_type(self, typ):
+assert self._schema is not None
+
 # Map the various integer types to plain int
 if typ.json_type() == 'int':
 typ = self._schema.lookup_type('int')
@@ -225,6 +227,8 @@ def visit_alternate_type(self, name, info, ifcond, 
features, variants):
 def visit_command(self, name, info, ifcond, features,
   arg_type, ret_type, gen, success_response, boxed,
   allow_oob, allow_preconfig, coroutine):
+assert self._schema is not None
+
 arg_type = arg_type or self._schema.the_empty_object_type
 ret_type = ret_type or self._schema.the_empty_object_type
 obj = {'arg-type': self._use_type(arg_type),
@@ -234,6 +238,7 @@ def visit_command(self, name, info, ifcond, features,
 self._gen_tree(name, 'command', obj, ifcond, features)
 
 def visit_event(self, name, info, ifcond, features, arg_type, boxed):
+assert self._schema is not None
 arg_type = arg_type or self._schema.the_empty_object_type
 self._gen_tree(name, 'event', {'arg-type': self._use_type(arg_type)},
ifcond, features)
-- 
2.26.2




[PATCH v2 1/2] accel: kvm: Fix memory waste under mismatch page size

2020-12-16 Thread Keqian Zhu
When handle dirty log, we face qemu_real_host_page_size and
TARGET_PAGE_SIZE. The first one is the granule of KVM dirty
bitmap, and the second one is the granule of QEMU dirty bitmap.

As qemu_real_host_page_size >= TARGET_PAGE_SIZE (kvm_init()
enforced it), misuse TARGET_PAGE_SIZE to init kvmslot dirty_bmap
may waste memory. For example, when qemu_real_host_page_size is
64K and TARGET_PAGE_SIZE is 4K, it wastes 93.75% (15/16) memory.

Signed-off-by: Keqian Zhu 
Reviewed-by: Andrew Jones 
Reviewed-by: Peter Xu 
---
 accel/kvm/kvm-all.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

---

v2
 - Address Andrew's comment (qemu_real_host_page_size >= TARGET_PAGE_SIZE
   is a rule).
 - Add Andrew and Peter's R-b.

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 389eaace72..f6b16a8df8 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -620,8 +620,12 @@ static void kvm_memslot_init_dirty_bitmap(KVMSlot *mem)
  * too, in most cases).
  * So for now, let's align to 64 instead of HOST_LONG_BITS here, in
  * a hope that sizeof(long) won't become >8 any time soon.
+ *
+ * Note: the granule of kvm dirty log is qemu_real_host_page_size.
+ * And mem->memory_size is aligned to it (otherwise this mem can't
+ * be registered to KVM).
  */
-hwaddr bitmap_size = ALIGN(((mem->memory_size) >> TARGET_PAGE_BITS),
+hwaddr bitmap_size = ALIGN(mem->memory_size / qemu_real_host_page_size,
 /*HOST_LONG_BITS*/ 64) / 8;
 mem->dirty_bmap = g_malloc0(bitmap_size);
 }
-- 
2.23.0




[PATCH v2 2/2] accel: kvm: Add aligment assert for kvm_log_clear_one_slot

2020-12-16 Thread Keqian Zhu
The parameters start and size are transfered from QEMU memory
emulation layer. It can promise that they are TARGET_PAGE_SIZE
aligned. However, KVM needs they are qemu_real_page_size aligned.

Though no caller breaks this aligned requirement currently, we'd
better add an explicit assert to avoid future breaking.

Signed-off-by: Keqian Zhu 
---
 accel/kvm/kvm-all.c | 7 +++
 1 file changed, 7 insertions(+)

---
v2
 - Address Andrew's commment (Use assert instead of return err).

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index f6b16a8df8..73b195cc41 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -692,6 +692,10 @@ out:
 #define KVM_CLEAR_LOG_ALIGN  (qemu_real_host_page_size << KVM_CLEAR_LOG_SHIFT)
 #define KVM_CLEAR_LOG_MASK   (-KVM_CLEAR_LOG_ALIGN)
 
+/*
+ * As the granule of kvm dirty log is qemu_real_host_page_size,
+ * @start and @size are expected and restricted to align to it.
+ */
 static int kvm_log_clear_one_slot(KVMSlot *mem, int as_id, uint64_t start,
   uint64_t size)
 {
@@ -701,6 +705,9 @@ static int kvm_log_clear_one_slot(KVMSlot *mem, int as_id, 
uint64_t start,
 unsigned long *bmap_clear = NULL, psize = qemu_real_host_page_size;
 int ret;
 
+/* Make sure start and size are qemu_real_host_page_size aligned */
+assert(QEMU_IS_ALIGNED(start | size, psize));
+
 /*
  * We need to extend either the start or the size or both to
  * satisfy the KVM interface requirement.  Firstly, do the start
-- 
2.23.0




[PATCH v2 0/2] accel: kvm: Some bugfixes for kvm dirty log

2020-12-16 Thread Keqian Zhu
Hi all,

This series fixes memory waste and adds alignment check for unmatched
qemu_real_host_page_size and TARGET_PAGE_SIZE.

Thanks.

Keqian Zhu (2):
  accel: kvm: Fix memory waste under mismatch page size
  accel: kvm: Add aligment assert for kvm_log_clear_one_slot

 accel/kvm/kvm-all.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

-- 
2.23.0




Re: [PATCH v5 0/2] MTE support for KVM guest

2020-12-16 Thread Haibo Xu
On Wed, 16 Dec 2020 at 18:23, Steven Price  wrote:
>
> On 16/12/2020 07:31, Haibo Xu wrote:
> [...]
> > Hi Steve,
>
> Hi Haibo
>
> > I have finished verifying the POC on a FVP setup, and the MTE test case can
> > be migrated from one VM to another successfully. Since the test case is very
> > simple which just maps one page with MTE enabled and does some memory
> > access, so I can't say it's OK for other cases.
>
> That's great progress.
>
> >
> > BTW, I noticed that you have sent out patch set v6 which mentions that 
> > mapping
> > all the guest memory with PROT_MTE was not feasible. So what's the plan for 
> > the
> > next step? Will new KVM APIs which can facilitate the tag store and recover 
> > be
> > available?
>
> I'm currently rebasing on top of the KASAN MTE patch series. My plan for
> now is to switch back to not requiring the VMM to supply PROT_MTE (so
> KVM 'upgrades' the pages as necessary) and I'll add an RFC patch on the
> end of the series to add an KVM API for doing bulk read/write of tags.
> That way the VMM can map guest memory without PROT_MTE (so device 'DMA'
> accesses will be unchecked), and use the new API for migration.
>

Great! Will have a try with the new API in my POC!

> Thanks,
>
> Steve



Re: [PATCH v2 05/11] qapi/introspect.py: add preliminary type hint annotations

2020-12-16 Thread John Snow

On 12/16/20 2:51 AM, Markus Armbruster wrote:


Is it too late to delay the introduction of type hints until after the
data structure cleanups?

If yes, I have to spend more time replying below.



No, I re-ordered the series again to delay typing until the end, or 
close to it.


Though I abandoned plans to slacken List[...] inputs to Iterable[...] or 
Sequence[...] like I had mentioned; I think it could still be done, but 
it's fine to just use List[...] for the inputs for now. We can worry 
about optimizing type flexibility later, I think.


Let's just get the dog hunting at all first.

--js




Re: [PATCH v2 09/11] qapi/introspect.py: create a typed 'Annotated' data strutcure

2020-12-16 Thread John Snow

On 12/16/20 2:08 AM, Markus Armbruster wrote:

We all have our phobias. I find "isinstance(x,
extremely_common_stdlib_type)" to be extremely fragile and likely to
frustrate.

You're applying programming-in-the-large reasoning to a
programming-in-the-small case.



"Surely, they won't use my proof of concept code in production!"

Ah, alas, ...


Say you're writing a piece of code you expect to be used in contexts you
prudently refuse to predict.  The code deals with a bunch of basic
Python types.  Reserving another basic Python type for internal use may
well be unwise then, because it can make your code break confusingly
when this other type appears in input.  Which it shouldn't, but making
your reusable code harder to misuse, and misuses easier to diagnose are
laudable goals.

This is not such a piece of code.  All the users it will ever have are
in the same file of 200-something LOC.



I'm just saying that this type of code has bitten me in the ass before. 
You're right that it's not likely to bite someone explicitly here, but 
that's indeed why it came in the "Also, ..." section.


I've reworked the commit message a bit by now, but I suspect you'll 
still want to take the red marker to it a bit.


--js




Re: [PATCH] tcg: Add tcg_gen_bswap_tl alias

2020-12-16 Thread Frank Chang
On Thu, Dec 17, 2020 at 2:05 AM Richard Henderson <
richard.hender...@linaro.org> wrote:

> The alias is intended to indicate that the bswap is for the
> entire target_long.  This should avoid ifdefs on some targets.
>
> Signed-off-by: Richard Henderson 
> ---
>  include/tcg/tcg-op.h | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
> index 5abf17fecc..5b3bdacc39 100644
> --- a/include/tcg/tcg-op.h
> +++ b/include/tcg/tcg-op.h
> @@ -1085,6 +1085,7 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base,
> TCGArg offset, TCGType t);
>  #define tcg_gen_bswap16_tl tcg_gen_bswap16_i64
>  #define tcg_gen_bswap32_tl tcg_gen_bswap32_i64
>  #define tcg_gen_bswap64_tl tcg_gen_bswap64_i64
> +#define tcg_gen_bswap_tl tcg_gen_bswap64_i64
>  #define tcg_gen_concat_tl_i64 tcg_gen_concat32_i64
>  #define tcg_gen_extr_i64_tl tcg_gen_extr32_i64
>  #define tcg_gen_andc_tl tcg_gen_andc_i64
> @@ -1197,6 +1198,7 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base,
> TCGArg offset, TCGType t);
>  #define tcg_gen_ext32s_tl tcg_gen_mov_i32
>  #define tcg_gen_bswap16_tl tcg_gen_bswap16_i32
>  #define tcg_gen_bswap32_tl tcg_gen_bswap32_i32
> +#define tcg_gen_bswap_tl tcg_gen_bswap32_i32
>  #define tcg_gen_concat_tl_i64 tcg_gen_concat_i32_i64
>  #define tcg_gen_extr_i64_tl tcg_gen_extr_i64_i32
>  #define tcg_gen_andc_tl tcg_gen_andc_i32
> --
> 2.25.1
>
>
Thanks, I'll apply this one to my RISC-V B-extension patchset.

Reviewed-by: Frank Chang 


Re: [PATCH 1/2] accel: kvm: Fix memory waste under mismatch page size

2020-12-16 Thread Keqian Zhu



On 2020/12/17 4:48, Peter Xu wrote:
> On Wed, Dec 16, 2020 at 04:21:17PM +0800, Keqian Zhu wrote:
>> One more thing, we should consider whether @start and @size is psize aligned 
>> (my second
>> patch). Do you agree to add assert on them directly?
> 
> Yes I think the 2nd patch is okay, but please address Drew's comments.
> 
> Returning -EINVAL is the same as abort() currently - it'll just abort() at
> kvm_log_clear() instead.
OK, I will send v2 soon.

Thanks,
Keqian

> 
> Thanks,
> 



[PATCH v4 2/6] hw/timer: Refactor NPCM7XX Timer to use CLK clock

2020-12-16 Thread Hao Wu via
This patch makes NPCM7XX Timer to use a the timer clock generated by the
CLK module instead of the magic number TIMER_REF_HZ.

Reviewed-by: Havard Skinnemoen 
Reviewed-by: Tyrone Ting 
Signed-off-by: Hao Wu 
---
 hw/arm/npcm7xx.c |  5 +
 hw/timer/npcm7xx_timer.c | 25 ++---
 include/hw/misc/npcm7xx_clk.h|  6 --
 include/hw/timer/npcm7xx_timer.h |  1 +
 4 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 47e2b6fc40..fabfb1697b 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -22,6 +22,7 @@
 #include "hw/char/serial.h"
 #include "hw/loader.h"
 #include "hw/misc/unimp.h"
+#include "hw/qdev-clock.h"
 #include "hw/qdev-properties.h"
 #include "qapi/error.h"
 #include "qemu/units.h"
@@ -420,6 +421,10 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 int first_irq;
 int j;
 
+/* Connect the timer clock. */
+qdev_connect_clock_in(DEVICE(>tim[i]), "clock", qdev_get_clock_out(
+DEVICE(>clk), "timer-clock"));
+
 sysbus_realize(sbd, _abort);
 sysbus_mmio_map(sbd, 0, npcm7xx_tim_addr[i]);
 
diff --git a/hw/timer/npcm7xx_timer.c b/hw/timer/npcm7xx_timer.c
index d24445bd6e..6e990d611a 100644
--- a/hw/timer/npcm7xx_timer.c
+++ b/hw/timer/npcm7xx_timer.c
@@ -17,8 +17,8 @@
 #include "qemu/osdep.h"
 
 #include "hw/irq.h"
+#include "hw/qdev-clock.h"
 #include "hw/qdev-properties.h"
-#include "hw/misc/npcm7xx_clk.h"
 #include "hw/timer/npcm7xx_timer.h"
 #include "migration/vmstate.h"
 #include "qemu/bitops.h"
@@ -130,7 +130,7 @@ static int64_t npcm7xx_timer_count_to_ns(NPCM7xxTimer *t, 
uint32_t count)
 {
 int64_t ns = count;
 
-ns *= NANOSECONDS_PER_SECOND / NPCM7XX_TIMER_REF_HZ;
+ns *= clock_get_ns(t->ctrl->clock);
 ns *= npcm7xx_tcsr_prescaler(t->tcsr);
 
 return ns;
@@ -141,7 +141,7 @@ static uint32_t npcm7xx_timer_ns_to_count(NPCM7xxTimer *t, 
int64_t ns)
 {
 int64_t count;
 
-count = ns / (NANOSECONDS_PER_SECOND / NPCM7XX_TIMER_REF_HZ);
+count = ns / clock_get_ns(t->ctrl->clock);
 count /= npcm7xx_tcsr_prescaler(t->tcsr);
 
 return count;
@@ -167,7 +167,7 @@ static void 
npcm7xx_watchdog_timer_reset_cycles(NPCM7xxWatchdogTimer *t,
 int64_t cycles)
 {
 uint32_t prescaler = npcm7xx_watchdog_timer_prescaler(t);
-int64_t ns = (NANOSECONDS_PER_SECOND / NPCM7XX_TIMER_REF_HZ) * cycles;
+int64_t ns = clock_get_ns(t->ctrl->clock) * cycles;
 
 /*
  * The reset function always clears the current timer. The caller of the
@@ -606,10 +606,11 @@ static void npcm7xx_timer_hold_reset(Object *obj)
 qemu_irq_lower(s->watchdog_timer.irq);
 }
 
-static void npcm7xx_timer_realize(DeviceState *dev, Error **errp)
+static void npcm7xx_timer_init(Object *obj)
 {
-NPCM7xxTimerCtrlState *s = NPCM7XX_TIMER(dev);
-SysBusDevice *sbd = >parent;
+NPCM7xxTimerCtrlState *s = NPCM7XX_TIMER(obj);
+DeviceState *dev = DEVICE(obj);
+SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 int i;
 NPCM7xxWatchdogTimer *w;
 
@@ -627,11 +628,12 @@ static void npcm7xx_timer_realize(DeviceState *dev, Error 
**errp)
 npcm7xx_watchdog_timer_expired, w);
 sysbus_init_irq(sbd, >irq);
 
-memory_region_init_io(>iomem, OBJECT(s), _timer_ops, s,
+memory_region_init_io(>iomem, obj, _timer_ops, s,
   TYPE_NPCM7XX_TIMER, 4 * KiB);
 sysbus_init_mmio(sbd, >iomem);
 qdev_init_gpio_out_named(dev, >reset_signal,
 NPCM7XX_WATCHDOG_RESET_GPIO_OUT, 1);
+s->clock = qdev_init_clock_in(dev, "clock", NULL, NULL);
 }
 
 static const VMStateDescription vmstate_npcm7xx_base_timer = {
@@ -675,10 +677,11 @@ static const VMStateDescription 
vmstate_npcm7xx_watchdog_timer = {
 
 static const VMStateDescription vmstate_npcm7xx_timer_ctrl = {
 .name = "npcm7xx-timer-ctrl",
-.version_id = 1,
-.minimum_version_id = 1,
+.version_id = 2,
+.minimum_version_id = 2,
 .fields = (VMStateField[]) {
 VMSTATE_UINT32(tisr, NPCM7xxTimerCtrlState),
+VMSTATE_CLOCK(clock, NPCM7xxTimerCtrlState),
 VMSTATE_STRUCT_ARRAY(timer, NPCM7xxTimerCtrlState,
  NPCM7XX_TIMERS_PER_CTRL, 0, vmstate_npcm7xx_timer,
  NPCM7xxTimer),
@@ -697,7 +700,6 @@ static void npcm7xx_timer_class_init(ObjectClass *klass, 
void *data)
 QEMU_BUILD_BUG_ON(NPCM7XX_TIMER_REGS_END > NPCM7XX_TIMER_NR_REGS);
 
 dc->desc = "NPCM7xx Timer Controller";
-dc->realize = npcm7xx_timer_realize;
 dc->vmsd = _npcm7xx_timer_ctrl;
 rc->phases.enter = npcm7xx_timer_enter_reset;
 rc->phases.hold = npcm7xx_timer_hold_reset;
@@ -708,6 +710,7 @@ static const TypeInfo npcm7xx_timer_info = {
 .parent = TYPE_SYS_BUS_DEVICE,
 .instance_size  = sizeof(NPCM7xxTimerCtrlState),
 .class_init = npcm7xx_timer_class_init,
+.instance_init  = npcm7xx_timer_init,
 

[PATCH v4 5/6] hw/misc: Add QTest for NPCM7XX PWM Module

2020-12-16 Thread Hao Wu via
We add a qtest for the PWM in the previous patch. It proves it works as
expected.

Reviewed-by: Havard Skinnemoen 
Reviewed-by: Tyrone Ting 
Signed-off-by: Hao Wu 
---
 tests/qtest/meson.build|   1 +
 tests/qtest/npcm7xx_pwm-test.c | 490 +
 2 files changed, 491 insertions(+)
 create mode 100644 tests/qtest/npcm7xx_pwm-test.c

diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 955710d1c5..0b5467f084 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -136,6 +136,7 @@ qtests_sparc64 = \
 qtests_npcm7xx = \
   ['npcm7xx_adc-test',
'npcm7xx_gpio-test',
+   'npcm7xx_pwm-test',
'npcm7xx_rng-test',
'npcm7xx_timer-test',
'npcm7xx_watchdog_timer-test']
diff --git a/tests/qtest/npcm7xx_pwm-test.c b/tests/qtest/npcm7xx_pwm-test.c
new file mode 100644
index 00..33fbdf5f54
--- /dev/null
+++ b/tests/qtest/npcm7xx_pwm-test.c
@@ -0,0 +1,490 @@
+/*
+ * QTests for Nuvoton NPCM7xx PWM Modules.
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/bitops.h"
+#include "libqos/libqtest.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qnum.h"
+
+#define REF_HZ  2500
+
+/* Register field definitions. */
+#define CH_EN   BIT(0)
+#define CH_INV  BIT(2)
+#define CH_MOD  BIT(3)
+
+/* Registers shared between all PWMs in a module */
+#define PPR 0x00
+#define CSR 0x04
+#define PCR 0x08
+#define PIER0x3c
+#define PIIR0x40
+
+/* CLK module related */
+#define CLK_BA  0xf0801000
+#define CLKSEL  0x04
+#define CLKDIV1 0x08
+#define CLKDIV2 0x2c
+#define PLLCON0 0x0c
+#define PLLCON1 0x10
+#define PLL_INDV(rv)extract32((rv), 0, 6)
+#define PLL_FBDV(rv)extract32((rv), 16, 12)
+#define PLL_OTDV1(rv)   extract32((rv), 8, 3)
+#define PLL_OTDV2(rv)   extract32((rv), 13, 3)
+#define APB3CKDIV(rv)   extract32((rv), 28, 2)
+#define CLK2CKDIV(rv)   extract32((rv), 0, 1)
+#define CLK4CKDIV(rv)   extract32((rv), 26, 2)
+#define CPUCKSEL(rv)extract32((rv), 0, 2)
+
+#define MAX_DUTY100
+
+typedef struct PWMModule {
+int irq;
+uint64_t base_addr;
+} PWMModule;
+
+typedef struct PWM {
+uint32_t cnr_offset;
+uint32_t cmr_offset;
+uint32_t pdr_offset;
+uint32_t pwdr_offset;
+} PWM;
+
+typedef struct TestData {
+const PWMModule *module;
+const PWM *pwm;
+} TestData;
+
+static const PWMModule pwm_module_list[] = {
+{
+.irq= 93,
+.base_addr  = 0xf0103000
+},
+{
+.irq= 94,
+.base_addr  = 0xf0104000
+}
+};
+
+static const PWM pwm_list[] = {
+{
+.cnr_offset = 0x0c,
+.cmr_offset = 0x10,
+.pdr_offset = 0x14,
+.pwdr_offset= 0x44,
+},
+{
+.cnr_offset = 0x18,
+.cmr_offset = 0x1c,
+.pdr_offset = 0x20,
+.pwdr_offset= 0x48,
+},
+{
+.cnr_offset = 0x24,
+.cmr_offset = 0x28,
+.pdr_offset = 0x2c,
+.pwdr_offset= 0x4c,
+},
+{
+.cnr_offset = 0x30,
+.cmr_offset = 0x34,
+.pdr_offset = 0x38,
+.pwdr_offset= 0x50,
+},
+};
+
+static const int ppr_base[] = { 0, 0, 8, 8 };
+static const int csr_base[] = { 0, 4, 8, 12 };
+static const int pcr_base[] = { 0, 8, 12, 16 };
+
+static const uint32_t ppr_list[] = {
+0,
+1,
+10,
+100,
+255, /* Max possible value. */
+};
+
+static const uint32_t csr_list[] = {
+0,
+1,
+2,
+3,
+4, /* Max possible value. */
+};
+
+static const uint32_t cnr_list[] = {
+0,
+1,
+50,
+100,
+150,
+200,
+1000,
+1,
+65535, /* Max possible value. */
+};
+
+static const uint32_t cmr_list[] = {
+0,
+1,
+10,
+50,
+100,
+150,
+200,
+1000,
+1,
+65535, /* Max possible value. */
+};
+
+/* Returns the index of the PWM module. */
+static int pwm_module_index(const PWMModule *module)
+{
+ptrdiff_t diff = module - pwm_module_list;
+
+g_assert_true(diff >= 0 && diff < ARRAY_SIZE(pwm_module_list));
+
+return diff;
+}
+
+/* Returns the index of the PWM entry. */
+static int pwm_index(const PWM *pwm)
+{
+ptrdiff_t diff = pwm - pwm_list;
+
+g_assert_true(diff >= 0 && diff < ARRAY_SIZE(pwm_list));
+
+return diff;
+}
+
+static 

[PATCH v4 1/6] hw/misc: Add clock converter in NPCM7XX CLK module

2020-12-16 Thread Hao Wu via
This patch allows NPCM7XX CLK module to compute clocks that are used by
other NPCM7XX modules.

Add a new struct NPCM7xxClockConverterState which represents a
single converter.  Each clock converter in CLK module represents one
converter in NPCM7XX CLK Module(PLL, SEL or Divider). Each converter
takes one or more input clocks and converts them into one output clock.
They form a clock hierarchy in the CLK module and are responsible for
outputing clocks for various other modules in an NPCM7XX SoC.

Each converter has a function pointer called "convert" which represents
the unique logic for that converter.

The clock contains two initialization information: ConverterInitInfo and
ConverterConnectionInfo. They represent the vertices and edges in the
clock diagram respectively.

Reviewed-by: Havard Skinnemoen 
Reviewed-by: Tyrone Ting 
Signed-off-by: Hao Wu 
---
 hw/misc/npcm7xx_clk.c | 795 +-
 include/hw/misc/npcm7xx_clk.h | 140 +-
 2 files changed, 927 insertions(+), 8 deletions(-)

diff --git a/hw/misc/npcm7xx_clk.c b/hw/misc/npcm7xx_clk.c
index 6732437fe2..48bc9bdda5 100644
--- a/hw/misc/npcm7xx_clk.c
+++ b/hw/misc/npcm7xx_clk.c
@@ -18,6 +18,7 @@
 
 #include "hw/misc/npcm7xx_clk.h"
 #include "hw/timer/npcm7xx_timer.h"
+#include "hw/qdev-clock.h"
 #include "migration/vmstate.h"
 #include "qemu/error-report.h"
 #include "qemu/log.h"
@@ -27,9 +28,22 @@
 #include "trace.h"
 #include "sysemu/watchdog.h"
 
+/*
+ * The reference clock hz, and the SECCNT and CNTR25M registers in this module,
+ * is always 25 MHz.
+ */
+#define NPCM7XX_CLOCK_REF_HZ(2500)
+
+/* Register Field Definitions */
+#define NPCM7XX_CLK_WDRCR_CA9C  BIT(0) /* Cortex A9 Cores */
+
 #define PLLCON_LOKI BIT(31)
 #define PLLCON_LOKS BIT(30)
 #define PLLCON_PWDENBIT(12)
+#define PLLCON_FBDV(con) extract32((con), 16, 12)
+#define PLLCON_OTDV2(con) extract32((con), 13, 3)
+#define PLLCON_OTDV1(con) extract32((con), 8, 3)
+#define PLLCON_INDV(con) extract32((con), 0, 6)
 
 enum NPCM7xxCLKRegisters {
 NPCM7XX_CLK_CLKEN1,
@@ -89,12 +103,609 @@ static const uint32_t 
cold_reset_values[NPCM7XX_CLK_NR_REGS] = {
 [NPCM7XX_CLK_AHBCKFI]   = 0x00c8,
 };
 
-/* Register Field Definitions */
-#define NPCM7XX_CLK_WDRCR_CA9C  BIT(0) /* Cortex A9 Cores */
-
 /* The number of watchdogs that can trigger a reset. */
 #define NPCM7XX_NR_WATCHDOGS(3)
 
+/* Clock converter functions */
+
+#define TYPE_NPCM7XX_CLOCK_PLL "npcm7xx-clock-pll"
+#define NPCM7XX_CLOCK_PLL(obj) OBJECT_CHECK(NPCM7xxClockPLLState, \
+(obj), TYPE_NPCM7XX_CLOCK_PLL)
+#define TYPE_NPCM7XX_CLOCK_SEL "npcm7xx-clock-sel"
+#define NPCM7XX_CLOCK_SEL(obj) OBJECT_CHECK(NPCM7xxClockSELState, \
+(obj), TYPE_NPCM7XX_CLOCK_SEL)
+#define TYPE_NPCM7XX_CLOCK_DIVIDER "npcm7xx-clock-divider"
+#define NPCM7XX_CLOCK_DIVIDER(obj) OBJECT_CHECK(NPCM7xxClockDividerState, \
+(obj), TYPE_NPCM7XX_CLOCK_DIVIDER)
+
+static void npcm7xx_clk_update_pll(void *opaque)
+{
+NPCM7xxClockPLLState *s = opaque;
+uint32_t con = s->clk->regs[s->reg];
+uint64_t freq;
+
+/* The PLL is grounded if it is not locked yet. */
+if (con & PLLCON_LOKI) {
+freq = clock_get_hz(s->clock_in);
+freq *= PLLCON_FBDV(con);
+freq /= PLLCON_INDV(con) * PLLCON_OTDV1(con) * PLLCON_OTDV2(con);
+} else {
+freq = 0;
+}
+
+clock_update_hz(s->clock_out, freq);
+}
+
+static void npcm7xx_clk_update_sel(void *opaque)
+{
+NPCM7xxClockSELState *s = opaque;
+uint32_t index = extract32(s->clk->regs[NPCM7XX_CLK_CLKSEL], s->offset,
+s->len);
+
+if (index >= s->input_size) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: SEL index: %u out of range\n",
+  __func__, index);
+index = 0;
+}
+clock_update_hz(s->clock_out, clock_get_hz(s->clock_in[index]));
+}
+
+static void npcm7xx_clk_update_divider(void *opaque)
+{
+NPCM7xxClockDividerState *s = opaque;
+uint32_t freq;
+
+freq = s->divide(s);
+clock_update_hz(s->clock_out, freq);
+}
+
+static uint32_t divide_by_constant(NPCM7xxClockDividerState *s)
+{
+return clock_get_hz(s->clock_in) / s->divisor;
+}
+
+static uint32_t divide_by_reg_divisor(NPCM7xxClockDividerState *s)
+{
+return clock_get_hz(s->clock_in) /
+(extract32(s->clk->regs[s->reg], s->offset, s->len) + 1);
+}
+
+static uint32_t divide_by_reg_divisor_times_2(NPCM7xxClockDividerState *s)
+{
+return divide_by_reg_divisor(s) / 2;
+}
+
+static uint32_t shift_by_reg_divisor(NPCM7xxClockDividerState *s)
+{
+return clock_get_hz(s->clock_in) >>
+extract32(s->clk->regs[s->reg], s->offset, s->len);
+}
+
+static NPCM7xxClockPLL find_pll_by_reg(enum NPCM7xxCLKRegisters reg)
+{
+switch (reg) {
+case NPCM7XX_CLK_PLLCON0:
+return NPCM7XX_CLOCK_PLL0;
+case NPCM7XX_CLK_PLLCON1:
+return NPCM7XX_CLOCK_PLL1;
+case NPCM7XX_CLK_PLLCON2:
+return 

[PATCH v4 6/6] hw/*: Use type casting for SysBusDevice in NPCM7XX

2020-12-16 Thread Hao Wu via
A device shouldn't access its parent object which is QOM internal.
Instead it should use type cast for this purporse. This patch fixes this
issue for all NPCM7XX Devices.

Signed-off-by: Hao Wu 
---
 hw/arm/npcm7xx_boards.c | 2 +-
 hw/mem/npcm7xx_mc.c | 2 +-
 hw/misc/npcm7xx_clk.c   | 2 +-
 hw/misc/npcm7xx_gcr.c   | 2 +-
 hw/misc/npcm7xx_rng.c   | 2 +-
 hw/nvram/npcm7xx_otp.c  | 2 +-
 hw/ssi/npcm7xx_fiu.c| 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 306260fa67..3fdd5cab01 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -82,7 +82,7 @@ static NPCM7xxState *npcm7xx_create_soc(MachineState *machine,
 uint32_t hw_straps)
 {
 NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_GET_CLASS(machine);
-MachineClass *mc = >parent;
+MachineClass *mc = MACHINE_CLASS(nmc);
 Object *obj;
 
 if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
diff --git a/hw/mem/npcm7xx_mc.c b/hw/mem/npcm7xx_mc.c
index 0435d06ab4..abc5af5620 100644
--- a/hw/mem/npcm7xx_mc.c
+++ b/hw/mem/npcm7xx_mc.c
@@ -62,7 +62,7 @@ static void npcm7xx_mc_realize(DeviceState *dev, Error **errp)
 
 memory_region_init_io(>mmio, OBJECT(s), _mc_ops, s, "regs",
   NPCM7XX_MC_REGS_SIZE);
-sysbus_init_mmio(>parent, >mmio);
+sysbus_init_mmio(SYS_BUS_DEVICE(s), >mmio);
 }
 
 static void npcm7xx_mc_class_init(ObjectClass *klass, void *data)
diff --git a/hw/misc/npcm7xx_clk.c b/hw/misc/npcm7xx_clk.c
index 48bc9bdda5..0bcae9ce95 100644
--- a/hw/misc/npcm7xx_clk.c
+++ b/hw/misc/npcm7xx_clk.c
@@ -913,7 +913,7 @@ static void npcm7xx_clk_init(Object *obj)
 
 memory_region_init_io(>iomem, obj, _clk_ops, s,
   TYPE_NPCM7XX_CLK, 4 * KiB);
-sysbus_init_mmio(>parent, >iomem);
+sysbus_init_mmio(SYS_BUS_DEVICE(s), >iomem);
 }
 
 static int npcm7xx_clk_post_load(void *opaque, int version_id)
diff --git a/hw/misc/npcm7xx_gcr.c b/hw/misc/npcm7xx_gcr.c
index 745f690809..eace9e1967 100644
--- a/hw/misc/npcm7xx_gcr.c
+++ b/hw/misc/npcm7xx_gcr.c
@@ -220,7 +220,7 @@ static void npcm7xx_gcr_init(Object *obj)
 
 memory_region_init_io(>iomem, obj, _gcr_ops, s,
   TYPE_NPCM7XX_GCR, 4 * KiB);
-sysbus_init_mmio(>parent, >iomem);
+sysbus_init_mmio(SYS_BUS_DEVICE(s), >iomem);
 }
 
 static const VMStateDescription vmstate_npcm7xx_gcr = {
diff --git a/hw/misc/npcm7xx_rng.c b/hw/misc/npcm7xx_rng.c
index f650f3401f..b01df7cdb2 100644
--- a/hw/misc/npcm7xx_rng.c
+++ b/hw/misc/npcm7xx_rng.c
@@ -143,7 +143,7 @@ static void npcm7xx_rng_init(Object *obj)
 
 memory_region_init_io(>iomem, obj, _rng_ops, s, "regs",
   NPCM7XX_RNG_REGS_SIZE);
-sysbus_init_mmio(>parent, >iomem);
+sysbus_init_mmio(SYS_BUS_DEVICE(s), >iomem);
 }
 
 static const VMStateDescription vmstate_npcm7xx_rng = {
diff --git a/hw/nvram/npcm7xx_otp.c b/hw/nvram/npcm7xx_otp.c
index b16ca530ba..c61f2fc1aa 100644
--- a/hw/nvram/npcm7xx_otp.c
+++ b/hw/nvram/npcm7xx_otp.c
@@ -371,7 +371,7 @@ static void npcm7xx_otp_realize(DeviceState *dev, Error 
**errp)
 {
 NPCM7xxOTPClass *oc = NPCM7XX_OTP_GET_CLASS(dev);
 NPCM7xxOTPState *s = NPCM7XX_OTP(dev);
-SysBusDevice *sbd = >parent;
+SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
 memset(s->array, 0, sizeof(s->array));
 
diff --git a/hw/ssi/npcm7xx_fiu.c b/hw/ssi/npcm7xx_fiu.c
index 5040132b07..4eedb2927e 100644
--- a/hw/ssi/npcm7xx_fiu.c
+++ b/hw/ssi/npcm7xx_fiu.c
@@ -498,7 +498,7 @@ static void npcm7xx_fiu_hold_reset(Object *obj)
 static void npcm7xx_fiu_realize(DeviceState *dev, Error **errp)
 {
 NPCM7xxFIUState *s = NPCM7XX_FIU(dev);
-SysBusDevice *sbd = >parent;
+SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 int i;
 
 if (s->cs_count <= 0) {
-- 
2.29.2.684.gfbc64c5ab5-goog




[PATCH v4 4/6] hw/misc: Add a PWM module for NPCM7XX

2020-12-16 Thread Hao Wu via
The PWM module is part of NPCM7XX module. Each NPCM7XX module has two
identical PWM modules. Each module contains 4 PWM entries. Each PWM has
two outputs: frequency and duty_cycle. Both are computed using inputs
from software side.

This module does not model detail pulse signals since it is expensive.
It also does not model interrupts and watchdogs that are dependant on
the detail models. The interfaces for these are left in the module so
that anyone in need for these functionalities can implement on their
own.

The user can read the duty cycle and frequency using qom-get command.

Reviewed-by: Havard Skinnemoen 
Reviewed-by: Tyrone Ting 
Signed-off-by: Hao Wu 
---
 docs/system/arm/nuvoton.rst   |   2 +-
 hw/arm/npcm7xx.c  |  26 +-
 hw/misc/meson.build   |   1 +
 hw/misc/npcm7xx_pwm.c | 559 ++
 hw/misc/trace-events  |   6 +
 include/hw/arm/npcm7xx.h  |   2 +
 include/hw/misc/npcm7xx_pwm.h | 106 +++
 7 files changed, 699 insertions(+), 3 deletions(-)
 create mode 100644 hw/misc/npcm7xx_pwm.c
 create mode 100644 include/hw/misc/npcm7xx_pwm.h

diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
index 35829f8d0b..a1786342e2 100644
--- a/docs/system/arm/nuvoton.rst
+++ b/docs/system/arm/nuvoton.rst
@@ -42,6 +42,7 @@ Supported devices
  * USB host (USBH)
  * GPIO controller
  * Analog to Digital Converter (ADC)
+ * Pulse Width Modulation (PWM)
 
 Missing devices
 ---
@@ -61,7 +62,6 @@ Missing devices
  * Peripheral SPI controller (PSPI)
  * SD/MMC host
  * PECI interface
- * Pulse Width Modulation (PWM)
  * Tachometer
  * PCI and PCIe root complex and bridges
  * VDM and MCTP support
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index b22a8c966d..72040d4079 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -102,6 +102,8 @@ enum NPCM7xxInterrupt {
 NPCM7XX_WDG2_IRQ,   /* Timer Module 2 Watchdog */
 NPCM7XX_EHCI_IRQ= 61,
 NPCM7XX_OHCI_IRQ= 62,
+NPCM7XX_PWM0_IRQ= 93,   /* PWM module 0 */
+NPCM7XX_PWM1_IRQ,   /* PWM module 1 */
 NPCM7XX_GPIO0_IRQ   = 116,
 NPCM7XX_GPIO1_IRQ,
 NPCM7XX_GPIO2_IRQ,
@@ -144,6 +146,12 @@ static const hwaddr npcm7xx_fiu3_flash_addr[] = {
 0xb800, /* CS3 */
 };
 
+/* Register base address for each PWM Module */
+static const hwaddr npcm7xx_pwm_addr[] = {
+0xf0103000,
+0xf0104000,
+};
+
 static const struct {
 hwaddr regs_addr;
 uint32_t unconnected_pins;
@@ -353,6 +361,10 @@ static void npcm7xx_init(Object *obj)
 object_initialize_child(obj, npcm7xx_fiu[i].name, >fiu[i],
 TYPE_NPCM7XX_FIU);
 }
+
+for (i = 0; i < ARRAY_SIZE(s->pwm); i++) {
+object_initialize_child(obj, "pwm[*]", >pwm[i], TYPE_NPCM7XX_PWM);
+}
 }
 
 static void npcm7xx_realize(DeviceState *dev, Error **errp)
@@ -513,6 +525,18 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 sysbus_connect_irq(SYS_BUS_DEVICE(>ohci), 0,
npcm7xx_irq(s, NPCM7XX_OHCI_IRQ));
 
+/* PWM Modules. Cannot fail. */
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_pwm_addr) != ARRAY_SIZE(s->pwm));
+for (i = 0; i < ARRAY_SIZE(s->pwm); i++) {
+SysBusDevice *sbd = SYS_BUS_DEVICE(>pwm[i]);
+
+qdev_connect_clock_in(DEVICE(>pwm[i]), "clock", qdev_get_clock_out(
+DEVICE(>clk), "apb3-clock"));
+sysbus_realize(sbd, _abort);
+sysbus_mmio_map(sbd, 0, npcm7xx_pwm_addr[i]);
+sysbus_connect_irq(sbd, i, npcm7xx_irq(s, NPCM7XX_PWM0_IRQ + i));
+}
+
 /*
  * Flash Interface Unit (FIU). Can fail if incorrect number of chip selects
  * specified, but this is a programming error.
@@ -580,8 +604,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 create_unimplemented_device("npcm7xx.peci", 0xf010,   4 * KiB);
 create_unimplemented_device("npcm7xx.siox[1]",  0xf0101000,   4 * KiB);
 create_unimplemented_device("npcm7xx.siox[2]",  0xf0102000,   4 * KiB);
-create_unimplemented_device("npcm7xx.pwm[0]",   0xf0103000,   4 * KiB);
-create_unimplemented_device("npcm7xx.pwm[1]",   0xf0104000,   4 * KiB);
 create_unimplemented_device("npcm7xx.mft[0]",   0xf018,   4 * KiB);
 create_unimplemented_device("npcm7xx.mft[1]",   0xf0181000,   4 * KiB);
 create_unimplemented_device("npcm7xx.mft[2]",   0xf0182000,   4 * KiB);
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index ce15ffceb9..607cd38a21 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -64,6 +64,7 @@ softmmu_ss.add(when: 'CONFIG_MAINSTONE', if_true: 
files('mst_fpga.c'))
 softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files(
   'npcm7xx_clk.c',
   'npcm7xx_gcr.c',
+  'npcm7xx_pwm.c',
   'npcm7xx_rng.c',
 ))
 softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files(
diff --git a/hw/misc/npcm7xx_pwm.c 

[PATCH v4 3/6] hw/adc: Add an ADC module for NPCM7XX

2020-12-16 Thread Hao Wu via
The ADC is part of NPCM7XX Module. Its behavior is controled by the
ADC_CON register. It converts one of the eight analog inputs into a
digital input and stores it in the ADC_DATA register when enabled.

Users can alter input value by using qom-set QMP command.

Reviewed-by: Havard Skinnemoen 
Reviewed-by: Tyrone Ting 
Signed-off-by: Hao Wu 
---
 docs/system/arm/nuvoton.rst|   2 +-
 hw/adc/meson.build |   1 +
 hw/adc/npcm7xx_adc.c   | 321 ++
 hw/adc/trace-events|   5 +
 hw/arm/npcm7xx.c   |  24 +-
 include/hw/adc/npcm7xx_adc.h   |  72 ++
 include/hw/arm/npcm7xx.h   |   2 +
 meson.build|   1 +
 tests/qtest/meson.build|   3 +-
 tests/qtest/npcm7xx_adc-test.c | 400 +
 10 files changed, 828 insertions(+), 3 deletions(-)
 create mode 100644 hw/adc/npcm7xx_adc.c
 create mode 100644 hw/adc/trace-events
 create mode 100644 include/hw/adc/npcm7xx_adc.h
 create mode 100644 tests/qtest/npcm7xx_adc-test.c

diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
index b00d405d52..35829f8d0b 100644
--- a/docs/system/arm/nuvoton.rst
+++ b/docs/system/arm/nuvoton.rst
@@ -41,6 +41,7 @@ Supported devices
  * Random Number Generator (RNG)
  * USB host (USBH)
  * GPIO controller
+ * Analog to Digital Converter (ADC)
 
 Missing devices
 ---
@@ -58,7 +59,6 @@ Missing devices
  * USB device (USBD)
  * SMBus controller (SMBF)
  * Peripheral SPI controller (PSPI)
- * Analog to Digital Converter (ADC)
  * SD/MMC host
  * PECI interface
  * Pulse Width Modulation (PWM)
diff --git a/hw/adc/meson.build b/hw/adc/meson.build
index 0d62ae96ae..6ddee23813 100644
--- a/hw/adc/meson.build
+++ b/hw/adc/meson.build
@@ -1 +1,2 @@
 softmmu_ss.add(when: 'CONFIG_STM32F2XX_ADC', if_true: files('stm32f2xx_adc.c'))
+softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_adc.c'))
diff --git a/hw/adc/npcm7xx_adc.c b/hw/adc/npcm7xx_adc.c
new file mode 100644
index 00..f213b6a6df
--- /dev/null
+++ b/hw/adc/npcm7xx_adc.c
@@ -0,0 +1,321 @@
+/*
+ * Nuvoton NPCM7xx ADC Module
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "hw/adc/npcm7xx_adc.h"
+#include "hw/qdev-clock.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/timer.h"
+#include "qemu/units.h"
+#include "trace.h"
+
+/* 32-bit register indices. */
+enum NPCM7xxADCRegisters {
+NPCM7XX_ADC_CON,
+NPCM7XX_ADC_DATA,
+NPCM7XX_ADC_REGS_END,
+};
+
+/* Register field definitions. */
+#define NPCM7XX_ADC_CON_MUX(rv) extract32(rv, 24, 4)
+#define NPCM7XX_ADC_CON_INT_EN  BIT(21)
+#define NPCM7XX_ADC_CON_REFSEL  BIT(19)
+#define NPCM7XX_ADC_CON_INT BIT(18)
+#define NPCM7XX_ADC_CON_EN  BIT(17)
+#define NPCM7XX_ADC_CON_RST BIT(16)
+#define NPCM7XX_ADC_CON_CONVBIT(14)
+#define NPCM7XX_ADC_CON_DIV(rv) extract32(rv, 1, 8)
+
+#define NPCM7XX_ADC_MAX_RESULT  1023
+#define NPCM7XX_ADC_DEFAULT_IREF200
+#define NPCM7XX_ADC_CONV_CYCLES 20
+#define NPCM7XX_ADC_RESET_CYCLES10
+#define NPCM7XX_ADC_R0_INPUT50
+#define NPCM7XX_ADC_R1_INPUT150
+
+static void npcm7xx_adc_reset(NPCM7xxADCState *s)
+{
+timer_del(>conv_timer);
+timer_del(>reset_timer);
+s->con = 0x000c0001;
+s->data = 0x;
+}
+
+static uint32_t npcm7xx_adc_convert(uint32_t input, uint32_t ref)
+{
+uint32_t result;
+
+result = input * (NPCM7XX_ADC_MAX_RESULT + 1) / ref;
+if (result > NPCM7XX_ADC_MAX_RESULT) {
+result = NPCM7XX_ADC_MAX_RESULT;
+}
+
+return result;
+}
+
+static uint32_t npcm7xx_adc_prescaler(NPCM7xxADCState *s)
+{
+return 2 * (NPCM7XX_ADC_CON_DIV(s->con) + 1);
+}
+
+static void npcm7xx_adc_start_timer(Clock *clk, QEMUTimer *timer,
+uint32_t cycles, uint32_t prescaler)
+{
+int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+int64_t freq = clock_get_hz(clk);
+int64_t ns;
+
+ns = (NANOSECONDS_PER_SECOND * cycles * prescaler / freq);
+ns += now;
+timer_mod(timer, ns);
+}
+
+static void npcm7xx_adc_start_reset(NPCM7xxADCState *s)
+{
+uint32_t prescaler = npcm7xx_adc_prescaler(s);
+
+npcm7xx_adc_start_timer(s->clock, >reset_timer, 
NPCM7XX_ADC_RESET_CYCLES,
+prescaler);
+}
+
+static void npcm7xx_adc_start_convert(NPCM7xxADCState *s)
+{
+uint32_t prescaler = npcm7xx_adc_prescaler(s);
+
+

[PATCH v4 0/6] Additional NPCM7xx devices

2020-12-16 Thread Hao Wu via
This patch series include a few more NPCM7XX devices including

- Analog Digital Converter (ADC)
- Pulse Width Modulation (PWM)

We also modified the CLK module to generate clock values using qdev_clock.
These clocks are used to determine various clocks in NPCM7XX devices.

Thank you for your review.

Changes since v3:
- Use type casting instead of accessing parent object in all devices.

Changes since v2:
- Split PWM test into a separate patch in the patch set
- Add trace events for PWM's update_freq/update_duty
- Add trace events for ioread/iowrite in ADC and PWM
- Use timer_get_ns in hw/timer/npcm7xx_timer.c
- Update commit message in ADC/PWM to mention qom-get/set method for usage
- Fix typos

Changes since v1:
- We removed the IPMI and KCS related code from this patch set.

Hao Wu (6):
  hw/misc: Add clock converter in NPCM7XX CLK module
  hw/timer: Refactor NPCM7XX Timer to use CLK clock
  hw/adc: Add an ADC module for NPCM7XX
  hw/misc: Add a PWM module for NPCM7XX
  hw/misc: Add QTest for NPCM7XX PWM Module
  hw/*: Use type casting for SysBusDevice in NPCM7XX

 docs/system/arm/nuvoton.rst  |   4 +-
 hw/adc/meson.build   |   1 +
 hw/adc/npcm7xx_adc.c | 321 +
 hw/adc/trace-events  |   5 +
 hw/arm/npcm7xx.c |  55 ++-
 hw/arm/npcm7xx_boards.c  |   2 +-
 hw/mem/npcm7xx_mc.c  |   2 +-
 hw/misc/meson.build  |   1 +
 hw/misc/npcm7xx_clk.c| 797 ++-
 hw/misc/npcm7xx_gcr.c|   2 +-
 hw/misc/npcm7xx_pwm.c| 559 ++
 hw/misc/npcm7xx_rng.c|   2 +-
 hw/misc/trace-events |   6 +
 hw/nvram/npcm7xx_otp.c   |   2 +-
 hw/ssi/npcm7xx_fiu.c |   2 +-
 hw/timer/npcm7xx_timer.c |  25 +-
 include/hw/adc/npcm7xx_adc.h |  72 +++
 include/hw/arm/npcm7xx.h |   4 +
 include/hw/misc/npcm7xx_clk.h| 146 +-
 include/hw/misc/npcm7xx_pwm.h| 106 
 include/hw/timer/npcm7xx_timer.h |   1 +
 meson.build  |   1 +
 tests/qtest/meson.build  |   4 +-
 tests/qtest/npcm7xx_adc-test.c   | 400 
 tests/qtest/npcm7xx_pwm-test.c   | 490 +++
 25 files changed, 2972 insertions(+), 38 deletions(-)
 create mode 100644 hw/adc/npcm7xx_adc.c
 create mode 100644 hw/adc/trace-events
 create mode 100644 hw/misc/npcm7xx_pwm.c
 create mode 100644 include/hw/adc/npcm7xx_adc.h
 create mode 100644 include/hw/misc/npcm7xx_pwm.h
 create mode 100644 tests/qtest/npcm7xx_adc-test.c
 create mode 100644 tests/qtest/npcm7xx_pwm-test.c

-- 
2.29.2.684.gfbc64c5ab5-goog




[Bug 1213196] Re: -serial tcp should hang up when DTR goes low

2020-12-16 Thread Darrin M. Gorski
Sent in a patch for this.

https://lists.gnu.org/archive/html/qemu-devel/2020-12/msg04658.html

DTR controls the socket.

DCD reflects the state of the socket.

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

Title:
  -serial tcp should hang up when DTR goes low

Status in QEMU:
  New

Bug description:
  In keeping with the spirit of serial modem control signals, de-
  asserting DTR should cause the TCP connection to break; asserting DTR
  should cause QEMU to initiate a new connection or for it to accept
  another (in server mode; this may involve waiting for one to arrive,
  too).

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



Re: [PATCH 03/11] target/mips/mips-defs: Use ISA_MIPS32R2 definition to check Release 2

2020-12-16 Thread Philippe Mathieu-Daudé
On 12/16/20 5:34 PM, Philippe Mathieu-Daudé wrote:
> On 12/16/20 4:16 PM, Jiaxun Yang wrote:
>> 在 2020/12/16 21:43, Philippe Mathieu-Daudé 写道:
>>> Use the single ISA_MIPS32R2 definition to check if the Release 2
>>> ISA is supported, whether the CPU support 32/64-bit.
>>>
>>> For now we keep '32' in the definition name, we will rename it
>>> as ISA_MIPS_R2 in few commits.
>>>
>>> Signed-off-by: Philippe Mathieu-Daudé 
>>> ---
>>>   target/mips/mips-defs.h    | 3 +--
>>>   linux-user/mips/cpu_loop.c | 1 -
>>>   target/mips/translate.c    | 4 ++--
>>>   3 files changed, 3 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h
>>> index 2756e72a9d6..9cfa4c346bf 100644
>>> --- a/target/mips/mips-defs.h
>>> +++ b/target/mips/mips-defs.h
>>> @@ -24,7 +24,6 @@
>>>   #define ISA_MIPS5 0x0010ULL
>>>   #define ISA_MIPS32    0x0020ULL
>>>   #define ISA_MIPS32R2  0x0040ULL
>>> -#define ISA_MIPS64R2  0x0100ULL
>>>   #define ISA_MIPS32R3  0x0200ULL
>>>   #define ISA_MIPS64R3  0x0400ULL
>>>   #define ISA_MIPS32R5  0x0800ULL
>>> @@ -81,7 +80,7 @@
>>>     /* MIPS Technologies "Release 2" */
>>>   #define CPU_MIPS32R2    (CPU_MIPS32 | ISA_MIPS32R2)
>>> -#define CPU_MIPS64R2    (CPU_MIPS64 | CPU_MIPS32R2 | ISA_MIPS64R2)
>>> +#define CPU_MIPS64R2    (CPU_MIPS64 | ISA_MIPS32R2)
>>>     /* MIPS Technologies "Release 3" */
>>>   #define CPU_MIPS32R3    (CPU_MIPS32R2 | ISA_MIPS32R3)
>>> diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
>>> index b58dbeb83d1..a2aa8167210 100644
>>> --- a/linux-user/mips/cpu_loop.c
>>> +++ b/linux-user/mips/cpu_loop.c
>>> @@ -386,7 +386,6 @@ void target_cpu_copy_regs(CPUArchState *env,
>>> struct target_pt_regs *regs)
>>>   prog_req.fre &= interp_req.fre;
>>>     bool cpu_has_mips_r2_r6 = env->insn_flags & ISA_MIPS32R2 ||
>>> -  env->insn_flags & ISA_MIPS64R2 ||
>>>     env->insn_flags & ISA_MIPS32R6 ||
>>>     env->insn_flags & ISA_MIPS64R6;
>>>   diff --git a/target/mips/translate.c b/target/mips/translate.c
>>> index 8c0ecfa17e1..0923dfdf451 100644
>>> --- a/target/mips/translate.c
>>> +++ b/target/mips/translate.c
>>> @@ -28212,7 +28212,7 @@ static void decode_opc_special3(CPUMIPSState
>>> *env, DisasContext *ctx)
>>>   case OPC_DINSM:
>>>   case OPC_DINSU:
>>>   case OPC_DINS:
>>> -    check_insn(ctx, ISA_MIPS64R2);
>>> +    check_insn(ctx, ISA_MIPS32R2);
>>>   check_mips_64(ctx);
>>
> 
> Sorry I respin v2 before noticing this reply.
> 
>> After this change, 32-bit CPUs emulated with TARGET_MIPS64
>> and got CP0.Status.KX and CP0.Status.UX accidentally set won't
>> emit RI exception.
> 
> 32-bit CPUs shouldn't have MIPS_HFLAG_64 set, regardless
> the build used. So check_mips_64() will emit it...
> 
> Anyhow, I'd rather remove 32-bit CPUs from 64-bit build unless
> we are sure this works.

$ qemu-system-mips64el -M malta -S -monitor stdio \
-bios /dev/null -smp 2 -cpu 4Kc
QEMU 5.2.50 monitor - type 'help' for more information
(qemu) info qom-tree
/machine (malta-machine)
  /peripheral (container)
  /peripheral-anon (container)
  /unattached (container)
/bios.1fc[0] (qemu:memory-region)
/device[0] (mips-malta)
  /cpu-refclk (clock)
  /cpu[0] (4Kc-mips64-cpu)
/clk-in (clock)
  /cpu[1] (4Kc-mips64-cpu)
/clk-in (clock)

"4Kc-mips64"???



Re: [PATCH v2 02/12] target/mips/mips-defs: Use ISA_MIPS3 for ISA_MIPS64

2020-12-16 Thread Philippe Mathieu-Daudé
On 12/16/20 8:08 PM, Richard Henderson wrote:
> On 12/16/20 10:27 AM, Philippe Mathieu-Daudé wrote:
>> MIPS 64-bit ISA is introduced with MIPS3.
>> No need for another bit/definition to check for 64-bit.
>>
>> Suggested-by: Jiaxun Yang 
>> Signed-off-by: Philippe Mathieu-Daudé 
>> ---
>>  target/mips/mips-defs.h | 2 +-
>>  hw/mips/boston.c| 2 +-
>>  2 files changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h
>> index f4d76e562d1..ab621a750d5 100644
>> --- a/target/mips/mips-defs.h
>> +++ b/target/mips/mips-defs.h
>> @@ -19,7 +19,7 @@
>>   */
>>  #define ISA_MIPS1 0x0001ULL
>>  #define ISA_MIPS2 0x0002ULL
>> -#define ISA_MIPS3 0x0004ULL
>> +#define ISA_MIPS3 0x0004ULL /* 64-bit */
>>  #define ISA_MIPS4 0x0008ULL
>>  #define ISA_MIPS5 0x0010ULL
>>  #define ISA_MIPS320x0020ULL
>> diff --git a/hw/mips/boston.c b/hw/mips/boston.c
>> index c3b94c68e1b..f44f681fab5 100644
>> --- a/hw/mips/boston.c
>> +++ b/hw/mips/boston.c
>> @@ -463,7 +463,7 @@ static void boston_mach_init(MachineState *machine)
>>  exit(1);
>>  }
>>  
>> -is_64b = cpu_type_supports_isa(machine->cpu_type, ISA_MIPS64);
>> +is_64b = cpu_type_supports_isa(machine->cpu_type, ISA_MIPS3);
> 
> Find this slightly confusing.
> 
> After all of the renaming, I would expect ISA_MIPS64R6 -> ISA_MIPS_R6 |
> ISA_MIPS_64, not ISA_MIPS_R6 | ISA_MIPS3.

Well all the ISA_* definitions now match:
https://images.anandtech.com/doci/8457/MIPS%20ISA%20Evolution.JPG

Except ISA_NANOMIPS32, which is listed in
MD01251-2B-nanoMIPS32PRA-06.09.pdf as an extension, similar to microMIPS:

  MIPS32, microMIPS32, and nanoMIPS32 Operating Modes

  Release 2 of the MIPS32 Architecture added support for 64-bit
  coprocessors (and, in particular, 64-bit floating-point units)
  with 32-bit CPUs. Thus, certain floating-point instructions
  that previously were enabled by 64-bit operations on a MIPS64
  processor now are enabled by new 64-bit floating-point operations.

  Release 3 introduced the microMIPS instruction set, allowing all
  microMIPS processors to implement a 64-bit floating-point unit.

  Release 6 introduces the nanoMIPS instruction set. The nanoMIPS
  instruction set provides access to the same instruction set extensions
  (example, COP1 floating-point instructions) that microMIPS had access
  to.

I'd rather keep one definitions per ISA. Eventually if you want
a definition to check if a CPU is 32/64-bit we can add an alias:

-- >8 --
diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h
index 376262fa250..2c3f4277cfe 100644
--- a/target/mips/mips-defs.h
+++ b/target/mips/mips-defs.h
@@ -65,6 +65,8 @@
 #define CPU_LOONGSON2E  (CPU_MIPS3 | INSN_LOONGSON2E)
 #define CPU_LOONGSON2F  (CPU_MIPS3 | INSN_LOONGSON2F | ASE_LMMI)

+#define CPU_MIPS64  (ISA_MIPS3)
+
 /* MIPS Technologies "Release 1" */
 #define CPU_MIPS32R1(CPU_MIPS2 | ISA_MIPS_R1)
 #define CPU_MIPS64R1(CPU_MIPS5 | CPU_MIPS32R1)
diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index f44f681fab5..9f56099e42f 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -463,7 +463,7 @@ static void boston_mach_init(MachineState *machine)
 exit(1);
 }

-is_64b = cpu_type_supports_isa(machine->cpu_type, ISA_MIPS3);
+is_64b = cpu_type_supports_isa(machine->cpu_type, CPU_MIPS64);

 object_initialize_child(OBJECT(machine), "cps", >cps,
TYPE_MIPS_CPS);
 object_property_set_str(OBJECT(>cps), "cpu-type", machine->cpu_type,
---

But for the Boston case, it is simpler to add an inline function in
cpu.h:

-- >8 --
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1302,6 +1302,11 @@ static inline bool ase_mt_available(CPUMIPSState
*env)
 return env->CP0_Config3 & (1 << CP0C3_MT);
 }

+static inline bool cpu_type_is_64bit(const char *cpu_type)
+{
+return cpu_type_supports_isa(cpu_type, CPU_MIPS64);
+}
+
 void cpu_set_exception_base(int vp_index, target_ulong address);

 /* addr.c */
---

Note, I'd still use ISA_MIPS3 in this cpu_type_is_64bit().

Or I could add the ISA_MIPS_64 alias and call it a day...

> 
> 
> r~
> 



[Bug 1879531] Re: Stack-overflow in _eth_get_rss_ex_dst_addr

2020-12-16 Thread Alexander Bulekov
Minimized Reproducer:
cat << EOF | ./qemu-system-i386 -M pc-q35-5.0 \
-accel qtest -monitor none \
-serial none -nographic -qtest stdio
outl 0xcf8 0x80001010
outl 0xcfc 0xe102
outl 0xcf8 0x80001004
outw 0xcfc 0x7
write 0x25 0x1 0x86
write 0x26 0x1 0xdd
write 0x4f 0x1 0x2b
write 0xe1020030 0x4 0x190002e1
write 0xe102003a 0x2 0x0807
write 0xe1020048 0x4 0x12077cdd
write 0xe1020400 0x4 0xba077cdd
write 0xe1020420 0x4 0x190002e1
write 0xe1020428 0x4 0x3509d807
write 0xe1020438 0x1 0xe2
EOF

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

Title:
  Stack-overflow in _eth_get_rss_ex_dst_addr

Status in QEMU:
  New

Bug description:
  Hello,
  While fuzzing, I found a 1-byte stack-overflow (read) through the
  e1000e. 

  ==10318==ERROR: AddressSanitizer: stack-buffer-overflow on address 
0x7ffdb76c16c2 at pc 0x55594f1a69e1 bp 0x7ffdb76c15a0 sp 0x7ffdb76c1598
  READ of size 1 at 0x7ffdb76c16c2 thread T0
  #0 0x55594f1a69e0 in _eth_get_rss_ex_dst_addr 
/home/alxndr/Development/qemu/net/eth.c:410:17
  #1 0x55594f1a39da in eth_parse_ipv6_hdr 
/home/alxndr/Development/qemu/net/eth.c:532:17
  #2 0x55594ebc34f2 in net_tx_pkt_parse_headers 
/home/alxndr/Development/qemu/hw/net/net_tx_pkt.c:228:14
  #3 0x55594ebc2149 in net_tx_pkt_parse 
/home/alxndr/Development/qemu/hw/net/net_tx_pkt.c:273:9
  #4 0x55594ec1ba76 in e1000e_process_tx_desc 
/home/alxndr/Development/qemu/hw/net/e1000e_core.c:737:29
  #5 0x55594ec1aea4 in e1000e_start_xmit 
/home/alxndr/Development/qemu/hw/net/e1000e_core.c:934:9
  #6 0x55594ec0e70e in e1000e_set_tdt 
/home/alxndr/Development/qemu/hw/net/e1000e_core.c:2451:9
  #7 0x55594ebec435 in e1000e_core_write 
/home/alxndr/Development/qemu/hw/net/e1000e_core.c:3261:9
  #8 0x55594ebdf11b in e1000e_mmio_write 
/home/alxndr/Development/qemu/hw/net/e1000e.c:109:5
  #9 0x55594dfd98b1 in memory_region_write_accessor 
/home/alxndr/Development/qemu/memory.c:483:5
  #10 0x55594dfd9211 in access_with_adjusted_size 
/home/alxndr/Development/qemu/memory.c:544:18
  #11 0x55594dfd7c30 in memory_region_dispatch_write 
/home/alxndr/Development/qemu/memory.c:1476:16
  #12 0x55594dde24b8 in flatview_write_continue 
/home/alxndr/Development/qemu/exec.c:3137:23
  #13 0x55594ddd12dc in flatview_write 
/home/alxndr/Development/qemu/exec.c:3177:14
  #14 0x55594ddd0dec in address_space_write 
/home/alxndr/Development/qemu/exec.c:3268:18
  #15 0x55594dfcdbdc in qtest_process_command 
/home/alxndr/Development/qemu/qtest.c:567:9
  #16 0x55594dfc3700 in qtest_process_inbuf 
/home/alxndr/Development/qemu/qtest.c:710:9
  #17 0x55594dfc2cc8 in qtest_read 
/home/alxndr/Development/qemu/qtest.c:722:5
  #18 0x55594f74b259 in qemu_chr_be_write_impl 
/home/alxndr/Development/qemu/chardev/char.c:183:9
  #19 0x55594f74b3ee in qemu_chr_be_write 
/home/alxndr/Development/qemu/chardev/char.c:195:9
  #20 0x55594f7556fc in fd_chr_read 
/home/alxndr/Development/qemu/chardev/char-fd.c:68:9
  #21 0x55594f7ea488 in qio_channel_fd_source_dispatch 
/home/alxndr/Development/qemu/io/channel-watch.c:84:12
  #22 0x7f43f6c1d897 in g_main_context_dispatch 
(/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x4e897)
  #23 0x55594f9dea5d in glib_pollfds_poll 
/home/alxndr/Development/qemu/util/main-loop.c:219:9
  #24 0x55594f9dd1d7 in os_host_main_loop_wait 
/home/alxndr/Development/qemu/util/main-loop.c:242:5
  #25 0x55594f9dcd6e in main_loop_wait 
/home/alxndr/Development/qemu/util/main-loop.c:518:11
  #26 0x55594e44cd01 in qemu_main_loop 
/home/alxndr/Development/qemu/softmmu/vl.c:1664:9
  #27 0x55594f803c21 in main 
/home/alxndr/Development/qemu/softmmu/main.c:49:5
  #28 0x7f43f57b4e0a in __libc_start_main 
/build/glibc-GwnBeO/glibc-2.30/csu/../csu/libc-start.c:308:16
  #29 0x55594dd03889 in _start 
(/home/alxndr/Development/qemu/build/i386-softmmu/qemu-system-i386+0xdbd889)

  Address 0x7ffdb76c16c2 is located in stack of thread T0 at offset 34 in frame
  #0 0x55594f1a303f in eth_parse_ipv6_hdr 
/home/alxndr/Development/qemu/net/eth.c:486

This frame has 1 object(s):
  [32, 34) 'ext_hdr' (line 487) <== Memory access at offset 34 overflows 
this variable
  HINT: this may be a false positive if your program uses some custom stack 
unwind mechanism, swapcontext or vfork
(longjmp and C++ exceptions *are* supported)
  SUMMARY: AddressSanitizer: stack-buffer-overflow 
/home/alxndr/Development/qemu/net/eth.c:410:17 in _eth_get_rss_ex_dst_addr
  Shadow bytes around the buggy address:
0x100036ed0280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100036ed0290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100036ed02a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100036ed02b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100036ed02c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  

Re: [PULL 00/12] Compile QEMU with -Wimplicit-fallthrough

2020-12-16 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20201216172949.57380-1-th...@redhat.com/



Hi,

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

Type: series
Message-id: 20201216172949.57380-1-th...@redhat.com
Subject: [PULL 00/12] Compile QEMU with -Wimplicit-fallthrough

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] patchew/20201216172949.57380-1-th...@redhat.com -> 
patchew/20201216172949.57380-1-th...@redhat.com
Switched to a new branch 'test'
7bedbc8 configure: Compile with -Wimplicit-fallthrough=2
e14bb9d tests/fp: Do not emit implicit-fallthrough warnings in the softfloat 
tests
ebd3c45 tcg/optimize: Add fallthrough annotations
cfe5662 target/sparc/win_helper: silence the compiler warnings
8ef9335 target/sparc/translate: silence the compiler warnings
4588bf9 accel/tcg/user-exec: silence the compiler warnings
be2108e hw/intc/arm_gicv3_kvm: silence the compiler warnings
7d033d0 target/i386: silence the compiler warnings in gen_shiftd_rm_T1
284b00a hw/timer/renesas_tmr: silence the compiler warnings
c3d2957 hw/rtc/twl92230: Silence warnings about missing fallthrough statements
1b1609c target/unicore32/translate: Add missing fallthrough annotations
99bc0f0 disas/libvixl: Fix fall-through annotation for GCC >= 7

=== OUTPUT BEGIN ===
1/12 Checking commit 99bc0f0e92b7 (disas/libvixl: Fix fall-through annotation 
for GCC >= 7)
ERROR: do not use C99 // comments
#49: FILE: disas/libvixl/vixl/globals.h:111:
+// Fallthrough annotation for Clang and C++11(201103L).

ERROR: do not use C99 // comments
#52: FILE: disas/libvixl/vixl/globals.h:114:
+// Fallthrough annotation for GCC >= 7.

total: 2 errors, 0 warnings, 24 lines checked

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

2/12 Checking commit 1b1609c7573a (target/unicore32/translate: Add missing 
fallthrough annotations)
3/12 Checking commit c3d2957383b8 (hw/rtc/twl92230: Silence warnings about 
missing fallthrough statements)
4/12 Checking commit 284b00aef566 (hw/timer/renesas_tmr: silence the compiler 
warnings)
5/12 Checking commit 7d033d02b90d (target/i386: silence the compiler warnings 
in gen_shiftd_rm_T1)
6/12 Checking commit be2108e641c9 (hw/intc/arm_gicv3_kvm: silence the compiler 
warnings)
7/12 Checking commit 4588bf97482b (accel/tcg/user-exec: silence the compiler 
warnings)
8/12 Checking commit 8ef9335f2838 (target/sparc/translate: silence the compiler 
warnings)
9/12 Checking commit cfe56623ece8 (target/sparc/win_helper: silence the 
compiler warnings)
10/12 Checking commit ebd3c45fd052 (tcg/optimize: Add fallthrough annotations)
WARNING: architecture specific defines should be avoided
#35: FILE: include/qemu/compiler.h:230:
+#if __has_attribute(fallthrough)

total: 0 errors, 1 warnings, 43 lines checked

Patch 10/12 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
11/12 Checking commit e14bb9ddd6f3 (tests/fp: Do not emit implicit-fallthrough 
warnings in the softfloat tests)
12/12 Checking commit 7bedbc83bcfa (configure: Compile with 
-Wimplicit-fallthrough=2)
=== OUTPUT END ===

Test command exited with code: 1


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

[PATCH v1 1/1] chardev: enable guest socket status/crontrol via DTR and DCD

2020-12-16 Thread Darrin M. Gorski
This patch adds a 'modemctl' option to "-chardev socket" to enable control
of the socket via the guest serial port.
The default state of the option is disabled.

1. disconnect a connected socket when DTR transitions to low, also reject
new connections while DTR is low.
2. provide socket connection status through the carrier detect line (CD or
DCD) on the guest serial port

Buglink: https://bugs.launchpad.net/qemu/+bug/1213196

Signed-off-by: Darrin M. Gorski 


diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 213a4c8dd0..94dd28e0cd 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -36,6 +36,7 @@
 #include "qapi/qapi-visit-sockets.h"

 #include "chardev/char-io.h"
+#include "chardev/char-serial.h"
 #include "qom/object.h"

 /***/
@@ -85,6 +86,9 @@ struct SocketChardev {
 bool connect_err_reported;

 QIOTask *connect_task;
+
+bool is_modemctl;
+int modem_state;
 };
 typedef struct SocketChardev SocketChardev;

@@ -98,12 +102,18 @@ static void tcp_chr_change_state(SocketChardev *s,
TCPChardevState state)
 {
 switch (state) {
 case TCP_CHARDEV_STATE_DISCONNECTED:
+if(s->is_modemctl) {
+s->modem_state &= ~(CHR_TIOCM_CAR);
+}
 break;
 case TCP_CHARDEV_STATE_CONNECTING:
 assert(s->state == TCP_CHARDEV_STATE_DISCONNECTED);
 break;
 case TCP_CHARDEV_STATE_CONNECTED:
 assert(s->state == TCP_CHARDEV_STATE_CONNECTING);
+if(s->is_modemctl) {
+s->modem_state |= CHR_TIOCM_CAR;
+}
 break;
 }
 s->state = state;
@@ -947,6 +957,12 @@ static void tcp_chr_accept(QIONetListener *listener,
 tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
 tcp_chr_set_client_ioc_name(chr, cioc);
 tcp_chr_new_client(chr, cioc);
+
+if(s->is_modemctl) {
+if(!(s->modem_state & CHR_TIOCM_DTR)) {
+tcp_chr_disconnect(chr); /* disconnect if DTR is low */
+}
+}
 }


@@ -1322,12 +1338,17 @@ static void qmp_chardev_open_socket(Chardev *chr,
 bool is_tn3270  = sock->has_tn3270  ? sock->tn3270  : false;
 bool is_waitconnect = sock->has_wait? sock->wait: false;
 bool is_websock = sock->has_websocket ? sock->websocket : false;
+bool is_modemctl = sock->has_modemctl ? sock->modemctl : false;
 int64_t reconnect   = sock->has_reconnect ? sock->reconnect : 0;
 SocketAddress *addr;

 s->is_listen = is_listen;
 s->is_telnet = is_telnet;
 s->is_tn3270 = is_tn3270;
+s->is_modemctl = is_modemctl;
+if(is_modemctl) {
+  s->modem_state = CHR_TIOCM_CTS | CHR_TIOCM_DSR;
+}
 s->is_websock = is_websock;
 s->do_nodelay = do_nodelay;
 if (sock->tls_creds) {
@@ -1448,6 +1469,8 @@ static void qemu_chr_parse_socket(QemuOpts *opts,
ChardevBackend *backend,
 sock->tls_creds = g_strdup(qemu_opt_get(opts, "tls-creds"));
 sock->has_tls_authz = qemu_opt_get(opts, "tls-authz");
 sock->tls_authz = g_strdup(qemu_opt_get(opts, "tls-authz"));
+sock->has_modemctl = qemu_opt_get(opts, "modemctl");
+sock->modemctl = qemu_opt_get_bool(opts, "modemctl", false);

 addr = g_new0(SocketAddressLegacy, 1);
 if (path) {
@@ -1501,6 +1524,51 @@ char_socket_get_connected(Object *obj, Error **errp)
 return s->state == TCP_CHARDEV_STATE_CONNECTED;
 }

+/* ioctl support: allow guest to control/track socket state
+ * via modem control lines (DCD/DTR)
+ */
+static int
+char_socket_ioctl(Chardev *chr, int cmd, void *arg)
+{
+SocketChardev *s = SOCKET_CHARDEV(chr);
+
+if(!(s->is_modemctl)) {
+return -ENOTSUP;
+}
+
+switch (cmd) {
+case CHR_IOCTL_SERIAL_GET_TIOCM:
+{
+int *targ = (int *)arg;
+*targ = s->modem_state;
+}
+break;
+case CHR_IOCTL_SERIAL_SET_TIOCM:
+{
+int sarg = *(int *)arg;
+if (sarg & CHR_TIOCM_RTS) {
+s->modem_state |= CHR_TIOCM_RTS;
+} else {
+s->modem_state &= ~(CHR_TIOCM_RTS);
+}
+if (sarg & CHR_TIOCM_DTR) {
+s->modem_state |= CHR_TIOCM_DTR;
+} else {
+s->modem_state &= ~(CHR_TIOCM_DTR);
+/* disconnect if DTR goes low */
+if(s->state == TCP_CHARDEV_STATE_CONNECTED) {
+tcp_chr_disconnect(chr);
+}
+}
+}
+break;
+default:
+return -ENOTSUP;
+}
+
+return 0;
+}
+
 static void char_socket_class_init(ObjectClass *oc, void *data)
 {
 ChardevClass *cc = CHARDEV_CLASS(oc);
@@ -1516,6 +1584,7 @@ static void char_socket_class_init(ObjectClass *oc,
void *data)
 cc->chr_add_client = tcp_chr_add_client;
 cc->chr_add_watch = tcp_chr_add_watch;
 

Re: [PATCH v4 3/3] target/arm: Use object_property_add_bool for "sve" property

2020-12-16 Thread Philippe Mathieu-Daudé
On 12/16/20 11:12 PM, Richard Henderson wrote:
> The interface for object_property_add_bool is simpler,
> making the code easier to understand.
> 
> Reviewed-by: Andrew Jones 
> Signed-off-by: Richard Henderson 
> ---
>  target/arm/cpu64.c | 24 ++--
>  1 file changed, 10 insertions(+), 14 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé 



[Bug 1908450] [NEW] ide/core.c ATA Major Version reporting incorrect

2020-12-16 Thread Gregory Price
Public bug reported:

@@ -165,7 +165,7 @@ static void ide_identify(IDEState *s)
put_le16(p + 76, (1 << 8));
}

put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */
-   put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */
+   put_le16(p + 80, ((1 << 6) | (1 << 5) (1 << 4) (1 << 3)); /* ata3 -> ata6 
supported */
put_le16(p + 81, 0x16); /* conforms to ata5 */
/* 14=NOP supported, 5=WCACHE supported, 0=SMART supported */
put_le16(p + 82, (1 << 14) | (1 << 5) | 1);


This field Major Version Number field is presently reporting support for ATA-4 
through ATA-7.
Bitfield[80] is defined in the ATA-6 specification below.

0xF0 = (1<<7) | (1<<6) | (1 << 5) | (1 << 4) // 4-7 - current settings
0x78 = (1<<6) | (1<<5) | (1 << 4) | (1 << 3) // 3-6 - new settings

Either the comment is wrong, or the field is wrong. If the field is
wrong it can cause errors in drivers that check support vs conformity.
This will not break most guests, since the conformity field is set to
ATA-5.

I'm not sure whether this component supports ATA-7, but since it's
commented as if it supports up through 6, correcting the field
assignment seems more correct.

ATA/ATAPI-6 Specification
https://web.archive.org/web/20200124094822/https://www.t13.org/Documents/UploadedDocuments/project/d1410r3b-ATA-ATAPI-6.pdf

Page 116
80 - M Major version number
h or h = device does not report version
F 15 Reserved
F 14 Reserved for ATA/ATAPI-14
F 13 Reserved for ATA/ATAPI-13
F 12 Reserved for ATA/ATAPI-12
F 11 Reserved for ATA/ATAPI-11
F 10 Reserved for ATA/ATAPI-10
F 9 Reserved for ATA/ATAPI-9
F 8 Reserved for ATA/ATAPI-8
F 7 Reserved for ATA/ATAPI-7
F 6 1 = supports ATA/ATAPI-6
F 5 1 = supports ATA/ATAPI-5
F 4 1 = supports ATA/ATAPI-4
F 3 1 = supports ATA-3
X 2 Obsolete
X 1 Obsolete
F 0 Reserved

** Affects: qemu
 Importance: Undecided
 Status: New


** Tags: ata atapi ide identify x86

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

Title:
  ide/core.c ATA Major Version reporting incorrect

Status in QEMU:
  New

Bug description:
  @@ -165,7 +165,7 @@ static void ide_identify(IDEState *s)
  put_le16(p + 76, (1 << 8));
  }

  put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */
  -   put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */
  +   put_le16(p + 80, ((1 << 6) | (1 << 5) (1 << 4) (1 << 3)); /* ata3 -> ata6 
supported */
  put_le16(p + 81, 0x16); /* conforms to ata5 */
  /* 14=NOP supported, 5=WCACHE supported, 0=SMART supported */
  put_le16(p + 82, (1 << 14) | (1 << 5) | 1);

  
  This field Major Version Number field is presently reporting support for 
ATA-4 through ATA-7.
  Bitfield[80] is defined in the ATA-6 specification below.

  0xF0 = (1<<7) | (1<<6) | (1 << 5) | (1 << 4) // 4-7 - current settings
  0x78 = (1<<6) | (1<<5) | (1 << 4) | (1 << 3) // 3-6 - new settings

  Either the comment is wrong, or the field is wrong. If the field is
  wrong it can cause errors in drivers that check support vs conformity.
  This will not break most guests, since the conformity field is set to
  ATA-5.

  I'm not sure whether this component supports ATA-7, but since it's
  commented as if it supports up through 6, correcting the field
  assignment seems more correct.

  ATA/ATAPI-6 Specification
  
https://web.archive.org/web/20200124094822/https://www.t13.org/Documents/UploadedDocuments/project/d1410r3b-ATA-ATAPI-6.pdf

  Page 116
  80 - M Major version number
  h or h = device does not report version
  F 15 Reserved
  F 14 Reserved for ATA/ATAPI-14
  F 13 Reserved for ATA/ATAPI-13
  F 12 Reserved for ATA/ATAPI-12
  F 11 Reserved for ATA/ATAPI-11
  F 10 Reserved for ATA/ATAPI-10
  F 9 Reserved for ATA/ATAPI-9
  F 8 Reserved for ATA/ATAPI-8
  F 7 Reserved for ATA/ATAPI-7
  F 6 1 = supports ATA/ATAPI-6
  F 5 1 = supports ATA/ATAPI-5
  F 4 1 = supports ATA/ATAPI-4
  F 3 1 = supports ATA-3
  X 2 Obsolete
  X 1 Obsolete
  F 0 Reserved

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



Re: [PATCH v3 0/3] target/arm: Implement an IMPDEF pauth algorithm

2020-12-16 Thread Richard Henderson
On 10/26/20 2:35 PM, Peter Maydell wrote:
> Anyway, I tried to rebase it on current master, but it
> fails 'make check':
> 
> MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))}
> QTEST_QEMU_IMG=./qemu-img
> G_TEST_DBUS_DAEMON=/home/petmay01/linaro/qemu-from-laptop/qemu/tests/dbus-vmstate-daemon.sh
> QTEST_QEMU_BINARY=./qemu-system-aarch64 tests/qtest/arm-cpu-features
> --tap -k
> **
> ERROR:../../tests/qtest/arm-cpu-features.c:439:pauth_tests_default:
> assertion failed: (_error)
> ERROR qtest-aarch64: arm-cpu-features - Bail out!
> ERROR:../../tests/qtest/arm-cpu-features.c:439:pauth_tests_default:
> assertion failed: (_error)
> 
> That's the "can't enable pauth-impdef without pauth" test, I think.

Odd.  I can't reproduce this.  Hopefully it's some difference in your rebase
from mine, so I'll just re-post mine.

r~




[PATCH v4 2/3] target/arm: Add cpu properties to control pauth

2020-12-16 Thread Richard Henderson
The crypto overhead of emulating pauth can be significant for
some workloads.  Add two boolean properties that allows the
feature to be turned off, on with the architected algorithm,
or on with an implementation defined algorithm.

We need two intermediate booleans to control the state while
parsing properties lest we clobber ID_AA64ISAR1 into an invalid
intermediate state.

Tested-by: Mark Rutland 
Reviewed-by: Andrew Jones 
Signed-off-by: Richard Henderson 
---
v2: Use boolean properties instead of an enum (drjones).
v3: Add tests (drjones).
---
 target/arm/cpu.h   | 10 +
 target/arm/cpu.c   | 13 +++
 target/arm/cpu64.c | 40 ++
 target/arm/monitor.c   |  3 ++-
 tests/qtest/arm-cpu-features.c | 13 +++
 5 files changed, 74 insertions(+), 5 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 70e9618d13..06f5169f45 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -197,9 +197,11 @@ typedef struct {
 #ifdef TARGET_AARCH64
 # define ARM_MAX_VQ16
 void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp);
+void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp);
 #else
 # define ARM_MAX_VQ1
 static inline void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) { }
+static inline void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) { }
 #endif
 
 typedef struct ARMVectorReg {
@@ -947,6 +949,14 @@ struct ARMCPU {
 uint64_t reset_cbar;
 uint32_t reset_auxcr;
 bool reset_hivecs;
+
+/*
+ * Intermediate values used during property parsing.
+ * Once finalized, the values should be read from ID_AA64ISAR1.
+ */
+bool prop_pauth;
+bool prop_pauth_impdef;
+
 /* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
 uint32_t dcz_blocksize;
 uint64_t rvbar;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index d6188f6566..5c5fb16114 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1321,6 +1321,19 @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
 error_propagate(errp, local_err);
 return;
 }
+
+/*
+ * KVM does not support modifications to this feature.
+ * We have not registered the cpu properties when KVM
+ * is in use, so the user will not be able to set them.
+ */
+if (!kvm_enabled()) {
+arm_cpu_pauth_finalize(cpu, _err);
+if (local_err != NULL) {
+error_propagate(errp, local_err);
+return;
+}
+}
 }
 
 if (kvm_enabled()) {
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 7cf9fc4bc6..d9feaa9cdb 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -28,6 +28,8 @@
 #include "sysemu/kvm.h"
 #include "kvm_arm.h"
 #include "qapi/visitor.h"
+#include "hw/qdev-properties.h"
+
 
 #ifndef CONFIG_USER_ONLY
 static uint64_t a57_a53_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
@@ -572,6 +574,36 @@ void aarch64_add_sve_properties(Object *obj)
 }
 }
 
+void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
+{
+int arch_val = 0, impdef_val = 0;
+uint64_t t;
+
+/* TODO: Handle HaveEnhancedPAC, HaveEnhancedPAC2, HaveFPAC. */
+if (cpu->prop_pauth) {
+if (cpu->prop_pauth_impdef) {
+impdef_val = 1;
+} else {
+arch_val = 1;
+}
+} else if (cpu->prop_pauth_impdef) {
+error_setg(errp, "cannot enable pauth-impdef without pauth");
+error_append_hint(errp, "Add pauth=on to the CPU property list.\n");
+}
+
+t = cpu->isar.id_aa64isar1;
+t = FIELD_DP64(t, ID_AA64ISAR1, APA, arch_val);
+t = FIELD_DP64(t, ID_AA64ISAR1, GPA, arch_val);
+t = FIELD_DP64(t, ID_AA64ISAR1, API, impdef_val);
+t = FIELD_DP64(t, ID_AA64ISAR1, GPI, impdef_val);
+cpu->isar.id_aa64isar1 = t;
+}
+
+static Property arm_cpu_pauth_property =
+DEFINE_PROP_BOOL("pauth", ARMCPU, prop_pauth, true);
+static Property arm_cpu_pauth_impdef_property =
+DEFINE_PROP_BOOL("pauth-impdef", ARMCPU, prop_pauth_impdef, false);
+
 /* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
  * otherwise, a CPU with as many features enabled as our emulation supports.
  * The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
@@ -627,10 +659,6 @@ static void aarch64_max_initfn(Object *obj)
 t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2);
 t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1);
 t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
-t = FIELD_DP64(t, ID_AA64ISAR1, APA, 1); /* PAuth, architected only */
-t = FIELD_DP64(t, ID_AA64ISAR1, API, 0);
-t = FIELD_DP64(t, ID_AA64ISAR1, GPA, 1);
-t = FIELD_DP64(t, ID_AA64ISAR1, GPI, 0);
 t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
 t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
 t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
@@ -720,6 +748,10 @@ static void 

[PATCH v4 3/3] target/arm: Use object_property_add_bool for "sve" property

2020-12-16 Thread Richard Henderson
The interface for object_property_add_bool is simpler,
making the code easier to understand.

Reviewed-by: Andrew Jones 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu64.c | 24 ++--
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index d9feaa9cdb..8e1fad00bb 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -488,6 +488,12 @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor 
*v, const char *name,
 cpu->sve_max_vq = max_vq;
 }
 
+/*
+ * Note that cpu_arm_get/set_sve_vq cannot use the simpler
+ * object_property_add_bool interface because they make use
+ * of the contents of "name" to determine which bit on which
+ * to operate.
+ */
 static void cpu_arm_get_sve_vq(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
 {
@@ -529,26 +535,17 @@ static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, 
const char *name,
 set_bit(vq - 1, cpu->sve_vq_init);
 }
 
-static void cpu_arm_get_sve(Object *obj, Visitor *v, const char *name,
-void *opaque, Error **errp)
+static bool cpu_arm_get_sve(Object *obj, Error **errp)
 {
 ARMCPU *cpu = ARM_CPU(obj);
-bool value = cpu_isar_feature(aa64_sve, cpu);
-
-visit_type_bool(v, name, , errp);
+return cpu_isar_feature(aa64_sve, cpu);
 }
 
-static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
-void *opaque, Error **errp)
+static void cpu_arm_set_sve(Object *obj, bool value, Error **errp)
 {
 ARMCPU *cpu = ARM_CPU(obj);
-bool value;
 uint64_t t;
 
-if (!visit_type_bool(v, name, , errp)) {
-return;
-}
-
 if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
 error_setg(errp, "'sve' feature not supported by KVM on this host");
 return;
@@ -563,8 +560,7 @@ void aarch64_add_sve_properties(Object *obj)
 {
 uint32_t vq;
 
-object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
-cpu_arm_set_sve, NULL, NULL);
+object_property_add_bool(obj, "sve", cpu_arm_get_sve, cpu_arm_set_sve);
 
 for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
 char name[8];
-- 
2.25.1




[PATCH v4 0/3] target/arm: Implement an IMPDEF pauth algorithm

2020-12-16 Thread Richard Henderson
The architected pauth algorithm is quite slow without
hardware support, and boot times for kernels that enable
use of the feature have been significantly impacted.

Version 1 blurb at
  https://lists.nongnu.org/archive/html/qemu-devel/2020-08/msg02172.html
which contains larger study of the tradeoffs.

Version 2 changes:
  * Use boolean properties, for qmp_query_cpu_model_expansion (drjones).
  * Move XXH64 implementation to xxhash.h (ajb).
  * Include a small cleanup to parsing the "sve" property
that I noticed along the way.

Version 3 changes:
  * Swap order of patches (drjones).
  * Add properties test case (drjones).

Version 4 changes:
  * Rebase.


r~


Richard Henderson (3):
  target/arm: Implement an IMPDEF pauth algorithm
  target/arm: Add cpu properties to control pauth
  target/arm: Use object_property_add_bool for "sve" property

 include/qemu/xxhash.h  | 82 ++
 target/arm/cpu.h   | 25 +--
 target/arm/cpu.c   | 13 ++
 target/arm/cpu64.c | 64 ++
 target/arm/monitor.c   |  3 +-
 target/arm/pauth_helper.c  | 41 ++---
 tests/qtest/arm-cpu-features.c | 13 ++
 7 files changed, 213 insertions(+), 28 deletions(-)

-- 
2.25.1




[PATCH v4 1/3] target/arm: Implement an IMPDEF pauth algorithm

2020-12-16 Thread Richard Henderson
Without hardware acceleration, a cryptographically strong
algorithm is too expensive for pauth_computepac.

Even with hardware accel, we are not currently expecting
to link the linux-user binaries to any crypto libraries,
and doing so would generally make the --static build fail.

So choose XXH64 as a reasonably quick and decent hash.

Tested-by: Mark Rutland 
Signed-off-by: Richard Henderson 
---
v2: Move the XXH64 bits to xxhash.h (ajb).
Create isar_feature_aa64_pauth_arch and fixup a comment
in isar_feature_aa64_pauth that no longer applies.
---
 include/qemu/xxhash.h | 82 +++
 target/arm/cpu.h  | 15 +--
 target/arm/pauth_helper.c | 41 +---
 3 files changed, 129 insertions(+), 9 deletions(-)

diff --git a/include/qemu/xxhash.h b/include/qemu/xxhash.h
index 076f1f6054..cf45859a19 100644
--- a/include/qemu/xxhash.h
+++ b/include/qemu/xxhash.h
@@ -119,4 +119,86 @@ static inline uint32_t qemu_xxhash6(uint64_t ab, uint64_t 
cd, uint32_t e,
 return qemu_xxhash7(ab, cd, e, f, 0);
 }
 
+/*
+ * Component parts of the XXH64 algorithm from
+ * https://github.com/Cyan4973/xxHash/blob/v0.8.0/xxhash.h
+ *
+ * The complete algorithm looks like
+ *
+ *  i = 0;
+ *  if (len >= 32) {
+ *  v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
+ *  v2 = seed + XXH_PRIME64_2;
+ *  v3 = seed + 0;
+ *  v4 = seed - XXH_PRIME64_1;
+ *  do {
+ *  v1 = XXH64_round(v1, get64bits(input + i));
+ *  v2 = XXH64_round(v2, get64bits(input + i + 8));
+ *  v3 = XXH64_round(v3, get64bits(input + i + 16));
+ *  v4 = XXH64_round(v4, get64bits(input + i + 24));
+ *  } while ((i += 32) <= len);
+ *  h64 = XXH64_mergerounds(v1, v2, v3, v4);
+ *  } else {
+ *  h64 = seed + XXH_PRIME64_5;
+ *  }
+ *  h64 += len;
+ *
+ *  for (; i + 8 <= len; i += 8) {
+ *  h64 ^= XXH64_round(0, get64bits(input + i));
+ *  h64 = rol64(h64, 27) * XXH_PRIME64_1 + XXH_PRIME64_4;
+ *  }
+ *  for (; i + 4 <= len; i += 4) {
+ *  h64 ^= get32bits(input + i) * PRIME64_1;
+ *  h64 = rol64(h64, 23) * XXH_PRIME64_2 + XXH_PRIME64_3;
+ *  }
+ *  for (; i < len; i += 1) {
+ *  h64 ^= get8bits(input + i) * XXH_PRIME64_5;
+ *  h64 = rol64(h64, 11) * XXH_PRIME64_1;
+ *  }
+ *
+ *  return XXH64_avalanche(h64)
+ *
+ * Exposing the pieces instead allows for simplified usage when
+ * the length is a known constant and the inputs are in registers.
+ */
+#define XXH_PRIME64_1   0x9E3779B185EBCA87ULL
+#define XXH_PRIME64_2   0xC2B2AE3D27D4EB4FULL
+#define XXH_PRIME64_3   0x165667B19E3779F9ULL
+#define XXH_PRIME64_4   0x85EBCA77C2B2AE63ULL
+#define XXH_PRIME64_5   0x27D4EB2F165667C5ULL
+
+static inline uint64_t XXH64_round(uint64_t acc, uint64_t input)
+{
+return rol64(acc + input * XXH_PRIME64_2, 31) * XXH_PRIME64_1;
+}
+
+static inline uint64_t XXH64_mergeround(uint64_t acc, uint64_t val)
+{
+return (acc ^ XXH64_round(0, val)) * XXH_PRIME64_1 + XXH_PRIME64_4;
+}
+
+static inline uint64_t XXH64_mergerounds(uint64_t v1, uint64_t v2,
+ uint64_t v3, uint64_t v4)
+{
+uint64_t h64;
+
+h64 = rol64(v1, 1) + rol64(v2, 7) + rol64(v3, 12) + rol64(v4, 18);
+h64 = XXH64_mergeround(h64, v1);
+h64 = XXH64_mergeround(h64, v2);
+h64 = XXH64_mergeround(h64, v3);
+h64 = XXH64_mergeround(h64, v4);
+
+return h64;
+}
+
+static inline uint64_t XXH64_avalanche(uint64_t h64)
+{
+h64 ^= h64 >> 33;
+h64 *= XXH_PRIME64_2;
+h64 ^= h64 >> 29;
+h64 *= XXH_PRIME64_3;
+h64 ^= h64 >> 32;
+return h64;
+}
+
 #endif /* QEMU_XXHASH_H */
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 7e6c881a7e..70e9618d13 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3852,10 +3852,8 @@ static inline bool isar_feature_aa64_fcma(const 
ARMISARegisters *id)
 static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id)
 {
 /*
- * Note that while QEMU will only implement the architected algorithm
- * QARMA, and thus APA+GPA, the host cpu for kvm may use implementation
- * defined algorithms, and thus API+GPI, and this predicate controls
- * migration of the 128-bit keys.
+ * Return true if any form of pauth is enabled, as this
+ * predicate controls migration of the 128-bit keys.
  */
 return (id->id_aa64isar1 &
 (FIELD_DP64(0, ID_AA64ISAR1, APA, 0xf) |
@@ -3864,6 +3862,15 @@ static inline bool isar_feature_aa64_pauth(const 
ARMISARegisters *id)
  FIELD_DP64(0, ID_AA64ISAR1, GPI, 0xf))) != 0;
 }
 
+static inline bool isar_feature_aa64_pauth_arch(const ARMISARegisters *id)
+{
+/*
+ * Return true if pauth is enabled with the architected QARMA algorithm.
+ * QEMU will always set APA+GPA to the same value.
+ */
+return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, APA) != 0;
+}
+
 static inline bool isar_feature_aa64_sb(const ARMISARegisters *id)
 {
 return FIELD_EX64(id->id_aa64isar1, 

Re: [PATCH v3 4/4] target/arm: Implement Cortex-M55 model

2020-12-16 Thread Richard Henderson
On 12/10/20 2:14 PM, Peter Maydell wrote:
> Now that we have implemented all the features needed by the v8.1M
> architecture, we can add the model of the Cortex-M55.  This is the
> configuration without MVE support; we'll add MVE later.
> 
> Signed-off-by: Peter Maydell 
> ---
>  target/arm/cpu_tcg.c | 42 ++
>  1 file changed, 42 insertions(+)

Reviewed-by: Richard Henderson 

r~



Re: [PATCH v3 3/4] target/arm: Implement FPCXT_NS fp system register

2020-12-16 Thread Richard Henderson
On 12/10/20 2:14 PM, Peter Maydell wrote:
> Implement the v8.1M FPCXT_NS floating-point system register.  This is
> a little more complicated than FPCXT_S, because it has specific
> handling for "current FP state is inactive", and it only wants to do
> PreserveFPState(), not the full set of actions done by
> ExecuteFPCheck() which vfp_access_check() implements.
> 
> Signed-off-by: Peter Maydell 
> ---
> Changes since v2: refactored along lines suggested by RTH
> ---
>  target/arm/translate-vfp.c.inc | 102 -
>  1 file changed, 99 insertions(+), 3 deletions(-)

Reviewed-by: Richard Henderson 

r~



Re: [PATCH v3 2/4] target/arm: Correct store of FPSCR value via FPCXT_S

2020-12-16 Thread Richard Henderson
On 12/10/20 2:14 PM, Peter Maydell wrote:
> In commit 64f863baeedc8659 we implemented the v8.1M FPCXT_S register,
> but we got the write behaviour wrong. On read, this register reads
> bits [27:0] of FPSCR plus the CONTROL.SFPA bit. On write, it doesn't
> just write back those bits -- it writes a value to the whole FPSCR,
> whose upper 4 bits are zeroes.
> 
> We also incorrectly implemented the write-to-FPSCR as a simple store
> to vfp.xregs; this skips the "update the softfloat flags" part of
> the vfp_set_fpscr helper so the value would read back correctly but
> not actually take effect.
> 
> Fix both of these things by doing a complete write to the FPSCR
> using the helper function.
> 
> Signed-off-by: Peter Maydell 
> ---
>  target/arm/translate-vfp.c.inc | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)

Reviewed-by: Richard Henderson 

r~



[Bug 1906193] Re: riscv32 user mode emulation: fork return values broken

2020-12-16 Thread Andreas K . Hüttel
Here's qemu's own strace log:

farino ~ # /usr/bin/qemu-riscv32 -strace /chroot/riscv-ilp32/tmp/wait-test-short
10123 brk(NULL) = 0x00073000
10123 brk(0x00073880) = 0x00073880
10123 uname(0x407ffed8) = 0
10123 readlinkat(AT_FDCWD,"/proc/self/exe",0x407feff0,4096) = 39
10123 brk(0x00094880) = 0x00094880
10123 brk(0x00095000) = 0x00095000
10123 mprotect(0x0006e000,8192,PROT_READ) = 0
10123 
clone(CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|0x11,child_stack=0x,parent_tidptr=0x,tls=0x,child_tidptr=0x00073068)
 = 10125
10123 
clone(CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|0x11,child_stack=0x,parent_tidptr=0x,tls=0x,child_tidptr=0x00073068)
 = 0
10125 exit_group(42)
10123 waitid(0,-1,0x407fff8c,0x4) = 0
10123 statx(1,"",AT_EMPTY_PATH,STATX_BASIC_STATS,0x407ff8e8) = 0
child wants to return 42 (0x2A), parent received 40 (0x28), difference -2
10123 write(1,0x73ad0,74) = 74
10123 exit_group(0)

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

Title:
  riscv32 user mode emulation: fork return values broken

Status in QEMU:
  New

Bug description:
  When running in a chroot with riscv32 (on x86_64; qemu git master as
  of today):

  The following short program forks; the child immediately returns with
  exit(42). The parent checks for the return value - and obtains 40!

  gcc-10.2

  ===
  #include 
  #include 
  #include 
  #include 

  main(c, v)
   int c;
   char **v;
  {
pid_t pid, p;
int s, i, n;

s = 0;
pid = fork();
if (pid == 0)
  exit(42);

/* wait for the process */
p = wait();
if (p != pid)
  exit (255);

if (WIFEXITED(s))
{
   int r=WEXITSTATUS(s);
   if (r!=42) {
printf("child wants to return %i (0x%X), parent received %i (0x%X), 
difference %i\n",42,42,r,r,r-42);
   }
}
  }
  ===

  (riscv-ilp32 chroot) farino /tmp # ./wait-test-short 
  child wants to return 42 (0x2A), parent received 40 (0x28), difference -2

  ===
  (riscv-ilp32 chroot) farino /tmp # gcc --version
  gcc (Gentoo 10.2.0-r1 p2) 10.2.0
  Copyright (C) 2020 Free Software Foundation, Inc.
  Dies ist freie Software; die Kopierbedingungen stehen in den Quellen. Es
  gibt KEINE Garantie; auch nicht für MARKTGÄNGIGKEIT oder FÜR SPEZIELLE ZWECKE.

  (riscv-ilp32 chroot) farino /tmp # ld --version
  GNU ld (Gentoo 2.34 p6) 2.34.0
  Copyright (C) 2020 Free Software Foundation, Inc.
  This program is free software; you may redistribute it under the terms of
  the GNU General Public License version 3 or (at your option) a later version.
  This program has absolutely no warranty.

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



Bug: qemu-system-ppc -M mac99 boots into compat-monitor, not openbios.

2020-12-16 Thread Howard Spoelstra
Hi all,

It seems a qemu-system-ppc from current master no longer boots into
openbios, but into to the compat monitor.
Command line to reproduce:
/home/hsp/src/qemu-master/build/qemu-system-ppc \
-L pc-bios \
-M mac99,via=pmu -m 1024 -boot c \
-drive file=/home/hsp/Mac-disks/9.2.img,format=raw,media=disk

Bisecting leads to this commit:

commit b4e1a342112e50e05b609e857f38c1f2b7aafdc4
Author: Paolo Bonzini 
Date:   Tue Oct 27 08:44:23 2020 -0400

vl: remove separate preconfig main_loop

Move post-preconfig initialization to the x-exit-preconfig.  If
preconfig
is not requested, just exit preconfig mode immediately with the QMP
command.

As a result, the preconfig loop will run with accel_setup_post
and os_setup_post restrictions (xen_restrict, chroot, etc.)
already done.

Reviewed-by: Igor Mammedov 
Signed-off-by: Paolo Bonzini 

 include/sysemu/runstate.h |  1 -
 monitor/qmp-cmds.c|  9 -
 softmmu/vl.c  | 95
---
 3 files changed, 41 insertions(+), 64 deletions(-)

Thanks for looking into this,

Best,
Howard


Re: [PATCH v3 1/4] hw/intc/armv7m_nvic: Correct handling of CCR.BFHFNMIGN

2020-12-16 Thread Richard Henderson
On 12/10/20 2:14 PM, Peter Maydell wrote:
> The CCR is a register most of whose bits are banked between security
> states but where BFHFNMIGN is not, and we keep it in the non-secure
> entry of the v7m.ccr[] array.  The logic which tries to handle this
> bit fails to implement the "RAZ/WI from Nonsecure if AIRCR.BFHFNMINS
> is zero" requirement; correct the omission.
> 
> Signed-off-by: Peter Maydell 
> ---
> Changes since v2: get the "WI" bit right
> ---
>  hw/intc/armv7m_nvic.c | 15 +++
>  1 file changed, 15 insertions(+)

Reviewed-by: Richard Henderson 

r~



[Bug 1906193] Re: riscv32 user mode emulation: fork return values broken

2020-12-16 Thread Andreas K . Hüttel
Here's the (abbreviated) output of strace'ing qemu:

farino ~ # strace -f /usr/bin/qemu-riscv32 
/chroot/riscv-ilp32/tmp/wait-test-short
execve("/usr/bin/qemu-riscv32", ["/usr/bin/qemu-riscv32", 
"/chroot/riscv-ilp32/tmp/wait-tes"...], 0x7ffd95fb1330 /* 40 vars */) = 0

[...]

[pid 16569] uname({sysname="Linux", nodename="farino", ...}) = 0
[pid 16569] lstat("/chroot", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
[pid 16569] lstat("/chroot/riscv-ilp32", {st_mode=S_IFDIR|S_ISGID|0755, 
st_size=4096, ...}) = 0
[pid 16569] lstat("/chroot/riscv-ilp32/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, 
st_size=4096, ...}) = 0
[pid 16569] lstat("/chroot/riscv-ilp32/tmp/wait-test-short", 
{st_mode=S_IFREG|0755, st_size=445632, ...}) = 0
[pid 16569] mmap(0x413f1000, 135168, PROT_READ|PROT_WRITE, 
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x413f1000
[pid 16569] mprotect(0x413eb000, 8192, PROT_READ) = 0
[pid 16569] rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], NULL, 8) = 0
[pid 16569] clone(child_stack=NULL, 
flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x1339710) 
= 16571
strace: Process 16571 attached
[pid 16571] set_robust_list(0x1339720, 24 
[pid 16569] rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], NULL, 8) = 0
[pid 16571] <... set_robust_list resumed>) = 0
[pid 16569] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
[pid 16571] rt_sigprocmask(SIG_SETMASK, ~[ILL FPE SEGV RTMIN RT_1], ~[KILL STOP 
RTMIN RT_1], 8) = 0
[pid 16571] rt_sigprocmask(SIG_BLOCK, ~[], ~[ILL FPE KILL SEGV STOP RTMIN 
RT_1], 8) = 0
[pid 16571] clone(child_stack=0x7fe5b73871f0, 
flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID,
 parent_tid=[16572], tls=0x7fe5b7387640, child_tidptr=0x7fe5b7387910) = 16572
[pid 16571] rt_sigprocmask(SIG_SETMASK, ~[ILL FPE KILL SEGV STOP RTMIN RT_1], 
NULL, 8) = 0
[pid 16571] rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0
[pid 16571] gettid()= 16571
[pid 16571] rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], NULL, 8) = 0
[pid 16571] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
[pid 16569] waitid(P_ALL, -1,  
[pid 16571] exit_group(42)  = ?
strace: Process 16572 attached
[pid 16572] +++ exited with 42 +++
[pid 16571] +++ exited with 42 +++
[pid 16569] <... waitid resumed>{si_signo=SIGCHLD, si_code=CLD_EXITED, 
si_pid=16571, si_uid=0, si_status=42, si_utime=3472328296226648184, 
si_stime=3475143045726351408}, WEXITED, NULL) = 0
[pid 16569] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=16571, 
si_uid=0, si_status=42, si_utime=0, si_stime=0} ---
[pid 16569] statx(1, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, 
STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID, stx_attributes=0, 
stx_mode=S_IFCHR|0600, stx_size=0, ...}) = 0
[pid 16569] write(1, "child wants to return 42 (0x2A),"..., 74child wants to 
return 42 (0x2A), parent received 40 (0x28), difference -2
) = 74
[pid 16569] brk(0x13c1000)  = 0x13c1000
[pid 16569] brk(0x13c)  = 0x13c
[pid 16569] exit_group(0)   = ?
[pid 16570] <... futex resumed>)= ?
[pid 16570] +++ exited with 0 +++
+++ exited with 0 +++

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

Title:
  riscv32 user mode emulation: fork return values broken

Status in QEMU:
  New

Bug description:
  When running in a chroot with riscv32 (on x86_64; qemu git master as
  of today):

  The following short program forks; the child immediately returns with
  exit(42). The parent checks for the return value - and obtains 40!

  gcc-10.2

  ===
  #include 
  #include 
  #include 
  #include 

  main(c, v)
   int c;
   char **v;
  {
pid_t pid, p;
int s, i, n;

s = 0;
pid = fork();
if (pid == 0)
  exit(42);

/* wait for the process */
p = wait();
if (p != pid)
  exit (255);

if (WIFEXITED(s))
{
   int r=WEXITSTATUS(s);
   if (r!=42) {
printf("child wants to return %i (0x%X), parent received %i (0x%X), 
difference %i\n",42,42,r,r,r-42);
   }
}
  }
  ===

  (riscv-ilp32 chroot) farino /tmp # ./wait-test-short 
  child wants to return 42 (0x2A), parent received 40 (0x28), difference -2

  ===
  (riscv-ilp32 chroot) farino /tmp # gcc --version
  gcc (Gentoo 10.2.0-r1 p2) 10.2.0
  Copyright (C) 2020 Free Software Foundation, Inc.
  Dies ist freie Software; die Kopierbedingungen stehen in den Quellen. Es
  gibt KEINE Garantie; auch nicht für MARKTGÄNGIGKEIT oder FÜR SPEZIELLE ZWECKE.

  (riscv-ilp32 chroot) farino /tmp # ld --version
  GNU ld (Gentoo 2.34 p6) 2.34.0
  Copyright (C) 2020 Free Software Foundation, Inc.
  This program is free software; you may redistribute it under the terms of
  the GNU 

Re: [PATCH v6 0/4] migration: UFFD write-tracking migration/snapshots

2020-12-16 Thread Peter Xu
On Tue, Dec 15, 2020 at 10:53:13PM +0300, Andrey Gruzdev wrote:
> First are series of runs without scan-rate-limiting.patch.
> Windows 10:
> 
>  msecs   : count distribution
>  0 -> 1  : 131913   ||
>  2 -> 3  : 106  ||
>  4 -> 7  : 362  ||
>  8 -> 15 : 619  ||
> 16 -> 31 : 28   ||
> 32 -> 63 : 1||
> 64 -> 127: 2||
> 
> 
>  msecs   : count distribution
>  0 -> 1  : 199273   ||
>  2 -> 3  : 190  ||
>  4 -> 7  : 425  ||
>  8 -> 15 : 927  ||
> 16 -> 31 : 69   ||
> 32 -> 63 : 3||
> 64 -> 127: 16   ||
>128 -> 255: 2||
> 
> Ubuntu 20.04:
> 
>  msecs   : count distribution
>  0 -> 1  : 104954   ||
>  2 -> 3  : 9||
> 
>  msecs   : count distribution
>  0 -> 1  : 147159   ||
>  2 -> 3  : 13   ||
>  4 -> 7  : 0||
>  8 -> 15 : 0||
> 16 -> 31 : 0||
> 32 -> 63 : 0||
> 64 -> 127: 1||
> 
> 
> Here are runs with scan-rate-limiting.patch.
> Windows 10:
> 
>  msecs   : count distribution
>  0 -> 1  : 234492   ||
>  2 -> 3  : 66   ||
>  4 -> 7  : 219  ||
>  8 -> 15 : 109  ||
> 16 -> 31 : 0||
> 32 -> 63 : 0||
> 64 -> 127: 1||
> 
>  msecs   : count distribution
>  0 -> 1  : 183171   ||
>  2 -> 3  : 109  ||
>  4 -> 7  : 281  ||
>  8 -> 15 : 444  ||
> 16 -> 31 : 3||
> 32 -> 63 : 1||
> 
> Ubuntu 20.04:
> 
>  msecs   : count distribution
>  0 -> 1  : 92224||
>  2 -> 3  : 9||
>  4 -> 7  : 0||
>  8 -> 15 : 0||
> 16 -> 31 : 1||
> 32 -> 63 : 0||
> 64 -> 127: 1||
> 
>  msecs   : count distribution
>  0 -> 1  : 97021||
>  2 -> 3  : 7||
>  4 -> 7  : 0||
>  8 -> 15 : 0||
> 16 -> 31 : 0||
> 32 -> 63 : 0||
> 64 -> 127: 0||
>128 -> 255: 1||
> 
> So, initial variant of rate-limiting makes some positive effect, but not very
> noticible. 

Re: [PATCH 5/5] i386: provide simple 'hyperv=on' option to x86 machine types

2020-12-16 Thread Eduardo Habkost
On Thu, Nov 19, 2020 at 11:32:21AM +0100, Vitaly Kuznetsov wrote:
> Enabling Hyper-V emulation for a Windows VM is a tiring experience as it
> requires listing all currently supported enlightenments ("hv_*" CPU
> features) explicitly. We do have a 'hv_passthrough' mode enabling
> everything but it can't be used in production as it prevents migration.
> 
> Introduce a simple 'hyperv=on' option for all x86 machine types enabling
> all currently supported Hyper-V enlightenments. Later, when new
> enlightenments get implemented, we will be adding them to newer machine
> types only (by disabling them for legacy machine types) thus preserving
> migration.
> 
> Signed-off-by: Vitaly Kuznetsov 
> Reviewed-by: Eduardo Habkost 
[...]
> ---
>  docs/hyperv.txt   |  8 
>  hw/i386/x86.c | 30 ++
>  include/hw/i386/x86.h |  7 +++
>  target/i386/cpu.c | 14 ++
>  4 files changed, 59 insertions(+)
> 
> diff --git a/docs/hyperv.txt b/docs/hyperv.txt
> index 5df00da54fc4..1a76a07f8417 100644
> --- a/docs/hyperv.txt
> +++ b/docs/hyperv.txt
> @@ -29,6 +29,14 @@ When any set of the Hyper-V enlightenments is enabled, 
> QEMU changes hypervisor
>  identification (CPUID 0x4000..0x400A) to Hyper-V. KVM identification
>  and features are kept in leaves 0x4100..0x4101.
>  
> +Hyper-V enlightenments can be enabled in bulk by specifying 'hyperv=on' to an
> +x86 machine type:
> +
> +  qemu-system-x86_64 -machine q35,accel=kvm,kernel-irqchip=split,hyperv=on 
> ...
> +
> +Note, new enlightenments are only added to the latest (in-develompent) 
> machine
> +type, older machine types keep the list of the supported features intact to
> +safeguard migration.
>  
>  3. Existing enlightenments
>  ===
> diff --git a/hw/i386/x86.c b/hw/i386/x86.c
> index 5944fc44edca..57f27d56ecc6 100644
> --- a/hw/i386/x86.c
> +++ b/hw/i386/x86.c
> @@ -1171,6 +1171,20 @@ static void x86_machine_set_acpi(Object *obj, Visitor 
> *v, const char *name,
>  visit_type_OnOffAuto(v, name, >acpi, errp);
>  }
>  
> +static bool x86_machine_get_hyperv(Object *obj, Error **errp)
> +{
> +X86MachineState *x86ms = X86_MACHINE(obj);
> +
> +return x86ms->hyperv_enabled;
> +}
> +
> +static void x86_machine_set_hyperv(Object *obj, bool value, Error **errp)
> +{
> +X86MachineState *x86ms = X86_MACHINE(obj);
> +
> +x86ms->hyperv_enabled = value;
> +}
> +
>  static void x86_machine_initfn(Object *obj)
>  {
>  X86MachineState *x86ms = X86_MACHINE(obj);
> @@ -1194,6 +1208,16 @@ static void x86_machine_class_init(ObjectClass *oc, 
> void *data)
>  x86mc->save_tsc_khz = true;
>  nc->nmi_monitor_handler = x86_nmi;
>  
> +/* Hyper-V features enabled with 'hyperv=on' */
> +x86mc->default_hyperv_features = BIT(HYPERV_FEAT_RELAXED) |
> +BIT(HYPERV_FEAT_VAPIC) | BIT(HYPERV_FEAT_TIME) |
> +BIT(HYPERV_FEAT_CRASH) | BIT(HYPERV_FEAT_RESET) |
> +BIT(HYPERV_FEAT_VPINDEX) | BIT(HYPERV_FEAT_RUNTIME) |
> +BIT(HYPERV_FEAT_SYNIC) | BIT(HYPERV_FEAT_STIMER) |
> +BIT(HYPERV_FEAT_FREQUENCIES) | BIT(HYPERV_FEAT_REENLIGHTENMENT) |
> +BIT(HYPERV_FEAT_TLBFLUSH) | BIT(HYPERV_FEAT_EVMCS) |
> +BIT(HYPERV_FEAT_IPI) | BIT(HYPERV_FEAT_STIMER_DIRECT);
> +
>  object_class_property_add(oc, X86_MACHINE_SMM, "OnOffAuto",
>  x86_machine_get_smm, x86_machine_set_smm,
>  NULL, NULL);
> @@ -1205,6 +1229,12 @@ static void x86_machine_class_init(ObjectClass *oc, 
> void *data)
>  NULL, NULL);
>  object_class_property_set_description(oc, X86_MACHINE_ACPI,
>  "Enable ACPI");
> +
> +object_class_property_add_bool(oc, X86_MACHINE_HYPERV,
> +x86_machine_get_hyperv, x86_machine_set_hyperv);
> +
> +object_class_property_set_description(oc, X86_MACHINE_HYPERV,
> +"Enable Hyper-V enlightenments");
>  }
>  
>  static const TypeInfo x86_machine_info = {
> diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
> index 739fac50871b..598abd1be806 100644
> --- a/include/hw/i386/x86.h
> +++ b/include/hw/i386/x86.h
> @@ -38,6 +38,9 @@ struct X86MachineClass {
>  bool save_tsc_khz;
>  /* Enables contiguous-apic-ID mode */
>  bool compat_apic_id_mode;
> +
> +/* Hyper-V features enabled with 'hyperv=on' */
> +uint64_t default_hyperv_features;
>  };
>  
>  struct X86MachineState {
> @@ -71,10 +74,14 @@ struct X86MachineState {
>   * will be translated to MSI messages in the address space.
>   */
>  AddressSpace *ioapic_as;
> +
> +/* Hyper-V emulation */
> +bool hyperv_enabled;
>  };
>  
>  #define X86_MACHINE_SMM  "smm"
>  #define X86_MACHINE_ACPI "acpi"
> +#define X86_MACHINE_HYPERV   "hyperv"
>  
>  #define TYPE_X86_MACHINE   MACHINE_TYPE_NAME("x86")
>  OBJECT_DECLARE_TYPE(X86MachineState, X86MachineClass, X86_MACHINE)
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 83aca942d87c..63a931679d73 100644

[PATCH] fuzz: fix the generic-fuzz-floppy config

2020-12-16 Thread Alexander Bulekov
On the pc-i440fx machine, the floppy drive relies on the i8257 DMA
controller. Add this device to the floppy fuzzer config, and silence the
warning about a missing format specifier for the null-co:// drive.

Signed-off-by: Alexander Bulekov 
---
 tests/qtest/fuzz/generic_fuzz_configs.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/qtest/fuzz/generic_fuzz_configs.h 
b/tests/qtest/fuzz/generic_fuzz_configs.h
index b4c5fefeca..0848c11308 100644
--- a/tests/qtest/fuzz/generic_fuzz_configs.h
+++ b/tests/qtest/fuzz/generic_fuzz_configs.h
@@ -92,9 +92,9 @@ const generic_fuzz_config predefined_configs[] = {
 },{
 .name = "floppy",
 .args = "-machine pc -nodefaults -device floppy,id=floppy0 "
-"-drive id=disk0,file=null-co://,file.read-zeroes=on,if=none "
+"-drive 
id=disk0,file=null-co://,file.read-zeroes=on,if=none,format=raw "
 "-device floppy,drive=disk0,drive-type=288",
-.objects = "fd* floppy*",
+.objects = "fd* floppy* i8257",
 },{
 .name = "xhci",
 .args = "-machine q35 -nodefaults "
-- 
2.29.2




Re: [PATCH 1/2] accel: kvm: Fix memory waste under mismatch page size

2020-12-16 Thread Peter Xu
On Wed, Dec 16, 2020 at 04:21:17PM +0800, Keqian Zhu wrote:
> One more thing, we should consider whether @start and @size is psize aligned 
> (my second
> patch). Do you agree to add assert on them directly?

Yes I think the 2nd patch is okay, but please address Drew's comments.

Returning -EINVAL is the same as abort() currently - it'll just abort() at
kvm_log_clear() instead.

Thanks,

-- 
Peter Xu




Re: [PATCH v12 00/23] i386 cleanup PART 1

2020-12-16 Thread Eduardo Habkost
On Sat, 12 Dec 2020 16:55:07 +0100, Claudio Fontana wrote:
> The series has been split into two separate parts,
> and this is PART 1.
> 
> v11 -> v12:
> 
> * "cpu: Move synchronize_from_tb() to tcg_ops":
>   removed review tags, as there is currently a bunch of conflicting
>   requirements (Eduardo, Richard, Philippe).
> 
> [...]

Queued the following:

[01/23] i386: move kvm accel files into kvm/
[02/23] i386: move whpx accel files into whpx/
[03/23] i386: move hax accel files into hax/
[04/23] i386: hvf: remove stale MAINTAINERS entry for old hvf stubs
[05/23] i386: move TCG accel files into tcg/
[06/23] i386: move cpu dump out of helper.c into cpu-dump.c
[07/23] i386: move TCG cpu class initialization to tcg/
[08/23] i386: tcg: remove inline from cpu_load_eflags
[09/23] tcg: cpu_exec_{enter,exit} helpers
[10/23] tcg: make CPUClass.cpu_exec_* optional
[11/23] tcg: Make CPUClass.debug_excp_handler optional
[12/23] cpu: Remove unnecessary noop methods

Thanks!

-- 
Eduardo




Re: [PATCH v12 16/23] cpu: Move synchronize_from_tb() to tcg_ops

2020-12-16 Thread Eduardo Habkost
On Mon, Dec 14, 2020 at 05:24:00PM -0500, Eduardo Habkost wrote:
> On Mon, Dec 14, 2020 at 10:56:13PM +0100, Philippe Mathieu-Daudé wrote:
> > Hi Claudio, Eduardo.
> > 
> > On 12/14/20 8:10 PM, Eduardo Habkost wrote:
> > > On Sat, Dec 12, 2020 at 04:55:23PM +0100, Claudio Fontana wrote:
> > >> From: Eduardo Habkost 
> > >>
> > >> since tcg_cpu_ops.h is only included in cpu.h,
> > >> and as a standalone header it is not really useful,
> > >> as tcg_cpu_ops.h starts requiring cpu.h defines,
> > >> enums, etc, as well as (later on in the series),
> > >> additional definitions coming from memattr.h.
> > >>
> > >> Therefore rename it to tcg_cpu_ops.h.inc, to warn
> > >> any potential user that this file is not a standalone
> > >> header, but rather a partition of cpu.h that is
> > >> included conditionally if CONFIG_TCG is true.
> > > 
> > > What's the benefit of moving definitions to a separate file, if
> > > the new file is not a standalone header?
> > 
> > Claudio, I haven't been following every respin. If you did that
> > change just to please me then the circular dependency remarked by
> > Richard, then if it simplify the series I'm OK if you have to
> > remove the includes.
> > 
> > Eduardo, if you are happy with patches 1-8 (x86 specific), maybe
> > you can queue them already. The rest is more TCG generic and
> > will likely go via Richard/Paolo trees IMO.
> 
> Patches 01-06 are queued.  Patches 07 and 08 need review.

Patches 07-12 are now queued too.

-- 
Eduardo




Re: [PATCH] x86/cpu: Add AVX512_FP16 cpu feature

2020-12-16 Thread Eduardo Habkost
On Thu, Dec 17, 2020 at 06:40:02AM +0800, Cathy Zhang wrote:
> AVX512 Half-precision floating point (FP16) has better performance
> compared to FP32 if the presicion or magnitude requirements are met.
> It's defined as CPUID.(EAX=7,ECX=0):EDX[bit 23].
> 
> Refer to
> https://software.intel.com/content/www/us/en/develop/download/\
> intel-architecture-instruction-set-extensions-programming-reference.html
> 
> Signed-off-by: Cathy Zhang 

Queued, thanks!

-- 
Eduardo




Re: [PATCH v1 6/6] gdbstub: ensure we clean-up when terminated

2020-12-16 Thread Richard Henderson
On 12/14/20 9:30 AM, Alex Bennée wrote:
> If you kill the inferior from GDB we end up leaving our socket lying
> around. Fix this by calling gdb_exit() first.
> 
> Signed-off-by: Alex Bennée 
> ---
>  gdbstub.c | 2 ++
>  1 file changed, 2 insertions(+)

Reviewed-by: Richard Henderson 

r~



Re: [PATCH v1 5/6] gdbstub: drop gdbserver_cleanup in favour of gdb_exit

2020-12-16 Thread Richard Henderson
On 12/14/20 9:30 AM, Alex Bennée wrote:
> Despite it's name it didn't actually clean-up so let us document
> gdb_exit() better and use that.
> 
> Signed-off-by: Alex Bennée 
> ---
>  include/exec/gdbstub.h | 14 +++---
>  gdbstub.c  |  7 ---
>  softmmu/vl.c   |  2 +-
>  3 files changed, 12 insertions(+), 11 deletions(-)

Reviewed-by: Richard Henderson 

r~



Re: [PATCH v3 4/5] hw/misc: Add a PWM module for NPCM7XX

2020-12-16 Thread Hao Wu via
Thanks for the review. We can add a patch in this patchset to fix this
issue.

On Wed, Dec 16, 2020 at 11:02 AM Peter Maydell 
wrote:

> On Tue, 15 Dec 2020 at 00:13, Hao Wu  wrote:
> >
> > The PWM module is part of NPCM7XX module. Each NPCM7XX module has two
> > identical PWM modules. Each module contains 4 PWM entries. Each PWM has
> > two outputs: frequency and duty_cycle. Both are computed using inputs
> > from software side.
> >
> > This module does not model detail pulse signals since it is expensive.
> > It also does not model interrupts and watchdogs that are dependant on
> > the detail models. The interfaces for these are left in the module so
> > that anyone in need for these functionalities can implement on their
> > own.
> >
> > The user can read the duty cycle and frequency using qom-get command.
> >
> > Reviewed-by: Havard Skinnemoen 
> > Reviewed-by: Tyrone Ting 
> > Signed-off-by: Hao Wu 
>
>
> > +static void npcm7xx_pwm_init(Object *obj)
> > +{
> > +NPCM7xxPWMState *s = NPCM7XX_PWM(obj);
> > +SysBusDevice *sbd = >parent;
>
> This isn't right. A device shouldn't be poking around
> in the 'parent' or 'parentobj' member of its struct --
> that is a QOM internal. If you want "this device, cast
> to a SysBusDevice", the way to write that is:
>SysBusDevice *sbd = SYS_BUS_DEVICE(s);
>
> (or you could pass 'obj'; same thing).
>
> Looking at the code currently in the tree it also is making this
> same mistake:
>
> $ git grep -- '->parent' hw/*/npcm*
> hw/arm/npcm7xx_boards.c:MachineClass *mc = >parent;
> hw/mem/npcm7xx_mc.c:sysbus_init_mmio(>parent, >mmio);
> hw/misc/npcm7xx_clk.c:sysbus_init_mmio(>parent, >iomem);
> hw/misc/npcm7xx_gcr.c:sysbus_init_mmio(>parent, >iomem);
> hw/misc/npcm7xx_rng.c:sysbus_init_mmio(>parent, >iomem);
> hw/nvram/npcm7xx_otp.c:SysBusDevice *sbd = >parent;
> hw/ssi/npcm7xx_fiu.c:SysBusDevice *sbd = >parent;
> hw/timer/npcm7xx_timer.c:SysBusDevice *sbd = >parent;
>
> These all should be using QOM cast macros. Would somebody
> who's working on these devices like to send a patch ?
>
> thanks
> -- PMM
>


Re: [PATCH v1 4/6] gdbstub: drop CPUEnv from gdb_exit()

2020-12-16 Thread Richard Henderson
On 12/14/20 9:30 AM, Alex Bennée wrote:
> gdb_exit() has never needed anything from env and I doubt we are going
> to start now.
> 
> Signed-off-by: Alex Bennée 
> ---
>  include/exec/gdbstub.h| 2 +-
>  bsd-user/syscall.c| 6 +++---
>  gdbstub.c | 2 +-
>  linux-user/exit.c | 2 +-
>  target/arm/arm-semi.c | 2 +-
>  target/m68k/m68k-semi.c   | 2 +-
>  target/nios2/nios2-semi.c | 2 +-
>  7 files changed, 9 insertions(+), 9 deletions(-)

Reviewed-by: Richard Henderson 

r~



  1   2   3   4   5   >