Re: [Qemu-devel] [PATCH] RISCV: support riscv vector extension 0.7.1

2019-12-27 Thread Richard Henderson
On 12/25/19 8:36 PM, LIU Zhiwei wrote:
> struct {
> 
>     uint64_t vreg[32 * RV_VLEN_MAX / 64] QEMU_ALIGNED(16);
>     target_ulong vxrm;
>     target_ulong vxsat;
>     target_ulong vl;
>     target_ulong vstart;
>     target_ulong vtype;
>     } vext;
> 
> Is it OK?
I don't think there's a good reason for the vext structure -- I would drop
that.  Otherwise it looks good.

> However, there are still some differences from SVE.
> 
> 1)cpu_env must be used as a parameter for helper function.
> 
>     The helpers need  use env->vext.vl and env->vext.vstart.  Thus it will be
> difficult to use out of line tcg_gen_gvec_ool.

Sure.  That's also true of any of the fp operations, which will want to
accumulate ieee exceptions.

See tcg_gen_gvec_*_ptr(), which allows you to pass in cpu_env.

> 2)simd_desc is not proper.
> 
>     I also need to transfer some members of DisasContext to helpers. 
> 
>     (Data, Vlmax, Mlen) is my current choice. Vlmax is the num of elements of
> this operation, so it will defined as ctx->lmul * ctx->vlen / ctx->sew;

The oprsz & maxsz parameters to tcg_gen_gvec_* should be given (ctx->lmul *
ctx->vlen).  The sew parameter should be implied by the helper function called,
each helper function using a different type.  Therefore vlmax can be trivially
computed within the helper from oprsz / sizeof(type).

> Data is reserved to expand.  Mlen is mask length for one elment, so it will
> defined as ctx->sew/ctx->lmul. As with Mlen, a active element will
> 
> be selected by
> 
> static inline int vext_elem_mask(void *v0, int mlen, int index)
> {
>     int idx = (index * mlen) / 8;
>     int pos = (index * mlen) % 8;
> 
>     return (v0[idx] >> pos) & 0x1;
> }
> 
>     So I may have to implement vext_desc instead of use the simd_desc, which
> will be another redundant. Maybe a better way to mask elements?

I think you will want to define your own vext_desc, building upon simd_desc,
such that lg2(mlen) is passed in the first N bits of simd_data.


r~



[PATCH V3] target/i386: Fix handling of k_gs_base register in 32-bit mode in gdbstub

2019-12-27 Thread Marek Dolata - mkdol...@us.ibm.com
Fixes: corrects clobbering of registers appearing after k_gs_base
Buglink: https://bugs.launchpad.net/qemu/+bug/1857640

Signed-off-by: Marek Dolata mailto:mkdol...@us.ibm.com>>
---
target/i386/gdbstub.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c
index aef25b70f1..572ead641c 100644
--- a/target/i386/gdbstub.c
+++ b/target/i386/gdbstub.c
@@ -350,15 +350,15 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 env->segs[R_GS].base = ldl_p(mem_buf);
 return 4;

-#ifdef TARGET_X86_64
 case IDX_SEG_REGS + 8:
+#ifdef TARGET_X86_64
 if (env->hflags & HF_CS64_MASK) {
 env->kernelgsbase = ldq_p(mem_buf);
 return 8;
 }
 env->kernelgsbase = ldl_p(mem_buf);
-return 4;
#endif
+return 4;

 case IDX_FP_REGS + 8:
 cpu_set_fpuc(env, ldl_p(mem_buf));
--
2.24.1



Re: [PATCH v2] target/i386: Fix handling of k_gs_base register in 32-bit mode in gdbstub

2019-12-27 Thread Philippe Mathieu-Daudé

Hi Marek,

Thanks for Cc'ing the maintainers :)

Still the same error occurs:

  Applying: target/i386: Fix handling of k_gs_base register in 32-bit 
mode in gdbstub

  error: corrupt patch at line 21
  Patch failed at 0001 target/i386: Fix handling of k_gs_base register 
in 32-bit mode in gdbstub


Please use a version number when you repost a patch, this is patch v2 
(next should be v3).


On 12/27/19 9:07 PM, Marek Dolata - mkdol...@us.ibm.com wrote:

Fixes: corrects clobbering of registers appearing after k_gs_base

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

Signed-off-by: Marek Dolata >


---

target/i386/gdbstub.c | 4 ++--

1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c

index aef25b70f1..572ead641c 100644

--- a/target/i386/gdbstub.c

+++ b/target/i386/gdbstub.c

@@ -350,15 +350,15 @@ int x86_cpu_gdb_write_register(CPUState *cs, 
uint8_t *mem_buf, int n)


  env->segs[R_GS].base = ldl_p(mem_buf);

  return 4;

-#ifdef TARGET_X86_64

  case IDX_SEG_REGS + 8:

+#ifdef TARGET_X86_64

  if (env->hflags & HF_CS64_MASK) {

  env->kernelgsbase = ldq_p(mem_buf);

  return 8;

  }

  env->kernelgsbase = ldl_p(mem_buf);

-    return 4;

#endif

+    return 4;

  case IDX_FP_REGS + 8:

  cpu_set_fpuc(env, ldl_p(mem_buf));

--

2.24.1






[PATCH v2] hw/i386: Allow building machines without IOMMU

2019-12-27 Thread Philippe Mathieu-Daudé
Commit 6c730e4af9 introduced a stub to build the MicroVM machine
without Intel IOMMU suppport. However when configure with
--without-default-devices, the build fails:

LINKx86_64-softmmu/qemu-system-x86_64
  /usr/bin/ld: hw/i386/pc.o: in function `pc_machine_done':
  hw/i386/pc.c:869: undefined reference to `x86_iommu_ir_supported'
  /usr/bin/ld: hw/i386/acpi-build.o: in function `acpi_build':
  hw/i386/acpi-build.c:2844: undefined reference to `x86_iommu_get_type'
  /usr/bin/ld: hw/i386/acpi-build.o: in function `build_dmar_q35':
  hw/i386/acpi-build.c:2478: undefined reference to `x86_iommu_ir_supported'
  /usr/bin/ld: hw/i386/acpi-build.o: in function `build_amd_iommu':
  hw/i386/acpi-build.c:2665: undefined reference to `x86_iommu_ir_supported'
  /usr/bin/ld: hw/i386/acpi-build.c:2700: undefined reference to 
`x86_iommu_ir_supported'
  collect2: error: ld returned 1 exit status
  make[1]: *** [Makefile:206: qemu-system-x86_64] Error 1

Since currently all PC machines can not be built without IOMMU,
select X86_IOMMU in the PC config, and remove the stubs.

Fixes: 6c730e4af9
Reported-by: Travis-CI
Signed-off-by: Philippe Mathieu-Daudé 
---
v2: simplify, remove the stub.
---
 hw/i386/x86-iommu-stub.c | 34 --
 hw/i386/Kconfig  |  2 +-
 hw/i386/Makefile.objs|  1 -
 3 files changed, 1 insertion(+), 36 deletions(-)
 delete mode 100644 hw/i386/x86-iommu-stub.c

diff --git a/hw/i386/x86-iommu-stub.c b/hw/i386/x86-iommu-stub.c
deleted file mode 100644
index 03576cdccb..00
--- a/hw/i386/x86-iommu-stub.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Stubs for X86 IOMMU emulation
- *
- * Copyright (C) 2019 Red Hat, Inc.
- *
- * Author: Paolo Bonzini 
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see .
- */
-
-#include "qemu/osdep.h"
-#include "hw/i386/x86-iommu.h"
-
-void x86_iommu_iec_register_notifier(X86IOMMUState *iommu,
- iec_notify_fn fn, void *data)
-{
-}
-
-X86IOMMUState *x86_iommu_get_default(void)
-{
-return NULL;
-}
-
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index 91cf5843b4..e428322a2c 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -35,6 +35,7 @@ config PC
 select ACPI_PCI
 select ACPI_VMGENID
 select VIRTIO_PMEM_SUPPORTED
+select X86_IOMMU
 
 config PC_PCI
 bool
@@ -105,7 +106,6 @@ config MICROVM
 
 config X86_IOMMU
 bool
-depends on PC
 
 config VTD
 bool
diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index 8ce1b26533..6ebb6d0cf0 100644
--- a/hw/i386/Makefile.objs
+++ b/hw/i386/Makefile.objs
@@ -7,7 +7,6 @@ obj-$(CONFIG_Q35) += pc_q35.o
 obj-$(CONFIG_MICROVM) += microvm.o
 obj-y += fw_cfg.o
 obj-$(CONFIG_X86_IOMMU) += x86-iommu.o
-obj-$(call lnot,$(CONFIG_X86_IOMMU)) += x86-iommu-stub.o
 obj-$(CONFIG_VTD) += intel_iommu.o
 obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o
 obj-$(CONFIG_XEN) += ../xenpv/ xen/
-- 
2.21.0




Re: [PATCH] hw/i386/x86-iommu: Add missing stubs

2019-12-27 Thread Philippe Mathieu-Daudé

On 12/22/19 11:31 AM, Paolo Bonzini wrote:

On 20/12/19 16:42, Philippe Mathieu-Daudé wrote:

In commit 6c730e4af9 we introduced a stub to build the MicroVM
machine without Intel IOMMU. This stub is incomplete for the
other PC machines. Add the missing stubs.


In other words, without this patch you cannot build without Q35 (which
brings in the IOMMU, at least unless building
--without-default-devices).  Is this correct?


No, this is the same, selecting either CONFIG_I440FX or CONFIG_Q35:

  LINKx86_64-softmmu/qemu-system-x86_64
/usr/bin/ld: hw/i386/pc.o: in function `pc_machine_done':
hw/i386/pc.c:869: undefined reference to `x86_iommu_ir_supported'
/usr/bin/ld: hw/i386/acpi-build.o: in function `acpi_build':
hw/i386/acpi-build.c:2844: undefined reference to `x86_iommu_get_type'
/usr/bin/ld: hw/i386/acpi-build.o: in function `build_dmar_q35':
hw/i386/acpi-build.c:2478: undefined reference to `x86_iommu_ir_supported'
/usr/bin/ld: hw/i386/acpi-build.o: in function `build_amd_iommu':
hw/i386/acpi-build.c:2665: undefined reference to `x86_iommu_ir_supported'
/usr/bin/ld: hw/i386/acpi-build.c:2700: undefined reference to 
`x86_iommu_ir_supported'

collect2: error: ld returned 1 exit status
make[1]: *** [Makefile:206: qemu-system-x86_64] Error 1
make: *** [Makefile:483: x86_64-softmmu/all] Error 2


Paolo



Fixes: 6c730e4af9
Reported-by: Travis-CI
Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/i386/x86-iommu-stub.c | 9 +
  1 file changed, 9 insertions(+)

diff --git a/hw/i386/x86-iommu-stub.c b/hw/i386/x86-iommu-stub.c
index 03576cdccb..c5ba077f9d 100644
--- a/hw/i386/x86-iommu-stub.c
+++ b/hw/i386/x86-iommu-stub.c
@@ -32,3 +32,12 @@ X86IOMMUState *x86_iommu_get_default(void)
  return NULL;
  }
  
+bool x86_iommu_ir_supported(X86IOMMUState *s)

+{
+return false;
+}
+
+IommuType x86_iommu_get_type(void)
+{
+abort();
+}








Re: [PATCH v5 5/6] hppa: Add emulation of Artist graphics

2019-12-27 Thread Helge Deller
On 24.12.19 01:18, Philippe Mathieu-Daudé wrote:
> On 12/23/19 6:50 PM, Sven Schnelle wrote:
>> Hi Philippe,
>>
>> On Sun, Dec 22, 2019 at 01:37:48PM +0100, Philippe Mathieu-Daudé wrote:
   +    if (vga_interface_type != VGA_NONE) {
 +    dev = qdev_create(NULL, "artist");
 +    qdev_init_nofail(dev);
 +    s = SYS_BUS_DEVICE(dev);
 +    sysbus_mmio_map(s, 0, LASI_GFX_HPA);
 +    sysbus_mmio_map(s, 1, ARTIST_FB_ADDR);
>>>
>>> How is this chipset connected on the board?
>>> If it is a card you can plug on a bus, you can use a condition.
>>> If it is soldered or part of another chipset, then it has to be mapped
>>> unconditionally.
>>
>> Depends on the Model. Hp 9000 712 and 715 had it onboard, for the B160L
>> we're emulating and others it was a GSC add-on card.
>
> The B160L case is unclear, do you mean this is not the chipset on the 
> machine, but the software is happy if another chipset is available?
>
> Looking at hw/hppa/ I only see one machine:
>
>   static void machine_hppa_machine_init(MachineClass *mc)
>   {
>   mc->desc = "HPPA generic machine";
>   ...
>   }
>   DEFINE_MACHINE("hppa", machine_hppa_machine_init)
>
> Are you saying this generic machine is able to run different physical hw? Why 
> not add them? This shouldn't take long and it would be clearer, what do you 
> think?
>
> Adding different machines here in QEMU mostly mean add a class which declare 
> the different properties used by each machine. Igor Mammedov recently 
> suggested to follow the example of aspeed_machine_types[] in hw/arm/aspeed.c.

Yes, we plan to add specific machines like 712 (or 715), and maybe a
C3000 or B2000 over time, as needed device emulations (e.g. tulip, artist)
gets accepted.
But for that it would be very beneficial if changes (like the Artist emulation
here in this thread) would be accepted faster upstream

Helge



Re: [PATCH] hw/i386/x86-iommu: Add missing stubs

2019-12-27 Thread Wainer dos Santos Moschetta



On 12/20/19 1:42 PM, Philippe Mathieu-Daudé wrote:

In commit 6c730e4af9 we introduced a stub to build the MicroVM
machine without Intel IOMMU. This stub is incomplete for the
other PC machines. Add the missing stubs.

Fixes: 6c730e4af9
Reported-by: Travis-CI
Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/i386/x86-iommu-stub.c | 9 +
  1 file changed, 9 insertions(+)

diff --git a/hw/i386/x86-iommu-stub.c b/hw/i386/x86-iommu-stub.c
index 03576cdccb..c5ba077f9d 100644
--- a/hw/i386/x86-iommu-stub.c
+++ b/hw/i386/x86-iommu-stub.c
@@ -32,3 +32,12 @@ X86IOMMUState *x86_iommu_get_default(void)
  return NULL;
  }
  
+bool x86_iommu_ir_supported(X86IOMMUState *s)

+{
+return false;
+}
+
+IommuType x86_iommu_get_type(void)
+{
+abort();
+}


I cannot say the fix is correct, but I can attest - with it - I no 
longer see the build fail when --without-default-devices --disable-user.


Tested-by: Wainer dos Santos Moschetta 





[PATCH] target/i386: Fix handling of k_gs_base register in 32-bit mode in gdbstub

2019-12-27 Thread Marek Dolata - mkdol...@us.ibm.com
Fixes: corrects clobbering of registers appearing after k_gs_base
Buglink: https://bugs.launchpad.net/qemu/+bug/1857640

Signed-off-by: Marek Dolata mailto:mkdol...@us.ibm.com>>
---
target/i386/gdbstub.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c
index aef25b70f1..572ead641c 100644
--- a/target/i386/gdbstub.c
+++ b/target/i386/gdbstub.c
@@ -350,15 +350,15 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 env->segs[R_GS].base = ldl_p(mem_buf);
 return 4;
-#ifdef TARGET_X86_64
 case IDX_SEG_REGS + 8:
+#ifdef TARGET_X86_64
 if (env->hflags & HF_CS64_MASK) {
 env->kernelgsbase = ldq_p(mem_buf);
 return 8;
 }
 env->kernelgsbase = ldl_p(mem_buf);
-return 4;
#endif
+return 4;
 case IDX_FP_REGS + 8:
 cpu_set_fpuc(env, ldl_p(mem_buf));
--
2.24.1



Re: [PATCH] /target/i386: fix gdbstub k_gs_base issue

2019-12-27 Thread Philippe Mathieu-Daudé

Hi Marek,

If you look at the other patches, you'll notice no leading slash is 
used, so please remove it when resending.


Maybe you can use "target/i386: Fix handling of k_gs_base register in 
32-bit mode in gdbstub" as patch subject.


Please Cc the maintainers. See:
https://wiki.qemu.org/Contribute/SubmitAPatch#CC_the_relevant_maintainer
Doing it for you now (adding Richard and Eduardo).

On 12/27/19 3:41 AM, Marek Dolata - mkdol...@us.ibm.com wrote:

Fixes: corrects clobbering of registers appearing after k_gs_base

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

Signed-off-by: Marek Dolata 

---

target/i386/gdbstub.c | 4 +++-

1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c

index aef25b70f1..7228d20674 100644

--- a/target/i386/gdbstub.c

+++ b/target/i386/gdbstub.c


I am having troubles trying to apply your patch:

Applying: /target/i386: fix gdbstub k_gs_base issue
error: corrupt patch at line 23
Patch failed at 0001 /target/i386: fix gdbstub k_gs_base issue
hint: Use 'git am --show-current-patch' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

The information on the wiki might help you to use proper format:
https://wiki.qemu.org/Contribute/SubmitAPatch#Use_git_format-patch



@@ -350,14 +350,16 @@ int x86_cpu_gdb_write_register(CPUState *cs, 
uint8_t *mem_buf, int n)


  env->segs[R_GS].base = ldl_p(mem_buf);

  return 4;

-#ifdef TARGET_X86_64

  case IDX_SEG_REGS + 8:

+#ifdef TARGET_X86_64

  if (env->hflags & HF_CS64_MASK) {

  env->kernelgsbase = ldq_p(mem_buf);

  return 8;

  }

  env->kernelgsbase = ldl_p(mem_buf);


You can add here the

#endif



  return 4;


and remove the '#else return 4; #endif' lines.



+#else

+    return 4;

#endif

  case IDX_FP_REGS + 8:

--

2.21.0



Regards,

Phil.




Re: [PATCH 3/5] python/qemu: qmp: Make accept()'s timeout configurable

2019-12-27 Thread Philippe Mathieu-Daudé

On 12/27/19 2:40 PM, Wainer dos Santos Moschetta wrote:

Currently the timeout of QEMUMonitorProtocol.accept() is
hard-coded to 15 seconds. This added the parameter `timeout`
so the value can be configured by the user.

Signed-off-by: Wainer dos Santos Moschetta 
---
  python/qemu/qmp.py | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/python/qemu/qmp.py b/python/qemu/qmp.py
index f4e04a6683..914b8c6774 100644
--- a/python/qemu/qmp.py
+++ b/python/qemu/qmp.py
@@ -154,16 +154,17 @@ class QEMUMonitorProtocol:
  return self.__negotiate_capabilities()
  return None
  
-def accept(self):

+def accept(self, timeout=15):
  """
  Await connection from QMP Monitor and perform capabilities 
negotiation.
  
+@param timeout (float): timeout in seconds. Default is 15.


Maybe name with unit: 'timeout_s'.

Reviewed-by: Philippe Mathieu-Daudé 


  @return QMP greeting dict
  @raise OSError on socket connection errors
  @raise QMPConnectError if the greeting is not received
  @raise QMPCapabilitiesError if fails to negotiate capabilities
  """
-self.__sock.settimeout(15)
+self.__sock.settimeout(timeout)
  self.__sock, _ = self.__sock.accept()
  self.__sockfile = self.__sock.makefile()
  return self.__negotiate_capabilities()






[PATCH] /target/i386: fix gdbstub k_gs_base issue

2019-12-27 Thread Marek Dolata - mkdol...@us.ibm.com
Fixes: corrects clobbering of registers appearing after k_gs_base
Buglink: https://bugs.launchpad.net/qemu/+bug/1857640

Signed-off-by: Marek Dolata 
---
target/i386/gdbstub.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c
index aef25b70f1..7228d20674 100644
--- a/target/i386/gdbstub.c
+++ b/target/i386/gdbstub.c
@@ -350,14 +350,16 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 env->segs[R_GS].base = ldl_p(mem_buf);
 return 4;
-#ifdef TARGET_X86_64
 case IDX_SEG_REGS + 8:
+#ifdef TARGET_X86_64
 if (env->hflags & HF_CS64_MASK) {
 env->kernelgsbase = ldq_p(mem_buf);
 return 8;
 }
 env->kernelgsbase = ldl_p(mem_buf);
 return 4;
+#else
+return 4;
#endif
 case IDX_FP_REGS + 8:
--
2.21.0




[PATCH] i.MX: add an emulation for RNGC

2019-12-27 Thread Martin Kaiser
Add an emulation for the RNGC random number generator and the compatible
RNGB variant. These peripherals are included (at least) in imx25 and
imx35 chipsets.

The emulation supports the initial self test, reseeding the prng and
reading random numbers.

Signed-off-by: Martin Kaiser 
---
 hw/arm/fsl-imx25.c |  11 ++
 hw/misc/Makefile.objs  |   1 +
 hw/misc/imx_rngc.c | 262 +
 include/hw/arm/fsl-imx25.h |   5 +
 include/hw/misc/imx_rngc.h |  36 +++
 5 files changed, 315 insertions(+)
 create mode 100644 hw/misc/imx_rngc.c
 create mode 100644 include/hw/misc/imx_rngc.h

diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index 3cb5a8fdfd..da3471b395 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -62,6 +62,9 @@ static void fsl_imx25_init(Object *obj)
 
 sysbus_init_child_obj(obj, "fec", &s->fec, sizeof(s->fec), TYPE_IMX_FEC);
 
+sysbus_init_child_obj(obj, "rngc", &s->rngc, sizeof(s->rngc),
+  TYPE_IMX_RNGC);
+
 for (i = 0; i < FSL_IMX25_NUM_I2CS; i++) {
 sysbus_init_child_obj(obj, "i2c[*]", &s->i2c[i], sizeof(s->i2c[i]),
   TYPE_IMX_I2C);
@@ -188,6 +191,14 @@ static void fsl_imx25_realize(DeviceState *dev, Error 
**errp)
 sysbus_connect_irq(SYS_BUS_DEVICE(&s->fec), 0,
qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX25_FEC_IRQ));
 
+object_property_set_bool(OBJECT(&s->rngc), true, "realized", &err);
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->rngc), 0, FSL_IMX25_RNGC_ADDR);
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->rngc), 0,
+   qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX25_RNGC_IRQ));
 
 /* Initialize all I2C */
 for (i = 0; i < FSL_IMX25_NUM_I2CS; i++) {
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index ba898a5781..2b28f8c096 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -42,6 +42,7 @@ common-obj-$(CONFIG_IMX) += imx7_ccm.o
 common-obj-$(CONFIG_IMX) += imx2_wdt.o
 common-obj-$(CONFIG_IMX) += imx7_snvs.o
 common-obj-$(CONFIG_IMX) += imx7_gpr.o
+common-obj-$(CONFIG_IMX) += imx_rngc.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 common-obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx_rngc.c b/hw/misc/imx_rngc.c
new file mode 100644
index 00..f935ec46a6
--- /dev/null
+++ b/hw/misc/imx_rngc.c
@@ -0,0 +1,262 @@
+/*
+ * Freescale i.MX RNGC emulation
+ *
+ * Copyright (C) 2019 Martin Kaiser 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * This driver provides the minimum functionality to initialize and seed
+ * an rngc and to read random numbers. The rngb that is found in imx25
+ * chipsets is also supported.
+ */
+
+
+#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
+#include "qemu/module.h"
+#include "qemu/log.h"
+#include "qemu/guest-random.h"
+#include "hw/irq.h"
+#include "hw/misc/imx_rngc.h"
+
+#define RNGC_VER_ID  0x00
+#define RNGC_COMMAND 0x04
+#define RNGC_CONTROL 0x08
+#define RNGC_STATUS  0x0C
+#define RNGC_FIFO0x14
+
+/* These version info are reported by the rngb in an imx258 chip. */
+#define RNG_TYPE_RNGB 0x1
+#define V_MAJ 0x2
+#define V_MIN 0x40
+
+#define RNGC_CMD_BIT_SW_RST0x40
+#define RNGC_CMD_BIT_CLR_ERR   0x20
+#define RNGC_CMD_BIT_CLR_INT   0x10
+#define RNGC_CMD_BIT_SEED  0x02
+#define RNGC_CMD_BIT_SELF_TEST 0x01
+
+#define RNGC_CTRL_BIT_MASK_ERR  0x40
+#define RNGC_CTRL_BIT_MASK_DONE 0x20
+#define RNGC_CTRL_BIT_AUTO_SEED 0x10
+
+/* the current status for self-test and seed operations */
+#define OP_IDLE 0
+#define OP_RUN  1
+#define OP_DONE 2
+
+static uint64_t imx_rngc_read(void *opaque, hwaddr offset, unsigned size)
+{
+IMXRNGCState *s = IMX_RNGC(opaque);
+uint64_t val = 0;
+
+switch (offset) {
+case RNGC_VER_ID:
+val |= RNG_TYPE_RNGB << 28 | V_MAJ << 8 | V_MIN;
+break;
+
+case RNGC_COMMAND:
+if (s->op_seed == OP_RUN) {
+val |= RNGC_CMD_BIT_SEED;
+}
+if (s->op_self_test == OP_RUN) {
+val |= RNGC_CMD_BIT_SELF_TEST;
+}
+break;
+
+case RNGC_CONTROL:
+/*
+ * The CTL_ACC and VERIF_MODE bits are not supported yet.
+ * They read as 0.
+ */
+val |= s->mask;
+if (s->auto_seed) {
+val |= RNGC_CTRL_BIT_AUTO_SEED;
+}
+/*
+ * We don't have an internal fifo like the real hardware.
+ * There's no need for strategy to handle fifo underflows.
+ * We return the FIFO_UFLOW_RESPONSE bits as 0.
+ */
+break;
+
+case RNGC_STATUS:
+/*
+ * We never report any statistics test or self-test errors or any
+ * other errors. STAT_TEST_PF, ST_PF and ERROR are always 0.
+   

[PATCH 5/5] python/qemu: qmp: Remove unnused attributes

2019-12-27 Thread Wainer dos Santos Moschetta
The `error` and `timeout` attributes in QEMUMonitorProtocol are
not used, so this delete them.

Signed-off-by: Wainer dos Santos Moschetta 
---
 python/qemu/qmp.py | 4 
 1 file changed, 4 deletions(-)

diff --git a/python/qemu/qmp.py b/python/qemu/qmp.py
index 6d55f53595..cddb94bb3c 100644
--- a/python/qemu/qmp.py
+++ b/python/qemu/qmp.py
@@ -45,10 +45,6 @@ class QEMUMonitorProtocol:
 
 #: Logger object for debugging messages
 logger = logging.getLogger('QMP')
-#: Socket's error class
-error = socket.error
-#: Socket's timeout
-timeout = socket.timeout
 
 def __init__(self, address, server=False):
 """
-- 
2.23.0




[PATCH 4/5] python/qemu: qmp: Make QEMUMonitorProtocol a context manager

2019-12-27 Thread Wainer dos Santos Moschetta
This implement the __enter__ and __exit__ functions on
QEMUMonitorProtocol class so that it can be used on 'with'
statement and the resources will be free up on block end:

with QEMUMonitorProtocol(socket_path) as qmp:
qmp.connect()
qmp.command('query-status')

Signed-off-by: Wainer dos Santos Moschetta 
---
 python/qemu/qmp.py | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/python/qemu/qmp.py b/python/qemu/qmp.py
index 914b8c6774..6d55f53595 100644
--- a/python/qemu/qmp.py
+++ b/python/qemu/qmp.py
@@ -139,6 +139,15 @@ class QEMUMonitorProtocol:
 raise QMPConnectError("Error while reading from socket")
 self.__sock.settimeout(None)
 
+def __enter__(self):
+# Implement context manager enter function.
+return self
+
+def __exit__(self, exc_type, exc_value, exc_traceback):
+# Implement context manager exit function.
+self.close()
+return False
+
 def connect(self, negotiate=True):
 """
 Connect to the QMP Monitor and perform capabilities negotiation.
@@ -259,8 +268,10 @@ class QEMUMonitorProtocol:
 """
 Close the socket and socket file.
 """
-self.__sock.close()
-self.__sockfile.close()
+if self.__sock:
+self.__sock.close()
+if self.__sockfile:
+self.__sockfile.close()
 
 def settimeout(self, timeout):
 """
-- 
2.23.0




[PATCH 2/5] python/qemu: Delint the qmp module

2019-12-27 Thread Wainer dos Santos Moschetta
This clean up the pylint-3 report on qmp:

* Module qemu.qmp
python/qemu/qmp.py:1:0: C0111: Missing module docstring (missing-docstring)
python/qemu/qmp.py:17:0: C0111: Missing class docstring (missing-docstring)
python/qemu/qmp.py:21:0: C0111: Missing class docstring (missing-docstring)
python/qemu/qmp.py:25:0: C0111: Missing class docstring (missing-docstring)
python/qemu/qmp.py:29:0: C0111: Missing class docstring (missing-docstring)
python/qemu/qmp.py:33:0: C0111: Missing class docstring (missing-docstring)
python/qemu/qmp.py:33:0: R0205: Class 'QEMUMonitorProtocol' inherits from 
object, can be safely removed from bases in python3 (useless-object-inheritance)
python/qemu/qmp.py:80:4: R1710: Either all return statements in a function 
should return an expression, or none of them should. 
(inconsistent-return-statements)
python/qemu/qmp.py:131:4: R1710: Either all return statements in a function 
should return an expression, or none of them should. 
(inconsistent-return-statements)
python/qemu/qmp.py:159:4: R1710: Either all return statements in a function 
should return an expression, or none of them should. 
(inconsistent-return-statements)
python/qemu/qmp.py:245:4: C0111: Missing method docstring (missing-docstring)
python/qemu/qmp.py:249:4: C0111: Missing method docstring (missing-docstring)
python/qemu/qmp.py:252:4: C0111: Missing method docstring (missing-docstring)
python/qemu/qmp.py:255:4: C0111: Missing method docstring (missing-docstring)

Signed-off-by: Wainer dos Santos Moschetta 
---
 python/qemu/qmp.py | 51 +-
 1 file changed, 41 insertions(+), 10 deletions(-)

diff --git a/python/qemu/qmp.py b/python/qemu/qmp.py
index 8c6c9847d0..f4e04a6683 100644
--- a/python/qemu/qmp.py
+++ b/python/qemu/qmp.py
@@ -1,5 +1,4 @@
-# QEMU Monitor Protocol Python class
-#
+""" QEMU Monitor Protocol Python class """
 # Copyright (C) 2009, 2010 Red Hat Inc.
 #
 # Authors:
@@ -15,22 +14,34 @@ import logging
 
 
 class QMPError(Exception):
-pass
+"""
+QMP base exception
+"""
 
 
 class QMPConnectError(QMPError):
-pass
+"""
+QMP connection exception
+"""
 
 
 class QMPCapabilitiesError(QMPError):
-pass
+"""
+QMP negotiate capabilities exception
+"""
 
 
 class QMPTimeoutError(QMPError):
-pass
+"""
+QMP timeout exception
+"""
 
 
-class QEMUMonitorProtocol(object):
+class QEMUMonitorProtocol:
+"""
+Provide an API to connect to QEMU via QEMU Monitor Protocol (QMP) and then
+allow to handle commands and events.
+"""
 
 #: Logger object for debugging messages
 logger = logging.getLogger('QMP')
@@ -81,7 +92,7 @@ class QEMUMonitorProtocol(object):
 while True:
 data = self.__sockfile.readline()
 if not data:
-return
+return None
 resp = json.loads(data)
 if 'event' in resp:
 self.logger.debug("<<< %s", resp)
@@ -132,7 +143,7 @@ class QEMUMonitorProtocol(object):
 """
 Connect to the QMP Monitor and perform capabilities negotiation.
 
-@return QMP greeting dict
+@return QMP greeting dict, or None if negotiate is false
 @raise OSError on socket connection errors
 @raise QMPConnectError if the greeting is not received
 @raise QMPCapabilitiesError if fails to negotiate capabilities
@@ -141,6 +152,7 @@ class QEMUMonitorProtocol(object):
 self.__sockfile = self.__sock.makefile()
 if negotiate:
 return self.__negotiate_capabilities()
+return None
 
 def accept(self):
 """
@@ -169,7 +181,7 @@ class QEMUMonitorProtocol(object):
 self.__sock.sendall(json.dumps(qmp_cmd).encode('utf-8'))
 except OSError as err:
 if err.errno == errno.EPIPE:
-return
+return None
 raise err
 resp = self.__json_read()
 self.logger.debug("<<< %s", resp)
@@ -243,14 +255,33 @@ class QEMUMonitorProtocol(object):
 self.__events = []
 
 def close(self):
+"""
+Close the socket and socket file.
+"""
 self.__sock.close()
 self.__sockfile.close()
 
 def settimeout(self, timeout):
+"""
+Set the socket timeout.
+
+@param timeout (float): timeout in seconds, or None.
+@note This is a wrap around socket.settimeout
+"""
 self.__sock.settimeout(timeout)
 
 def get_sock_fd(self):
+"""
+Get the socket file descriptor.
+
+@return The file descriptor number.
+"""
 return self.__sock.fileno()
 
 def is_scm_available(self):
+"""
+Check if the socket allows for SCM_RIGHTS.
+
+@return True if SCM_RIGHTS is available, otherwise False.
+"""
 return self.__sock.family == socket.AF_UNIX
-- 
2.23.0




[PATCH 0/5] python/qemu: qmp: Fix, delint and improvements

2019-12-27 Thread Wainer dos Santos Moschetta
I started fixing an issue on exception handling which in some places
currently use the deprecated (in Python 3.3) `socket.error`. Then I
ended up delinting the module code and making some improvements.

Git:
- Tree: https://github.com/wainersm/qemu
- Branch: python_qmp_sockets_error 

CI:
- Travis (FAIL): https://travis-ci.org/wainersm/qemu/builds/629772066
  Failure not related with this series. Even QEMU master branch is
  failing to build when `--without-default-devices --disable-user`.

Wainer dos Santos Moschetta (5):
  python/qemu: qmp: Replace socket.error with OSError
  python/qemu: Delint the qmp module
  python/qemu: qmp: Make accept()'s timeout configurable
  python/qemu: qmp: Make QEMUMonitorProtocol a context manager
  python/qemu: qmp: Remove unnused attributes

 python/qemu/qmp.py | 91 +-
 1 file changed, 65 insertions(+), 26 deletions(-)

-- 
2.23.0




[PATCH 3/5] python/qemu: qmp: Make accept()'s timeout configurable

2019-12-27 Thread Wainer dos Santos Moschetta
Currently the timeout of QEMUMonitorProtocol.accept() is
hard-coded to 15 seconds. This added the parameter `timeout`
so the value can be configured by the user.

Signed-off-by: Wainer dos Santos Moschetta 
---
 python/qemu/qmp.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/python/qemu/qmp.py b/python/qemu/qmp.py
index f4e04a6683..914b8c6774 100644
--- a/python/qemu/qmp.py
+++ b/python/qemu/qmp.py
@@ -154,16 +154,17 @@ class QEMUMonitorProtocol:
 return self.__negotiate_capabilities()
 return None
 
-def accept(self):
+def accept(self, timeout=15):
 """
 Await connection from QMP Monitor and perform capabilities negotiation.
 
+@param timeout (float): timeout in seconds. Default is 15.
 @return QMP greeting dict
 @raise OSError on socket connection errors
 @raise QMPConnectError if the greeting is not received
 @raise QMPCapabilitiesError if fails to negotiate capabilities
 """
-self.__sock.settimeout(15)
+self.__sock.settimeout(timeout)
 self.__sock, _ = self.__sock.accept()
 self.__sockfile = self.__sock.makefile()
 return self.__negotiate_capabilities()
-- 
2.23.0




[PATCH 1/5] python/qemu: qmp: Replace socket.error with OSError

2019-12-27 Thread Wainer dos Santos Moschetta
The socket.error is deprecated from Python 3.3, instead it is
made a link to OSError. This change replaces the occurences
of socket.error with OSError.

Signed-off-by: Wainer dos Santos Moschetta 
---
 python/qemu/qmp.py | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/python/qemu/qmp.py b/python/qemu/qmp.py
index 5c8cf6a056..8c6c9847d0 100644
--- a/python/qemu/qmp.py
+++ b/python/qemu/qmp.py
@@ -47,7 +47,7 @@ class QEMUMonitorProtocol(object):
 or a tuple in the form ( address, port ) for a TCP
 connection
 @param server: server mode listens on the socket (bool)
-@raise socket.error on socket connection errors
+@raise OSError on socket connection errors
 @note No connection is established, this is done by the connect() or
   accept() methods
 """
@@ -107,8 +107,8 @@ class QEMUMonitorProtocol(object):
 self.__sock.setblocking(0)
 try:
 self.__json_read()
-except socket.error as err:
-if err[0] == errno.EAGAIN:
+except OSError as err:
+if err.errno == errno.EAGAIN:
 # No data available
 pass
 self.__sock.setblocking(1)
@@ -133,7 +133,7 @@ class QEMUMonitorProtocol(object):
 Connect to the QMP Monitor and perform capabilities negotiation.
 
 @return QMP greeting dict
-@raise socket.error on socket connection errors
+@raise OSError on socket connection errors
 @raise QMPConnectError if the greeting is not received
 @raise QMPCapabilitiesError if fails to negotiate capabilities
 """
@@ -147,7 +147,7 @@ class QEMUMonitorProtocol(object):
 Await connection from QMP Monitor and perform capabilities negotiation.
 
 @return QMP greeting dict
-@raise socket.error on socket connection errors
+@raise OSError on socket connection errors
 @raise QMPConnectError if the greeting is not received
 @raise QMPCapabilitiesError if fails to negotiate capabilities
 """
@@ -167,10 +167,10 @@ class QEMUMonitorProtocol(object):
 self.logger.debug(">>> %s", qmp_cmd)
 try:
 self.__sock.sendall(json.dumps(qmp_cmd).encode('utf-8'))
-except socket.error as err:
-if err[0] == errno.EPIPE:
+except OSError as err:
+if err.errno == errno.EPIPE:
 return
-raise socket.error(err)
+raise err
 resp = self.__json_read()
 self.logger.debug("<<< %s", resp)
 return resp
-- 
2.23.0




[PATCH 2/2] qcow2: dump QCOW2 metadata

2019-12-27 Thread Andrey Shinkevich
Let QEMU-IMG CHECK command show QCOW2 structure to inform a user about
metadata allocations on disk. Introduce '-M'('--dump-meta') key option.

Suggested-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: Andrey Shinkevich 
---
 block/qcow2-bitmap.c   | 53 ---
 block/qcow2-refcount.c | 84 +-
 block/qcow2.c  | 30 ++
 block/qcow2.h  |  6 ++--
 include/block/block.h  |  3 +-
 qemu-img.c | 29 -
 qemu-img.texi  |  2 +-
 7 files changed, 183 insertions(+), 24 deletions(-)

diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
index c6c8ebb..4f7b375 100644
--- a/block/qcow2-bitmap.c
+++ b/block/qcow2-bitmap.c
@@ -659,20 +659,29 @@ fail:
 
 int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
   void **refcount_table,
-  int64_t *refcount_table_size)
+  int64_t *refcount_table_size,
+  Qcow2Bitmaps *bitmaps)
 {
 int ret;
 BDRVQcow2State *s = bs->opaque;
 Qcow2BitmapList *bm_list;
 Qcow2Bitmap *bm;
+Qcow2BitmapDirectoryEntryList **pp_dir =
+bitmaps ? &bitmaps->bitmap_dir->dir_entries : NULL;
 
 if (s->nb_bitmaps == 0) {
 return 0;
 }
 
+if (bitmaps) {
+bitmaps->nb_bitmaps = s->nb_bitmaps;
+}
+
 ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, 
refcount_table_size,
s->bitmap_directory_offset,
-   s->bitmap_directory_size);
+   s->bitmap_directory_size,
+   bitmaps ? bitmaps->bitmap_dir->location
+   : NULL);
 if (ret < 0) {
 return ret;
 }
@@ -686,12 +695,28 @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, 
BdrvCheckResult *res,
 
 QSIMPLEQ_FOREACH(bm, bm_list, entry) {
 uint64_t *bitmap_table = NULL;
+Qcow2BitmapTblEntryList **pp_table;
 int i;
 
+Qcow2BitmapDirectoryEntry *bmde = NULL;
+if (bitmaps) {
+bmde = g_new0(Qcow2BitmapDirectoryEntry, 1);
+bmde->bitmap_name = g_strdup(bm->name);
+bmde->bitmap_table = g_new0(Qcow2BitmapTbl, 1);
+bmde->bitmap_table->location = g_new0(Qcow2Allocation, 1);
+Qcow2BitmapDirectoryEntryList *obj =
+g_new0(Qcow2BitmapDirectoryEntryList, 1);
+obj->value = bmde;
+*pp_dir = obj;
+pp_dir = &obj->next;
+}
+
 ret = qcow2_inc_refcounts_imrt(bs, res,
refcount_table, refcount_table_size,
bm->table.offset,
-   bm->table.size * sizeof(uint64_t));
+   bm->table.size * sizeof(uint64_t),
+   bmde ? bmde->bitmap_table->location
+   : NULL);
 if (ret < 0) {
 goto out;
 }
@@ -702,6 +727,8 @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, 
BdrvCheckResult *res,
 goto out;
 }
 
+pp_table = bmde ? &bmde->bitmap_table->table_entries : NULL;
+
 for (i = 0; i < bm->table.size; ++i) {
 uint64_t entry = bitmap_table[i];
 uint64_t offset = entry & BME_TABLE_ENTRY_OFFSET_MASK;
@@ -711,13 +738,31 @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, 
BdrvCheckResult *res,
 continue;
 }
 
+Qcow2BitmapTblEntry *bmte = NULL;
+if (bmde) {
+bmte = g_new0(Qcow2BitmapTblEntry, 1);
+bmte->type = offset ? QCOW2_BITMAP_TBL_ENTRY_TYPE_SERIALIZED :
+entry & BME_TABLE_ENTRY_FLAG_ALL_ONES;
+if (offset) {
+bmte->cluster = g_new0(Qcow2Allocation, 1);
+}
+bmte->has_cluster = !!(bmte->cluster);
+Qcow2BitmapTblEntryList *elem =
+g_new0(Qcow2BitmapTblEntryList, 1);
+elem->value = bmte;
+*pp_table = elem;
+pp_table = &elem->next;
+}
+
 if (offset == 0) {
 continue;
 }
 
 ret = qcow2_inc_refcounts_imrt(bs, res,
refcount_table, refcount_table_size,
-   offset, s->cluster_size);
+   offset, s->cluster_size,
+   bmte && bmte->cluster ? 
bmte->cluster
+   : NULL);
 if (ret < 0) {
 g_free(bitmap_table);
 goto out;
diff --git a/block/qcow2-ref

[PATCH 1/2] qcow2: introduce Qcow2Metadata structure

2019-12-27 Thread Andrey Shinkevich
The preliminary patch to provide an extendable structure for dumping
QCOW2 metadata allocations in image.

Suggested-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: Andrey Shinkevich 
---
 qapi/block-core.json | 208 ++-
 1 file changed, 207 insertions(+), 1 deletion(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 0cf68fe..3eaac13 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -176,6 +176,209 @@
'*backing-image': 'ImageInfo',
'*format-specific': 'ImageInfoSpecific' } }
 
+
+##
+# @Qcow2Metadata:
+#
+# Encapsulates QCOW2 metadata information
+#
+# @qcow2-header: QCOW2 header info
+#
+# @active-l1: L1 active table info
+#
+# @refcount-table: refcount table info
+#
+# @crypt-header: encryption header info
+#
+# @bitmaps: bitmap tables info
+#
+# @snapshot-table: snapshot tables info
+#
+# Since: 5.0
+##
+{ 'struct': 'Qcow2Metadata',
+  'data': { 'qcow2-header': 'Qcow2Header',
+'refcount-table': 'Qcow2RefcountTable',
+'active-l1': 'Qcow2L1Table',
+'*crypt-header': 'Qcow2EncryptionHeader',
+'*bitmaps': 'Qcow2Bitmaps',
+'*snapshot-table': 'Qcow2SnapshotsTable' } }
+
+##
+# @Qcow2Header:
+#
+# QCOW2 header information
+#
+# @version: version number
+#
+# @location: header offset and size in image
+#
+# Since: 5.0
+##
+{ 'struct': 'Qcow2Header',
+  'data': {'version': 'int',
+   'location': 'Qcow2Allocation' } }
+
+##
+# @Qcow2EncryptionHeader:
+#
+# QCOW2 encryption header information
+#
+# @location: header offset and size in image
+#
+# Since: 5.0
+##
+{ 'struct': 'Qcow2EncryptionHeader',
+  'data': {'location': 'Qcow2Allocation' } }
+
+##
+# @Qcow2RefcountTable:
+#
+# QCOW2 refcount table information
+#
+# @location: refcount table offset and size in image
+#
+# Since: 5.0
+##
+{ 'struct': 'Qcow2RefcountTable',
+  'data': {'location': 'Qcow2Allocation' } }
+
+##
+# @Qcow2L1Table:
+#
+# L1 table information
+#
+# @l2-list: list of L2 table locations
+#
+# @location: L1 table offset and size in image
+#
+# @name: entity name the table relates to
+#
+# Since: 5.0
+##
+{ 'struct': 'Qcow2L1Table',
+  'data': {'l2-list': ['Qcow2Allocation'],
+   'location': 'Qcow2Allocation',
+   'name': 'str'} }
+
+##
+# @Qcow2Allocation:
+#
+# QCOW2 data location in image
+#
+# @offset: data offset
+#
+# @size: data size
+#
+# Since: 5.0
+##
+{ 'struct': 'Qcow2Allocation',
+  'data': {'offset': 'uint64', 'size': 'uint64' } }
+
+##
+# @Qcow2Bitmaps:
+#
+# QCOW2 bitmaps information
+#
+# @nb-bitmaps: the number of bitmaps contained in the image
+#
+# @bitmap-dir: bitmap directory information
+#
+# Since: 5.0
+##
+{ 'struct': 'Qcow2Bitmaps',
+  'data': {'nb-bitmaps': 'int',
+   'bitmap-dir': 'Qcow2BitmapDir' } }
+
+##
+# @Qcow2BitmapDir:
+#
+# QCOW2 bitmap directory information
+#
+# @dir-entries: list of bitmap directory entries
+#
+# @location: bitmap directory offset and size in image
+#
+# Since: 5.0
+##
+{ 'struct': 'Qcow2BitmapDir',
+  'data': {'dir-entries': ['Qcow2BitmapDirectoryEntry'],
+   'location': 'Qcow2Allocation' } }
+
+##
+# @Qcow2BitmapDirectoryEntry:
+#
+# QCOW2 bitmap directory entry information
+#
+# @bitmap-table: bitmap table offset and size in image
+#
+# Since: 5.0
+##
+{ 'struct': 'Qcow2BitmapDirectoryEntry',
+  'data': {'bitmap-table': 'Qcow2BitmapTbl',
+   'bitmap-name': 'str' } }
+
+##
+# @Qcow2BitmapTbl:
+#
+# QCOW2 bitmap table information
+#
+# @table-entries: list of bitmap table entries
+#
+# @location: bitmap table offset and size in image
+#
+# Since: 5.0
+##
+{ 'struct': 'Qcow2BitmapTbl',
+  'data': {'table-entries': ['Qcow2BitmapTblEntry'],
+   'location': 'Qcow2Allocation' } }
+
+##
+# @Qcow2BitmapTblEntry:
+#
+# QCOW2 bitmap table entry information
+#
+# @type: bitmap table entry type
+#
+# @cluster: bitmap table entry offset and size in image
+#
+# Since: 5.0
+##
+{ 'struct': 'Qcow2BitmapTblEntry',
+  'data': {'type': 'Qcow2BitmapTblEntryType',
+   '*cluster': 'Qcow2Allocation' } }
+
+##
+# @Qcow2BitmapTblEntryType:
+#
+# An enumeration of cluster types in bitmap table
+#
+# @all-zeros: cluster should be read as all zeros
+#
+# @all-ones: cluster should be read as all ones
+#
+# @serialized: cluster data are written on disk
+#
+# Since: 5.0
+##
+{ 'enum': 'Qcow2BitmapTblEntryType',
+  'data': ['all-zeros', 'all-ones', 'serialized'] }
+
+##
+# @Qcow2SnapshotsTable:
+#
+# Snapshots table location in image file.
+#
+# @location: offset and size of snapshot table
+#
+# @l1-list: list of snapshots L1 tables
+#
+# Since: 5.0
+##
+{ 'struct': 'Qcow2SnapshotsTable',
+  'data': {'location': 'Qcow2Allocation',
+   'l1-list': ['Qcow2L1Table'] } }
+
 ##
 # @ImageCheck:
 #
@@ -215,6 +418,8 @@
 #   field is present if the driver for the image format
 #   supports it
 #
+# @viscera: encapsulates QCOW2 tables allocation information
+#

[PATCH 0/2] Dump QCOW2 metadata

2019-12-27 Thread Andrey Shinkevich
The information about QCOW2 metadata allocations in an image ELF-file is
helpful for finding issues with the image data integrity.

Snapshots dump example:

$ sudo ./qemu-img check /.../.../harddisk.hdd -M --output=json
{
"image-end-offset": 24820842496,
"total-clusters": 153600,
"check-errors": 0,
"viscera": {
"refcount-table": {
"location": {
"offset": 3845128192,
"size": 1048576
}
},
"active-l1": {
"name": "L1 active table",
"location": {
"offset": 4194304,
"size": 16
},
"l2-list": [
{
"offset": 619708416,
"size": 1048576
},
{
"offset": 1156579328,
"size": 1048576
}
]
},
"qcow2-header": {
"location": {
"offset": 0,
"size": 1048576
},
"version": 3
},
"snapshot-table": {
"location": {
"offset": 648019968,
"size": 191
},
"l1-list": [
{
"name": "{3036f6c5-3a1f-44cb-af1f-653cc87fba04}",
"location": {
"offset": 14680064,
"size": 16
},
"l2-list": [
{
"offset": 3957325824,
"size": 1048576
},
{
"offset": 7025459200,
"size": 1048576
}
]
},
{
"name": "{0aa1a7d6-16ee-4b44-a515-b5ecc571c959}",
"location": {
"offset": 638582784,
"size": 16
},
"l2-list": [
{
"offset": 3957325824,
"size": 1048576
},
{
"offset": 7025459200,
"size": 1048576
}
]
}
]
}
},
"allocated-clusters": 22485,
"filename": "/.../.../harddisk.hdd",
"format": "qcow2",
"fragmented-clusters": 3549
}

Bitmaps dump example:

$ ./qemu-img check /home/disk -M --output=json
{
"image-end-offset": 1441792,
"total-clusters": 16,
"check-errors": 0,
"viscera": {
"refcount-table": {
"location": {
"offset": 65536,
"size": 65536
}
},
"active-l1": {
"name": "L1 active table",
"location": {
"offset": 196608,
"size": 8
},
"l2-list": [
{
"offset": 262144,
"size": 65536
}
]
},
"bitmaps": {
"bitmap-dir": {
"location": {
"offset": 1048576,
"size": 64
},
"dir-entries": [
{
"bitmap-table": {
"location": {
"offset": 589824,
"size": 8
},
"table-entries": [
{
"type": "all-zeros"
}
]
},
"bitmap-name": "bitmap-1"
},
{
"bitmap-table": {
"location": {
"offset": 983040,
"size": 8
},
"table-entries": [
{
"cluster": {
"offset": 655360,
"size": 65536
},
"type": "serialized"
}
]
},
"bitmap-name": "bitmap-2"
}
]
},
"nb-bitmaps": 2
},
"qcow2-header": {
"location": {
"offset": 0,
"size": 65536
},
"version": 3
}
},
"allocated-clusters": 12,
"filename": "/home/disk",
"format": "