Re: [PATCH v4 4/5] qcow2: add zstd cluster compression

2020-03-03 Thread Vladimir Sementsov-Ogievskiy

03.03.2020 16:34, Denis Plotnikov wrote:

zstd significantly reduces cluster compression time.
It provides better compression performance maintaining
the same level of the compression ratio in comparison with
zlib, which, at the moment, is the only compression
method available.

The performance test results:
Test compresses and decompresses qemu qcow2 image with just
installed rhel-7.6 guest.
Image cluster size: 64K. Image on disk size: 2.2G

The test was conducted with brd disk to reduce the influence
of disk subsystem to the test results.
The results is given in seconds.

compress cmd:
   time ./qemu-img convert -O qcow2 -c -o compression_type=[zlib|zstd]
   src.img [zlib|zstd]_compressed.img
decompress cmd
   time ./qemu-img convert -O qcow2
   [zlib|zstd]_compressed.img uncompressed.img

compression   decompression
  zlib   zstd   zlib zstd

real 65.5   16.3 (-75 %)1.9  1.6 (-16 %)
user 65.0   15.85.3  2.5
sys   3.30.22.0  2.0

Both ZLIB and ZSTD gave the same compression ratio: 1.57
compressed image size in both cases: 1.4G

Signed-off-by: Denis Plotnikov 
---


[..]


+static ssize_t qcow2_zstd_compress(void *dest, size_t dest_size,
+   const void *src, size_t src_size)
+{
+size_t ret;
+
+/*
+ * steal ZSTD_LEN_BUF bytes in the very beginning of the buffer
+ * to store compressed chunk size
+ */
+char *d_buf = ((char *) dest) + ZSTD_LEN_BUF;
+
+/*
+ * sanity check that we can store the compressed data length,
+ * and there is some space left for the compressor buffer
+ */
+if (dest_size <= ZSTD_LEN_BUF) {
+return -ENOMEM;
+}
+
+dest_size -= ZSTD_LEN_BUF;
+
+ret = ZSTD_compress(d_buf, dest_size, src, src_size, 5);


You may want to define ZSTD_COMPRESSION_LEVEL constant instead of raw number.

anyway,
Reviewed-by: Vladimir Sementsov-Ogievskiy 




--
Best regards,
Vladimir



Re: [PATCH v4 3/5] qcow2: rework the cluster compression routine

2020-03-03 Thread Vladimir Sementsov-Ogievskiy

03.03.2020 16:34, Denis Plotnikov wrote:

The patch enables processing the image compression type defined
for the image and chooses an appropriate method for image clusters
(de)compression.

Signed-off-by: Denis Plotnikov 
---
  block/qcow2-threads.c | 71 ---
  1 file changed, 60 insertions(+), 11 deletions(-)

diff --git a/block/qcow2-threads.c b/block/qcow2-threads.c
index a68126f291..9bfcda6918 100644
--- a/block/qcow2-threads.c
+++ b/block/qcow2-threads.c
@@ -74,7 +74,9 @@ typedef struct Qcow2CompressData {
  } Qcow2CompressData;
  
  /*

- * qcow2_compress()
+ * qcow2_zlib_compress()
+ *
+ * Compress @src_size bytes of data using zlib compression method
   *
   * @dest - destination buffer, @dest_size bytes
   * @src - source buffer, @src_size bytes
@@ -83,8 +85,8 @@ typedef struct Qcow2CompressData {
   *  -ENOMEM destination buffer is not enough to store compressed data
   *  -EIOon any other error
   */
-static ssize_t qcow2_compress(void *dest, size_t dest_size,
-  const void *src, size_t src_size)
+static ssize_t qcow2_zlib_compress(void *dest, size_t dest_size,
+   const void *src, size_t src_size)
  {
  ssize_t ret;
  z_stream strm;
@@ -119,10 +121,10 @@ static ssize_t qcow2_compress(void *dest, size_t 
dest_size,
  }
  
  /*

- * qcow2_decompress()
+ * qcow2_zlib_decompress()
   *
   * Decompress some data (not more than @src_size bytes) to produce exactly
- * @dest_size bytes.
+ * @dest_size bytes using zlib compression method
   *
   * @dest - destination buffer, @dest_size bytes
   * @src - source buffer, @src_size bytes
@@ -130,8 +132,8 @@ static ssize_t qcow2_compress(void *dest, size_t dest_size,
   * Returns: 0 on success
   *  -EIO on fail
   */
-static ssize_t qcow2_decompress(void *dest, size_t dest_size,
-const void *src, size_t src_size)
+static ssize_t qcow2_zlib_decompress(void *dest, size_t dest_size,
+ const void *src, size_t src_size)
  {
  int ret;
  z_stream strm;
@@ -191,20 +193,67 @@ qcow2_co_do_compress(BlockDriverState *bs, void *dest, 
size_t dest_size,
  return arg.ret;
  }
  
+/*

+ * qcow2_co_compress()
+ *
+ * Compress @src_size bytes of data using the compression
+ * method defined by the image compression type
+ *
+ * @dest - destination buffer, @dest_size bytes
+ * @src - source buffer, @src_size bytes
+ *
+ * Returns: compressed size on success
+ *  a negative error code on failure
+ */
  ssize_t coroutine_fn
  qcow2_co_compress(BlockDriverState *bs, void *dest, size_t dest_size,
const void *src, size_t src_size)
  {
-return qcow2_co_do_compress(bs, dest, dest_size, src, src_size,
-qcow2_compress);
+BDRVQcow2State *s = bs->opaque;
+Qcow2CompressFunc fn;
+
+switch (s->compression_type) {
+case QCOW2_COMPRESSION_TYPE_ZLIB:
+fn = qcow2_zlib_compress;
+break;
+
+default:
+abort();
+}
+
+return qcow2_co_do_compress(bs, dest, dest_size, src, src_size, fn);
  }
  
+/*

+ * qcow2_co_decompress()
+ *
+ * Decompress some data (not more than @src_size bytes) to produce exactly
+ * @dest_size bytes using the compression method defined by the image
+ * compression type
+ *
+ * @dest - destination buffer, @dest_size bytes
+ * @src - source buffer, @src_size bytes
+ *
+ * Returns: 0 on success
+ *  a negative error code on failure
+ */
  ssize_t coroutine_fn
  qcow2_co_decompress(BlockDriverState *bs, void *dest, size_t dest_size,
  const void *src, size_t src_size)
  {
-return qcow2_co_do_compress(bs, dest, dest_size, src, src_size,
-qcow2_decompress);
+BDRVQcow2State *s = bs->opaque;
+Qcow2CompressFunc fn;
+
+switch (s->compression_type) {
+case QCOW2_COMPRESSION_TYPE_ZLIB:
+fn = qcow2_zlib_decompress;
+break;
+
+default:
+return -ENOTSUP;


abort() here, like in _compress()


+}
+
+return qcow2_co_do_compress(bs, dest, dest_size, src, src_size, fn);
  }
  
  




--
Best regards,
Vladimir



RE: The issues about architecture of the COLO checkpoint

2020-03-03 Thread Zhang, Chen


> -Original Message-
> From: Daniel Cho 
> Sent: Monday, February 24, 2020 3:15 PM
> To: Zhang, Chen 
> Cc: Dr. David Alan Gilbert ; Zhanghailiang
> ; qemu-devel@nongnu.org; Jason
> Wang 
> Subject: Re: The issues about architecture of the COLO checkpoint
> 
> Hi Zhang,
> 
> Thanks for your help.
> However, did you occur the error which the function qemu_hexdump in
> colo-compare.c will crash the qemu process while doing operation with
> network?
> 

No, qemu_hexdump looks no relationship with network...
Do you means it will crashed in qemu_hexdump sometimes? 

> We are working on VM fault tolerance study and COLO function evalutation
> first. Currently we did not have a confirmed plan on it.

OK, keep connection.

Thanks
Zhang Chen

> 
> Best regard,
> Daniel Cho
> 
> Zhang, Chen  於 2020年2月24日 週一 上午2:43
> 寫道:
> 
> >
> >
> >
> >
> >
> > From: Daniel Cho 
> > Sent: Thursday, February 20, 2020 11:49 AM
> > To: Zhang, Chen 
> > Cc: Dr. David Alan Gilbert ; Zhanghailiang
> > ; qemu-devel@nongnu.org; Jason
> Wang
> > 
> > Subject: Re: The issues about architecture of the COLO checkpoint
> >
> >
> >
> > Hi Zhang,
> >
> >
> >
> > Thanks, I will configure on code for testing first.
> >
> > However, if you have free time, could you please send the patch file to us,
> Thanks.
> >
> >
> >
> > OK, I will send this patch recently.
> >
> > By the way, can you share QNAP’s plan and status for COLO?
> >
> >
> >
> > Best Regard,
> >
> > Daniel Cho
> >
> >
> >
> >
> >
> > Zhang, Chen  於 2020年2月20日 週四 上午
> 11:07寫道:
> >
> >
> >
> > On 2/18/2020 5:22 PM, Daniel Cho wrote:
> >
> > Hi Hailiang,
> >
> > Thanks for your help. If we have any problems we will contact you for your
> favor.
> >
> >
> >
> >
> >
> > Hi Zhang,
> >
> >
> >
> > " If colo-compare got a primary packet without related secondary packet in
> a certain time , it will automatically trigger checkpoint.  "
> >
> > As you said, the colo-compare will trigger checkpoint, but does it need to
> limit checkpoint times?
> >
> > There is a problem about doing many checkpoints while we use fio to
> random write files. Then it will cause low throughput on PVM.
> >
> > Is this situation is normal on COLO?
> >
> >
> >
> > Hi Daniel,
> >
> > The checkpoint time is designed to be user adjustable based on user
> environment(workload/network status/business conditions...).
> >
> > In net/colo-compare.c
> >
> > /* TODO: Should be configurable */
> > #define REGULAR_PACKET_CHECK_MS 3000
> >
> > If you need, I can send a patch for this issue. Make users can change the
> value by QMP and qemu monitor commands.
> >
> > Thanks
> >
> > Zhang Chen
> >
> >
> >
> >
> >
> > Best regards,
> >
> > Daniel Cho
> >
> >
> >
> > Zhang, Chen  於 2020年2月17日 週一 下午
> 1:36寫道:
> >
> >
> >
> > On 2/15/2020 11:35 AM, Daniel Cho wrote:
> >
> > Hi Dave,
> >
> >
> >
> > Yes, I agree with you, it does need a timeout.
> >
> >
> >
> > Hi Daniel and Dave,
> >
> > Current colo-compare already have the timeout mechanism.
> >
> > Named packet_check_timer,  It will scan primary packet queue to make
> sure all the primary packet not stay too long time.
> >
> > If colo-compare got a primary packet without related secondary packet in a
> certain time , it will automatic trigger checkpoint.
> >
> > https://github.com/qemu/qemu/blob/master/net/colo-compare.c#L847
> >
> >
> >
> > Thanks
> >
> > Zhang Chen
> >
> >
> >
> >
> >
> > Hi Hailiang,
> >
> >
> >
> > We base on qemu-4.1.0 for using COLO feature, in your patch, we found a
> lot of difference  between your version and ours.
> >
> > Could you give us a latest release version which is close your developing
> code?
> >
> >
> >
> > Thanks.
> >
> >
> >
> > Regards
> >
> > Daniel Cho
> >
> >
> >
> > Dr. David Alan Gilbert  於 2020年2月13日 週四
> 下午6:38寫道:
> >
> > * Daniel Cho (daniel...@qnap.com) wrote:
> > > Hi Hailiang,
> > >
> > > 1.
> > > OK, we will try the patch
> > > “0001-COLO-Optimize-memory-back-up-process.patch”,
> > > and thanks for your help.
> > >
> > > 2.
> > > We understand the reason to compare PVM and SVM's packet.
> > > However, the empty of SVM's packet queue might happened on setting
> > > COLO feature and SVM broken.
> > >
> > > On situation 1 ( setting COLO feature ):
> > > We could force do checkpoint after setting COLO feature finish,
> > > then it will protect the state of PVM and SVM . As the Zhang Chen said.
> > >
> > > On situation 2 ( SVM broken ):
> > > COLO will do failover for PVM, so it might not cause any wrong on PVM.
> > >
> > > However, those situations are our views, so there might be a big
> > > difference between reality and our views.
> > > If we have any wrong views and opinions, please let us know, and
> > > correct us.
> >
> > It does need a timeout; the SVM being broken or being in a state where
> > it never sends the corresponding packet (because of a state
> > difference) can happen and COLO needs to timeout when the packet
> > hasn't arrived after a while and trigger the checkpoint.
> >
> > Dave
> >
> > > 

Re: [PATCH 3/4] qapi: Use super() now we have Python 3

2020-03-03 Thread Markus Armbruster
Markus Armbruster  writes:

> Signed-off-by: Markus Armbruster 
> ---
[...]
> diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
> index c8bcfe2c49..e132442c04 100644
> --- a/scripts/qapi/schema.py
> +++ b/scripts/qapi/schema.py
[...]
> @@ -614,7 +614,7 @@ class 
> QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
>  role = 'branch'
>  
>  def __init__(self, name, info, typ, ifcond=None):
> -QAPISchemaObjectTypeMember.__init__(self, name, info, typ,
> +super().__init__(name, info, typ,
>  False, ifcond)

pycodestyle-3 gripes:

scripts/qapi/schema.py:618:45: E127 continuation line over-indented for 
visual indent

Will fix.

[...]




Re: [PATCH v6 9/9] iotests: add pylintrc file

2020-03-03 Thread Markus Armbruster
John Snow  writes:

> Repeatable results. run `pylint iotests.py` and you should get a pass.

Start your sentences with a capital letter, please.

>
> Signed-off-by: John Snow 
> ---
>  tests/qemu-iotests/pylintrc | 20 
>  1 file changed, 20 insertions(+)
>  create mode 100644 tests/qemu-iotests/pylintrc
>
> diff --git a/tests/qemu-iotests/pylintrc b/tests/qemu-iotests/pylintrc
> new file mode 100644
> index 00..feed506f75
> --- /dev/null
> +++ b/tests/qemu-iotests/pylintrc
> @@ -0,0 +1,20 @@
> +[MESSAGES CONTROL]
> +
> +# Disable the message, report, category or checker with the given id(s). You
> +# can either give multiple identifiers separated by comma (,) or put this
> +# option multiple times (only on the command line, not in the configuration
> +# file where it should appear only once). You can also use "--disable=all" to
> +# disable everything first and then reenable specific checks. For example, if
> +# you want to run only the similarities checker, you can use "--disable=all
> +# --enable=similarities". If you want to run only the classes checker, but 
> have
> +# no Warning level messages displayed, use "--disable=all --enable=classes
> +# --disable=W".
> +disable=invalid-name,
> +missing-docstring,
> +line-too-long,
> +too-many-lines,
> +too-few-public-methods,
> +too-many-arguments,
> +too-many-locals,
> +too-many-branches,
> +too-many-public-methods,
> \ No newline at end of file

Add the newline, please.

German pejorative for the too-many- and too-few- warnings: "Müsli".
Implies it's for muesli-knitters / granola-crunchers indulging their
orthorexia.

missing-docstring is not advisable for libraries.  Feels okay here.

line-too-long might be worth cleaning up.  How many of them do we have
now?




Re: [PATCH v16 00/10] VIRTIO-IOMMU device

2020-03-03 Thread Zhangfei Gao
On Tue, Mar 3, 2020 at 5:41 PM Auger Eric  wrote:
>
> Hi Zhangfei,
> On 3/3/20 4:23 AM, Zhangfei Gao wrote:
> > Hi Eric
> >
> > On Thu, Feb 27, 2020 at 9:50 PM Auger Eric  wrote:
> >>
> >> Hi Daniel,
> >>
> >> On 2/27/20 12:17 PM, Daniel P. Berrangé wrote:
> >>> On Fri, Feb 14, 2020 at 02:27:35PM +0100, Eric Auger wrote:
>  This series implements the QEMU virtio-iommu device.
> 
>  This matches the v0.12 spec (voted) and the corresponding
>  virtio-iommu driver upstreamed in 5.3. All kernel dependencies
>  are resolved for DT integration. The virtio-iommu can be
>  instantiated in ARM virt using:
> 
>  "-device virtio-iommu-pci".
> >>>
> >>> Is there any more documentation besides this ?
> >>
> >> not yet in qemu.
> >>>
> >>> I'm wondering on the intended usage of this, and its relation
> >>> or pros/cons vs other iommu devices
> >>
> >> Maybe if you want to catch up on the topic, looking at the very first
> >> kernel RFC may be a good starting point. Motivation, pros & cons were
> >> discussed in that thread (hey, April 2017!)
> >> https://lists.linuxfoundation.org/pipermail/iommu/2017-April/021217.html
> >>
> >> on ARM we have SMMUv3 emulation. But the VFIO integration is not
> >> possible because SMMU does not have any "caching mode" and my nested
> >> paging kernel series is blocked. So the only solution to integrate with
> >> VFIO is looming virtio-iommu.
> >>
> >> In general the pros that were put forward are: virtio-iommu is
> >> architecture agnostic, removes the burden to accurately model complex
> >> device states, driver can support virtualization specific optimizations
> >> without being constrained by production driver maintenance. Cons is perf
> >> and mem footprint if we do not consider any optimization.
> >>
> >> You can have a look at
> >>
> >> http://events17.linuxfoundation.org/sites/events/files/slides/viommu_arm.pdf
> >>
> > Thanks for the patches.
> >
> > Could I ask one question?
> > To support vSVA and pasid in guest, which direction you recommend,
> > virtio-iommu or vSMMU (your nested paging)
> >
> > Do we still have any obstacles?
> you can ask the question but not sure I can answer ;-)
>
> 1) SMMUv3 2stage implementation is blocked by Will at kernel level.
>
> Despite this situation I may/can respin as Marvell said they were
> interested in this effort. If you are also interested in (I know you
> tested it several times and I am grateful to you for that), please reply
> to:
> [PATCH v9 00/14] SMMUv3 Nested Stage Setup (IOMMU part)
> (https://patchwork.kernel.org/cover/11039871/) and say you are
> interested in that work so that maintainers are aware there are
> potential users.
>
> At the moment I have not supported multiple CDs because it introduced
> other dependencies.
>
> 2) virtio-iommu
>
> So only virtio-iommu dt boot on machvirt is currently supported. For non
> DT, Jean respinned his kernel series
> "[PATCH v2 0/3] virtio-iommu on x86 and non-devicetree platforms" as you
> may know. However non DT integration still is controversial. Michael is
> pushing for putting the binding info the PCI config space. Joerg
> yesterday challenged this solution and said he would prefer ACPI
> integration. ACPI support depends on ACPI spec update & vote anyway.
>
> To support PASID at virtio-iommu level you also need virtio-iommu API
> extensions to be proposed and written + kernel works. So that's a long
> road. I will let Jean-Philippe comment on that.
>
> I would just say that Intel is working on nested paging solution with
> their emulated intel-iommu. We can help them getting that upstream and
> partly benefit from this work.
>
> > Would you mind give some breakdown.
> > Jean mentioned PASID still not supported in QEMU.
> Do you mean support of multiple CDs in the emulated SMMU? That's a thing
> I could implement quite easily. What is more tricky is how to test it.

Thanks Eric

Discussed with Jean before, here are some obstacles for vSVA via nested paging.
Do you think they are still big issues?

Copy "
* PASID support in QEMU, I don't think there is anything yet
// this is not a big issue as your comments.

* Page response support in VFIO and QEMU. With Eric's series we can
inject recoverable faults into the guest, but there is no channel for
the guest to RESUME the stall after fixing it.

* We can't use DVM in nested mode unless the VMID is shared with the
CPU. For that we'll need the host SMMU driver to hook into the KVM VMID
allocator, just like we do for the ASID allocator. I haven't yet
investigated how to do that. It's possible to do vSVA without DVM
though, by sending all TLB invalidations through the SMMU command queue.
"

Thanks



[PATCH] dp8393x: Mask EOL bit from descriptor addresses, take 2

2020-03-03 Thread Finn Thain
A portion of a recent patch got lost due to a merge snafu. That patch is
now commit 88f632fbb1 ("dp8393x: Mask EOL bit from descriptor addresses").
This patch restores the portion that got lost.

Signed-off-by: Finn Thain 
---
 hw/net/dp8393x.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index 8a3504d962..81fc13ee9f 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -525,8 +525,8 @@ static void dp8393x_do_transmit_packets(dp8393xState *s)
  * (4 + 3 * s->regs[SONIC_TFC]),
MEMTXATTRS_UNSPECIFIED, s->data,
size);
-s->regs[SONIC_CTDA] = dp8393x_get(s, width, 0) & ~0x1;
-if (dp8393x_get(s, width, 0) & SONIC_DESC_EOL) {
+s->regs[SONIC_CTDA] = dp8393x_get(s, width, 0);
+if (s->regs[SONIC_CTDA] & SONIC_DESC_EOL) {
 /* EOL detected */
 break;
 }
-- 
2.24.1



Re: [PATCH] hw/ide: Remove status register read side effect

2020-03-03 Thread jasper.lowell
> cmd646_update_irq() only seems to raise PCI interrupt, should it also
> have 
> an option to use INT 14 and 15 in legacy mode similar to what my
> patch 
> does for via-ide?

Looking through /qemu/hw/ide/cmd646.c it doesn't look like QEMU has
support for legacy mode. At the very least, it looks like we default to
PCI native mode:

static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
...
pci_conf[PCI_CLASS_PROG] = 0x8f;
...

To add support for legacy mode it would require changing
cmd646_update_irq() and maybe cmd646_set_irq() so that interrupts are
conditionally raised on IRQ14 and/or IRQ15 when the ports are in legacy
mode.

Thanks,
Jasper Lowell.


On Sun, 2020-03-01 at 19:02 +0100, BALATON Zoltan wrote:
> Hello,
> 
> On Wed, 26 Feb 2020, jasper.low...@bt.com wrote:
> > According to the CMD646U2 specification:
> > "When an IDE port is in PCI IDE Legacy Mode, the PCI646U2 is
> > compatible
> > with standard ISA IDE. The IDE task file registers are mapped to
> > the
> > standard ISA port addresses, and IDE drive interrupts occur at
> > IRQ14
> > (primary) or IRQ15 (secondary)."
> > 
> > In legacy mode, IRQ14 and IRQ15 mirror the state of INTRQ on each
> > of
> > the selected IDE devices. QEMU appears to emulate this correctly.
> 
> So CMD646 also seems to have a legacy mode. I've also seen a CMD
> PCI0640B 
> spec which is proabably a similar chip which says for interrupt
> handling:
> 
> "When DSA1 is pulled low during reset, both IDE ports are in PCI IDE 
> Legacy Mode. When DSA1 has no pull-down during reset, each IDE port
> may 
> independently be set to PCI IDE Legacy Mode or Native Mode via the 
> Programming Interface Byte (configuration register PROGIF, Index 9h).
> When 
> an IDE port is in PCI IDE Legacy Mode, the PCI-0640B is compatible
> with 
> standard ISA IDE. The IDE task file registers are mapped to the
> standard 
> ISA port addresses, and IDE drive interrupts occur at IRQ14 (primary)
> or 
> IRQ15 (secondary).
> 
> When an IDE port is in PCI IDE Native Mode, the IDE task file
> registers 
> may be mapped to non-standard port addresses, and IDE drive
> interrupts 
> occur at PCI INTA. Therefore, if both IDE ports are in PCI IDE
> Native 
> Mode, drive interrupts from both IDE ports are multiplexed into PCI
> INTA. 
> In this case, the interrupt status bits must be polled to determine
> which 
> IDE port generated the interrupt, or whether the interrupt was
> generated 
> by another PCI device sharing INTA on the bus."
> 
> This same explanation also appears in CMD646 doc. So what mode is
> the 
> PROG_IF config reg set to and do the interrupts raised match that? 
> cmd646_update_irq() only seems to raise PCI interrupt, should it also
> have 
> an option to use INT 14 and 15 in legacy mode similar to what my
> patch 
> does for via-ide?
> 
> Additionally Solaris may also get info from the OF device tree so
> that may 
> also have to match the device config.
> 
> I'm not sure this helps but I don't have any better idea.
> 
> Regards,
> BALATON Zoltan
> 


[PATCH] kvm: support to get/set dirty log initial-all-set capability

2020-03-03 Thread Jay Zhou
Since the new capability KVM_DIRTY_LOG_INITIALLY_SET of
KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 has been introduced in the
kernel, tweak the userspace side to detect and enable this
capability.

Signed-off-by: Jay Zhou 
---
 accel/kvm/kvm-all.c   | 21 ++---
 linux-headers/linux/kvm.h |  3 +++
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 439a4efe52..45ab25be63 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -100,7 +100,7 @@ struct KVMState
 bool kernel_irqchip_required;
 OnOffAuto kernel_irqchip_split;
 bool sync_mmu;
-bool manual_dirty_log_protect;
+uint64_t manual_dirty_log_protect;
 /* The man page (and posix) say ioctl numbers are signed int, but
  * they're not.  Linux, glibc and *BSD all treat ioctl numbers as
  * unsigned, and treating them as signed here can break things */
@@ -1882,6 +1882,7 @@ static int kvm_init(MachineState *ms)
 int ret;
 int type = 0;
 const char *kvm_type;
+uint64_t dirty_log_manual_caps;
 
 s = KVM_STATE(ms->accelerator);
 
@@ -2007,14 +2008,20 @@ static int kvm_init(MachineState *ms)
 s->coalesced_pio = s->coalesced_mmio &&
kvm_check_extension(s, KVM_CAP_COALESCED_PIO);
 
-s->manual_dirty_log_protect =
+dirty_log_manual_caps =
 kvm_check_extension(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2);
-if (s->manual_dirty_log_protect) {
-ret = kvm_vm_enable_cap(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, 0, 1);
+dirty_log_manual_caps &= (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE |
+  KVM_DIRTY_LOG_INITIALLY_SET);
+s->manual_dirty_log_protect = dirty_log_manual_caps;
+if (dirty_log_manual_caps) {
+ret = kvm_vm_enable_cap(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, 0,
+   dirty_log_manual_caps);
 if (ret) {
-warn_report("Trying to enable KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 "
-"but failed.  Falling back to the legacy mode. ");
-s->manual_dirty_log_protect = false;
+warn_report("Trying to enable capability %"PRIu64" of "
+"KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 but failed. "
+"Falling back to the legacy mode. ",
+dirty_log_manual_caps);
+s->manual_dirty_log_protect = 0;
 }
 }
 
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 265099100e..3cb71c2b19 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -1628,4 +1628,7 @@ struct kvm_hyperv_eventfd {
 #define KVM_HYPERV_CONN_ID_MASK0x00ff
 #define KVM_HYPERV_EVENTFD_DEASSIGN(1 << 0)
 
+#define KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE(1 << 0)
+#define KVM_DIRTY_LOG_INITIALLY_SET(1 << 1)
+
 #endif /* __LINUX_KVM_H */
-- 
2.14.1.windows.1





Re: [PATCH v7 17/17] spapr: Fold spapr_node0_size() into its only caller

2020-03-03 Thread David Gibson
On Tue, Mar 03, 2020 at 11:32:49AM +0100, Greg Kurz wrote:
> On Tue,  3 Mar 2020 14:43:51 +1100
> David Gibson  wrote:
> 
> > The Real Mode Area (RMA) needs to fit within the NUMA node owning memory
> > at address 0.  That's usually node 0, but can be a later one if there are
> > some nodes which have no memory (only CPUs).
> > 
> > This is currently handled by the spapr_node0_size() helper.  It has only
> > one caller, so there's not a lot of point splitting it out.  It's also
> > extremely easy to misread the code as clamping to the size of the smallest
> > node rather than the first node with any memory.
> > 
> > So, fold it into the caller, and add some commentary to make it a bit
> > clearer exactly what it's doing.
> > 
> > Signed-off-by: David Gibson 
> > ---
> >  hw/ppc/spapr.c | 37 +
> >  1 file changed, 21 insertions(+), 16 deletions(-)
> > 
> > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > index 2eb0d8f70d..d674a9f48f 100644
> > --- a/hw/ppc/spapr.c
> > +++ b/hw/ppc/spapr.c
> > @@ -296,20 +296,6 @@ static void 
> > spapr_populate_pa_features(SpaprMachineState *spapr,
> >  _FDT((fdt_setprop(fdt, offset, "ibm,pa-features", pa_features, 
> > pa_size)));
> >  }
> >  
> > -static hwaddr spapr_node0_size(MachineState *machine)
> > -{
> > -if (machine->numa_state->num_nodes) {
> > -int i;
> > -for (i = 0; i < machine->numa_state->num_nodes; ++i) {
> > -if (machine->numa_state->nodes[i].node_mem) {
> > -return 
> > MIN(pow2floor(machine->numa_state->nodes[i].node_mem),
> > -   machine->ram_size);
> > -}
> > -}
> > -}
> > -return machine->ram_size;
> > -}
> > -
> >  static void add_str(GString *s, const gchar *s1)
> >  {
> >  g_string_append_len(s, s1, strlen(s1) + 1);
> > @@ -2653,10 +2639,24 @@ static hwaddr spapr_rma_size(SpaprMachineState 
> > *spapr, Error **errp)
> >  MachineState *machine = MACHINE(spapr);
> >  SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
> >  hwaddr rma_size = machine->ram_size;
> > -hwaddr node0_size = spapr_node0_size(machine);
> >  
> >  /* RMA has to fit in the first NUMA node */
> > -rma_size = MIN(rma_size, node0_size);
> > +if (machine->numa_state->num_nodes) {
> > +/*
> > + * It's possible for there to be some zero-memory nodes first
> > + * in the list.  We need the RMA to fit inside the memory of
> > + * the first node which actually has some memory.
> > + */
> > +int i;
> > +
> > +for (i = 0; i < machine->numa_state->num_nodes; ++i) {
> > +if (machine->numa_state->nodes[i].node_mem != 0) {
> > +rma_size = MIN(rma_size,
> > +   machine->numa_state->nodes[i].node_mem);
> > +break;
> > +}
> > +}
> > +}
> >  
> >  /*
> >   * VRMA access is via a special 1TiB SLB mapping, so the RMA can
> > @@ -2673,6 +2673,11 @@ static hwaddr spapr_rma_size(SpaprMachineState 
> > *spapr, Error **errp)
> >  rma_size = MIN(rma_size, smc->rma_limit);
> >  }
> >  
> > +/*
> > + * RMA size must be a power of 2
> > + */
> > +rma_size = pow2floor(rma_size);
> > +
> 
> I saw somewhere else that the reason behind this might be
> related to:
> 
> https://git.qemu.org/?p=qemu.git;a=commitdiff;h=6010818c30ce9c
> 
> commit 6010818c30ce9c796b4e22fd261fc6fea1cecbfc
> Author: Alexey Kardashevskiy 
> Date:   Thu Jul 3 13:10:05 2014 +1000
> 
> spapr: Split memory nodes to power-of-two blocks
> 
> Is this the reason ?

Quite likely.

> In any case, it would probably help to mention somewhere
> why the rounding is introduced by this patch.

Drat.  I meant to sort out your comment on the last spin better than
this, but got part way through and forgot what I was doing.

I'm going to merge everything except this last patch into ppc-for-5.0
now, and try to sort out this one a bit later.

> 
> >  if (rma_size < MIN_RMA_SLOF) {
> >  error_setg(errp,
> >  "pSeries SLOF firmware requires >= %ldMiB guest RMA (Real Mode Area 
> > memory)",
> 

-- 
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 V2 01/23] dp8393x: Mask EOL bit from descriptor addresses

2020-03-03 Thread Jason Wang



On 2020/3/4 上午6:44, Finn Thain wrote:

Hi Jason,

The patch in this pull request (since merged) differs from the patch that
I sent. In particular, the change below is missing from commit 88f632fbb1
("dp8393x: Mask EOL bit from descriptor addresses") in mainline.

--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -525,8 +525,8 @@ static void dp8393x_do_transmit_packets(dp8393xState *s)
   * (4 + 3 * s->regs[SONIC_TFC]),
 MEMTXATTRS_UNSPECIFIED, s->data,
 size);
-s->regs[SONIC_CTDA] = dp8393x_get(s, width, 0) & ~0x1;
-if (dp8393x_get(s, width, 0) & SONIC_DESC_EOL) {
+s->regs[SONIC_CTDA] = dp8393x_get(s, width, 0);
+if (s->regs[SONIC_CTDA] & SONIC_DESC_EOL) {
  /* EOL detected */
  break;
  }

Please compare with "[PATCH v4 01/14] dp8393x: Mask EOL bit from
descriptor addresses" in the mailing list archives:
https://lore.kernel.org/qemu-devel/d6e8d06ad4d02f4a30c4caa6001967f806f21a1a.1580290069.git.fth...@telegraphics.com.au/

It appears that this portion of my patch went missing when merge conflicts
were resolved. The conflicts were apparently caused by commit 19f7034773
("Avoid address_space_rw() with a constant is_write argument").

Regards,
Finn



Exactly.

Please send a patch to fix this.

Thanks




[PATCH v1 3/3] riscv/sifive_u: Add a serial property to the sifive_u machine

2020-03-03 Thread Alistair Francis
From: Bin Meng 

At present the board serial number is hard-coded to 1, and passed
to OTP model during initialization. Firmware (FSBL, U-Boot) uses
the serial number to generate a unique MAC address for the on-chip
ethernet controller. When multiple QEMU 'sifive_u' instances are
created and connected to the same subnet, they all have the same
MAC address hence it creates a unusable network.

A new "serial" property is introduced to specify the board serial
number. When not given, the default serial number 1 is used.

Signed-off-by: Bin Meng 
Reviewed-by: Palmer Dabbelt 
Reviewed-by: Alistair Francis 
Message-Id: <1573916930-19068-1-git-send-email-bmeng...@gmail.com>
[ Changed by AF:
 - Use the SoC's serial property to pass the info to the SoC
 - Fixup commit title
 - Rebase on file restructuring
]
Signed-off-by: Alistair Francis 
---
 hw/riscv/sifive_u.c | 20 
 include/hw/riscv/sifive_u.h |  1 +
 2 files changed, 21 insertions(+)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index e52f9d0bd4..f3f67cc0e3 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -34,6 +34,7 @@
 #include "qemu/log.h"
 #include "qemu/error-report.h"
 #include "qapi/error.h"
+#include "qapi/visitor.h"
 #include "hw/boards.h"
 #include "hw/loader.h"
 #include "hw/sysbus.h"
@@ -322,6 +323,8 @@ static void riscv_sifive_u_init(MachineState *machine)
 object_initialize_child(OBJECT(machine), "soc", >soc,
 sizeof(s->soc), TYPE_RISCV_U_SOC,
 _abort, NULL);
+object_property_set_uint(OBJECT(>soc), s->serial, "serial",
+_abort);
 object_property_set_bool(OBJECT(>soc), true, "realized",
 _abort);
 
@@ -413,6 +416,18 @@ static void sifive_u_set_start_in_flash(Object *obj, bool 
value, Error **errp)
 s->start_in_flash = value;
 }
 
+static void sifive_u_get_serial(Object *obj, Visitor *v, const char *name,
+void *opaque, Error **errp)
+{
+visit_type_uint32(v, name, (uint32_t *)opaque, errp);
+}
+
+static void sifive_u_set_serial(Object *obj, Visitor *v, const char *name,
+void *opaque, Error **errp)
+{
+visit_type_uint32(v, name, (uint32_t *)opaque, errp);
+}
+
 static void riscv_sifive_u_machine_instance_init(Object *obj)
 {
 SiFiveUState *s = RISCV_U_MACHINE(obj);
@@ -424,6 +439,11 @@ static void riscv_sifive_u_machine_instance_init(Object 
*obj)
 "Set on to tell QEMU's ROM to jump to " \
 "flash. Otherwise QEMU will jump to DRAM",
 NULL);
+
+s->serial = OTP_SERIAL;
+object_property_add(obj, "serial", "uint32", sifive_u_get_serial,
+sifive_u_set_serial, NULL, >serial, NULL);
+object_property_set_description(obj, "serial", "Board serial number", 
NULL);
 }
 
 
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index a2baa1de5f..16c297ec5f 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -61,6 +61,7 @@ typedef struct SiFiveUState {
 int fdt_size;
 
 bool start_in_flash;
+uint32_t serial;
 } SiFiveUState;
 
 enum {
-- 
2.25.1




[PATCH v1 2/3] riscv/sifive_u: Add a serial property to the sifive_u SoC

2020-03-03 Thread Alistair Francis
At present the board serial number is hard-coded to 1, and passed
to OTP model during initialization. Firmware (FSBL, U-Boot) uses
the serial number to generate a unique MAC address for the on-chip
ethernet controller. When multiple QEMU 'sifive_u' instances are
created and connected to the same subnet, they all have the same
MAC address hence it creates a unusable network.

A new "serial" property is introduced to the sifive_u SoC to specify
the board serial number. When not given, the default serial number
1 is used.

Suggested-by: Bin Meng 
Signed-off-by: Alistair Francis 
---
 hw/riscv/sifive_u.c | 8 +++-
 include/hw/riscv/sifive_u.h | 2 ++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 9a0145b5b4..e52f9d0bd4 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -488,7 +488,7 @@ static void riscv_sifive_u_soc_init(Object *obj)
   TYPE_SIFIVE_U_PRCI);
 sysbus_init_child_obj(obj, "otp", >otp, sizeof(s->otp),
   TYPE_SIFIVE_U_OTP);
-qdev_prop_set_uint32(DEVICE(>otp), "serial", OTP_SERIAL);
+qdev_prop_set_uint32(DEVICE(>otp), "serial", s->serial);
 sysbus_init_child_obj(obj, "gem", >gem, sizeof(s->gem),
   TYPE_CADENCE_GEM);
 }
@@ -607,10 +607,16 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, 
Error **errp)
 memmap[SIFIVE_U_GEM_MGMT].base, memmap[SIFIVE_U_GEM_MGMT].size);
 }
 
+static Property riscv_sifive_u_soc_props[] = {
+DEFINE_PROP_UINT32("serial", SiFiveUSoCState, serial, OTP_SERIAL),
+DEFINE_PROP_END_OF_LIST()
+};
+
 static void riscv_sifive_u_soc_class_init(ObjectClass *oc, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(oc);
 
+device_class_set_props(dc, riscv_sifive_u_soc_props);
 dc->realize = riscv_sifive_u_soc_realize;
 /* Reason: Uses serial_hds in realize function, thus can't be used twice */
 dc->user_creatable = false;
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 82667b5746..a2baa1de5f 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -42,6 +42,8 @@ typedef struct SiFiveUSoCState {
 SiFiveUPRCIState prci;
 SiFiveUOTPState otp;
 CadenceGEMState gem;
+
+uint32_t serial;
 } SiFiveUSoCState;
 
 #define TYPE_RISCV_U_MACHINE MACHINE_TYPE_NAME("sifive_u")
-- 
2.25.1




[PATCH v1 1/3] riscv/sifive_u: Fix up file ordering

2020-03-03 Thread Alistair Francis
Split the file into clear machine and SoC sections.

Signed-off-by: Alistair Francis 
---
 hw/riscv/sifive_u.c | 107 ++--
 1 file changed, 54 insertions(+), 53 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 156a003642..9a0145b5b4 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -399,6 +399,60 @@ static void riscv_sifive_u_init(MachineState *machine)
   _space_memory);
 }
 
+static bool sifive_u_get_start_in_flash(Object *obj, Error **errp)
+{
+SiFiveUState *s = RISCV_U_MACHINE(obj);
+
+return s->start_in_flash;
+}
+
+static void sifive_u_set_start_in_flash(Object *obj, bool value, Error **errp)
+{
+SiFiveUState *s = RISCV_U_MACHINE(obj);
+
+s->start_in_flash = value;
+}
+
+static void riscv_sifive_u_machine_instance_init(Object *obj)
+{
+SiFiveUState *s = RISCV_U_MACHINE(obj);
+
+s->start_in_flash = false;
+object_property_add_bool(obj, "start-in-flash", 
sifive_u_get_start_in_flash,
+ sifive_u_set_start_in_flash, NULL);
+object_property_set_description(obj, "start-in-flash",
+"Set on to tell QEMU's ROM to jump to " \
+"flash. Otherwise QEMU will jump to DRAM",
+NULL);
+}
+
+
+static void riscv_sifive_u_machine_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+
+mc->desc = "RISC-V Board compatible with SiFive U SDK";
+mc->init = riscv_sifive_u_init;
+mc->max_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + SIFIVE_U_COMPUTE_CPU_COUNT;
+mc->min_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 1;
+mc->default_cpus = mc->min_cpus;
+}
+
+static const TypeInfo riscv_sifive_u_machine_typeinfo = {
+.name   = MACHINE_TYPE_NAME("sifive_u"),
+.parent = TYPE_MACHINE,
+.class_init = riscv_sifive_u_machine_class_init,
+.instance_init = riscv_sifive_u_machine_instance_init,
+.instance_size = sizeof(SiFiveUState),
+};
+
+static void riscv_sifive_u_machine_init_register_types(void)
+{
+type_register_static(_sifive_u_machine_typeinfo);
+}
+
+type_init(riscv_sifive_u_machine_init_register_types)
+
 static void riscv_sifive_u_soc_init(Object *obj)
 {
 MachineState *ms = MACHINE(qdev_get_machine());
@@ -439,33 +493,6 @@ static void riscv_sifive_u_soc_init(Object *obj)
   TYPE_CADENCE_GEM);
 }
 
-static bool sifive_u_get_start_in_flash(Object *obj, Error **errp)
-{
-SiFiveUState *s = RISCV_U_MACHINE(obj);
-
-return s->start_in_flash;
-}
-
-static void sifive_u_set_start_in_flash(Object *obj, bool value, Error **errp)
-{
-SiFiveUState *s = RISCV_U_MACHINE(obj);
-
-s->start_in_flash = value;
-}
-
-static void riscv_sifive_u_machine_instance_init(Object *obj)
-{
-SiFiveUState *s = RISCV_U_MACHINE(obj);
-
-s->start_in_flash = false;
-object_property_add_bool(obj, "start-in-flash", 
sifive_u_get_start_in_flash,
- sifive_u_set_start_in_flash, NULL);
-object_property_set_description(obj, "start-in-flash",
-"Set on to tell QEMU's ROM to jump to " \
-"flash. Otherwise QEMU will jump to DRAM",
-NULL);
-}
-
 static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
 {
 MachineState *ms = MACHINE(qdev_get_machine());
@@ -603,29 +630,3 @@ static void riscv_sifive_u_soc_register_types(void)
 }
 
 type_init(riscv_sifive_u_soc_register_types)
-
-static void riscv_sifive_u_machine_class_init(ObjectClass *oc, void *data)
-{
-MachineClass *mc = MACHINE_CLASS(oc);
-
-mc->desc = "RISC-V Board compatible with SiFive U SDK";
-mc->init = riscv_sifive_u_init;
-mc->max_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + SIFIVE_U_COMPUTE_CPU_COUNT;
-mc->min_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 1;
-mc->default_cpus = mc->min_cpus;
-}
-
-static const TypeInfo riscv_sifive_u_machine_typeinfo = {
-.name   = MACHINE_TYPE_NAME("sifive_u"),
-.parent = TYPE_MACHINE,
-.class_init = riscv_sifive_u_machine_class_init,
-.instance_init = riscv_sifive_u_machine_instance_init,
-.instance_size = sizeof(SiFiveUState),
-};
-
-static void riscv_sifive_u_machine_init_register_types(void)
-{
-type_register_static(_sifive_u_machine_typeinfo);
-}
-
-type_init(riscv_sifive_u_machine_init_register_types)
-- 
2.25.1




[PATCH v1 0/3] hw/riscv: Add a serial property to the sifive_u machine

2020-03-03 Thread Alistair Francis
At present the board serial number is hard-coded to 1, and passed
to OTP model during initialization. Firmware (FSBL, U-Boot) uses
the serial number to generate a unique MAC address for the on-chip
ethernet controller. When multiple QEMU 'sifive_u' instances are
created and connected to the same subnet, they all have the same
MAC address hence it creates a unusable network.

A new "serial" property is introduced to specify the board serial
number. When not given, the default serial number 1 is used.

Alistair Francis (2):
  riscv/sifive_u: Fix up file ordering
  riscv/sifive_u: Add a serial property to the sifive_u SoC

Bin Meng (1):
  riscv/sifive_u: Add a serial property to the sifive_u machine

 hw/riscv/sifive_u.c | 135 +---
 include/hw/riscv/sifive_u.h |   3 +
 2 files changed, 84 insertions(+), 54 deletions(-)

-- 
2.25.1




[PATCH v1 1/1] target/riscv: Don't set write permissions on dirty PTEs

2020-03-03 Thread Alistair Francis
The RISC-V spec specifies that when a write happens and the D bit is
clear the implementation will set the bit in the PTE. It does not
describe that the PTE being dirty means that we should provide write
access. This patch removes the write access granted to pages when the
dirty bit is set.

Following the prot variable we can see that it affects all of these
functions:
 riscv_cpu_tlb_fill()
   tlb_set_page()
 tlb_set_page_with_attrs()
   address_space_translate_for_iotlb()

Looking at the cputlb code (tlb_set_page_with_attrs() and
address_space_translate_for_iotlb()) it looks like the main affect of
setting write permissions is that the page can be marked as TLB_NOTDIRTY.

I don't see any other impacts (related to the dirty bit) for giving a
page write permissions.

Setting write permission on dirty PTEs results in userspace inside a
Hypervisor guest (VU) becoming corrupted. This appears to be because it
ends up with write permission in the second stage translation in cases
where we aren't doing a store.

Signed-off-by: Alistair Francis 
Reviewed-by: Bin Meng 
---
 target/riscv/cpu_helper.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 5ea5d133aa..cc9f20b471 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -572,10 +572,8 @@ restart:
 if ((pte & PTE_X)) {
 *prot |= PAGE_EXEC;
 }
-/* add write permission on stores or if the page is already dirty,
-   so that we TLB miss on later writes to update the dirty bit */
-if ((pte & PTE_W) &&
-(access_type == MMU_DATA_STORE || (pte & PTE_D))) {
+/* add write permission on stores */
+if ((pte & PTE_W) && (access_type == MMU_DATA_STORE)) {
 *prot |= PAGE_WRITE;
 }
 return TRANSLATE_SUCCESS;
-- 
2.25.1




[PATCH 2/2] misc: Replace zero-length arrays with flexible array member (manual)

2020-03-03 Thread Philippe Mathieu-Daudé
Description copied from Linux kernel commit from Gustavo A. R. Silva
(see [3]):

--v-- description start --v--

  The current codebase makes use of the zero-length array language
  extension to the C90 standard, but the preferred mechanism to
  declare variable-length types such as these ones is a flexible
  array member [1], introduced in C99:

  struct foo {
  int stuff;
  struct boo array[];
  };

  By making use of the mechanism above, we will get a compiler
  warning in case the flexible array does not occur last in the
  structure, which will help us prevent some kind of undefined
  behavior bugs from being unadvertenly introduced [2] to the
  Linux codebase from now on.

--^-- description end --^--

Do the similar housekeeping in the QEMU codebase (which uses
C99 since commit 7be41675f7cb).

All these instances of code were found with the help of the
following command (then manual analysis):

  git grep -F '[0];'

[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=76497732932f
[3] 
https://git.kernel.org/pub/scm/linux/kernel/git/gustavoars/linux.git/commit/?id=17642a2fbd2c1

Inspired-by: Gustavo A. R. Silva 
Signed-off-by: Philippe Mathieu-Daudé 
---
 docs/interop/vhost-user.rst   | 4 ++--
 block/qed.h   | 2 +-
 include/hw/acpi/acpi-defs.h   | 4 ++--
 include/hw/boards.h   | 2 +-
 include/hw/s390x/event-facility.h | 2 +-
 include/hw/s390x/sclp.h   | 8 
 block/vmdk.c  | 2 +-
 hw/char/sclpconsole-lm.c  | 2 +-
 hw/char/sclpconsole.c | 2 +-
 hw/s390x/virtio-ccw.c | 2 +-
 target/s390x/ioinst.c | 2 +-
 11 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst
index 401652397c..3b1b6602c7 100644
--- a/docs/interop/vhost-user.rst
+++ b/docs/interop/vhost-user.rst
@@ -568,7 +568,7 @@ For split virtqueue, queue region can be implemented as:
   uint16_t used_idx;
 
   /* Used to track the state of each descriptor in descriptor table */
-  DescStateSplit desc[0];
+  DescStateSplit desc[];
   } QueueRegionSplit;
 
 To track inflight I/O, the queue region should be processed as follows:
@@ -690,7 +690,7 @@ For packed virtqueue, queue region can be implemented as:
   uint8_t padding[7];
 
   /* Used to track the state of each descriptor fetched from descriptor 
ring */
-  DescStatePacked desc[0];
+  DescStatePacked desc[];
   } QueueRegionPacked;
 
 To track inflight I/O, the queue region should be processed as follows:
diff --git a/block/qed.h b/block/qed.h
index 42c115d822..87428ba00e 100644
--- a/block/qed.h
+++ b/block/qed.h
@@ -103,7 +103,7 @@ typedef struct {
 } QEMU_PACKED QEDHeader;
 
 typedef struct {
-uint64_t offsets[0];/* in bytes */
+uint64_t offsets[]; /* in bytes */
 } QEDTable;
 
 /* The L2 cache is a simple write-through cache for L2 structures */
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index 19f7ba7b70..c13327fa78 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -152,7 +152,7 @@ typedef struct AcpiSerialPortConsoleRedirection
  */
 struct AcpiRsdtDescriptorRev1 {
 ACPI_TABLE_HEADER_DEF   /* ACPI common table header */
-uint32_t table_offset_entry[0];  /* Array of pointers to other */
+uint32_t table_offset_entry[];  /* Array of pointers to other */
 /* ACPI tables */
 } QEMU_PACKED;
 typedef struct AcpiRsdtDescriptorRev1 AcpiRsdtDescriptorRev1;
@@ -162,7 +162,7 @@ typedef struct AcpiRsdtDescriptorRev1 
AcpiRsdtDescriptorRev1;
  */
 struct AcpiXsdtDescriptorRev2 {
 ACPI_TABLE_HEADER_DEF   /* ACPI common table header */
-uint64_t table_offset_entry[0];  /* Array of pointers to other */
+uint64_t table_offset_entry[];  /* Array of pointers to other */
 /* ACPI tables */
 } QEMU_PACKED;
 typedef struct AcpiXsdtDescriptorRev2 AcpiXsdtDescriptorRev2;
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 9bc42dfb22..c96120d15f 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -71,7 +71,7 @@ typedef struct CPUArchId {
  */
 typedef struct {
 int len;
-CPUArchId cpus[0];
+CPUArchId cpus[];
 } CPUArchIdList;
 
 /**
diff --git a/include/hw/s390x/event-facility.h 
b/include/hw/s390x/event-facility.h
index bdc32a3c09..700a610f33 100644
--- a/include/hw/s390x/event-facility.h
+++ b/include/hw/s390x/event-facility.h
@@ -122,7 +122,7 @@ typedef struct MDBO {
 
 typedef struct MDB {
 MdbHeader header;
-MDBO mdbo[0];
+MDBO mdbo[];
 } QEMU_PACKED MDB;
 
 typedef struct SclpMsg {
diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h
index c54413b78c..cd7b24359f 100644
--- a/include/hw/s390x/sclp.h
+++ b/include/hw/s390x/sclp.h
@@ -132,7 +132,7 @@ typedef struct ReadInfo {
 uint16_t highest_cpu;
 uint8_t  _reserved5[124 

Re: [PATCH] hw/ide: Remove status register read side effect

2020-03-03 Thread jasper.lowell
I'm happy to do this. It will take a while for me to collect the
results though. I'll chime in once I have the results.

> That should give the ultimate answer to our guessing.
Agreed.

Thanks,
Jasper Lowell.

On Thu, 2020-02-27 at 12:38 +0100, BALATON Zoltan wrote:
> On Thu, 27 Feb 2020, jasper.low...@bt.com wrote:
> > I've since looked at a Ultra 5 board and can confirm that it
> > shipped
> > with a CMD646U chip like the Ultra 10.
> 
> If you have access to an Ultra 5 maybe you could try testing what it
> does 
> with irqs. That should give the ultimate answer to our guessing. It
> may 
> need patching a Linux driver to log more info and recompile the
> kernel so 
> not sure you have time for that but maybe it would help if you can do
> it.
> 
> Regards,
> BALATON Zoltan


Re: [PATCH] hw/ide: Remove status register read side effect

2020-03-03 Thread jasper.lowell
I haven't.

I did a pull this morning on master and everything seems to be working
again. The problem was likely the same.

Thanks,
Jasper Lowell.

On Thu, 2020-02-27 at 12:35 +0100, BALATON Zoltan wrote:
> On Thu, 27 Feb 2020, jasper.low...@bt.com wrote:
> > > I'll submit a RFC V2 patch with a proposed fix.
> > 
> > This will have to wait.
> > 
> > Recent commits have caused Solaris 10 to error out of booting much
> > earlier than previously.
> 
> Can you bisect which commit broke it? Is it the same that caused
> slowness 
> for arm and ppc? For that one there are patches that should fix it on
> the 
> list.
> 
> Regards,
> BALATON Zoltan
> 


[PATCH v4 3/3] linux-user/riscv: Update the syscall_nr's to the 5.5 kernel

2020-03-03 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 linux-user/riscv/syscall32_nr.h | 295 +++
 linux-user/riscv/syscall64_nr.h | 301 
 linux-user/riscv/syscall_nr.h   | 294 +--
 3 files changed, 598 insertions(+), 292 deletions(-)
 create mode 100644 linux-user/riscv/syscall32_nr.h
 create mode 100644 linux-user/riscv/syscall64_nr.h

diff --git a/linux-user/riscv/syscall32_nr.h b/linux-user/riscv/syscall32_nr.h
new file mode 100644
index 00..4fef73e954
--- /dev/null
+++ b/linux-user/riscv/syscall32_nr.h
@@ -0,0 +1,295 @@
+/*
+ * This file contains the system call numbers.
+ */
+#ifndef LINUX_USER_RISCV_SYSCALL32_NR_H
+#define LINUX_USER_RISCV_SYSCALL32_NR_H
+
+#define TARGET_NR_io_setup 0
+#define TARGET_NR_io_destroy 1
+#define TARGET_NR_io_submit 2
+#define TARGET_NR_io_cancel 3
+#define TARGET_NR_setxattr 5
+#define TARGET_NR_lsetxattr 6
+#define TARGET_NR_fsetxattr 7
+#define TARGET_NR_getxattr 8
+#define TARGET_NR_lgetxattr 9
+#define TARGET_NR_fgetxattr 10
+#define TARGET_NR_listxattr 11
+#define TARGET_NR_llistxattr 12
+#define TARGET_NR_flistxattr 13
+#define TARGET_NR_removexattr 14
+#define TARGET_NR_lremovexattr 15
+#define TARGET_NR_fremovexattr 16
+#define TARGET_NR_getcwd 17
+#define TARGET_NR_lookup_dcookie 18
+#define TARGET_NR_eventfd2 19
+#define TARGET_NR_epoll_create1 20
+#define TARGET_NR_epoll_ctl 21
+#define TARGET_NR_epoll_pwait 22
+#define TARGET_NR_dup 23
+#define TARGET_NR_dup3 24
+#define TARGET_NR_fcntl64 25
+#define TARGET_NR_inotify_init1 26
+#define TARGET_NR_inotify_add_watch 27
+#define TARGET_NR_inotify_rm_watch 28
+#define TARGET_NR_ioctl 29
+#define TARGET_NR_ioprio_set 30
+#define TARGET_NR_ioprio_get 31
+#define TARGET_NR_flock 32
+#define TARGET_NR_mknodat 33
+#define TARGET_NR_mkdirat 34
+#define TARGET_NR_unlinkat 35
+#define TARGET_NR_symlinkat 36
+#define TARGET_NR_linkat 37
+#define TARGET_NR_umount2 39
+#define TARGET_NR_mount 40
+#define TARGET_NR_pivot_root 41
+#define TARGET_NR_nfsservctl 42
+#define TARGET_NR_statfs64 43
+#define TARGET_NR_fstatfs64 44
+#define TARGET_NR_truncate64 45
+#define TARGET_NR_ftruncate64 46
+#define TARGET_NR_fallocate 47
+#define TARGET_NR_faccessat 48
+#define TARGET_NR_chdir 49
+#define TARGET_NR_fchdir 50
+#define TARGET_NR_chroot 51
+#define TARGET_NR_fchmod 52
+#define TARGET_NR_fchmodat 53
+#define TARGET_NR_fchownat 54
+#define TARGET_NR_fchown 55
+#define TARGET_NR_openat 56
+#define TARGET_NR_close 57
+#define TARGET_NR_vhangup 58
+#define TARGET_NR_pipe2 59
+#define TARGET_NR_quotactl 60
+#define TARGET_NR_getdents64 61
+#define TARGET_NR_llseek 62
+#define TARGET_NR_read 63
+#define TARGET_NR_write 64
+#define TARGET_NR_readv 65
+#define TARGET_NR_writev 66
+#define TARGET_NR_pread64 67
+#define TARGET_NR_pwrite64 68
+#define TARGET_NR_preadv 69
+#define TARGET_NR_pwritev 70
+#define TARGET_NR_sendfile64 71
+#define TARGET_NR_signalfd4 74
+#define TARGET_NR_vmsplice 75
+#define TARGET_NR_splice 76
+#define TARGET_NR_tee 77
+#define TARGET_NR_readlinkat 78
+#define TARGET_NR_fstatat64 79
+#define TARGET_NR_fstat64 80
+#define TARGET_NR_sync 81
+#define TARGET_NR_fsync 82
+#define TARGET_NR_fdatasync 83
+#define TARGET_NR_sync_file_range 84
+#define TARGET_NR_timerfd_create 85
+#define TARGET_NR_acct 89
+#define TARGET_NR_capget 90
+#define TARGET_NR_capset 91
+#define TARGET_NR_personality 92
+#define TARGET_NR_exit 93
+#define TARGET_NR_exit_group 94
+#define TARGET_NR_waitid 95
+#define TARGET_NR_set_tid_address 96
+#define TARGET_NR_unshare 97
+#define TARGET_NR_set_robust_list 99
+#define TARGET_NR_get_robust_list 100
+#define TARGET_NR_getitimer 102
+#define TARGET_NR_setitimer 103
+#define TARGET_NR_kexec_load 104
+#define TARGET_NR_init_module 105
+#define TARGET_NR_delete_module 106
+#define TARGET_NR_timer_create 107
+#define TARGET_NR_timer_getoverrun 109
+#define TARGET_NR_timer_delete 111
+#define TARGET_NR_syslog 116
+#define TARGET_NR_ptrace 117
+#define TARGET_NR_sched_setparam 118
+#define TARGET_NR_sched_setscheduler 119
+#define TARGET_NR_sched_getscheduler 120
+#define TARGET_NR_sched_getparam 121
+#define TARGET_NR_sched_setaffinity 122
+#define TARGET_NR_sched_getaffinity 123
+#define TARGET_NR_sched_yield 124
+#define TARGET_NR_sched_get_priority_max 125
+#define TARGET_NR_sched_get_priority_min 126
+#define TARGET_NR_restart_syscall 128
+#define TARGET_NR_kill 129
+#define TARGET_NR_tkill 130
+#define TARGET_NR_tgkill 131
+#define TARGET_NR_sigaltstack 132
+#define TARGET_NR_rt_sigsuspend 133
+#define TARGET_NR_rt_sigaction 134
+#define TARGET_NR_rt_sigprocmask 135
+#define TARGET_NR_rt_sigpending 136
+#define TARGET_NR_rt_sigqueueinfo 138
+#define TARGET_NR_rt_sigreturn 139
+#define TARGET_NR_setpriority 140
+#define TARGET_NR_getpriority 141
+#define TARGET_NR_reboot 142
+#define TARGET_NR_setregid 143
+#define TARGET_NR_setgid 144
+#define TARGET_NR_setreuid 145
+#define TARGET_NR_setuid 146
+#define 

[PATCH v4 1/3] linux-user: Protect more syscalls

2020-03-03 Thread Alistair Francis
New y2038 safe 32-bit architectures (like RISC-V) don't support old
syscalls with a 32-bit time_t. The kernel defines new *_time64 versions
of these syscalls. Add some more #ifdefs to syscall.c in linux-user to
allow us to compile without these old syscalls.

Signed-off-by: Alistair Francis 
---
 linux-user/strace.c  |  2 ++
 linux-user/syscall.c | 77 ++--
 2 files changed, 76 insertions(+), 3 deletions(-)

diff --git a/linux-user/strace.c b/linux-user/strace.c
index 4f7130b2ff..6420ccd97b 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -775,6 +775,7 @@ print_syscall_ret_newselect(const struct syscallname *name, 
abi_long ret)
 #define TARGET_TIME_OOP  3   /* leap second in progress */
 #define TARGET_TIME_WAIT 4   /* leap second has occurred */
 #define TARGET_TIME_ERROR5   /* clock not synchronized */
+#ifdef TARGET_NR_adjtimex
 static void
 print_syscall_ret_adjtimex(const struct syscallname *name, abi_long ret)
 {
@@ -813,6 +814,7 @@ print_syscall_ret_adjtimex(const struct syscallname *name, 
abi_long ret)
 
 qemu_log("\n");
 }
+#endif
 
 UNUSED static struct flags access_flags[] = {
 FLAG_GENERIC(F_OK),
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 8d27d10807..c000fb07c5 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -245,7 +245,11 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 
arg4,type5 arg5,  \
 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
 #define __NR_sys_rt_tgsigqueueinfo __NR_rt_tgsigqueueinfo
 #define __NR_sys_syslog __NR_syslog
-#define __NR_sys_futex __NR_futex
+#ifdef __NR_futex
+# define __NR_sys_futex __NR_futex
+#elif defined(__NR_futex_time64)
+# define __NR_sys_futex __NR_futex_time64
+#endif
 #define __NR_sys_inotify_init __NR_inotify_init
 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
@@ -295,7 +299,9 @@ _syscall1(int,exit_group,int,error_code)
 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
 _syscall1(int,set_tid_address,int *,tidptr)
 #endif
-#if defined(TARGET_NR_futex) && defined(__NR_futex)
+#if ((defined(TARGET_NR_futex) || defined(TARGET_NR_futex_time64)) && \
+ defined(__NR_futex)) || \
+(defined(TARGET_NR_futex_time64) && defined(__NR_futex_time64))
 _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
   const struct timespec *,timeout,int *,uaddr2,int,val3)
 #endif
@@ -742,21 +748,30 @@ safe_syscall3(ssize_t, read, int, fd, void *, buff, 
size_t, count)
 safe_syscall3(ssize_t, write, int, fd, const void *, buff, size_t, count)
 safe_syscall4(int, openat, int, dirfd, const char *, pathname, \
   int, flags, mode_t, mode)
+#if defined(TARGET_NR_wait4) || defined(TARGET_NR_waitpid)
 safe_syscall4(pid_t, wait4, pid_t, pid, int *, status, int, options, \
   struct rusage *, rusage)
+#endif
 safe_syscall5(int, waitid, idtype_t, idtype, id_t, id, siginfo_t *, infop, \
   int, options, struct rusage *, rusage)
 safe_syscall3(int, execve, const char *, filename, char **, argv, char **, 
envp)
+#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) || \
+defined(TARGET_NR_pselect6)
 safe_syscall6(int, pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds, 
\
   fd_set *, exceptfds, struct timespec *, timeout, void *, sig)
+#endif
+#if defined(TARGET_NR_ppoll) || defined(TARGET_NR_poll)
 safe_syscall5(int, ppoll, struct pollfd *, ufds, unsigned int, nfds,
   struct timespec *, tsp, const sigset_t *, sigmask,
   size_t, sigsetsize)
+#endif
 safe_syscall6(int, epoll_pwait, int, epfd, struct epoll_event *, events,
   int, maxevents, int, timeout, const sigset_t *, sigmask,
   size_t, sigsetsize)
+#ifdef TARGET_NR_futex
 safe_syscall6(int,futex,int *,uaddr,int,op,int,val, \
   const struct timespec *,timeout,int *,uaddr2,int,val3)
+#endif
 safe_syscall2(int, rt_sigsuspend, sigset_t *, newset, size_t, sigsetsize)
 safe_syscall2(int, kill, pid_t, pid, int, sig)
 safe_syscall2(int, tkill, int, tid, int, sig)
@@ -776,12 +791,16 @@ safe_syscall6(ssize_t, recvfrom, int, fd, void *, buf, 
size_t, len,
 safe_syscall3(ssize_t, sendmsg, int, fd, const struct msghdr *, msg, int, 
flags)
 safe_syscall3(ssize_t, recvmsg, int, fd, struct msghdr *, msg, int, flags)
 safe_syscall2(int, flock, int, fd, int, operation)
+#ifdef TARGET_NR_rt_sigtimedwait
 safe_syscall4(int, rt_sigtimedwait, const sigset_t *, these, siginfo_t *, 
uinfo,
   const struct timespec *, uts, size_t, sigsetsize)
+#endif
 safe_syscall4(int, accept4, int, fd, struct sockaddr *, addr, socklen_t *, len,
   int, flags)
+#if defined(TARGET_NR_nanosleep)
 safe_syscall2(int, nanosleep, const struct timespec *, req,
   struct timespec *, rem)
+#endif
 #ifdef TARGET_NR_clock_nanosleep
 safe_syscall4(int, clock_nanosleep, const clockid_t, 

[PATCH v4 2/3] linux-user/syscall: Add support for clock_gettime64/clock_settime64

2020-03-03 Thread Alistair Francis
Add support for the clock_gettime64/clock_settime64 syscalls. Currently
we only support these syscalls when running on 64-bit hosts.

Signed-off-by: Alistair Francis 
---
 linux-user/syscall.c | 43 +++
 1 file changed, 43 insertions(+)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index c000fb07c5..82468e018d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1236,6 +1236,22 @@ static inline abi_long target_to_host_timespec(struct 
timespec *host_ts,
 }
 #endif
 
+#if defined(TARGET_NR_clock_settime64) && HOST_LONG_BITS == 64
+static inline abi_long target_to_host_timespec64(struct timespec *host_ts,
+ abi_ulong target_addr)
+{
+struct target_timespec *target_ts;
+
+if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1)) {
+return -TARGET_EFAULT;
+}
+__get_user(host_ts->tv_sec, _ts->tv_sec);
+__get_user(host_ts->tv_nsec, _ts->tv_nsec);
+unlock_user_struct(target_ts, target_addr, 0);
+return 0;
+}
+#endif
+
 static inline abi_long host_to_target_timespec(abi_ulong target_addr,
struct timespec *host_ts)
 {
@@ -11465,6 +11481,20 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 return ret;
 }
 #endif
+#ifdef TARGET_NR_clock_settime64
+# if HOST_LONG_BITS == 64
+case TARGET_NR_clock_settime64:
+{
+struct timespec ts;
+
+ret = target_to_host_timespec64(, arg2);
+if (!is_error(ret)) {
+ret = get_errno(clock_settime(arg1, ));
+}
+return ret;
+}
+# endif
+#endif
 #ifdef TARGET_NR_clock_gettime
 case TARGET_NR_clock_gettime:
 {
@@ -11476,6 +11506,19 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 return ret;
 }
 #endif
+#ifdef TARGET_NR_clock_gettime64
+# if HOST_LONG_BITS == 64
+case TARGET_NR_clock_gettime64:
+{
+struct timespec ts;
+ret = get_errno(clock_gettime(arg1, ));
+if (!is_error(ret)) {
+ret = host_to_target_timespec64(arg2, );
+}
+return ret;
+}
+# endif
+#endif
 #ifdef TARGET_NR_clock_getres
 case TARGET_NR_clock_getres:
 {
-- 
2.25.1




[PATCH 1/2] misc: Replace zero-length arrays with flexible array member (automatic)

2020-03-03 Thread Philippe Mathieu-Daudé
Description copied from Linux kernel commit from Gustavo A. R. Silva
(see [3]):

--v-- description start --v--

  The current codebase makes use of the zero-length array language
  extension to the C90 standard, but the preferred mechanism to
  declare variable-length types such as these ones is a flexible
  array member [1], introduced in C99:

  struct foo {
  int stuff;
  struct boo array[];
  };

  By making use of the mechanism above, we will get a compiler
  warning in case the flexible array does not occur last in the
  structure, which will help us prevent some kind of undefined
  behavior bugs from being unadvertenly introduced [2] to the
  Linux codebase from now on.

--^-- description end --^--

Do the similar housekeeping in the QEMU codebase (which uses
C99 since commit 7be41675f7cb).

All these instances of code were found with the help of the
following Coccinelle script:

  @@
  identifier s, a;
  type T;
  @@
   struct s {
  ...
  -   T a[0];
  +   T a[];
  };
  @@
  identifier s, a;
  type T;
  @@
   struct s {
  ...
  -   T a[0];
  +   T a[];
   } QEMU_PACKED;

[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=76497732932f
[3] 
https://git.kernel.org/pub/scm/linux/kernel/git/gustavoars/linux.git/commit/?id=17642a2fbd2c1

Inspired-by: Gustavo A. R. Silva 
Signed-off-by: Philippe Mathieu-Daudé 
---
 bsd-user/qemu.h   |  2 +-
 contrib/libvhost-user/libvhost-user.h |  2 +-
 hw/m68k/bootinfo.h|  2 +-
 hw/scsi/srp.h |  6 +++---
 hw/xen/xen_pt.h   |  2 +-
 include/hw/acpi/acpi-defs.h   | 12 ++--
 include/hw/arm/smmu-common.h  |  2 +-
 include/hw/i386/intel_iommu.h |  3 ++-
 include/hw/virtio/virtio-iommu.h  |  2 +-
 include/sysemu/cryptodev.h|  2 +-
 include/tcg/tcg.h |  2 +-
 pc-bios/s390-ccw/bootmap.h|  2 +-
 pc-bios/s390-ccw/sclp.h   |  2 +-
 tests/qtest/libqos/ahci.h |  2 +-
 block/linux-aio.c |  2 +-
 hw/acpi/nvdimm.c  |  6 +++---
 hw/dma/soc_dma.c  |  2 +-
 hw/i386/x86.c |  2 +-
 hw/misc/omap_l4.c |  2 +-
 hw/nvram/eeprom93xx.c |  2 +-
 hw/rdma/vmw/pvrdma_qp_ops.c   |  4 ++--
 hw/usb/dev-network.c  |  2 +-
 hw/usb/dev-smartcard-reader.c |  4 ++--
 hw/virtio/virtio.c|  4 ++--
 net/queue.c   |  2 +-
 25 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 09e8aed9c7..f8bb1e5459 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -95,7 +95,7 @@ typedef struct TaskState {
 struct sigqueue *first_free; /* first free siginfo queue entry */
 int signal_pending; /* non zero if a signal may be pending */
 
-uint8_t stack[0];
+uint8_t stack[];
 } __attribute__((aligned(16))) TaskState;
 
 void init_task_state(TaskState *ts);
diff --git a/contrib/libvhost-user/libvhost-user.h 
b/contrib/libvhost-user/libvhost-user.h
index 6fc8000e99..f30394fab6 100644
--- a/contrib/libvhost-user/libvhost-user.h
+++ b/contrib/libvhost-user/libvhost-user.h
@@ -286,7 +286,7 @@ typedef struct VuVirtqInflight {
 uint16_t used_idx;
 
 /* Used to track the state of each descriptor in descriptor table */
-VuDescStateSplit desc[0];
+VuDescStateSplit desc[];
 } VuVirtqInflight;
 
 typedef struct VuVirtqInflightDesc {
diff --git a/hw/m68k/bootinfo.h b/hw/m68k/bootinfo.h
index 5f8ded2686..c954270aad 100644
--- a/hw/m68k/bootinfo.h
+++ b/hw/m68k/bootinfo.h
@@ -14,7 +14,7 @@
 struct bi_record {
 uint16_t tag;/* tag ID */
 uint16_t size;   /* size of record */
-uint32_t data[0];/* data */
+uint32_t data[]; /* data */
 };
 
 /* machine independent tags */
diff --git a/hw/scsi/srp.h b/hw/scsi/srp.h
index d27f31d2d5..54c954badd 100644
--- a/hw/scsi/srp.h
+++ b/hw/scsi/srp.h
@@ -112,7 +112,7 @@ struct srp_direct_buf {
 struct srp_indirect_buf {
 struct srp_direct_buftable_desc;
 uint32_t len;
-struct srp_direct_bufdesc_list[0];
+struct srp_direct_bufdesc_list[];
 } QEMU_PACKED;
 
 enum {
@@ -211,7 +211,7 @@ struct srp_cmd {
 uint8_treserved4;
 uint8_tadd_cdb_len;
 uint8_tcdb[16];
-uint8_tadd_data[0];
+uint8_tadd_data[];
 } QEMU_PACKED;
 
 enum {
@@ -241,7 +241,7 @@ struct srp_rsp {
 uint32_t   data_in_res_cnt;
 uint32_t   sense_data_len;
 uint32_t   resp_data_len;
-uint8_tdata[0];
+uint8_tdata[];
 } QEMU_PACKED;
 
 #endif /* SCSI_SRP_H */
diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index 9167bbaf6d..179775db7b 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -203,7 +203,7 @@ typedef struct XenPTMSIX {
 uint64_t 

[PATCH v4 0/3] linux-user: generate syscall_nr.sh for RISC-V

2020-03-03 Thread Alistair Francis
This series updates the RISC-V syscall_nr.sh based on the 5.5 kernel.

There are two parts to this. One is just adding the new syscalls, the
other part is updating the RV32 syscalls to match the fact that RV32 is
a 64-bit time_t architectures (y2038) safe.

We need to make some changes to syscall.c to avoid warnings/errors
during compliling with the new syscall.

I did some RV32 user space testing after applying these patches. I ran the
glibc testsuite in userspace and I don't see any regressions.

Alistair Francis (3):
  linux-user: Protect more syscalls
  linux-user/syscall: Add support for clock_gettime64/clock_settime64
  linux-user/riscv: Update the syscall_nr's to the 5.5 kernel

 linux-user/riscv/syscall32_nr.h | 295 +++
 linux-user/riscv/syscall64_nr.h | 301 
 linux-user/riscv/syscall_nr.h   | 294 +--
 linux-user/strace.c |   2 +
 linux-user/syscall.c| 120 -
 5 files changed, 717 insertions(+), 295 deletions(-)
 create mode 100644 linux-user/riscv/syscall32_nr.h
 create mode 100644 linux-user/riscv/syscall64_nr.h

-- 
2.25.1




[PATCH 0/2] misc: Replace zero-length arrays with flexible array member

2020-03-03 Thread Philippe Mathieu-Daudé
This is a tree-wide cleanup inspired by a Linux kernel commit
(from Gustavo A. R. Silva).

--v-- description start --v--

  The current codebase makes use of the zero-length array language
  extension to the C90 standard, but the preferred mechanism to
  declare variable-length types such as these ones is a flexible
  array member [1], introduced in C99:

  struct foo {
  int stuff;
  struct boo array[];
  };

  By making use of the mechanism above, we will get a compiler
  warning in case the flexible array does not occur last in the
  structure, which will help us prevent some kind of undefined
  behavior bugs from being unadvertenly introduced [2] to the
  Linux codebase from now on.

--^-- description end --^--

Do the similar housekeeping in the QEMU codebase (which uses
C99 since commit 7be41675f7cb).

The first patch is done with the help of a coccinelle semantic
patch. However Coccinelle does not recognize:

  struct foo {
  int stuff;
  struct boo array[];
  } QEMU_PACKED;

but does recognize:

  struct QEMU_PACKED foo {
  int stuff;
  struct boo array[];
  };

I'm not sure why, neither it is worth refactoring all QEMU
structures to use the attributes before the structure name,
so I did the 2nd patch manually.

Anyway this is annoying, because many structures are not handled
by coccinelle. Maybe this needs to be reported to upstream
coccinelle?

I used spatch 1.0.8 with:

  -I include --include-headers \
  --macro-file scripts/cocci-macro-file.h \
  --keep-comments --indent 4

Regards,

Phil.

Philippe Mathieu-Daudé (2):
  misc: Replace zero-length arrays with flexible array member
(automatic)
  misc: Replace zero-length arrays with flexible array member (manual)

 docs/interop/vhost-user.rst   |  4 ++--
 block/qed.h   |  2 +-
 bsd-user/qemu.h   |  2 +-
 contrib/libvhost-user/libvhost-user.h |  2 +-
 hw/m68k/bootinfo.h|  2 +-
 hw/scsi/srp.h |  6 +++---
 hw/xen/xen_pt.h   |  2 +-
 include/hw/acpi/acpi-defs.h   | 16 
 include/hw/arm/smmu-common.h  |  2 +-
 include/hw/boards.h   |  2 +-
 include/hw/i386/intel_iommu.h |  3 ++-
 include/hw/s390x/event-facility.h |  2 +-
 include/hw/s390x/sclp.h   |  8 
 include/hw/virtio/virtio-iommu.h  |  2 +-
 include/sysemu/cryptodev.h|  2 +-
 include/tcg/tcg.h |  2 +-
 pc-bios/s390-ccw/bootmap.h|  2 +-
 pc-bios/s390-ccw/sclp.h   |  2 +-
 tests/qtest/libqos/ahci.h |  2 +-
 block/linux-aio.c |  2 +-
 block/vmdk.c  |  2 +-
 hw/acpi/nvdimm.c  |  6 +++---
 hw/char/sclpconsole-lm.c  |  2 +-
 hw/char/sclpconsole.c |  2 +-
 hw/dma/soc_dma.c  |  2 +-
 hw/i386/x86.c |  2 +-
 hw/misc/omap_l4.c |  2 +-
 hw/nvram/eeprom93xx.c |  2 +-
 hw/rdma/vmw/pvrdma_qp_ops.c   |  4 ++--
 hw/s390x/virtio-ccw.c |  2 +-
 hw/usb/dev-network.c  |  2 +-
 hw/usb/dev-smartcard-reader.c |  4 ++--
 hw/virtio/virtio.c|  4 ++--
 net/queue.c   |  2 +-
 target/s390x/ioinst.c |  2 +-
 35 files changed, 54 insertions(+), 53 deletions(-)

-- 
2.21.1




Re: [PATCH 2/2] via-ide: Also emulate non 100% native mode

2020-03-03 Thread BALATON Zoltan

On Tue, 3 Mar 2020, Mark Cave-Ayland wrote:

On 02/03/2020 21:40, BALATON Zoltan wrote:

I had a quick look at the schematics linked from the page above, and they 
confirm
that the VIA IDE interface is connected directly to IRQs 14 and 15 and not to 
the PCI
interrupt pins.


Where did you see that? What I got from trying to look this up in the 
schematics was
that VT8231 has two pins named IRQ14 and IRQ15 (but described as Primary and
Secondary Channel Interrupt Request in doc) where the interrupt lines of the 
two IDE
ports/channels are connected but how they are routed within the chip after that 
was
not clear. The chip doc says that in native mode the interrupt should be 
configurable
and use a single interrupt for both channels and in legacy mode they use the 
usual 14
and 15 but this is not what guest drivers expect so I think not how really 
works on
PegasosII. It is true however that connection to PCI interrupts aren't 
mentioned so
it always uses ISA IRQ numbers, it just depends on legacy vs. native mode which 
line
is raised. But that was never really a question for VT8231 and maybe only CMD646
could have such interconnection with PCI interrupts. (Proabable reason is that
via-ide is part of a southbridge chip where it has connections to ISA bus while
CMD646 is a PCI IDE controller but I could be wrong as my knowledge is limited 
about
these.)


Presumably the VIA southbridge has its own internal pair of cascaded 8259s so 
the IRQ
line from the drive is connected to IRQ14/15 as per an typical ISA PC. You can 
see
this in the "Common Hardware Reference Platform: I/O Device Reference" PDF 
section 4.1.


Yes the VIA southbridge chip integrates all usual PC devices including 
PICs so these may have connection internally. I haven't checked these docs 
before but now I think another chapter in the doc you referenced and its 
companion "Common Hardware Reference Platform: A System Architecture" may 
explain the unusal combination of PCI like io regs with legacy interrupts 
the Pegasos2 seems to have. In the I/O Device Reference, chapter 11 about 
IDE says that the device must be addressed only with PCI I/O addresses 
where io addresses are completely relocatable and that when OpenFirmware 
passes control to the OS IDE must be configured as a PCI device. So this 
probably means io addresses coming from PCI BARs. But the CHRP System 
Architecture, chapter 9.2 about ISA devices says that "ISA devices 
included in a PCI part must route their interrupt signals to the legacy 
interrupt controller" and this is what the Pegasos2 seems to do. This may 
be a misinterpretation of the spec because elsewhere (I've lost the exact 
reference and have no time to find it again) it also says something about 
native devices must be using OpenPIC but Pegasos2 does not have OpenPIC so 
that part surely cannot apply anyway.



So on that basis the best explanation as to what is happening is the
comment in the link you provided here:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/powerpc/platforms/chrp/pci.c?h=v4.14.172#n353


/* Pegasos2 firmware version 20040810 configures the built-in IDE controller
* in legacy mode, but sets the PCI registers to PCI native mode.
* The chip can only operate in legacy mode, so force the PCI class into legacy
* mode as well. The same fixup must be done to the class-code property in
* the IDE node /pci@8000/ide@C,1
*/


I'm not sure that it makes much sense that the firmware configures the chip one 
way
then puts info about a different way in the device tree. There could be bugs 
but this
is not likely. Especially because I see in traces that the firmware does try to
configure the device in native mode. These are the first few accesses of the 
firmware
to via-ide:


But that is exactly what is happening! The comment above clearly indicates the
firmware incorrectly sets the IDE controller in native mode which is in exact
agreement with the trace you provide below. And in fact if you look at


I may be reading the comment wrong but to me that says that "firmware 
configures IDE in _legacy_ mode" whereas the trace shows it actually 
configures it in _native_ mode which is complying to the CHRP doc above. 
But since it cannot comply to the "native devices using OpenPIC" part it 
probably tries to apply the "ISA devices embedded in PCI" part and locks 
IRQ to 14 and 15. Or it just wants to avoid sharing IRQs as much as 
possible and the designers decided they will use IRQ14 and 15 for IDE.



https://www.powerdeveloper.org/platforms/pegasos/devicetree you can see the 
nvramrc
hack that was released in order to fix the device tree to boot Linux which 
alters the
class-code and sets interrupts to 14 (which I believe is invalid, but seemingly 
good
enough here).


Isn't this the same fixup that newer Linux kernels already include? Maybe 
this was needed before Linux properly supported Pegasos2 but later kernels 
will do this anyway. This does not give us any new info 

Re: [PATCH] cpu: Use DeviceClass reset instead of a special CPUClass reset

2020-03-03 Thread Philippe Mathieu-Daudé

On 3/3/20 7:36 PM, Peter Maydell wrote:

On Tue, 3 Mar 2020 at 18:33, Philippe Mathieu-Daudé  wrote:

Nitpick: you don't need to include the bracket symbol in the diff:

@@
-resetfn(CPUState *cpu)
+resetfn(DeviceState *dev)
 {

(simply indent it with a space).


I think this was probably leftover from trying to get Coccinelle
to not rewrap the '{' onto the previous line, before I found
--smpl-spacing.

In general I don't find it terribly useful to spend a great
deal of time streamlining Coccinelle scripts -- I think they
are basically one-shot uses almost all of the time, so once
they're producing the right changes I prefer to move on.


I agree in this case it is not useful to add the script to the 
repository as a file, because the cleanup is done (as you said, 
'one-shot script'). The script is however valuable as in the commit 
description.


Cleaning it up is not for performance, but as the script is buried into 
the git repository, it can (and will) be used as reference/example by 
other developers.


Anyway this patch is queued now, so let's move on :)




Re: [PATCH v6 7/9] iotests: ignore import warnings from pylint

2020-03-03 Thread Philippe Mathieu-Daudé

On 3/3/20 8:57 PM, John Snow wrote:

On 2/27/20 9:14 AM, Philippe Mathieu-Daudé wrote:

On 2/27/20 1:06 AM, John Snow wrote:

The right way to solve this is to come up with a virtual environment
infrastructure that sets all the paths correctly, and/or to create
installable python modules that can be imported normally.

That's hard, so just silence this error for now.


I'm tempted to NAck this and require an "installable python module"...

Let's discuss why it is that hard!



I've been tricked into this before. It's not work I am interested in
doing right now; it's WAY beyond the scope of what I am doing here.

It involves properly factoring all of our python code, deciding which
portions are meant to be installed separately from QEMU itself, coming
up with a versioning scheme, packaging code, and moving code around in
many places.

Then it involves coming up with tooling and infrastructure for creating
virtual environments, installing the right packages to it, and using it
to run our python tests.

No, that's way too invasive. I'm not doing it and I will scream loudly
if you make me.

A less invasive hack involves setting the python import path in a
consolidated spot so that python knows where it can import from. This
works, but might break the ability to run such tests as one-offs without
executing the environment setup.

Again, not work I care to do right now and so I won't. The benefit of
these patches is to provide some minimum viable CI CQA for Python where
we had none before, NOT fix every possible Python problem in one shot.


OK I guess we misunderstood each other :)

I didn't understood your comment as personal to you for this patch, but 
generic. It makes sense it is not your priority and it is obvious this 
task will take a single developer a lot of time resources. I am 
certainly NOT asking you to do it.


My question was rather community-oriented.
(Cc'ing Eduardo because we talked about this after the last KVM forum).



--js



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

diff --git a/tests/qemu-iotests/iotests.py
b/tests/qemu-iotests/iotests.py
index 60c4c7f736..214f59995e 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -30,6 +30,7 @@
   from collections import OrderedDict
   from typing import Collection
   +# pylint: disable=import-error, wrong-import-position
   sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..',
'python'))
   from qemu import qtest
  









Re: [PATCH] Fixed integer overflow in e1000e

2020-03-03 Thread Philippe Mathieu-Daudé

Hi Andrew,

Please Cc all the maintainers:

  ./scripts/get_maintainer.pl -f hw/net/e1000e.c
  Dmitry Fleytman  (maintainer:e1000e)
  Jason Wang  (odd fixer:Network devices)
  qemu-devel@nongnu.org (open list:All patches CC here)

On 3/3/20 7:29 PM, and...@daynix.com wrote:

From: Andrew Melnychenko 

https://bugzilla.redhat.com/show_bug.cgi?id=1737400


The BZ backtrace lists e1000e_tx_pkt_send() which you fixes,
but you also fixes e1000e_start_recv(). Good.

Please include the BZ backtrace.


Fixed setting max_queue_num if there are no peers in NICConf. qemu_new_nic() 
creates NICState with 1 NetClientState(index 0) without peers, set 
max_queue_num to 0 - It prevents undefined behavior and possible crashes, 
especially during pcie hotplug.



Please add:

Cc: qemu-sta...@nongnu.org
Fixes: 6f3fbe4ed06
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1737400


Signed-off-by: Andrew Melnychenko 
---
  hw/net/e1000e.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
index a91dbdca3c..f2cc1552c5 100644
--- a/hw/net/e1000e.c
+++ b/hw/net/e1000e.c
@@ -328,7 +328,7 @@ e1000e_init_net_peer(E1000EState *s, PCIDevice *pci_dev, 
uint8_t *macaddr)
  s->nic = qemu_new_nic(_e1000e_info, >conf,
  object_get_typename(OBJECT(s)), dev->id, s);
  
-s->core.max_queue_num = s->conf.peers.queues - 1;

+s->core.max_queue_num = s->conf.peers.queues ? s->conf.peers.queues - 1 : 
0;
  
  trace_e1000e_mac_set_permanent(MAC_ARG(macaddr));

  memcpy(s->core.permanent_mac, macaddr, sizeof(s->core.permanent_mac));






Re: [PATCH v2] linux-user: Add AT_EXECFN auxval

2020-03-03 Thread Lirong Yuan
On Tue, Mar 3, 2020 at 1:40 AM Laurent Vivier  wrote:
>
> Le 02/03/2020 à 20:31, Lirong Yuan a écrit :
> > This change adds the support for AT_EXECFN auxval.
> >
> > Signed-off-by: Lirong Yuan 
> > ---
> > Changelog since v1:
> > - remove implementation for AT_EXECFD auxval.
> >
> >  linux-user/elfload.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> > index db748c5877..8198be0446 100644
> > --- a/linux-user/elfload.c
> > +++ b/linux-user/elfload.c
> > @@ -1573,7 +1573,7 @@ struct exec
> >   ~(abi_ulong)(TARGET_ELF_EXEC_PAGESIZE-1))
> >  #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
> >
> > -#define DLINFO_ITEMS 15
> > +#define DLINFO_ITEMS 16
> >
> >  static inline void memcpy_fromfs(void * to, const void * from, unsigned 
> > long n)
> >  {
> > @@ -2037,6 +2037,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int 
> > argc, int envc,
> >  NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
> >  NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes);
> >  NEW_AUX_ENT(AT_SECURE, (abi_ulong) qemu_getauxval(AT_SECURE));
> > +NEW_AUX_ENT(AT_EXECFN, info->file_string);
> >
> >  #ifdef ELF_HWCAP2
> >  NEW_AUX_ENT(AT_HWCAP2, (abi_ulong) ELF_HWCAP2);
> >
>
> Applied to my linux-user branch.
>
> Thanks,
> Laurent

Awesome, thanks for the review! :)

Regards,
Lirong



Re: [PULL V2 01/23] dp8393x: Mask EOL bit from descriptor addresses

2020-03-03 Thread Finn Thain
Hi Jason,

The patch in this pull request (since merged) differs from the patch that 
I sent. In particular, the change below is missing from commit 88f632fbb1 
("dp8393x: Mask EOL bit from descriptor addresses") in mainline.

--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -525,8 +525,8 @@ static void dp8393x_do_transmit_packets(dp8393xState *s)
  * (4 + 3 * s->regs[SONIC_TFC]),
MEMTXATTRS_UNSPECIFIED, s->data,
size);
-s->regs[SONIC_CTDA] = dp8393x_get(s, width, 0) & ~0x1;
-if (dp8393x_get(s, width, 0) & SONIC_DESC_EOL) {
+s->regs[SONIC_CTDA] = dp8393x_get(s, width, 0);
+if (s->regs[SONIC_CTDA] & SONIC_DESC_EOL) {
 /* EOL detected */
 break;
 }

Please compare with "[PATCH v4 01/14] dp8393x: Mask EOL bit from 
descriptor addresses" in the mailing list archives: 
https://lore.kernel.org/qemu-devel/d6e8d06ad4d02f4a30c4caa6001967f806f21a1a.1580290069.git.fth...@telegraphics.com.au/

It appears that this portion of my patch went missing when merge conflicts 
were resolved. The conflicts were apparently caused by commit 19f7034773 
("Avoid address_space_rw() with a constant is_write argument").

Regards,
Finn

On Tue, 3 Mar 2020, Jason Wang wrote:

> From: Finn Thain 
> 
> The Least Significant bit of a descriptor address register is used as
> an EOL flag. It has to be masked when the register value is to be used
> as an actual address for copying memory around. But when the registers
> are to be updated the EOL bit should not be masked.
> 
> Signed-off-by: Finn Thain 
> Tested-by: Laurent Vivier 
> Signed-off-by: Jason Wang 
> ---
>  hw/net/dp8393x.c | 17 +++--
>  1 file changed, 11 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
> index 7045193..216d44b 100644
> --- a/hw/net/dp8393x.c
> +++ b/hw/net/dp8393x.c
> @@ -145,6 +145,9 @@ do { printf("sonic ERROR: %s: " fmt, __func__ , ## 
> __VA_ARGS__); } while (0)
>  #define SONIC_ISR_PINT   0x0800
>  #define SONIC_ISR_LCD0x1000
>  
> +#define SONIC_DESC_EOL   0x0001
> +#define SONIC_DESC_ADDR  0xFFFE
> +
>  #define TYPE_DP8393X "dp8393x"
>  #define DP8393X(obj) OBJECT_CHECK(dp8393xState, (obj), TYPE_DP8393X)
>  
> @@ -197,7 +200,8 @@ static uint32_t dp8393x_crba(dp8393xState *s)
>  
>  static uint32_t dp8393x_crda(dp8393xState *s)
>  {
> -return (s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA];
> +return (s->regs[SONIC_URDA] << 16) |
> +   (s->regs[SONIC_CRDA] & SONIC_DESC_ADDR);
>  }
>  
>  static uint32_t dp8393x_rbwc(dp8393xState *s)
> @@ -217,7 +221,8 @@ static uint32_t dp8393x_tsa(dp8393xState *s)
>  
>  static uint32_t dp8393x_ttda(dp8393xState *s)
>  {
> -return (s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_TTDA];
> +return (s->regs[SONIC_UTDA] << 16) |
> +   (s->regs[SONIC_TTDA] & SONIC_DESC_ADDR);
>  }
>  
>  static uint32_t dp8393x_wt(dp8393xState *s)
> @@ -509,7 +514,7 @@ static void dp8393x_do_transmit_packets(dp8393xState *s)
> MEMTXATTRS_UNSPECIFIED, s->data,
> size);
>  s->regs[SONIC_CTDA] = dp8393x_get(s, width, 0) & ~0x1;
> -if (dp8393x_get(s, width, 0) & 0x1) {
> +if (dp8393x_get(s, width, 0) & SONIC_DESC_EOL) {
>  /* EOL detected */
>  break;
>  }
> @@ -765,13 +770,13 @@ static ssize_t dp8393x_receive(NetClientState *nc, 
> const uint8_t * buf,
>  /* XXX: Check byte ordering */
>  
>  /* Check for EOL */
> -if (s->regs[SONIC_LLFA] & 0x1) {
> +if (s->regs[SONIC_LLFA] & SONIC_DESC_EOL) {
>  /* Are we still in resource exhaustion? */
>  size = sizeof(uint16_t) * 1 * width;
>  address = dp8393x_crda(s) + sizeof(uint16_t) * 5 * width;
>  address_space_read(>as, address, MEMTXATTRS_UNSPECIFIED,
> s->data, size);
> -if (dp8393x_get(s, width, 0) & 0x1) {
> +if (dp8393x_get(s, width, 0) & SONIC_DESC_EOL) {
>  /* Still EOL ; stop reception */
>  return -1;
>  } else {
> @@ -831,7 +836,7 @@ static ssize_t dp8393x_receive(NetClientState *nc, const 
> uint8_t * buf,
> dp8393x_crda(s) + sizeof(uint16_t) * 5 * width,
> MEMTXATTRS_UNSPECIFIED, s->data, size);
>  s->regs[SONIC_LLFA] = dp8393x_get(s, width, 0);
> -if (s->regs[SONIC_LLFA] & 0x1) {
> +if (s->regs[SONIC_LLFA] & SONIC_DESC_EOL) {
>  /* EOL detected */
>  s->regs[SONIC_ISR] |= SONIC_ISR_RDE;
>  } else {
> 



Re: [PATCH] cpu: Use DeviceClass reset instead of a special CPUClass reset

2020-03-03 Thread David Gibson
On Tue, Mar 03, 2020 at 10:05:11AM +, Peter Maydell wrote:
> The CPUClass has a 'reset' method.  This is a legacy from when
> TYPE_CPU used not to inherit from TYPE_DEVICE.  We don't need it any
> more, as we can simply use the TYPE_DEVICE reset.  The 'cpu_reset()'
> function is kept as the API which most places use to reset a CPU; it
> is now a wrapper which calls device_cold_reset() and then the
> tracepoint function.
> 
> This change should not cause CPU objects to be reset more often
> than they are at the moment, because:
>  * nobody is directly calling device_cold_reset() or
>qdev_reset_all() on CPU objects
>  * no CPU object is on a qbus, so they will not be reset either
>by somebody calling qbus_reset_all()/bus_cold_reset(), or
>by the main "reset sysbus and everything in the qbus tree"
>reset that most devices are reset by
> 
> Note that this does not change the need for each machine or whatever
> to use qemu_register_reset() to arrange to call cpu_reset() -- that
> is necessary because CPU objects are not on any qbus, so they don't
> get reset when the qbus tree rooted at the sysbus bus is reset, and
> this isn't being changed here.
> 
> All the changes to the files under target/ were made using the
> included Coccinelle script, except:
> 
> (1) the deletion of the now-inaccurate and not terribly useful
> "CPUClass::reset" comments was done with a perl one-liner afterwards:
>   perl -n -i -e '/ CPUClass::reset/ or print' target/*/*.c
> 
> (2) this bit of the s390 change was done by hand, because the
> Coccinelle script is not sophisticated enough to handle the
> parent_reset call being inside another function:
> 
> | @@ -96,8 +96,9 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type 
> type)
> | S390CPU *cpu = S390_CPU(s);
> | S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
> | CPUS390XState *env = >env;
> |+DeviceState *dev = DEVICE(s);
> |
> |-scc->parent_reset(s);
> |+scc->parent_reset(dev);
> | cpu->env.sigp_order = 0;
> | s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
> 
> Signed-off-by: Peter Maydell 

ppc parts

Acked-by: David Gibson 

> ---
> Testing was by 'make check' and 'make check-acceptance'.
> 
> I need this patch as a preliminary to some arm stuff I'm
> doing, but I think it makes sense as a cleanup in its own
> right so I'm sending it out early for review. If it's not
> yet in master before I get round to finishing the stuff
> that depends on it I'll resend it as part of that series.
> ---
>  include/hw/core/cpu.h  |  6 
>  target/alpha/cpu-qom.h |  2 +-
>  target/arm/cpu-qom.h   |  2 +-
>  target/cris/cpu-qom.h  |  2 +-
>  target/hppa/cpu-qom.h  |  2 +-
>  target/i386/cpu-qom.h  |  2 +-
>  target/lm32/cpu-qom.h  |  2 +-
>  target/m68k/cpu-qom.h  |  2 +-
>  target/microblaze/cpu-qom.h|  2 +-
>  target/mips/cpu-qom.h  |  2 +-
>  target/moxie/cpu.h |  2 +-
>  target/nios2/cpu.h |  2 +-
>  target/openrisc/cpu.h  |  2 +-
>  target/ppc/cpu-qom.h   |  2 +-
>  target/riscv/cpu.h |  2 +-
>  target/s390x/cpu-qom.h |  2 +-
>  target/sh4/cpu-qom.h   |  2 +-
>  target/sparc/cpu-qom.h |  2 +-
>  target/tilegx/cpu.h|  2 +-
>  target/tricore/cpu-qom.h   |  2 +-
>  target/xtensa/cpu-qom.h|  2 +-
>  hw/core/cpu.c  | 19 +++-
>  target/arm/cpu.c   |  8 ++---
>  target/cris/cpu.c  |  8 ++---
>  target/i386/cpu.c  |  8 ++---
>  target/lm32/cpu.c  |  8 ++---
>  target/m68k/cpu.c  |  8 ++---
>  target/microblaze/cpu.c|  8 ++---
>  target/mips/cpu.c  |  8 ++---
>  target/moxie/cpu.c |  7 +++--
>  target/nios2/cpu.c |  8 ++---
>  target/openrisc/cpu.c  |  8 ++---
>  target/ppc/translate_init.inc.c|  8 ++---
>  target/riscv/cpu.c |  7 +++--
>  target/s390x/cpu.c |  8 +++--
>  target/sh4/cpu.c   |  8 ++---
>  target/sparc/cpu.c |  8 ++---
>  target/tilegx/cpu.c|  7 +++--
>  target/tricore/cpu.c   |  7 +++--
>  target/xtensa/cpu.c|  8 ++---
>  scripts/coccinelle/cpu-reset.cocci | 47 ++
>  41 files changed, 144 insertions(+), 108 deletions(-)
>  create mode 100644 scripts/coccinelle/cpu-reset.cocci
> 
> diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
> index 73e9a869a41..88ee543722d 100644
> --- a/include/hw/core/cpu.h
> +++ b/include/hw/core/cpu.h
> @@ -79,7 +79,6 @@ struct TranslationBlock;
>   * @class_by_name: Callback to map -cpu command line model name to an
>   * instantiatable CPU type.
>   * @parse_features: Callback to parse command line arguments.
> - * 

Re: [PATCH 4/4] qapi: Brush off some (py)lint

2020-03-03 Thread John Snow



On 2/27/20 9:45 AM, Markus Armbruster wrote:
> Signed-off-by: Markus Armbruster 

I wrote some pylint cleanup for iotests recently, too. Are you targeting
a subset of pylint errors to clean here?

(Do any files pass 100%?)

Consider checking in a pylintrc file that lets others run the same
subset of pylint tests as you are doing so that we can prevent future
regressions.

Take a peek at [PATCH v6 0/9] iotests: use python logging​

Thanks for this series. I had a very similar series sitting waiting to
go out, but this goes further in a few places.

--js

> ---
>  scripts/qapi/commands.py   | 2 +-
>  scripts/qapi/expr.py   | 3 +--
>  scripts/qapi/gen.py| 9 ++---
>  scripts/qapi/introspect.py | 2 --
>  scripts/qapi/parser.py | 6 ++
>  scripts/qapi/schema.py | 9 -
>  6 files changed, 14 insertions(+), 17 deletions(-)
> 
> diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
> index 8bb6316061..0e13e82989 100644
> --- a/scripts/qapi/commands.py
> +++ b/scripts/qapi/commands.py
> @@ -274,7 +274,7 @@ class 
> QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
>  
>  void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
>  ''',
> -   c_prefix=c_name(self._prefix, protect=False)))
> + c_prefix=c_name(self._prefix, protect=False)))
>  self._genc.preamble_add(mcgen('''
>  #include "qemu/osdep.h"
>  #include "%(prefix)sqapi-commands.h"
> diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
> index d7a289eded..fecf466fa7 100644
> --- a/scripts/qapi/expr.py
> +++ b/scripts/qapi/expr.py
> @@ -35,7 +35,6 @@ def check_name_is_str(name, info, source):
>  def check_name_str(name, info, source,
> allow_optional=False, enum_member=False,
> permit_upper=False):
> -global valid_name
>  membername = name
>  
>  if allow_optional and name.startswith('*'):
> @@ -249,7 +248,7 @@ def check_union(expr, info):
>  def check_alternate(expr, info):
>  members = expr['data']
>  
> -if len(members) == 0:
> +if not members:
>  raise QAPISemError(info, "'data' must not be empty")
>  for (key, value) in members.items():
>  source = "'data' member '%s'" % key
> diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
> index e17354392b..33690bfa3b 100644
> --- a/scripts/qapi/gen.py
> +++ b/scripts/qapi/gen.py
> @@ -45,10 +45,10 @@ class QAPIGen:
>  
>  def write(self, output_dir):
>  pathname = os.path.join(output_dir, self.fname)
> -dir = os.path.dirname(pathname)
> -if dir:
> +odir = os.path.dirname(pathname)
> +if odir:
>  try:
> -os.makedirs(dir)
> +os.makedirs(odir)
>  except os.error as e:
>  if e.errno != errno.EEXIST:
>  raise
> @@ -261,6 +261,9 @@ class QAPISchemaModularCVisitor(QAPISchemaVisitor):
>  genc.write(output_dir)
>  genh.write(output_dir)
>  
> +def _begin_system_module(self, name):
> +pass
> +
>  def _begin_user_module(self, name):
>  pass
>  
> diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
> index 0cc655fd9f..b5537eddc0 100644
> --- a/scripts/qapi/introspect.py
> +++ b/scripts/qapi/introspect.py
> @@ -10,8 +10,6 @@ This work is licensed under the terms of the GNU GPL, 
> version 2.
>  See the COPYING file in the top-level directory.
>  """
>  
> -import string
> -
>  from qapi.common import *
>  from qapi.gen import QAPISchemaMonolithicCVisitor
>  from qapi.schema import (QAPISchemaArrayType, QAPISchemaBuiltinType,
> diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py
> index 340f7c4633..abadacbb0e 100644
> --- a/scripts/qapi/parser.py
> +++ b/scripts/qapi/parser.py
> @@ -282,8 +282,7 @@ class QAPISchemaParser:
>  doc.end_comment()
>  self.accept()
>  return doc
> -else:
> -doc.append(self.val)
> +doc.append(self.val)
>  self.accept(False)
>  
>  raise QAPIParseError(self, "documentation comment must end with 
> '##'")
> @@ -492,7 +491,7 @@ class QAPIDoc:
>  raise QAPIParseError(self._parser,
>   "'%s' can't follow '%s' section"
>   % (name, self.sections[0].name))
> -elif self._is_section_tag(name):
> +if self._is_section_tag(name):
>  line = line[len(name)+1:]
>  self._start_section(name[:-1])
>  
> @@ -556,7 +555,6 @@ class QAPIDoc:
>  raise QAPISemError(feature.info,
> "feature '%s' lacks documentation"
> % feature.name)
> -self.features[feature.name] = QAPIDoc.ArgSection(feature.name)
>  self.features[feature.name].connect(feature)
>  
>  def check_expr(self, expr):
> diff --git 

Re: [PATCH 5/6] qmp.py: change event_wait to use a dict

2020-03-03 Thread John Snow



On 2/27/20 6:25 AM, Vladimir Sementsov-Ogievskiy wrote:
> 25.02.2020 3:56, John Snow wrote:
>> It's easier to work with than a list of tuples, because we can check the
>> keys for membership.
>>
>> Signed-off-by: John Snow 
>> ---
>>   python/qemu/machine.py    | 10 +-
>>   tests/qemu-iotests/040    | 12 ++--
>>   tests/qemu-iotests/260    |  5 +++--
>>   tests/qemu-iotests/iotests.py | 16 
>>   4 files changed, 22 insertions(+), 21 deletions(-)
>>
>> diff --git a/python/qemu/machine.py b/python/qemu/machine.py
>> index 183d8f3d38..748de5f322 100644
>> --- a/python/qemu/machine.py
>> +++ b/python/qemu/machine.py
>> @@ -476,21 +476,21 @@ def event_wait(self, name, timeout=60.0,
>> match=None):
>>   timeout: QEMUMonitorProtocol.pull_event timeout parameter.
>>   match: Optional match criteria. See event_match for details.
>>   """
>> -    return self.events_wait([(name, match)], timeout)
>> +    return self.events_wait({name: match}, timeout)
>>     def events_wait(self, events, timeout=60.0):
>>   """
>>   events_wait waits for and returns a named event from QMP
>> with a timeout.
>>   -    events: a sequence of (name, match_criteria) tuples.
>> +    events: a mapping containing {name: match_criteria}.
>>   The match criteria are optional and may be None.
>>   See event_match for details.
>>   timeout: QEMUMonitorProtocol.pull_event timeout parameter.
>>   """
>>   def _match(event):
>> -    for name, match in events:
>> -    if event['event'] == name and self.event_match(event,
>> match):
>> -    return True
>> +    name = event['event']
>> +    if name in events:
>> +    return self.event_match(event, events[name])
>>   return False
>>     # Search cached events
>> diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040
>> index 32c82b4ec6..90b59081ff 100755
>> --- a/tests/qemu-iotests/040
>> +++ b/tests/qemu-iotests/040
>> @@ -485,12 +485,12 @@ class TestErrorHandling(iotests.QMPTestCase):
>>     def run_job(self, expected_events, error_pauses_job=False):
>>   match_device = {'data': {'device': 'job0'}}
>> -    events = [
>> -    ('BLOCK_JOB_COMPLETED', match_device),
>> -    ('BLOCK_JOB_CANCELLED', match_device),
>> -    ('BLOCK_JOB_ERROR', match_device),
>> -    ('BLOCK_JOB_READY', match_device),
>> -    ]
>> +    events = {
>> +    'BLOCK_JOB_COMPLETED': match_device,
>> +    'BLOCK_JOB_CANCELLED': match_device,
>> +    'BLOCK_JOB_ERROR': match_device,
>> +    'BLOCK_JOB_READY': match_device,
>> +    }
>>     completed = False
>>   log = []
>> diff --git a/tests/qemu-iotests/260 b/tests/qemu-iotests/260
>> index 30c0de380d..b2fb045ddd 100755
>> --- a/tests/qemu-iotests/260
>> +++ b/tests/qemu-iotests/260
>> @@ -65,8 +65,9 @@ def test(persistent, restart):
>>     vm.qmp_log('block-commit', device='drive0', top=top,
>>  filters=[iotests.filter_qmp_testfiles])
>> -    ev = vm.events_wait((('BLOCK_JOB_READY', None),
>> - ('BLOCK_JOB_COMPLETED', None)))
>> +    ev = vm.events_wait({
>> +    'BLOCK_JOB_READY': None,
>> +    'BLOCK_JOB_COMPLETED': None })
> 
> may be better to keep it 2-lines. Or, otherwise, put closing "})" on a
> separate line too.
> 

Sure.

>>   log(filter_qmp_event(ev))
>>   if (ev['event'] == 'BLOCK_JOB_COMPLETED'):
>>   vm.shutdown()
>> diff --git a/tests/qemu-iotests/iotests.py
>> b/tests/qemu-iotests/iotests.py
>> index 5d2990a0e4..3390fab021 100644
>> --- a/tests/qemu-iotests/iotests.py
>> +++ b/tests/qemu-iotests/iotests.py
>> @@ -604,14 +604,14 @@ def run_job(self, job, auto_finalize=True,
>> auto_dismiss=False,
>>   """
>>   match_device = {'data': {'device': job}}
>>   match_id = {'data': {'id': job}}
>> -    events = [
>> -    ('BLOCK_JOB_COMPLETED', match_device),
>> -    ('BLOCK_JOB_CANCELLED', match_device),
>> -    ('BLOCK_JOB_ERROR', match_device),
>> -    ('BLOCK_JOB_READY', match_device),
>> -    ('BLOCK_JOB_PENDING', match_id),
>> -    ('JOB_STATUS_CHANGE', match_id)
>> -    ]
>> +    events = {
>> +    'BLOCK_JOB_COMPLETED': match_device,
>> +    'BLOCK_JOB_CANCELLED': match_device,
>> +    'BLOCK_JOB_ERROR': match_device,
>> +    'BLOCK_JOB_READY': match_device,
>> +    'BLOCK_JOB_PENDING': match_id,
>> +    'JOB_STATUS_CHANGE': match_id,
>> +    }
>>   error = None
>>   while True:
>>   ev = filter_qmp_event(self.events_wait(events,
>> timeout=wait))
>>
> 
> 
> Not sure that I like new interface more (neither that it is faster), but
> it works too:
> Reviewed-by: Vladimir 

Re: [PATCH 3/6] iotests: move bitmap helpers into their own file

2020-03-03 Thread John Snow



On 2/27/20 5:54 AM, Vladimir Sementsov-Ogievskiy wrote:
> 
> Clean code movement, no changes. If test passes, it should be correct :)
> 
> The only thing: I'd prefer not exporting global variables and use
> bitmaps.GROUPS instead (even then, it's not very good interface but..)
> 
> with or without it:
> Reviewed-by: Vladimir Sementsov-Ogievskiy 

Hm, yeah -- it's not great, it's definitely just a bit of a quick
shuffle instead of a more serious effort at a refactor to provide bitmap
services for all tests.

I don't think it's worth the time just yet to make a serious attempt at
making this module bigger -- but maybe there is work that can be done at
providing bitmap management services targeted for use outside of testing
code. (i.e. into the python/ folder somewhere.)

Well, I can just do this:
"
import bitmaps
from bitmaps import EmulatedBitmap
"

and bitmaps.GROUPS makes it a little more obvious in-context at the
expense of one extra import line, so I'll do that.




Re: [PATCH 2/6] qmp: expose block-dirty-bitmap-populate

2020-03-03 Thread John Snow



On 2/27/20 5:44 AM, Vladimir Sementsov-Ogievskiy wrote:
> 25.02.2020 3:56, John Snow wrote:
>> This is a new job-creating command.
>>
>> Signed-off-by: John Snow 
>> ---
>>   qapi/block-core.json  | 18 ++
>>   qapi/transaction.json |  2 ++
>>   blockdev.c    | 78 +++
>>   3 files changed, 98 insertions(+)
>>
>> diff --git a/qapi/block-core.json b/qapi/block-core.json
>> index df1797681a..a8be1fb36b 100644
>> --- a/qapi/block-core.json
>> +++ b/qapi/block-core.json
>> @@ -2293,6 +2293,24 @@
>>   '*auto-finalize': 'bool',
>>   '*auto-dismiss': 'bool' } }
>>   +##
>> +# @block-dirty-bitmap-populate:
>> +#
>> +# Creates a new job that writes a pattern into a dirty bitmap.
>> +#
>> +# Since: 5.0
>> +#
>> +# Example:
>> +#
>> +# -> { "execute": "block-dirty-bitmap-populate",
>> +#  "arguments": { "node": "drive0", "target": "bitmap0",
>> +# "job-id": "job0", "pattern": "allocate-top" } }
>> +# <- { "return": {} }
>> +#
>> +##
>> +{ 'command': 'block-dirty-bitmap-populate', 'boxed': true,
>> +  'data': 'BlockDirtyBitmapPopulate' }
>> +
>>   ##
>>   # @BlockDirtyBitmapSha256:
>>   #
>> diff --git a/qapi/transaction.json b/qapi/transaction.json
>> index 04301f1be7..28521d5c7f 100644
>> --- a/qapi/transaction.json
>> +++ b/qapi/transaction.json
>> @@ -50,6 +50,7 @@
>>   # - @block-dirty-bitmap-enable: since 4.0
>>   # - @block-dirty-bitmap-disable: since 4.0
>>   # - @block-dirty-bitmap-merge: since 4.0
>> +# - @block-dirty-bitmap-populate: since 5.0
>>   # - @blockdev-backup: since 2.3
>>   # - @blockdev-snapshot: since 2.5
>>   # - @blockdev-snapshot-internal-sync: since 1.7
>> @@ -67,6 +68,7 @@
>>  'block-dirty-bitmap-enable': 'BlockDirtyBitmap',
>>  'block-dirty-bitmap-disable': 'BlockDirtyBitmap',
>>  'block-dirty-bitmap-merge': 'BlockDirtyBitmapMerge',
>> +   'block-dirty-bitmap-populate': 'BlockDirtyBitmapPopulate',
>>  'blockdev-backup': 'BlockdevBackup',
>>  'blockdev-snapshot': 'BlockdevSnapshot',
>>  'blockdev-snapshot-internal-sync': 'BlockdevSnapshotInternal',
>> diff --git a/blockdev.c b/blockdev.c
>> index 011dcfec27..33c0e35399 100644
>> --- a/blockdev.c
>> +++ b/blockdev.c
>> @@ -2314,6 +2314,67 @@ static void
>> block_dirty_bitmap_remove_commit(BlkActionState *common)
>>   bdrv_release_dirty_bitmap(state->bitmap);
>>   }
>>   +static void block_dirty_bitmap_populate_prepare(BlkActionState
>> *common, Error **errp)
> 
> over80 line (not the only)
> 

OK, will fix all instances.

>> +{
>> +    BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState,
>> common, common);
> 
> At first glance using *Backup* looks like a mistake. May be rename it,
> or at least add a comment.
> 

You're right, it's tricky. A rename would be helpful.

>> +    BlockDirtyBitmapPopulate *bitpop;
>> +    BlockDriverState *bs;
>> +    AioContext *aio_context;
>> +    BdrvDirtyBitmap *bmap = NULL;
>> +    int job_flags = JOB_DEFAULT;
>> +
>> +    assert(common->action->type ==
>> TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_POPULATE);
>> +    bitpop = common->action->u.block_dirty_bitmap_populate.data;
>> +
>> +    bs = bdrv_lookup_bs(bitpop->node, bitpop->node, errp);
>> +    if (!bs) {
>> +    return;
>> +    }
>> +
>> +    aio_context = bdrv_get_aio_context(bs);
>> +    aio_context_acquire(aio_context);
>> +    state->bs = bs;
>> +
>> +    bmap = bdrv_find_dirty_bitmap(bs, bitpop->name);
> 
> Could we use block_dirty_bitmap_lookup ?
> 

Yes.

>> +    if (!bmap) {
>> +    error_setg(errp, "Bitmap '%s' could not be found",
>> bitpop->name);
>> +    return;
> 
> aio context lock leaked
> 

Good spot.

>> +    }
>> +
>> +    /* Paired with .clean() */
>> +    bdrv_drained_begin(state->bs);
>> +
>> +    if (!bitpop->has_on_error) {
>> +    bitpop->on_error = BLOCKDEV_ON_ERROR_REPORT;
>> +    }
>> +    if (!bitpop->has_auto_finalize) {
>> +    bitpop->auto_finalize = true;
>> +    }
>> +    if (!bitpop->has_auto_dismiss) {
>> +    bitpop->auto_dismiss = true;
>> +    }
>> +
>> +    if (!bitpop->auto_finalize) {
>> +    job_flags |= JOB_MANUAL_FINALIZE;
>> +    }
>> +    if (!bitpop->auto_dismiss) {
>> +    job_flags |= JOB_MANUAL_DISMISS;
>> +    }
>> +
>> +    state->job = bitpop_job_create(
>> +    bitpop->job_id,
>> +    bs,
>> +    bmap,
>> +    bitpop->pattern,
>> +    bitpop->on_error,
>> +    job_flags,
>> +    NULL, NULL,
>> +    common->block_job_txn,
>> +    errp);
>> +
>> +    aio_context_release(aio_context);
>> +}
>> +
>>   static void abort_prepare(BlkActionState *common, Error **errp)
>>   {
>>   error_setg(errp, "Transaction aborted using Abort action");
>> @@ -2397,6 +2458,13 @@ static const BlkActionOps actions[] = {
>>   .commit = block_dirty_bitmap_remove_commit,
>>   .abort = block_dirty_bitmap_remove_abort,
>>   },
>> +    

Re: [PATCH 1/6] block: add bitmap-populate job

2020-03-03 Thread John Snow



On 2/27/20 1:11 AM, Vladimir Sementsov-Ogievskiy wrote:
> 
> Still, if user pass disabled bitmap, it will be invalid immediately after
> job finish.

Yes ... In truth, I really want to augment this job to provide a defined
point-in-time semantic so it can be fully useful in all circumstances.

At the moment, the point-in-time it provides is "at finalize", which may
or may not be the single most useful semantic. (It matches mirror --
because that was easier.)

The other option is "at start" which matches backup, but will require a
new filter and some changes to permissions. That was more invasive, so I
avoided it for now.

(In the interest of a speedy resolution for libvirt, can we add a
critical_moment=[START|FINALIZE] option to this job *later*?)




Re: [PATCH 1/2] iotests: add JobRunner class

2020-03-03 Thread John Snow



On 2/27/20 6:44 AM, Max Reitz wrote:
>> I'll just clean up the logging series I had to do it at a more
>> fundamental level.
> OK.  So you’re looking to basically get VM.qmp() to log automatically if
> necessary?  (or maybe qmp_log() to not log unless necessary)
> 
> Max
> 

Yes. If this series looks good I will just rebase it on top of the
logging series. Then self.logging goes away and the calls to qmp_log et
al just become unconditional.

Then we can enable/disable "all QMP logging" globally instead of
individually throughout the iotests shared codebase.

--js




Re: [PATCH v6 1/9] iotests: do a light delinting

2020-03-03 Thread John Snow



On 2/27/20 7:59 AM, Max Reitz wrote:
> On 27.02.20 01:06, John Snow wrote:
>> This doesn't fix everything in here, but it does help clean up the
>> pylint report considerably.
>>
>> This should be 100% style changes only; the intent is to make pylint
>> more useful by working on establishing a baseline for iotests that we
>> can gate against in the future. This will be important if (when?) we
>> begin adding type hints to our code base.
>>
>> Signed-off-by: John Snow 
>> ---
>>  tests/qemu-iotests/iotests.py | 88 ++-
>>  1 file changed, 45 insertions(+), 43 deletions(-)
> 
> I feel like I’m the wrongest person there is for reviewing a Python
> style-fixing patch, but here I am and so here I go:
> 

No, it's good.

>> diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
>> index 8815052eb5..e8a0ea14fc 100644
>> --- a/tests/qemu-iotests/iotests.py
>> +++ b/tests/qemu-iotests/iotests.py
> 
> [...]
> 
>> @@ -245,8 +243,7 @@ def qemu_nbd_early_pipe(*args):
>>' '.join(qemu_nbd_args + ['--fork'] + 
>> list(args
>>  if exitcode == 0:
>>  return exitcode, ''
>> -else:
>> -return exitcode, subp.communicate()[0]
>> +return exitcode, subp.communicate()[0]
> 
> If we want to make such a change (which I don’t doubt we want), I think
> it should be the other way around: Make the condition “exitcode != 0”,
> so the final return is the return for the successful case.  (Just
> because I think that’s how we usually do it, at least in the qemu code?)
> 
> [...]
> 

Yes, makes sense. I was behaving a little more mechanically.

>> @@ -455,10 +452,9 @@ def file_path(*names, base_dir=test_dir):
>>  def remote_filename(path):
>>  if imgproto == 'file':
>>  return path
>> -elif imgproto == 'ssh':
>> +if imgproto == 'ssh':
> 
> This seems like a weird thing to complain about for a coding style
> check, but whatever.
> 
> (As in, I prefer the elif form)
> 

Honestly, I do too. We can silence the warning instead.

This warning option doesn't like "if return else return" constructs,
preferring instead:

if x:
return 0
return 1

but I have to admit that I often like to see the branches laid out as
branches, too.

Other Pythonistas (Eduardo, Philippe, Markus?) -- strong feelings one
way or the other?

>>  return "ssh://%s@127.0.0.1:22%s" % (os.environ.get('USER'), path)
>> -else:
>> -raise Exception("Protocol %s not supported" % (imgproto))
>> +raise Exception("Protocol %s not supported" % (imgproto))
>>  
>>  class VM(qtest.QEMUQtestMachine):
>>  '''A QEMU VM'''
> 
> [...]
> 
>> @@ -756,12 +750,13 @@ def assert_block_path(self, root, path, expected_node, 
>> graph=None):
>>  assert node is not None, 'Cannot follow path %s%s' % (root, 
>> path)
>>  
>>  try:
>> -node_id = next(edge['child'] for edge in graph['edges'] \
>> - if edge['parent'] == 
>> node['id'] and
>> -edge['name'] == child_name)
>> +node_id = next(edge['child'] for edge in graph['edges']
>> +   if edge['parent'] == node['id'] and
>> +   edge['name'] == child_name)
> 
> I don’t mind the if alignment, but I do mind not aligning the third line
> to the “edge” above it (i.e. the third line is part of the condition, so
> I’d align it to the “if” condition).
> 
> But then again it’s nothing new that I like to disagree with commonly
> agreed-upon Python coding styles, so.
> 
> [...]
> 

OK, that can be addressed by highlighting the sub-expression with
parentheses:

node_id = next(edge['child'] for edge in graph['edges']
   if (edge['parent'] == node['id'] and
   edge['name'] == child_name))


>> @@ -891,13 +892,14 @@ def wait_until_completed(self, drive='drive0', 
>> check_offset=True, wait=60.0,
>>  self.assert_qmp(event, 'data/error', error)
>>  self.assert_no_active_block_jobs()
>>  return event
>> -elif event['event'] == 'JOB_STATUS_CHANGE':
>> +if event['event'] == 'JOB_STATUS_CHANGE':
>>  self.assert_qmp(event, 'data/id', drive)
>>  
>>  def wait_ready(self, drive='drive0'):
>>  '''Wait until a block job BLOCK_JOB_READY event'''
>> -f = {'data': {'type': 'mirror', 'device': drive } }
>> +f = {'data': {'type': 'mirror', 'device': drive}}
>>  event = self.vm.event_wait(name='BLOCK_JOB_READY', match=f)
>> +return event
> 
> Why not just “return self.vm.event_wait…”?
> 

Shrug. Sometimes I name my return variables when working in Python to
give some semantic clue over what exactly I'm even returning.

I can change it; but the docstring will grow to describe what it returns
to re-document the same.


Re: [PATCH v6 2/9] iotests: add script_initialize

2020-03-03 Thread John Snow



On 2/27/20 8:47 AM, Max Reitz wrote:
> On 27.02.20 01:06, John Snow wrote:
>> Like script_main, but doesn't require a single point of entry.
>> Replace all existing initialization sections with this drop-in replacement.
>>
>> This brings debug support to all existing script-style iotests.
>>
>> Signed-off-by: John Snow 
>> ---
>>  tests/qemu-iotests/149|  3 +-
>>  tests/qemu-iotests/194|  4 +-
>>  tests/qemu-iotests/202|  4 +-
>>  tests/qemu-iotests/203|  4 +-
>>  tests/qemu-iotests/206|  2 +-
>>  tests/qemu-iotests/207|  6 ++-
>>  tests/qemu-iotests/208|  2 +-
>>  tests/qemu-iotests/209|  2 +-
>>  tests/qemu-iotests/210|  6 ++-
>>  tests/qemu-iotests/211|  6 ++-
>>  tests/qemu-iotests/212|  6 ++-
>>  tests/qemu-iotests/213|  6 ++-
>>  tests/qemu-iotests/216|  4 +-
>>  tests/qemu-iotests/218|  2 +-
>>  tests/qemu-iotests/219|  2 +-
>>  tests/qemu-iotests/222|  7 ++--
>>  tests/qemu-iotests/224|  4 +-
>>  tests/qemu-iotests/228|  6 ++-
>>  tests/qemu-iotests/234|  4 +-
>>  tests/qemu-iotests/235|  4 +-
>>  tests/qemu-iotests/236|  2 +-
>>  tests/qemu-iotests/237|  2 +-
>>  tests/qemu-iotests/238|  2 +
>>  tests/qemu-iotests/242|  2 +-
>>  tests/qemu-iotests/246|  2 +-
>>  tests/qemu-iotests/248|  2 +-
>>  tests/qemu-iotests/254|  2 +-
>>  tests/qemu-iotests/255|  2 +-
>>  tests/qemu-iotests/256|  2 +-
>>  tests/qemu-iotests/258|  7 ++--
>>  tests/qemu-iotests/260|  4 +-
>>  tests/qemu-iotests/262|  4 +-
>>  tests/qemu-iotests/264|  4 +-
>>  tests/qemu-iotests/277|  2 +
>>  tests/qemu-iotests/280|  8 ++--
>>  tests/qemu-iotests/283|  4 +-
>>  tests/qemu-iotests/iotests.py | 73 +++
>>  37 files changed, 128 insertions(+), 80 deletions(-)
> 
> Reviewed-by: Max Reitz 
> 
> [...]
> 
>> diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
>> index e8a0ea14fc..fdcf8a940c 100644
>> --- a/tests/qemu-iotests/iotests.py
>> +++ b/tests/qemu-iotests/iotests.py
> 
> [...]
> 
>> @@ -1092,13 +1105,18 @@ def execute_unittest(output, verbosity, debug):
>>  
>>  sys.stderr.write(out)
>>  
>> -def execute_test(test_function=None,
>> - supported_fmts=[],
>> - supported_platforms=None,
>> - supported_cache_modes=[], supported_aio_modes={},
>> - unsupported_fmts=[], supported_protocols=[],
>> - unsupported_protocols=[]):
>> -"""Run either unittest or script-style tests."""
>> +def execute_setup_common(supported_fmts: Collection[str] = (),
> 
> First time I see something like this, but I suppose it means any
> collection (i.e. list or tuple in this case) that has str values?
> 
> Max
> 

Yes. Testing the waters for idiomatic type annotations. We chose our
python version to allow us to use them, so I'm pushing on that boundary.

A Collection in this case is a Python ABC that collects the Sized,
Iterable and Container ABCs.

Roughly:
Sized: provides __len__  (len(x))
Iterable: provides __iter__  ("for x in y")
Container: provides __contains__ ("if 'x' in y")

In this case, we want Iterable (to enumerate the atoms) and Sized (to
provide truth-testing that returns False when the collection has a size
of zero.) "Collection" is the nearest available type that describes all
of the desired types of duck, without becoming overly specific for
features of the type we are not using.

More information:
https://docs.python.org/3.6/library/collections.abc.html#module-collections.abc

>> + supported_platforms: Collection[str] = (),
>> + supported_cache_modes: Collection[str] = (),
>> + supported_aio_modes: Collection[str] = (),
>> + unsupported_fmts: Collection[str] = (),
>> + supported_protocols: Collection[str] = (),
>> + unsupported_protocols: Collection[str] = ()) -> 
>> bool:
> 




Re: [PATCH 2/2] via-ide: Also emulate non 100% native mode

2020-03-03 Thread Mark Cave-Ayland
On 02/03/2020 21:40, BALATON Zoltan wrote:

>> I had a quick look at the schematics linked from the page above, and they 
>> confirm
>> that the VIA IDE interface is connected directly to IRQs 14 and 15 and not 
>> to the PCI
>> interrupt pins.
> 
> Where did you see that? What I got from trying to look this up in the 
> schematics was
> that VT8231 has two pins named IRQ14 and IRQ15 (but described as Primary and
> Secondary Channel Interrupt Request in doc) where the interrupt lines of the 
> two IDE
> ports/channels are connected but how they are routed within the chip after 
> that was
> not clear. The chip doc says that in native mode the interrupt should be 
> configurable
> and use a single interrupt for both channels and in legacy mode they use the 
> usual 14
> and 15 but this is not what guest drivers expect so I think not how really 
> works on
> PegasosII. It is true however that connection to PCI interrupts aren't 
> mentioned so
> it always uses ISA IRQ numbers, it just depends on legacy vs. native mode 
> which line
> is raised. But that was never really a question for VT8231 and maybe only 
> CMD646
> could have such interconnection with PCI interrupts. (Proabable reason is that
> via-ide is part of a southbridge chip where it has connections to ISA bus 
> while
> CMD646 is a PCI IDE controller but I could be wrong as my knowledge is 
> limited about
> these.)

Presumably the VIA southbridge has its own internal pair of cascaded 8259s so 
the IRQ
line from the drive is connected to IRQ14/15 as per an typical ISA PC. You can 
see
this in the "Common Hardware Reference Platform: I/O Device Reference" PDF 
section 4.1.

>> So on that basis the best explanation as to what is happening is the
>> comment in the link you provided here:
>> https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/powerpc/platforms/chrp/pci.c?h=v4.14.172#n353
>>
>>
>> /* Pegasos2 firmware version 20040810 configures the built-in IDE controller
>> * in legacy mode, but sets the PCI registers to PCI native mode.
>> * The chip can only operate in legacy mode, so force the PCI class into 
>> legacy
>> * mode as well. The same fixup must be done to the class-code property in
>> * the IDE node /pci@8000/ide@C,1
>> */
> 
> I'm not sure that it makes much sense that the firmware configures the chip 
> one way
> then puts info about a different way in the device tree. There could be bugs 
> but this
> is not likely. Especially because I see in traces that the firmware does try 
> to
> configure the device in native mode. These are the first few accesses of the 
> firmware
> to via-ide:

But that is exactly what is happening! The comment above clearly indicates the
firmware incorrectly sets the IDE controller in native mode which is in exact
agreement with the trace you provide below. And in fact if you look at
https://www.powerdeveloper.org/platforms/pegasos/devicetree you can see the 
nvramrc
hack that was released in order to fix the device tree to boot Linux which 
alters the
class-code and sets interrupts to 14 (which I believe is invalid, but seemingly 
good
enough here).

> pci_cfg_write via-ide 12:1 @0x9 <- 0xf
> pci_cfg_write via-ide 12:1 @0x40 <- 0xb
> pci_cfg_write via-ide 12:1 @0x41 <- 0xf2
> pci_cfg_write via-ide 12:1 @0x43 <- 0x35
> pci_cfg_write via-ide 12:1 @0x44 <- 0x18
> pci_cfg_write via-ide 12:1 @0x45 <- 0x1c
> pci_cfg_write via-ide 12:1 @0x46 <- 0xc0
> pci_cfg_write via-ide 12:1 @0x50 <- 0x17171717
> pci_cfg_write via-ide 12:1 @0x54 <- 0x14
> pci_cfg_read via-ide 12:1 @0x0 -> 0x5711106
> pci_cfg_read via-ide 12:1 @0x0 -> 0x5711106
> pci_cfg_read via-ide 12:1 @0x8 -> 0x1018f06
> pci_cfg_read via-ide 12:1 @0xc -> 0x0
> pci_cfg_read via-ide 12:1 @0x2c -> 0x11001af4
> pci_cfg_read via-ide 12:1 @0x3c -> 0x10e
> pci_cfg_read via-ide 12:1 @0x4 -> 0x2800080
> pci_cfg_read via-ide 12:1 @0x3c -> 0x10e
> pci_cfg_write via-ide 12:1 @0x3c <- 0x109
> 
> The very first write is to turn on native mode, so I think it's not about 
> what the
> firmware does but something about how hardware is wired on Pegasos II or the 
> VT8231
> chip itself that only allows legacy interrupts instead of 100% native mode 
> for IDE.
> 
>> Given that the DT is wrong, then we should assume that all OSs would have to
>> compensate for this in the same way as Linux, and therefore this should be 
>> handled
>> automatically.
>>
>> AFAICT this then only leaves the question: why does the firmware set
>> PCI_INTERRUPT_LINE to 9, which is presumably why you are seeing problems 
>> running
>> MorphOS under QEMU.
> 
> Linux does try to handle both true native mode and half-native mode. It only 
> uses
> half-native mode if finds IRQ14 on Pegasos, otherwise skips Pegasos specific 
> fixup
> and uses true native mode setup. I don't know what MorphOS does but I think 
> it justs
> knows that Pegasos2 has this quirk and does not look at the device tree at 
> all.
> 
>> Could it be that setting prog-if to 0x8a legacy mode also resets 

Re: New Hardware model emulation

2020-03-03 Thread Stefan Hajnoczi
On Tue, Mar 3, 2020 at 5:12 PM Priyamvad Acharya
 wrote:
> > These errors are probably due to the Makefile.objs changes in your commit:
>
> If I am not wrong, we need to add a rule i.e " common-obj-$(CONFIG_TESTPCI) 
> += testpci.o " in Makefile.objs to compile custom device in Qemu.
> Shall I should remove that rule to remove the errors?

No, keep that line.  All the other changes to Makefile.objs in that
commit seem spurious though and should be removed.

Stefan



Re: [PATCH v6 06/18] hw/arm/allwinner: add CPU Configuration module

2020-03-03 Thread Niek Linnenbank
Hi Alex,

First thanks for all your reviews, I'll add the tags in the next version of
this series.

On Tue, Mar 3, 2020 at 1:09 PM Alex Bennée  wrote:

>
> Niek Linnenbank  writes:
>
> > Various Allwinner System on Chip designs contain multiple processors
> > that can be configured and reset using the generic CPU Configuration
> > module interface. This commit adds support for the Allwinner CPU
> > configuration interface which emulates the following features:
> >
> >  * CPU reset
> >  * CPU status
> >
> > Signed-off-by: Niek Linnenbank 
> 
> > +
> > +/* CPUCFG constants */
> > +enum {
> > +CPU_EXCEPTION_LEVEL_ON_RESET = 3, /* EL3 */
> > +};
> > +
> > +static void allwinner_cpucfg_cpu_reset(AwCpuCfgState *s, uint8_t cpu_id)
> > +{
> > +int ret;
> > +
> > +trace_allwinner_cpucfg_cpu_reset(cpu_id, s->entry_addr);
> > +
> > +ret = arm_set_cpu_on(cpu_id, s->entry_addr, 0,
> > + CPU_EXCEPTION_LEVEL_ON_RESET, false);
>
> According to the arm_set_cpu_on code:
>
> if (!target_aa64 && arm_feature(_cpu->env,
> ARM_FEATURE_AARCH64)) {
> /*
>  * For now we don't support booting an AArch64 CPU in AArch32 mode
>  * TODO: We should add this support later
>  */
> qemu_log_mask(LOG_UNIMP,
>   "[ARM]%s: Starting AArch64 CPU %" PRId64
>   " in AArch32 mode is not supported yet\n",
>   __func__, cpuid);
> return QEMU_ARM_POWERCTL_INVALID_PARAM;
> }
>
> Do you really want to reboot in aarch32 mode on a reset? If so we should
> fix the TODO.
>

Very good remark, I'll try to clarify what I did here. In earlier version
of this series, I made this CPU Configuration Module specific
to the Allwinner H3 SoC, as I thought it was a SoC specific component.
Later I discovered that the CPU Configuration Module is
actually a generic Allwinner component and used in multiple SoCs. Taking
that into account, I renamed it to allwinner-cpucfg.c and
updated the comments/docs. That way it should be re-usable in future SoC
modules.

The Allwinner H3 has four ARM Cortex-A7 cores and are 32-bit, so in the
early version I filled the @target_aa64 parameter with false to
keep it in 32-bit mode. And for usage in the current Allwinner H3 SoC that
is sufficient, but as soon as a potential new SoC implementation
with a 64-bit CPU starts to use this module, the hardcoded @target_aa64
parameter will become a problem.

And the TODO inside the arm_set_cpu_on() function I was not yet aware of as
well, so that will also need to be resolved
indeed once this module is going to be used for a new SoC with a 64-bit CPU.

Maybe I should just use some function to check if the current emulated CPU
its 32-bit or 64-bit and use that for @target_aa64?
That way the CPU Configuration Module itself should be ready for 64-bit and
the TODO for arm_set_cpu_on() can be
resolved in a later series for newer SoCs.

Regards,
Niek





>
> --
> Alex Bennée
>


-- 
Niek Linnenbank


[PATCH v5 16/16] tests: Update the Unit tests

2020-03-03 Thread Babu Moger
Since the topology routines have changed, update
the unit tests to use the new APIs.

Signed-off-by: Babu Moger 
---
 tests/test-x86-cpuid.c |  115 
 1 file changed, 68 insertions(+), 47 deletions(-)

diff --git a/tests/test-x86-cpuid.c b/tests/test-x86-cpuid.c
index 1942287f33..00553c1d77 100644
--- a/tests/test-x86-cpuid.c
+++ b/tests/test-x86-cpuid.c
@@ -28,79 +28,100 @@
 
 static void test_topo_bits(void)
 {
+X86CPUTopoInfo topo_info = {0};
+
 /* simple tests for 1 thread per core, 1 core per die, 1 die per package */
-g_assert_cmpuint(apicid_smt_width(1, 1, 1), ==, 0);
-g_assert_cmpuint(apicid_core_width(1, 1, 1), ==, 0);
-g_assert_cmpuint(apicid_die_width(1, 1, 1), ==, 0);
+topo_info = (X86CPUTopoInfo) {0, 1, 1, 1};
+g_assert_cmpuint(apicid_smt_width(_info), ==, 0);
+g_assert_cmpuint(apicid_core_width(_info), ==, 0);
+g_assert_cmpuint(apicid_die_width(_info), ==, 0);
 
-g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 1, 0), ==, 0);
-g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 1, 1), ==, 1);
-g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 1, 2), ==, 2);
-g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 1, 3), ==, 3);
+g_assert_cmpuint(x86_apicid_from_cpu_idx(_info, 0), ==, 0);
+g_assert_cmpuint(x86_apicid_from_cpu_idx(_info, 1), ==, 1);
+g_assert_cmpuint(x86_apicid_from_cpu_idx(_info, 2), ==, 2);
+g_assert_cmpuint(x86_apicid_from_cpu_idx(_info, 3), ==, 3);
 
 
 /* Test field width calculation for multiple values
  */
-g_assert_cmpuint(apicid_smt_width(1, 1, 2), ==, 1);
-g_assert_cmpuint(apicid_smt_width(1, 1, 3), ==, 2);
-g_assert_cmpuint(apicid_smt_width(1, 1, 4), ==, 2);
-
-g_assert_cmpuint(apicid_smt_width(1, 1, 14), ==, 4);
-g_assert_cmpuint(apicid_smt_width(1, 1, 15), ==, 4);
-g_assert_cmpuint(apicid_smt_width(1, 1, 16), ==, 4);
-g_assert_cmpuint(apicid_smt_width(1, 1, 17), ==, 5);
-
-
-g_assert_cmpuint(apicid_core_width(1, 30, 2), ==, 5);
-g_assert_cmpuint(apicid_core_width(1, 31, 2), ==, 5);
-g_assert_cmpuint(apicid_core_width(1, 32, 2), ==, 5);
-g_assert_cmpuint(apicid_core_width(1, 33, 2), ==, 6);
-
-g_assert_cmpuint(apicid_die_width(1, 30, 2), ==, 0);
-g_assert_cmpuint(apicid_die_width(2, 30, 2), ==, 1);
-g_assert_cmpuint(apicid_die_width(3, 30, 2), ==, 2);
-g_assert_cmpuint(apicid_die_width(4, 30, 2), ==, 2);
+topo_info = (X86CPUTopoInfo) {0, 1, 1, 2};
+g_assert_cmpuint(apicid_smt_width(_info), ==, 1);
+topo_info = (X86CPUTopoInfo) {0, 1, 1, 3};
+g_assert_cmpuint(apicid_smt_width(_info), ==, 2);
+topo_info = (X86CPUTopoInfo) {0, 1, 1, 4};
+g_assert_cmpuint(apicid_smt_width(_info), ==, 2);
+
+topo_info = (X86CPUTopoInfo) {0, 1, 1, 14};
+g_assert_cmpuint(apicid_smt_width(_info), ==, 4);
+topo_info = (X86CPUTopoInfo) {0, 1, 1, 15};
+g_assert_cmpuint(apicid_smt_width(_info), ==, 4);
+topo_info = (X86CPUTopoInfo) {0, 1, 1, 16};
+g_assert_cmpuint(apicid_smt_width(_info), ==, 4);
+topo_info = (X86CPUTopoInfo) {0, 1, 1, 17};
+g_assert_cmpuint(apicid_smt_width(_info), ==, 5);
+
+
+topo_info = (X86CPUTopoInfo) {0, 1, 30, 2};
+g_assert_cmpuint(apicid_core_width(_info), ==, 5);
+topo_info = (X86CPUTopoInfo) {0, 1, 31, 2};
+g_assert_cmpuint(apicid_core_width(_info), ==, 5);
+topo_info = (X86CPUTopoInfo) {0, 1, 32, 2};
+g_assert_cmpuint(apicid_core_width(_info), ==, 5);
+topo_info = (X86CPUTopoInfo) {0, 1, 33, 2};
+g_assert_cmpuint(apicid_core_width(_info), ==, 6);
+
+topo_info = (X86CPUTopoInfo) {0, 1, 30, 2};
+g_assert_cmpuint(apicid_die_width(_info), ==, 0);
+topo_info = (X86CPUTopoInfo) {0, 2, 30, 2};
+g_assert_cmpuint(apicid_die_width(_info), ==, 1);
+topo_info = (X86CPUTopoInfo) {0, 3, 30, 2};
+g_assert_cmpuint(apicid_die_width(_info), ==, 2);
+topo_info = (X86CPUTopoInfo) {0, 4, 30, 2};
+g_assert_cmpuint(apicid_die_width(_info), ==, 2);
 
 /* build a weird topology and see if IDs are calculated correctly
  */
 
 /* This will use 2 bits for thread ID and 3 bits for core ID
  */
-g_assert_cmpuint(apicid_smt_width(1, 6, 3), ==, 2);
-g_assert_cmpuint(apicid_core_offset(1, 6, 3), ==, 2);
-g_assert_cmpuint(apicid_die_offset(1, 6, 3), ==, 5);
-g_assert_cmpuint(apicid_pkg_offset(1, 6, 3), ==, 5);
-
-g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 0), ==, 0);
-g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 1), ==, 1);
-g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 2), ==, 2);
-
-g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 1 * 3 + 0), ==,
+topo_info = (X86CPUTopoInfo) {0, 1, 6, 3};
+g_assert_cmpuint(apicid_smt_width(_info), ==, 2);
+g_assert_cmpuint(apicid_core_offset(_info), ==, 2);
+g_assert_cmpuint(apicid_die_offset(_info), ==, 5);
+g_assert_cmpuint(apicid_pkg_offset(_info), ==, 5);
+
+topo_info = (X86CPUTopoInfo) {0, 

[PATCH v5 12/16] hw/i386: Use the apicid handlers from X86MachineState

2020-03-03 Thread Babu Moger
Check and Load the apicid handlers from X86CPUDefinition if available.
Update the calling convention for the apicid handlers.

Signed-off-by: Babu Moger 
---
 hw/i386/pc.c  |6 +++---
 hw/i386/x86.c |   11 +++
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 17cce3f074..c600ba0432 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1581,14 +1581,14 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 topo_ids.die_id = cpu->die_id;
 topo_ids.core_id = cpu->core_id;
 topo_ids.smt_id = cpu->thread_id;
-cpu->apic_id = x86_apicid_from_topo_ids(_info, _ids);
+cpu->apic_id = x86ms->apicid_from_topo_ids(_info, _ids);
 }
 
 cpu_slot = pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, );
 if (!cpu_slot) {
 MachineState *ms = MACHINE(pcms);
 
-x86_topo_ids_from_apicid(cpu->apic_id, _info, _ids);
+x86ms->topo_ids_from_apicid(cpu->apic_id, _info, _ids);
 error_setg(errp,
 "Invalid CPU [socket: %u, die: %u, core: %u, thread: %u] with"
 " APIC ID %" PRIu32 ", valid index range 0:%d",
@@ -1609,7 +1609,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 /* TODO: move socket_id/core_id/thread_id checks into x86_cpu_realizefn()
  * once -smp refactoring is complete and there will be CPU private
  * CPUState::nr_cores and CPUState::nr_threads fields instead of globals */
-x86_topo_ids_from_apicid(cpu->apic_id, _info, _ids);
+x86ms->topo_ids_from_apicid(cpu->apic_id, _info, _ids);
 if (cpu->socket_id != -1 && cpu->socket_id != topo_ids.pkg_id) {
 error_setg(errp, "property socket-id: %u doesn't match set apic-id:"
 " 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id,
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 15b7815bb0..d46dd4ad9e 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -86,7 +86,7 @@ uint32_t x86_cpu_apic_id_from_index(X86MachineState *x86ms,
 
 init_topo_info(_info, x86ms);
 
-correct_id = x86_apicid_from_cpu_idx(_info, cpu_index);
+correct_id = x86ms->apicid_from_cpu_idx(_info, cpu_index);
 if (x86mc->compat_apic_id_mode) {
 if (cpu_index != correct_id && !warned && !qtest_enabled()) {
 error_report("APIC IDs set in compatibility mode, "
@@ -158,8 +158,8 @@ int64_t x86_get_default_cpu_node_id(const MachineState *ms, 
int idx)
init_topo_info(_info, x86ms);
 
assert(idx < ms->possible_cpus->len);
-   x86_topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id,
-_info, _ids);
+   x86ms->topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id,
+   _info, _ids);
return topo_ids.pkg_id % ms->numa_state->num_nodes;
 }
 
@@ -179,6 +179,9 @@ const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState 
*ms)
 return ms->possible_cpus;
 }
 
+/* Initialize apicid handlers */
+cpu_x86_init_apicid_fns(ms);
+
 ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
   sizeof(CPUArchId) * max_cpus);
 ms->possible_cpus->len = max_cpus;
@@ -192,7 +195,7 @@ const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState 
*ms)
 ms->possible_cpus->cpus[i].vcpus_count = 1;
 ms->possible_cpus->cpus[i].arch_id =
 x86_cpu_apic_id_from_index(x86ms, i);
-x86_topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id,
+x86ms->topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id,
  _info, _ids);
 ms->possible_cpus->cpus[i].props.has_socket_id = true;
 ms->possible_cpus->cpus[i].props.socket_id = topo_ids.pkg_id;




[PATCH v5 15/16] i386: Fix pkg_id offset for EPYC cpu models

2020-03-03 Thread Babu Moger
If the system is numa configured the pkg_offset needs
to be adjusted for EPYC cpu models. Fix it calling the
model specific handler.

Signed-off-by: Babu Moger 
---
 hw/i386/pc.c  |1 +
 target/i386/cpu.c |4 ++--
 target/i386/cpu.h |1 +
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index c600ba0432..b6237a3a14 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1527,6 +1527,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 
 env->nr_dies = x86ms->smp_dies;
 env->nr_nodes = topo_info.nodes_per_pkg;
+env->pkg_offset = x86ms->apicid_pkg_offset(_info);
 
 /*
  * If APIC ID is not set,
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index f870f7c55b..9b160cbdd1 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -5503,7 +5503,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
 *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
 break;
 case 1:
-*eax = apicid_pkg_offset(_info);
+*eax = env->pkg_offset;
 *ebx = cs->nr_cores * cs->nr_threads;
 *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
 break;
@@ -5537,7 +5537,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
 *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
 break;
 case 2:
-*eax = apicid_pkg_offset(_info);
+*eax = env->pkg_offset;
 *ebx = env->nr_dies * cs->nr_cores * cs->nr_threads;
 *ecx |= CPUID_TOPOLOGY_LEVEL_DIE;
 break;
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 34f0d994ef..aac86af5cf 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1608,6 +1608,7 @@ typedef struct CPUX86State {
 
 unsigned nr_dies;
 unsigned nr_nodes;
+unsigned pkg_offset;
 } CPUX86State;
 
 struct kvm_msrs;




[PATCH v5 14/16] hw/i386: Move arch_id decode inside x86_cpus_init

2020-03-03 Thread Babu Moger
Apicid calculation depends on knowing the total number of numa nodes
for EPYC cpu models. Right now, we are calculating the arch_id while
parsing the numa(parse_numa). At this time, it is not known how many
total numa nodes are configured in the system.

Move the arch_id inside x86_cpus_init. At this time smp parameter is already
completed and numa node information is available.

Signed-off-by: Babu Moger 
---
 hw/i386/x86.c |   17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index d46dd4ad9e..66998b065c 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -121,6 +121,9 @@ void x86_cpus_init(X86MachineState *x86ms, int 
default_cpu_version)
 MachineState *ms = MACHINE(x86ms);
 MachineClass *mc = MACHINE_GET_CLASS(x86ms);
 
+/* Initialize apicid handlers first */
+cpu_x86_init_apicid_fns(ms);
+
 x86_cpu_set_default_version(default_cpu_version);
 
 /*
@@ -134,6 +137,12 @@ void x86_cpus_init(X86MachineState *x86ms, int 
default_cpu_version)
 x86ms->apic_id_limit = x86_cpu_apic_id_from_index(x86ms,
   ms->smp.max_cpus - 1) + 
1;
 possible_cpus = mc->possible_cpu_arch_ids(ms);
+
+for (i = 0; i < ms->smp.cpus; i++) {
+ms->possible_cpus->cpus[i].arch_id =
+x86_cpu_apic_id_from_index(x86ms, i);
+}
+
 for (i = 0; i < ms->smp.cpus; i++) {
 x86_cpu_new(x86ms, possible_cpus->cpus[i].arch_id, _fatal);
 }
@@ -158,8 +167,7 @@ int64_t x86_get_default_cpu_node_id(const MachineState *ms, 
int idx)
init_topo_info(_info, x86ms);
 
assert(idx < ms->possible_cpus->len);
-   x86ms->topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id,
-   _info, _ids);
+   x86_topo_ids_from_idx(_info, idx, _ids);
return topo_ids.pkg_id % ms->numa_state->num_nodes;
 }
 
@@ -193,10 +201,7 @@ const CPUArchIdList 
*x86_possible_cpu_arch_ids(MachineState *ms)
 
 ms->possible_cpus->cpus[i].type = ms->cpu_type;
 ms->possible_cpus->cpus[i].vcpus_count = 1;
-ms->possible_cpus->cpus[i].arch_id =
-x86_cpu_apic_id_from_index(x86ms, i);
-x86ms->topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id,
- _info, _ids);
+x86_topo_ids_from_idx(_info, i, _ids);
 ms->possible_cpus->cpus[i].props.has_socket_id = true;
 ms->possible_cpus->cpus[i].props.socket_id = topo_ids.pkg_id;
 if (x86ms->smp_dies > 1) {




[PATCH v5 11/16] target/i386: Load apicid model specific handlers from X86CPUDefinition

2020-03-03 Thread Babu Moger
Load the model specific handlers if available or else default handlers
will be loaded. Add the model specific handlers if apicid decoding
differs from the standard sequential numbering.

Signed-off-by: Babu Moger 
---
 target/i386/cpu.c |   34 ++
 target/i386/cpu.h |1 +
 2 files changed, 35 insertions(+)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index c75cf744ab..f33d8b77f5 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -51,6 +51,7 @@
 #include "sysemu/sysemu.h"
 #include "sysemu/tcg.h"
 #include "hw/qdev-properties.h"
+#include "hw/i386/x86.h"
 #include "hw/i386/topology.h"
 #ifndef CONFIG_USER_ONLY
 #include "exec/address-spaces.h"
@@ -1614,6 +1615,16 @@ typedef struct X86CPUDefinition {
 FeatureWordArray features;
 const char *model_id;
 CPUCaches *cache_info;
+
+/* Apic id specific handlers */
+uint32_t (*apicid_from_cpu_idx)(X86CPUTopoInfo *topo_info,
+unsigned cpu_index);
+void (*topo_ids_from_apicid)(apic_id_t apicid, X86CPUTopoInfo *topo_info,
+ X86CPUTopoIDs *topo_ids);
+apic_id_t (*apicid_from_topo_ids)(X86CPUTopoInfo *topo_info,
+  const X86CPUTopoIDs *topo_ids);
+uint32_t (*apicid_pkg_offset)(X86CPUTopoInfo *topo_info);
+
 /*
  * Definitions for alternative versions of CPU model.
  * List is terminated by item with version == 0.
@@ -1654,6 +1665,29 @@ static const X86CPUVersionDefinition 
*x86_cpu_def_get_versions(X86CPUDefinition
 return def->versions ?: default_version_list;
 }
 
+void cpu_x86_init_apicid_fns(MachineState *machine)
+{
+X86CPUClass *xcc = X86_CPU_CLASS(object_class_by_name(machine->cpu_type));
+X86CPUModel *model = xcc->model;
+X86CPUDefinition *def = model->cpudef;
+X86MachineState *x86ms = X86_MACHINE(machine);
+
+if (def) {
+if (def->apicid_from_cpu_idx) {
+x86ms->apicid_from_cpu_idx = def->apicid_from_cpu_idx;
+}
+if (def->topo_ids_from_apicid) {
+x86ms->topo_ids_from_apicid = def->topo_ids_from_apicid;
+}
+if (def->apicid_from_topo_ids) {
+x86ms->apicid_from_topo_ids = def->apicid_from_topo_ids;
+}
+if (def->apicid_pkg_offset) {
+x86ms->apicid_pkg_offset = def->apicid_pkg_offset;
+}
+}
+}
+
 static CPUCaches epyc_cache_info = {
 .l1d_cache = &(CPUCacheInfo) {
 .type = DATA_CACHE,
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 20abbda647..34f0d994ef 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1895,6 +1895,7 @@ void cpu_clear_apic_feature(CPUX86State *env);
 void host_cpuid(uint32_t function, uint32_t count,
 uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
 void host_vendor_fms(char *vendor, int *family, int *model, int *stepping);
+void cpu_x86_init_apicid_fns(MachineState *machine);
 
 /* helper.c */
 bool x86_cpu_tlb_fill(CPUState *cs, vaddr address, int size,




Re: [PATCH v6 6/9] iotests: use python logging for iotests.log()

2020-03-03 Thread John Snow



On 2/27/20 9:21 AM, Max Reitz wrote:
> On 27.02.20 01:06, John Snow wrote:
>> We can turn logging on/off globally instead of per-function.
>>
>> Remove use_log from run_job, and use python logging to turn on
>> diffable output when we run through a script entry point.
>>
>> iotest 245 changes output order due to buffering reasons.
>>
>> Signed-off-by: John Snow 
>> ---
>>  tests/qemu-iotests/030|  4 +--
>>  tests/qemu-iotests/245|  1 +
>>  tests/qemu-iotests/245.out| 24 -
>>  tests/qemu-iotests/iotests.py | 50 +--
>>  4 files changed, 45 insertions(+), 34 deletions(-)
> 
> [...]
> 
>> diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
>> index b02d7932fa..60c4c7f736 100644
>> --- a/tests/qemu-iotests/iotests.py
>> +++ b/tests/qemu-iotests/iotests.py
>> @@ -35,6 +35,14 @@
>>  
>>  assert sys.version_info >= (3, 6)
>>  
>> +# Use this logger for logging messages directly from the iotests module
>> +logger = logging.getLogger('qemu.iotests')
>> +logger.addHandler(logging.NullHandler())
> 
> Hm, I never see another handler added to this, so how can these messages
> actually be printed?  Will enabling debug mode somehow make all loggers
> print everything?
> 

Implicit fallback to root logger which handles them when the root logger
is configured, which happens when logging.basicConfig is called.

>> +# Use this logger for messages that ought to be used for diff output.
>> +test_logger = logging.getLogger('qemu.iotests.diff_io')
> 
> Also, why does logger get a null handler and this by default does not?
> I’m asking because test_logger makes it look like you don’t necessarily
> need a handler for output to be silently discarded.
> 
> Max
> 

It's a library trick. By adding a null handler at `qemu.iotests` I add a
default handler to everything produced by iotests. When logging is not
configured, this stops messages from being printed -- there IS a default
"nonconfigured" logging behavior and this stops it.

What I learned since the last time I wrote this patchset is that you
only need a NullHandler at some particular root, so "qemu.iotests"
suffices. "qemu.iotests.diff_io" is a child of that other logger.

>>  # This will not work if arguments contain spaces but is necessary if we
>>  # want to support the override options that ./check supports.
>>  qemu_img_args = [os.environ.get('QEMU_IMG_PROG', 'qemu-img')]
> 

-- 
—js




[PATCH v5 10/16] hw/i386: Introduce apicid functions inside X86MachineState

2020-03-03 Thread Babu Moger
Introduce model specific apicid functions inside X86MachineState.
These functions will be loaded from X86CPUDefinition.

Signed-off-by: Babu Moger 
---
 hw/i386/x86.c |5 +
 include/hw/i386/x86.h |9 +
 2 files changed, 14 insertions(+)

diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 929b80c9c7..15b7815bb0 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -911,6 +911,11 @@ static void x86_machine_initfn(Object *obj)
 x86ms->smm = ON_OFF_AUTO_AUTO;
 x86ms->max_ram_below_4g = 0; /* use default */
 x86ms->smp_dies = 1;
+
+x86ms->apicid_from_cpu_idx = x86_apicid_from_cpu_idx;
+x86ms->topo_ids_from_apicid = x86_topo_ids_from_apicid;
+x86ms->apicid_from_topo_ids = x86_apicid_from_topo_ids;
+x86ms->apicid_pkg_offset = apicid_pkg_offset;
 }
 
 static void x86_machine_class_init(ObjectClass *oc, void *data)
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
index 22babcb3bb..2643b57629 100644
--- a/include/hw/i386/x86.h
+++ b/include/hw/i386/x86.h
@@ -65,6 +65,15 @@ typedef struct {
 
 OnOffAuto smm;
 
+/* Apic id specific handlers */
+uint32_t (*apicid_from_cpu_idx)(X86CPUTopoInfo *topo_info,
+unsigned cpu_index);
+void (*topo_ids_from_apicid)(apic_id_t apicid, X86CPUTopoInfo *topo_info,
+ X86CPUTopoIDs *topo_ids);
+apic_id_t (*apicid_from_topo_ids)(X86CPUTopoInfo *topo_info,
+  const X86CPUTopoIDs *topo_ids);
+uint32_t (*apicid_pkg_offset)(X86CPUTopoInfo *topo_info);
+
 /*
  * Address space used by IOAPIC device. All IOAPIC interrupts
  * will be translated to MSI messages in the address space.




[PATCH v5 13/16] target/i386: Add EPYC model specific handlers

2020-03-03 Thread Babu Moger
Add the new EPYC model specific handlers to fix the apicid decoding.

The APIC ID is decoded based on the sequence sockets->dies->cores->threads.
This works fine for most standard AMD and other vendors' configurations,
but this decoding sequence does not follow that of AMD's APIC ID enumeration
strictly. In some cases this can cause CPU topology inconsistency.

When booting a guest VM, the kernel tries to validate the topology, and finds
it inconsistent with the enumeration of EPYC cpu models. The more details are
in the bug https://bugzilla.redhat.com/show_bug.cgi?id=1728166.

To fix the problem we need to build the topology as per the Processor
Programming Reference (PPR) for AMD Family 17h Model 01h, Revision B1
Processors.
It is available at https://www.amd.com/system/files/TechDocs/55570-B1_PUB.zip

Here is the text from the PPR.
Operating systems are expected to use Core::X86::Cpuid::SizeId[ApicIdSize], the
number of least significant bits in the Initial APIC ID that indicate core ID
within a processor, in constructing per-core CPUID masks.
Core::X86::Cpuid::SizeId[ApicIdSize] determines the maximum number of cores
(MNC) that the processor could theoretically support, not the actual number of
cores that are actually implemented or enabled on the processor, as indicated
by Core::X86::Cpuid::SizeId[NC].
Each Core::X86::Apic::ApicId[ApicId] register is preset as follows:
• ApicId[6] = Socket ID.
• ApicId[5:4] = Node ID.
• ApicId[3] = Logical CCX L3 complex ID
• ApicId[2:0]= (SMT) ? {LogicalCoreID[1:0],ThreadId} : {1'b0,LogicalCoreID[1:0]}

Signed-off-by: Babu Moger 
---
 target/i386/cpu.c |4 
 1 file changed, 4 insertions(+)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index f33d8b77f5..f870f7c55b 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -3884,6 +3884,10 @@ static X86CPUDefinition builtin_x86_defs[] = {
 .xlevel = 0x801E,
 .model_id = "AMD EPYC Processor",
 .cache_info = _cache_info,
+.apicid_from_cpu_idx = x86_apicid_from_cpu_idx_epyc,
+.topo_ids_from_apicid = x86_topo_ids_from_apicid_epyc,
+.apicid_from_topo_ids = x86_apicid_from_topo_ids_epyc,
+.apicid_pkg_offset = apicid_pkg_offset_epyc,
 .versions = (X86CPUVersionDefinition[]) {
 { .version = 1 },
 {




[PATCH v5 08/16] hw/386: Add EPYC mode topology decoding functions

2020-03-03 Thread Babu Moger
These functions add support for building EPYC mode topology given the smp
details like numa nodes, cores, threads and sockets.

The new apic id decoding is mostly similar to current apic id decoding
except that it adds a new field node_id when numa configured. Removes all
the hardcoded values. Subsequent patches will use these functions to build
the topology.

Following functions are added.
apicid_llc_width_epyc
apicid_llc_offset_epyc
apicid_pkg_offset_epyc
apicid_from_topo_ids_epyc
x86_topo_ids_from_idx_epyc
x86_topo_ids_from_apicid_epyc
x86_apicid_from_cpu_idx_epyc

The topology details are available in Processor Programming Reference (PPR)
for AMD Family 17h Model 01h, Revision B1 Processors. The revision guides are
available from the bugzilla Link below.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=206537

Signed-off-by: Babu Moger 
Acked-by: Igor Mammedov 
---
 include/hw/i386/topology.h |  100 
 1 file changed, 100 insertions(+)

diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h
index b9593b9905..07239f95f4 100644
--- a/include/hw/i386/topology.h
+++ b/include/hw/i386/topology.h
@@ -47,6 +47,7 @@ typedef uint32_t apic_id_t;
 
 typedef struct X86CPUTopoIDs {
 unsigned pkg_id;
+unsigned node_id;
 unsigned die_id;
 unsigned core_id;
 unsigned smt_id;
@@ -88,6 +89,11 @@ static inline unsigned apicid_die_width(X86CPUTopoInfo 
*topo_info)
 return apicid_bitwidth_for_count(topo_info->dies_per_pkg);
 }
 
+/* Bit width of the node_id field per socket */
+static inline unsigned apicid_node_width_epyc(X86CPUTopoInfo *topo_info)
+{
+return apicid_bitwidth_for_count(MAX(topo_info->nodes_per_pkg, 1));
+}
 /* Bit offset of the Core_ID field
  */
 static inline unsigned apicid_core_offset(X86CPUTopoInfo *topo_info)
@@ -108,6 +114,100 @@ static inline unsigned apicid_pkg_offset(X86CPUTopoInfo 
*topo_info)
 return apicid_die_offset(topo_info) + apicid_die_width(topo_info);
 }
 
+#define NODE_ID_OFFSET 3 /* Minimum node_id offset if numa configured */
+
+/*
+ * Bit offset of the node_id field
+ *
+ * Make sure nodes_per_pkg >  0 if numa configured else zero.
+ */
+static inline unsigned apicid_node_offset_epyc(X86CPUTopoInfo *topo_info)
+{
+unsigned offset = apicid_die_offset(topo_info) +
+  apicid_die_width(topo_info);
+
+if (topo_info->nodes_per_pkg) {
+return MAX(NODE_ID_OFFSET, offset);
+} else {
+return offset;
+}
+}
+
+/* Bit offset of the Pkg_ID (socket ID) field */
+static inline unsigned apicid_pkg_offset_epyc(X86CPUTopoInfo *topo_info)
+{
+return apicid_node_offset_epyc(topo_info) +
+   apicid_node_width_epyc(topo_info);
+}
+
+/*
+ * Make APIC ID for the CPU based on Pkg_ID, Core_ID, SMT_ID
+ *
+ * The caller must make sure core_id < nr_cores and smt_id < nr_threads.
+ */
+static inline apic_id_t
+x86_apicid_from_topo_ids_epyc(X86CPUTopoInfo *topo_info,
+  const X86CPUTopoIDs *topo_ids)
+{
+return (topo_ids->pkg_id  << apicid_pkg_offset_epyc(topo_info)) |
+   (topo_ids->node_id << apicid_node_offset_epyc(topo_info)) |
+   (topo_ids->die_id  << apicid_die_offset(topo_info)) |
+   (topo_ids->core_id << apicid_core_offset(topo_info)) |
+   topo_ids->smt_id;
+}
+
+static inline void x86_topo_ids_from_idx_epyc(X86CPUTopoInfo *topo_info,
+  unsigned cpu_index,
+  X86CPUTopoIDs *topo_ids)
+{
+unsigned nr_nodes = MAX(topo_info->nodes_per_pkg, 1);
+unsigned nr_dies = topo_info->dies_per_pkg;
+unsigned nr_cores = topo_info->cores_per_die;
+unsigned nr_threads = topo_info->threads_per_core;
+unsigned cores_per_node = DIV_ROUND_UP((nr_dies * nr_cores * nr_threads),
+nr_nodes);
+
+topo_ids->pkg_id = cpu_index / (nr_dies * nr_cores * nr_threads);
+topo_ids->node_id = (cpu_index / cores_per_node) % nr_nodes;
+topo_ids->die_id = cpu_index / (nr_cores * nr_threads) % nr_dies;
+topo_ids->core_id = cpu_index / nr_threads % nr_cores;
+topo_ids->smt_id = cpu_index % nr_threads;
+}
+
+/*
+ * Calculate thread/core/package IDs for a specific topology,
+ * based on APIC ID
+ */
+static inline void x86_topo_ids_from_apicid_epyc(apic_id_t apicid,
+X86CPUTopoInfo *topo_info,
+X86CPUTopoIDs *topo_ids)
+{
+topo_ids->smt_id = apicid &
+~(0xUL << apicid_smt_width(topo_info));
+topo_ids->core_id =
+(apicid >> apicid_core_offset(topo_info)) &
+~(0xUL << apicid_core_width(topo_info));
+topo_ids->die_id =
+(apicid >> apicid_die_offset(topo_info)) &
+~(0xUL << apicid_die_width(topo_info));
+topo_ids->node_id =
+(apicid >> 

[PATCH v5 06/16] hw/i386: Update structures to save the number of nodes per package

2020-03-03 Thread Babu Moger
Update structures X86CPUTopoIDs and CPUX86State to hold the number of
nodes per package. This is required to build EPYC mode topology.

Signed-off-by: Babu Moger 
---
 hw/i386/pc.c   |1 +
 hw/i386/x86.c  |1 +
 include/hw/i386/topology.h |1 +
 target/i386/cpu.c  |1 +
 target/i386/cpu.h  |1 +
 5 files changed, 5 insertions(+)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 68bf08f285..3d13cd46d6 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1526,6 +1526,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 init_topo_info(_info, x86ms);
 
 env->nr_dies = x86ms->smp_dies;
+env->nr_nodes = topo_info.nodes_per_pkg;
 
 /*
  * If APIC ID is not set,
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 79badcc4ec..929b80c9c7 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -62,6 +62,7 @@ inline void init_topo_info(X86CPUTopoInfo *topo_info,
 {
 MachineState *ms = MACHINE(x86ms);
 
+topo_info->nodes_per_pkg = ms->numa_state->num_nodes / ms->smp.sockets;
 topo_info->dies_per_pkg = x86ms->smp_dies;
 topo_info->cores_per_die = ms->smp.cores;
 topo_info->threads_per_core = ms->smp.threads;
diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h
index ba52d49079..04f01e2a09 100644
--- a/include/hw/i386/topology.h
+++ b/include/hw/i386/topology.h
@@ -53,6 +53,7 @@ typedef struct X86CPUTopoIDs {
 } X86CPUTopoIDs;
 
 typedef struct X86CPUTopoInfo {
+unsigned nodes_per_pkg;
 unsigned dies_per_pkg;
 unsigned cores_per_die;
 unsigned threads_per_core;
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 1263271edd..40670f8aca 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6829,6 +6829,7 @@ static void x86_cpu_initfn(Object *obj)
 FeatureWord w;
 
 env->nr_dies = 1;
+env->nr_nodes = 1;
 cpu_set_cpustate_pointers(cpu);
 
 object_property_add(obj, "family", "int",
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 576f309bbf..20abbda647 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1607,6 +1607,7 @@ typedef struct CPUX86State {
 TPRAccess tpr_access_type;
 
 unsigned nr_dies;
+unsigned nr_nodes;
 } CPUX86State;
 
 struct kvm_msrs;




Re: [PATCH v6 7/9] iotests: ignore import warnings from pylint

2020-03-03 Thread John Snow



On 2/27/20 9:14 AM, Philippe Mathieu-Daudé wrote:
> On 2/27/20 1:06 AM, John Snow wrote:
>> The right way to solve this is to come up with a virtual environment
>> infrastructure that sets all the paths correctly, and/or to create
>> installable python modules that can be imported normally.
>>
>> That's hard, so just silence this error for now.
> 
> I'm tempted to NAck this and require an "installable python module"...
> 
> Let's discuss why it is that hard!
> 

I've been tricked into this before. It's not work I am interested in
doing right now; it's WAY beyond the scope of what I am doing here.

It involves properly factoring all of our python code, deciding which
portions are meant to be installed separately from QEMU itself, coming
up with a versioning scheme, packaging code, and moving code around in
many places.

Then it involves coming up with tooling and infrastructure for creating
virtual environments, installing the right packages to it, and using it
to run our python tests.

No, that's way too invasive. I'm not doing it and I will scream loudly
if you make me.

A less invasive hack involves setting the python import path in a
consolidated spot so that python knows where it can import from. This
works, but might break the ability to run such tests as one-offs without
executing the environment setup.

Again, not work I care to do right now and so I won't. The benefit of
these patches is to provide some minimum viable CI CQA for Python where
we had none before, NOT fix every possible Python problem in one shot.

--js

>>
>> Signed-off-by: John Snow 
>> ---
>>   tests/qemu-iotests/iotests.py | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/tests/qemu-iotests/iotests.py
>> b/tests/qemu-iotests/iotests.py
>> index 60c4c7f736..214f59995e 100644
>> --- a/tests/qemu-iotests/iotests.py
>> +++ b/tests/qemu-iotests/iotests.py
>> @@ -30,6 +30,7 @@
>>   from collections import OrderedDict
>>   from typing import Collection
>>   +# pylint: disable=import-error, wrong-import-position
>>   sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..',
>> 'python'))
>>   from qemu import qtest
>>  
> 




[PATCH v5 09/16] target/i386: Cleanup and use the EPYC mode topology functions

2020-03-03 Thread Babu Moger
Use the new functions from topology.h and delete the unused code. Given the
sockets, nodes, cores and threads, the new functions generate apic id for EPYC
mode. Removes all the hardcoded values.

Signed-off-by: Babu Moger 
---
 target/i386/cpu.c |  162 +++--
 1 file changed, 35 insertions(+), 127 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 40670f8aca..c75cf744ab 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -338,68 +338,15 @@ static void encode_cache_cpuid8006(CPUCacheInfo *l2,
 }
 }
 
-/*
- * Definitions used for building CPUID Leaf 0x801D and 0x801E
- * Please refer to the AMD64 Architecture Programmer’s Manual Volume 3.
- * Define the constants to build the cpu topology. Right now, TOPOEXT
- * feature is enabled only on EPYC. So, these constants are based on
- * EPYC supported configurations. We may need to handle the cases if
- * these values change in future.
- */
-/* Maximum core complexes in a node */
-#define MAX_CCX 2
-/* Maximum cores in a core complex */
-#define MAX_CORES_IN_CCX 4
-/* Maximum cores in a node */
-#define MAX_CORES_IN_NODE 8
-/* Maximum nodes in a socket */
-#define MAX_NODES_PER_SOCKET 4
-
-/*
- * Figure out the number of nodes required to build this config.
- * Max cores in a node is 8
- */
-static int nodes_in_socket(int nr_cores)
-{
-int nodes;
-
-nodes = DIV_ROUND_UP(nr_cores, MAX_CORES_IN_NODE);
-
-   /* Hardware does not support config with 3 nodes, return 4 in that case */
-return (nodes == 3) ? 4 : nodes;
-}
-
-/*
- * Decide the number of cores in a core complex with the given nr_cores using
- * following set constants MAX_CCX, MAX_CORES_IN_CCX, MAX_CORES_IN_NODE and
- * MAX_NODES_PER_SOCKET. Maintain symmetry as much as possible
- * L3 cache is shared across all cores in a core complex. So, this will also
- * tell us how many cores are sharing the L3 cache.
- */
-static int cores_in_core_complex(int nr_cores)
-{
-int nodes;
-
-/* Check if we can fit all the cores in one core complex */
-if (nr_cores <= MAX_CORES_IN_CCX) {
-return nr_cores;
-}
-/* Get the number of nodes required to build this config */
-nodes = nodes_in_socket(nr_cores);
-
-/*
- * Divide the cores accros all the core complexes
- * Return rounded up value
- */
-return DIV_ROUND_UP(nr_cores, nodes * MAX_CCX);
-}
-
 /* Encode cache info for CPUID[801D] */
-static void encode_cache_cpuid801d(CPUCacheInfo *cache, CPUState *cs,
-uint32_t *eax, uint32_t *ebx,
-uint32_t *ecx, uint32_t *edx)
+static void encode_cache_cpuid801d(CPUCacheInfo *cache,
+   X86CPUTopoInfo *topo_info,
+   uint32_t *eax, uint32_t *ebx,
+   uint32_t *ecx, uint32_t *edx)
 {
 uint32_t l3_cores;
+unsigned nodes = MAX(topo_info->nodes_per_pkg, 1);
+
 assert(cache->size == cache->line_size * cache->associativity *
   cache->partitions * cache->sets);
 
@@ -408,10 +355,13 @@ static void encode_cache_cpuid801d(CPUCacheInfo 
*cache, CPUState *cs,
 
 /* L3 is shared among multiple cores */
 if (cache->level == 3) {
-l3_cores = cores_in_core_complex(cs->nr_cores);
-*eax |= ((l3_cores * cs->nr_threads) - 1) << 14;
+l3_cores = DIV_ROUND_UP((topo_info->dies_per_pkg *
+ topo_info->cores_per_die *
+ topo_info->threads_per_core),
+ nodes);
+*eax |= (l3_cores - 1) << 14;
 } else {
-*eax |= ((cs->nr_threads - 1) << 14);
+*eax |= ((topo_info->threads_per_core - 1) << 14);
 }
 
 assert(cache->line_size > 0);
@@ -431,55 +381,17 @@ static void encode_cache_cpuid801d(CPUCacheInfo 
*cache, CPUState *cs,
(cache->complex_indexing ? CACHE_COMPLEX_IDX : 0);
 }
 
-/* Data structure to hold the configuration info for a given core index */
-struct core_topology {
-/* core complex id of the current core index */
-int ccx_id;
-/*
- * Adjusted core index for this core in the topology
- * This can be 0,1,2,3 with max 4 cores in a core complex
- */
-int core_id;
-/* Node id for this core index */
-int node_id;
-/* Number of nodes in this config */
-int num_nodes;
-};
-
-/*
- * Build the configuration closely match the EPYC hardware. Using the EPYC
- * hardware configuration values (MAX_CCX, MAX_CORES_IN_CCX, MAX_CORES_IN_NODE)
- * right now. This could change in future.
- * nr_cores : Total number of cores in the config
- * core_id  : Core index of the current CPU
- * topo : Data structure to hold all the config info for this core index
- */
-static void build_core_topology(int nr_cores, int core_id,
-struct core_topology *topo)
-{
- 

[PATCH v5 05/16] hw/i386: Remove unnecessary initialization in x86_cpu_new

2020-03-03 Thread Babu Moger
The function pc_cpu_pre_plug takes care of initialization of CPUX86State.
So, remove the initialization here.

Suggested-by: Igor Mammedov 
Signed-off-by: Babu Moger 
---
 hw/i386/x86.c |4 
 1 file changed, 4 deletions(-)

diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 03b8962c98..79badcc4ec 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -103,13 +103,9 @@ void x86_cpu_new(X86MachineState *x86ms, int64_t apic_id, 
Error **errp)
 {
 Object *cpu = NULL;
 Error *local_err = NULL;
-CPUX86State *env = NULL;
 
 cpu = object_new(MACHINE(x86ms)->cpu_type);
 
-env = _CPU(cpu)->env;
-env->nr_dies = x86ms->smp_dies;
-
 object_property_set_uint(cpu, apic_id, "apic-id", _err);
 object_property_set_bool(cpu, true, "realized", _err);
 




[PATCH v5 07/16] hw/i386: Rename apicid_from_topo_ids to x86_apicid_from_topo_ids

2020-03-03 Thread Babu Moger
For consistancy rename apicid_from_topo_ids to x86_apicid_from_topo_ids.
No functional change.

Signed-off-by: Babu Moger 
Reviewed-by: Igor Mammedov 
---
 hw/i386/pc.c   |2 +-
 include/hw/i386/topology.h |6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 3d13cd46d6..17cce3f074 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1581,7 +1581,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 topo_ids.die_id = cpu->die_id;
 topo_ids.core_id = cpu->core_id;
 topo_ids.smt_id = cpu->thread_id;
-cpu->apic_id = apicid_from_topo_ids(_info, _ids);
+cpu->apic_id = x86_apicid_from_topo_ids(_info, _ids);
 }
 
 cpu_slot = pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, );
diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h
index 04f01e2a09..b9593b9905 100644
--- a/include/hw/i386/topology.h
+++ b/include/hw/i386/topology.h
@@ -112,8 +112,8 @@ static inline unsigned apicid_pkg_offset(X86CPUTopoInfo 
*topo_info)
  *
  * The caller must make sure core_id < nr_cores and smt_id < nr_threads.
  */
-static inline apic_id_t apicid_from_topo_ids(X86CPUTopoInfo *topo_info,
- const X86CPUTopoIDs *topo_ids)
+static inline apic_id_t x86_apicid_from_topo_ids(X86CPUTopoInfo *topo_info,
+ const X86CPUTopoIDs *topo_ids)
 {
 return (topo_ids->pkg_id  << apicid_pkg_offset(topo_info)) |
(topo_ids->die_id  << apicid_die_offset(topo_info)) |
@@ -165,7 +165,7 @@ static inline apic_id_t 
x86_apicid_from_cpu_idx(X86CPUTopoInfo *topo_info,
 {
 X86CPUTopoIDs topo_ids;
 x86_topo_ids_from_idx(topo_info, cpu_index, _ids);
-return apicid_from_topo_ids(topo_info, _ids);
+return x86_apicid_from_topo_ids(topo_info, _ids);
 }
 
 #endif /* HW_I386_TOPOLOGY_H */




[PATCH v5 02/16] hw/i386: Introduce X86CPUTopoInfo to contain topology info

2020-03-03 Thread Babu Moger
This is an effort to re-arrange few data structure for better readability.

1. Add X86CPUTopoInfo which will have all the topology informations
   required to build the cpu topology. There is no functional changes.
2. Introduce init_topo_info to initialize X86CPUTopoInfo members from
   X86MachineState.

There is no functional changes.

Signed-off-by: Babu Moger 
---
 hw/i386/pc.c   |   12 ++--
 hw/i386/x86.c  |   32 
 include/hw/i386/topology.h |   38 --
 include/hw/i386/x86.h  |3 +++
 4 files changed, 57 insertions(+), 28 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 715f79f58c..ef23ae2af5 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1514,6 +1514,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 X86MachineState *x86ms = X86_MACHINE(pcms);
 unsigned int smp_cores = ms->smp.cores;
 unsigned int smp_threads = ms->smp.threads;
+X86CPUTopoInfo topo_info;
 
 if(!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) {
 error_setg(errp, "Invalid CPU type, expected cpu type: '%s'",
@@ -1521,6 +1522,8 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 return;
 }
 
+init_topo_info(_info, x86ms);
+
 env->nr_dies = x86ms->smp_dies;
 
 /*
@@ -1576,16 +1579,14 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 topo_ids.die_id = cpu->die_id;
 topo_ids.core_id = cpu->core_id;
 topo_ids.smt_id = cpu->thread_id;
-cpu->apic_id = apicid_from_topo_ids(x86ms->smp_dies, smp_cores,
-smp_threads, _ids);
+cpu->apic_id = apicid_from_topo_ids(_info, _ids);
 }
 
 cpu_slot = pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, );
 if (!cpu_slot) {
 MachineState *ms = MACHINE(pcms);
 
-x86_topo_ids_from_apicid(cpu->apic_id, x86ms->smp_dies,
- smp_cores, smp_threads, _ids);
+x86_topo_ids_from_apicid(cpu->apic_id, _info, _ids);
 error_setg(errp,
 "Invalid CPU [socket: %u, die: %u, core: %u, thread: %u] with"
 " APIC ID %" PRIu32 ", valid index range 0:%d",
@@ -1606,8 +1607,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 /* TODO: move socket_id/core_id/thread_id checks into x86_cpu_realizefn()
  * once -smp refactoring is complete and there will be CPU private
  * CPUState::nr_cores and CPUState::nr_threads fields instead of globals */
-x86_topo_ids_from_apicid(cpu->apic_id, x86ms->smp_dies,
- smp_cores, smp_threads, _ids);
+x86_topo_ids_from_apicid(cpu->apic_id, _info, _ids);
 if (cpu->socket_id != -1 && cpu->socket_id != topo_ids.pkg_id) {
 error_setg(errp, "property socket-id: %u doesn't match set apic-id:"
 " 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id,
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 322fb6abbc..03b8962c98 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -57,6 +57,16 @@
 /* Physical Address of PVH entry point read from kernel ELF NOTE */
 static size_t pvh_start_addr;
 
+inline void init_topo_info(X86CPUTopoInfo *topo_info,
+  const X86MachineState *x86ms)
+{
+MachineState *ms = MACHINE(x86ms);
+
+topo_info->dies_per_pkg = x86ms->smp_dies;
+topo_info->cores_per_die = ms->smp.cores;
+topo_info->threads_per_core = ms->smp.threads;
+}
+
 /*
  * Calculates initial APIC ID for a specific CPU index
  *
@@ -68,13 +78,14 @@ static size_t pvh_start_addr;
 uint32_t x86_cpu_apic_id_from_index(X86MachineState *x86ms,
 unsigned int cpu_index)
 {
-MachineState *ms = MACHINE(x86ms);
 X86MachineClass *x86mc = X86_MACHINE_GET_CLASS(x86ms);
+X86CPUTopoInfo topo_info;
 uint32_t correct_id;
 static bool warned;
 
-correct_id = x86_apicid_from_cpu_idx(x86ms->smp_dies, ms->smp.cores,
- ms->smp.threads, cpu_index);
+init_topo_info(_info, x86ms);
+
+correct_id = x86_apicid_from_cpu_idx(_info, cpu_index);
 if (x86mc->compat_apic_id_mode) {
 if (cpu_index != correct_id && !warned && !qtest_enabled()) {
 error_report("APIC IDs set in compatibility mode, "
@@ -145,19 +156,22 @@ int64_t x86_get_default_cpu_node_id(const MachineState 
*ms, int idx)
 {
X86CPUTopoIDs topo_ids;
X86MachineState *x86ms = X86_MACHINE(ms);
+   X86CPUTopoInfo topo_info;
+
+   init_topo_info(_info, x86ms);
 
assert(idx < ms->possible_cpus->len);
x86_topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id,
-x86ms->smp_dies, ms->smp.cores,
-ms->smp.threads, _ids);
+_info, _ids);
return topo_ids.pkg_id % ms->numa_state->num_nodes;
 }
 
 const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms)
 {
 X86MachineState 

[PATCH v5 04/16] machine: Add SMP Sockets in CpuTopology

2020-03-03 Thread Babu Moger
Store the  smp sockets in CpuTopology. The socket information required to
build the apic id in EPYC mode. Right now socket information is not passed
to down when decoding the apic id. Add the socket information here.

Signed-off-by: Babu Moger 
Reviewed-by: Eduardo Habkost 
Reviewed-by: Igor Mammedov 
---
 hw/core/machine.c   |1 +
 hw/i386/pc.c|1 +
 include/hw/boards.h |2 ++
 vl.c|1 +
 4 files changed, 5 insertions(+)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index d8e30e4895..2582ce94f6 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -728,6 +728,7 @@ static void smp_parse(MachineState *ms, QemuOpts *opts)
 ms->smp.cpus = cpus;
 ms->smp.cores = cores;
 ms->smp.threads = threads;
+ms->smp.sockets = sockets;
 }
 
 if (ms->smp.cpus > 1) {
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index ef23ae2af5..68bf08f285 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -780,6 +780,7 @@ void pc_smp_parse(MachineState *ms, QemuOpts *opts)
 ms->smp.cpus = cpus;
 ms->smp.cores = cores;
 ms->smp.threads = threads;
+ms->smp.sockets = sockets;
 x86ms->smp_dies = dies;
 }
 
diff --git a/include/hw/boards.h b/include/hw/boards.h
index fb1b43d5b9..320dd14e02 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -252,12 +252,14 @@ typedef struct DeviceMemoryState {
  * @cpus: the number of present logical processors on the machine
  * @cores: the number of cores in one package
  * @threads: the number of threads in one core
+ * @sockets: the number of sockets on the machine
  * @max_cpus: the maximum number of logical processors on the machine
  */
 typedef struct CpuTopology {
 unsigned int cpus;
 unsigned int cores;
 unsigned int threads;
+unsigned int sockets;
 unsigned int max_cpus;
 } CpuTopology;
 
diff --git a/vl.c b/vl.c
index 7dcb0879c4..f77b1285c6 100644
--- a/vl.c
+++ b/vl.c
@@ -3949,6 +3949,7 @@ int main(int argc, char **argv, char **envp)
 current_machine->smp.max_cpus = machine_class->default_cpus;
 current_machine->smp.cores = 1;
 current_machine->smp.threads = 1;
+current_machine->smp.sockets = 1;
 
 machine_class->smp_parse(current_machine,
 qemu_opts_find(qemu_find_opts("smp-opts"), NULL));




[PATCH v5 01/16] hw/i386: Rename X86CPUTopoInfo structure to X86CPUTopoIDs

2020-03-03 Thread Babu Moger
Rename few data structures related to X86 topology.  X86CPUTopoIDs will
have individual arch ids. Next patch introduces X86CPUTopoInfo which will
have all topology information(like cores, threads etc..).

Signed-off-by: Babu Moger 
Reviewed-by: Eduardo Habkost 
---
 hw/i386/pc.c   |   45 +++-
 hw/i386/x86.c  |   18 +-
 include/hw/i386/topology.h |   44 +++
 3 files changed, 57 insertions(+), 50 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 2ddce4230a..715f79f58c 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1506,7 +1506,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 int idx;
 CPUState *cs;
 CPUArchId *cpu_slot;
-X86CPUTopoInfo topo;
+X86CPUTopoIDs topo_ids;
 X86CPU *cpu = X86_CPU(dev);
 CPUX86State *env = >env;
 MachineState *ms = MACHINE(hotplug_dev);
@@ -1572,12 +1572,12 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 return;
 }
 
-topo.pkg_id = cpu->socket_id;
-topo.die_id = cpu->die_id;
-topo.core_id = cpu->core_id;
-topo.smt_id = cpu->thread_id;
+topo_ids.pkg_id = cpu->socket_id;
+topo_ids.die_id = cpu->die_id;
+topo_ids.core_id = cpu->core_id;
+topo_ids.smt_id = cpu->thread_id;
 cpu->apic_id = apicid_from_topo_ids(x86ms->smp_dies, smp_cores,
-smp_threads, );
+smp_threads, _ids);
 }
 
 cpu_slot = pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, );
@@ -1585,11 +1585,11 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 MachineState *ms = MACHINE(pcms);
 
 x86_topo_ids_from_apicid(cpu->apic_id, x86ms->smp_dies,
- smp_cores, smp_threads, );
+ smp_cores, smp_threads, _ids);
 error_setg(errp,
 "Invalid CPU [socket: %u, die: %u, core: %u, thread: %u] with"
 " APIC ID %" PRIu32 ", valid index range 0:%d",
-topo.pkg_id, topo.die_id, topo.core_id, topo.smt_id,
+topo_ids.pkg_id, topo_ids.die_id, topo_ids.core_id, 
topo_ids.smt_id,
 cpu->apic_id, ms->possible_cpus->len - 1);
 return;
 }
@@ -1607,34 +1607,37 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
  * once -smp refactoring is complete and there will be CPU private
  * CPUState::nr_cores and CPUState::nr_threads fields instead of globals */
 x86_topo_ids_from_apicid(cpu->apic_id, x86ms->smp_dies,
- smp_cores, smp_threads, );
-if (cpu->socket_id != -1 && cpu->socket_id != topo.pkg_id) {
+ smp_cores, smp_threads, _ids);
+if (cpu->socket_id != -1 && cpu->socket_id != topo_ids.pkg_id) {
 error_setg(errp, "property socket-id: %u doesn't match set apic-id:"
-" 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id, 
topo.pkg_id);
+" 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id,
+topo_ids.pkg_id);
 return;
 }
-cpu->socket_id = topo.pkg_id;
+cpu->socket_id = topo_ids.pkg_id;
 
-if (cpu->die_id != -1 && cpu->die_id != topo.die_id) {
+if (cpu->die_id != -1 && cpu->die_id != topo_ids.die_id) {
 error_setg(errp, "property die-id: %u doesn't match set apic-id:"
-" 0x%x (die-id: %u)", cpu->die_id, cpu->apic_id, topo.die_id);
+" 0x%x (die-id: %u)", cpu->die_id, cpu->apic_id, topo_ids.die_id);
 return;
 }
-cpu->die_id = topo.die_id;
+cpu->die_id = topo_ids.die_id;
 
-if (cpu->core_id != -1 && cpu->core_id != topo.core_id) {
+if (cpu->core_id != -1 && cpu->core_id != topo_ids.core_id) {
 error_setg(errp, "property core-id: %u doesn't match set apic-id:"
-" 0x%x (core-id: %u)", cpu->core_id, cpu->apic_id, topo.core_id);
+" 0x%x (core-id: %u)", cpu->core_id, cpu->apic_id,
+topo_ids.core_id);
 return;
 }
-cpu->core_id = topo.core_id;
+cpu->core_id = topo_ids.core_id;
 
-if (cpu->thread_id != -1 && cpu->thread_id != topo.smt_id) {
+if (cpu->thread_id != -1 && cpu->thread_id != topo_ids.smt_id) {
 error_setg(errp, "property thread-id: %u doesn't match set apic-id:"
-" 0x%x (thread-id: %u)", cpu->thread_id, cpu->apic_id, 
topo.smt_id);
+" 0x%x (thread-id: %u)", cpu->thread_id, cpu->apic_id,
+topo_ids.smt_id);
 return;
 }
-cpu->thread_id = topo.smt_id;
+cpu->thread_id = topo_ids.smt_id;
 
 if (hyperv_feat_enabled(cpu, HYPERV_FEAT_VPINDEX) &&
 !kvm_hv_vpindex_settable()) {
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 7f38e6ba8b..322fb6abbc 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -143,14 +143,14 @@ x86_cpu_index_to_props(MachineState *ms, unsigned 
cpu_index)

[PATCH v5 03/16] hw/i386: Consolidate topology functions

2020-03-03 Thread Babu Moger
Now that we have all the parameters in X86CPUTopoInfo, we can just
pass the structure to calculate the offsets and width.

Signed-off-by: Babu Moger 
Reviewed-by: Igor Mammedov 
---
 include/hw/i386/topology.h |   68 ++--
 target/i386/cpu.c  |   23 +++
 2 files changed, 32 insertions(+), 59 deletions(-)

diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h
index 7ea507f376..ba52d49079 100644
--- a/include/hw/i386/topology.h
+++ b/include/hw/i386/topology.h
@@ -69,56 +69,42 @@ static unsigned apicid_bitwidth_for_count(unsigned count)
 
 /* Bit width of the SMT_ID (thread ID) field on the APIC ID
  */
-static inline unsigned apicid_smt_width(unsigned nr_dies,
-unsigned nr_cores,
-unsigned nr_threads)
+static inline unsigned apicid_smt_width(X86CPUTopoInfo *topo_info)
 {
-return apicid_bitwidth_for_count(nr_threads);
+return apicid_bitwidth_for_count(topo_info->threads_per_core);
 }
 
 /* Bit width of the Core_ID field
  */
-static inline unsigned apicid_core_width(unsigned nr_dies,
- unsigned nr_cores,
- unsigned nr_threads)
+static inline unsigned apicid_core_width(X86CPUTopoInfo *topo_info)
 {
-return apicid_bitwidth_for_count(nr_cores);
+return apicid_bitwidth_for_count(topo_info->cores_per_die);
 }
 
 /* Bit width of the Die_ID field */
-static inline unsigned apicid_die_width(unsigned nr_dies,
-unsigned nr_cores,
-unsigned nr_threads)
+static inline unsigned apicid_die_width(X86CPUTopoInfo *topo_info)
 {
-return apicid_bitwidth_for_count(nr_dies);
+return apicid_bitwidth_for_count(topo_info->dies_per_pkg);
 }
 
 /* Bit offset of the Core_ID field
  */
-static inline unsigned apicid_core_offset(unsigned nr_dies,
-  unsigned nr_cores,
-  unsigned nr_threads)
+static inline unsigned apicid_core_offset(X86CPUTopoInfo *topo_info)
 {
-return apicid_smt_width(nr_dies, nr_cores, nr_threads);
+return apicid_smt_width(topo_info);
 }
 
 /* Bit offset of the Die_ID field */
-static inline unsigned apicid_die_offset(unsigned nr_dies,
-  unsigned nr_cores,
-   unsigned nr_threads)
+static inline unsigned apicid_die_offset(X86CPUTopoInfo *topo_info)
 {
-return apicid_core_offset(nr_dies, nr_cores, nr_threads) +
-   apicid_core_width(nr_dies, nr_cores, nr_threads);
+return apicid_core_offset(topo_info) + apicid_core_width(topo_info);
 }
 
 /* Bit offset of the Pkg_ID (socket ID) field
  */
-static inline unsigned apicid_pkg_offset(unsigned nr_dies,
- unsigned nr_cores,
- unsigned nr_threads)
+static inline unsigned apicid_pkg_offset(X86CPUTopoInfo *topo_info)
 {
-return apicid_die_offset(nr_dies, nr_cores, nr_threads) +
-   apicid_die_width(nr_dies, nr_cores, nr_threads);
+return apicid_die_offset(topo_info) + apicid_die_width(topo_info);
 }
 
 /* Make APIC ID for the CPU based on Pkg_ID, Core_ID, SMT_ID
@@ -128,16 +114,9 @@ static inline unsigned apicid_pkg_offset(unsigned nr_dies,
 static inline apic_id_t apicid_from_topo_ids(X86CPUTopoInfo *topo_info,
  const X86CPUTopoIDs *topo_ids)
 {
-unsigned nr_dies = topo_info->dies_per_pkg;
-unsigned nr_cores = topo_info->cores_per_die;
-unsigned nr_threads = topo_info->threads_per_core;
-
-return (topo_ids->pkg_id  <<
-   apicid_pkg_offset(nr_dies, nr_cores, nr_threads)) |
-   (topo_ids->die_id  <<
-   apicid_die_offset(nr_dies, nr_cores, nr_threads)) |
-   (topo_ids->core_id <<
-   apicid_core_offset(nr_dies, nr_cores, nr_threads)) |
+return (topo_ids->pkg_id  << apicid_pkg_offset(topo_info)) |
+   (topo_ids->die_id  << apicid_die_offset(topo_info)) |
+   (topo_ids->core_id << apicid_core_offset(topo_info)) |
topo_ids->smt_id;
 }
 
@@ -165,20 +144,15 @@ static inline void x86_topo_ids_from_apicid(apic_id_t 
apicid,
 X86CPUTopoInfo *topo_info,
 X86CPUTopoIDs *topo_ids)
 {
-unsigned nr_dies = topo_info->dies_per_pkg;
-unsigned nr_cores = topo_info->cores_per_die;
-unsigned nr_threads = topo_info->threads_per_core;
-
 topo_ids->smt_id = apicid &
-~(0xUL << apicid_smt_width(nr_dies, nr_cores, nr_threads));
+~(0xUL << apicid_smt_width(topo_info));
 topo_ids->core_id =
-(apicid >> apicid_core_offset(nr_dies, nr_cores, nr_threads)) &
-~(0xUL << 

Re: [PATCH v5 08/50] multi-process: add functions to synchronize proxy and remote endpoints

2020-03-03 Thread Dr. David Alan Gilbert
* Jagannathan Raman (jag.ra...@oracle.com) wrote:
> In some cases, for example MMIO read, QEMU has to wait for the remote to
> complete a command before proceeding. An eventfd based mechanism is
> added to synchronize QEMU & remote process.
> 
> Signed-off-by: John G Johnson 
> Signed-off-by: Jagannathan Raman 
> Signed-off-by: Elena Ufimtseva 
> ---
>  include/io/mpqemu-link.h |  7 +++
>  io/mpqemu-link.c | 41 +
>  2 files changed, 48 insertions(+)
> 
> diff --git a/include/io/mpqemu-link.h b/include/io/mpqemu-link.h
> index 2f2dd83..ae04fca 100644
> --- a/include/io/mpqemu-link.h
> +++ b/include/io/mpqemu-link.h
> @@ -135,4 +135,11 @@ void mpqemu_link_set_callback(MPQemuLinkState *s,
>mpqemu_link_callback callback);
>  void mpqemu_start_coms(MPQemuLinkState *s);
>  
> +#define GET_REMOTE_WAIT eventfd(0, EFD_CLOEXEC)
> +#define PUT_REMOTE_WAIT(wait) close(wait)
> +#define PROXY_LINK_WAIT_DONE 1
> +
> +uint64_t wait_for_remote(int efd);
> +void notify_proxy(int fd, uint64_t val);
> +
>  #endif
> diff --git a/io/mpqemu-link.c b/io/mpqemu-link.c
> index bac120b..73b7032 100644
> --- a/io/mpqemu-link.c
> +++ b/io/mpqemu-link.c
> @@ -10,6 +10,7 @@
>  
>  #include "qemu/osdep.h"
>  #include "qemu-common.h"
> +#include 
>  
>  #include "qemu/module.h"
>  #include "io/mpqemu-link.h"
> @@ -216,6 +217,46 @@ int mpqemu_msg_recv(MPQemuMsg *msg, MPQemuChannel *chan)
>  return rc;
>  }
>  
> +uint64_t wait_for_remote(int efd)
> +{
> +struct pollfd pfd = { .fd = efd, .events = POLLIN };
> +uint64_t val;
> +int ret;
> +
> +ret = poll(, 1, 1000);
> +
> +switch (ret) {
> +case 0:
> +qemu_log_mask(LOG_REMOTE_DEBUG, "Error wait_for_remote: Timed 
> out\n");
> +/* TODO: Kick-off error recovery */
> +return ULLONG_MAX;

Shouldn't these be UINT64_MAX?

> +case -1:
> +qemu_log_mask(LOG_REMOTE_DEBUG, "Poll error wait_for_remote: %s\n",
> +  strerror(errno));
> +return ULLONG_MAX;
> +default:
> +if (read(efd, , sizeof(val)) == -1) {
> +qemu_log_mask(LOG_REMOTE_DEBUG, "Error wait_for_remote: %s\n",
> +  strerror(errno));
> +return ULLONG_MAX;
> +}
> +}
> +
> +val = (val == ULLONG_MAX) ? val : (val - 1);

Can you explain what's going on there??

> +return val;
> +}
> +
> +void notify_proxy(int efd, uint64_t val)
> +{
> +val = (val == ULLONG_MAX) ? val : (val + 1);
> +
> +if (write(efd, , sizeof(val)) == -1) {

I'd actually check the write/read's are returning sizeof(val) - they
can on a bad day return 0 or send only a few bytes; in theory?

Dave

> +qemu_log_mask(LOG_REMOTE_DEBUG, "Error notify_proxy: %s\n",
> +  strerror(errno));
> +}
> +}
> +
>  static gboolean mpqemu_link_handler_prepare(GSource *gsrc, gint *timeout)
>  {
>  g_assert(timeout);
> -- 
> 1.8.3.1
> 
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




[PATCH v5 00/16] APIC ID fixes for AMD EPYC CPU model

2020-03-03 Thread Babu Moger
This series fixes APIC ID encoding problem reported on AMD EPYC cpu models.
https://bugzilla.redhat.com/show_bug.cgi?id=1728166

Currently, the APIC ID is decoded based on the sequence
sockets->dies->cores->threads. This works for most standard AMD and other
vendors' configurations, but this decoding sequence does not follow that of
AMD's APIC ID enumeration strictly. In some cases this can cause CPU topology
inconsistency.  When booting a guest VM, the kernel tries to validate the
topology, and finds it inconsistent with the enumeration of EPYC cpu models.

To fix the problem we need to build the topology as per the Processor
Programming Reference (PPR) for AMD Family 17h Model 01h, Revision B1
Processors. The documentation is available from the bugzilla Link below.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=206537

Here is the text from the PPR.
Operating systems are expected to use Core::X86::Cpuid::SizeId[ApicIdSize], the
number of least significant bits in the Initial APIC ID that indicate core ID
within a processor, in constructing per-core CPUID masks.
Core::X86::Cpuid::SizeId[ApicIdSize] determines the maximum number of cores
(MNC) that the processor could theoretically support, not the actual number of
cores that are actually implemented or enabled on the processor, as indicated
by Core::X86::Cpuid::SizeId[NC].
Each Core::X86::Apic::ApicId[ApicId] register is preset as follows:
• ApicId[6] = Socket ID.
• ApicId[5:4] = Node ID.
• ApicId[3] = Logical CCX L3 complex ID
• ApicId[2:0]= (SMT) ? {LogicalCoreID[1:0],ThreadId} : {1'b0,LogicalCoreID[1:0]}

v5:
 Generated the patches on top of git://github.com/ehabkost/qemu.git (x86-next).
 Changes from v4.
 1. Re-arranged the patches 2 and 4 as suggested by Igor.
 2. Kept the apicid handler functions inside X86MachineState as discussed.
These handlers are loaded from X86CPUDefinitions.
 3. Removed unnecessary X86CPUstate initialization from x86_cpu_new. Suggested
by Igor.
 4. And other minor changes related to patch format.

v4:
 
https://lore.kernel.org/qemu-devel/158161767653.48948.10578064482878399556.st...@naples-babu.amd.com/
 Changes from v3.
 1. Moved the arch_id calculation inside the function x86_cpus_init. With this 
change,
we dont need to change common numa code.(suggested by Igor)
 2. Introduced the model specific handlers inside X86CPUDefinitions.
These handlers are loaded into X86MachineState during the init.
 3. Removed llc_id from x86CPU.
 4. Removed init_apicid_fn hanlder from MachineClass. Kept all the code changes
inside the x86.
 5. Added new handler function apicid_pkg_offset for pkg_offset calculation.
 6. And some Other minor changes.

v3:
  
https://lore.kernel.org/qemu-devel/157541968844.46157.17994918142533791313.st...@naples-babu.amd.com/
 
  1. Consolidated the topology information in structure X86CPUTopoInfo.
  2. Changed the ccx_id to llc_id as commented by upstream.
  3. Generalized the apic id decoding. It is mostly similar to current apic id
 except that it adds new field llc_id when numa configured. Removes all the
 hardcoded values.
  4. Removed the earlier parse_numa split. And moved the numa node 
initialization
 inside the numa_complete_configuration. This is bit cleaner as commented 
by 
 Eduardo.
  5. Added new function init_apicid_fn inside machine_class structure. This
 will be used to update the apic id handler specific to cpu model.
  6. Updated the cpuid unit tests.
  7. TODO : Need to figure out how to dynamically update the handlers using cpu 
models.
 I might some guidance on that.

v2:
  
https://lore.kernel.org/qemu-devel/156779689013.21957.1631551572950676212.stgit@localhost.localdomain/
  1. Introduced the new property epyc to enable new epyc mode.
  2. Separated the epyc mode and non epyc mode function.
  3. Introduced function pointers in PCMachineState to handle the
 differences.
  4. Mildly tested different combinations to make things are working as 
expected.
  5. TODO : Setting the epyc feature bit needs to be worked out. This feature is
 supported only on AMD EPYC models. I may need some guidance on that.

v1:
  https://lore.kernel.org/qemu-devel/20190731232032.51786-1-babu.mo...@amd.com/

---

Babu Moger (16):
  hw/i386: Rename X86CPUTopoInfo structure to X86CPUTopoIDs
  hw/i386: Introduce X86CPUTopoInfo to contain topology info
  hw/i386: Consolidate topology functions
  machine: Add SMP Sockets in CpuTopology
  hw/i386: Remove unnecessary initialization in x86_cpu_new
  hw/i386: Update structures to save the number of nodes per package
  hw/i386: Rename apicid_from_topo_ids to x86_apicid_from_topo_ids
  hw/386: Add EPYC mode topology decoding functions
  target/i386: Cleanup and use the EPYC mode topology functions
  hw/i386: Introduce apicid functions inside X86MachineState
  target/i386: Load apicid model specific handlers from X86CPUDefinition
  hw/i386: Use the apicid handlers from 

Re: [PATCH v6 9/9] iotests: add pylintrc file

2020-03-03 Thread John Snow



On 2/27/20 9:11 AM, Philippe Mathieu-Daudé wrote:
> On 2/27/20 1:06 AM, John Snow wrote:
>> Repeatable results. run `pylint iotests.py` and you should get a pass.
>>
>> Signed-off-by: John Snow 
>> ---
>>   tests/qemu-iotests/pylintrc | 20 
>>   1 file changed, 20 insertions(+)
>>   create mode 100644 tests/qemu-iotests/pylintrc
>>
>> diff --git a/tests/qemu-iotests/pylintrc b/tests/qemu-iotests/pylintrc
>> new file mode 100644
>> index 00..feed506f75
>> --- /dev/null
>> +++ b/tests/qemu-iotests/pylintrc
>> @@ -0,0 +1,20 @@
>> +[MESSAGES CONTROL]
>> +
>> +# Disable the message, report, category or checker with the given
>> id(s). You
>> +# can either give multiple identifiers separated by comma (,) or put
>> this
>> +# option multiple times (only on the command line, not in the
>> configuration
>> +# file where it should appear only once). You can also use
>> "--disable=all" to
>> +# disable everything first and then reenable specific checks. For
>> example, if
>> +# you want to run only the similarities checker, you can use
>> "--disable=all
>> +# --enable=similarities". If you want to run only the classes
>> checker, but have
>> +# no Warning level messages displayed, use "--disable=all
>> --enable=classes
>> +# --disable=W".
>> +disable=invalid-name,
>> +    missing-docstring,
>> +    line-too-long,
>> +    too-many-lines,
>> +    too-few-public-methods,
>> +    too-many-arguments,
>> +    too-many-locals,
>> +    too-many-branches,
>> +    too-many-public-methods,
>> \ No newline at end of file
>>
> 
> Can you run it in one of the CI jobs?
> 

Tell me where to add it and I will do so.




Re: [PATCH v5 01/50] multi-process: memory: alloc RAM from file at offset

2020-03-03 Thread Dr. David Alan Gilbert
* Jagannathan Raman (jag.ra...@oracle.com) wrote:
> Allow RAM MemoryRegion to be created from an offset in a file, instead
> of allocating at offset of 0 by default. This is needed to synchronize
> RAM between QEMU & remote process.
> This will be needed for the following patches.
> 
> Signed-off-by: Jagannathan Raman 
> Signed-off-by: John G Johnson 
> Signed-off-by: Elena Ufimtseva 

This looks reasonable to me, so :

Reviewed-by: Dr. David Alan Gilbert 

but can I suggest you take simple things like this and split them out
into a separate little series;  I think people would probably take them
even though the current users have a 0 offset.

Dave

> ---
>  exec.c| 11 +++
>  include/exec/ram_addr.h   |  2 +-
>  include/qemu/mmap-alloc.h |  3 ++-
>  memory.c  |  2 +-
>  util/mmap-alloc.c |  7 ---
>  util/oslib-posix.c|  2 +-
>  6 files changed, 16 insertions(+), 11 deletions(-)
> 
> diff --git a/exec.c b/exec.c
> index c930040..e524185 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -1841,6 +1841,7 @@ static void *file_ram_alloc(RAMBlock *block,
>  ram_addr_t memory,
>  int fd,
>  bool truncate,
> +off_t offset,
>  Error **errp)
>  {
>  Error *err = NULL;
> @@ -1893,7 +1894,8 @@ static void *file_ram_alloc(RAMBlock *block,
>  }
>  
>  area = qemu_ram_mmap(fd, memory, block->mr->align,
> - block->flags & RAM_SHARED, block->flags & RAM_PMEM);
> + block->flags & RAM_SHARED, block->flags & RAM_PMEM,
> + offset);
>  if (area == MAP_FAILED) {
>  error_setg_errno(errp, errno,
>   "unable to map backing store for guest RAM");
> @@ -2322,7 +2324,7 @@ static void ram_block_add(RAMBlock *new_block, Error 
> **errp, bool shared)
>  #ifdef CONFIG_POSIX
>  RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
>   uint32_t ram_flags, int fd,
> - Error **errp)
> + off_t offset, Error **errp)
>  {
>  RAMBlock *new_block;
>  Error *local_err = NULL;
> @@ -2367,7 +2369,8 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, 
> MemoryRegion *mr,
>  new_block->used_length = size;
>  new_block->max_length = size;
>  new_block->flags = ram_flags;
> -new_block->host = file_ram_alloc(new_block, size, fd, !file_size, errp);
> +new_block->host = file_ram_alloc(new_block, size, fd, !file_size, offset,
> + errp);
>  if (!new_block->host) {
>  g_free(new_block);
>  return NULL;
> @@ -2397,7 +2400,7 @@ RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size, 
> MemoryRegion *mr,
>  return NULL;
>  }
>  
> -block = qemu_ram_alloc_from_fd(size, mr, ram_flags, fd, errp);
> +block = qemu_ram_alloc_from_fd(size, mr, ram_flags, fd, 0, errp);
>  if (!block) {
>  if (created) {
>  unlink(mem_path);
> diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
> index 5e59a3d..1b9f489 100644
> --- a/include/exec/ram_addr.h
> +++ b/include/exec/ram_addr.h
> @@ -121,7 +121,7 @@ RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size, 
> MemoryRegion *mr,
> Error **errp);
>  RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
>   uint32_t ram_flags, int fd,
> - Error **errp);
> + off_t offset, Error **errp);
>  
>  RAMBlock *qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
>MemoryRegion *mr, Error **errp);
> diff --git a/include/qemu/mmap-alloc.h b/include/qemu/mmap-alloc.h
> index e786266..4f57985 100644
> --- a/include/qemu/mmap-alloc.h
> +++ b/include/qemu/mmap-alloc.h
> @@ -25,7 +25,8 @@ void *qemu_ram_mmap(int fd,
>  size_t size,
>  size_t align,
>  bool shared,
> -bool is_pmem);
> +bool is_pmem,
> +off_t start);
>  
>  void qemu_ram_munmap(int fd, void *ptr, size_t size);
>  
> diff --git a/memory.c b/memory.c
> index aeaa8dc..131bc6c 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -1595,7 +1595,7 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr,
>  mr->destructor = memory_region_destructor_ram;
>  mr->ram_block = qemu_ram_alloc_from_fd(size, mr,
> share ? RAM_SHARED : 0,
> -   fd, );
> +   fd, 0, );
>  mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
>  if (err) {
>  mr->size = int128_zero();
> diff --git a/util/mmap-alloc.c 

Re: [PATCH] cpu: Use DeviceClass reset instead of a special CPUClass reset

2020-03-03 Thread Eduardo Habkost
On Tue, Mar 03, 2020 at 10:05:11AM +, Peter Maydell wrote:
> The CPUClass has a 'reset' method.  This is a legacy from when
> TYPE_CPU used not to inherit from TYPE_DEVICE.  We don't need it any
> more, as we can simply use the TYPE_DEVICE reset.  The 'cpu_reset()'
> function is kept as the API which most places use to reset a CPU; it
> is now a wrapper which calls device_cold_reset() and then the
> tracepoint function.
> 
> This change should not cause CPU objects to be reset more often
> than they are at the moment, because:
>  * nobody is directly calling device_cold_reset() or
>qdev_reset_all() on CPU objects
>  * no CPU object is on a qbus, so they will not be reset either
>by somebody calling qbus_reset_all()/bus_cold_reset(), or
>by the main "reset sysbus and everything in the qbus tree"
>reset that most devices are reset by
> 
> Note that this does not change the need for each machine or whatever
> to use qemu_register_reset() to arrange to call cpu_reset() -- that
> is necessary because CPU objects are not on any qbus, so they don't
> get reset when the qbus tree rooted at the sysbus bus is reset, and
> this isn't being changed here.
> 
> All the changes to the files under target/ were made using the
> included Coccinelle script, except:
> 
> (1) the deletion of the now-inaccurate and not terribly useful
> "CPUClass::reset" comments was done with a perl one-liner afterwards:
>   perl -n -i -e '/ CPUClass::reset/ or print' target/*/*.c
> 
> (2) this bit of the s390 change was done by hand, because the
> Coccinelle script is not sophisticated enough to handle the
> parent_reset call being inside another function:
> 
> | @@ -96,8 +96,9 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type 
> type)
> | S390CPU *cpu = S390_CPU(s);
> | S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
> | CPUS390XState *env = >env;
> |+DeviceState *dev = DEVICE(s);
> |
> |-scc->parent_reset(s);
> |+scc->parent_reset(dev);
> | cpu->env.sigp_order = 0;
> | s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
> 
> Signed-off-by: Peter Maydell 

Queued, thanks.

However, if you want to do additional arch-specific work on top
of this patch, feel free to merge it through your tree.

Acked-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH v2 8/9] tests/acceptance: bump avocado requirements to 76.0

2020-03-03 Thread Richard Henderson
On 3/3/20 7:06 AM, Alex Bennée wrote:
> If we want to use @skipUnless decorations on the class we need a
> newer version of avocado.
> 
> Signed-off-by: Alex Bennée 
> ---
>  tests/requirements.txt | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Richard Henderson 


r~



Re: [PATCH v2 7/9] configure: detect and report genisoimage

2020-03-03 Thread Richard Henderson
On 3/3/20 7:06 AM, Alex Bennée wrote:
> This is used for some of the vm-build tests so lets detect it and
> behave sanely when it is not installed.
> 
> Signed-off-by: Alex Bennée 
> ---
>  configure | 13 +
>  tests/vm/Makefile.include | 14 +++---
>  2 files changed, 24 insertions(+), 3 deletions(-)

Reviewed-by: Richard Henderson 


r~



Re: [PATCH] cpu: Use DeviceClass reset instead of a special CPUClass reset

2020-03-03 Thread Richard Henderson
On 3/3/20 2:05 AM, Peter Maydell wrote:
> The CPUClass has a 'reset' method.  This is a legacy from when
> TYPE_CPU used not to inherit from TYPE_DEVICE.  We don't need it any
> more, as we can simply use the TYPE_DEVICE reset.  The 'cpu_reset()'
> function is kept as the API which most places use to reset a CPU; it
> is now a wrapper which calls device_cold_reset() and then the
> tracepoint function.
> 
> This change should not cause CPU objects to be reset more often
> than they are at the moment, because:
>  * nobody is directly calling device_cold_reset() or
>qdev_reset_all() on CPU objects
>  * no CPU object is on a qbus, so they will not be reset either
>by somebody calling qbus_reset_all()/bus_cold_reset(), or
>by the main "reset sysbus and everything in the qbus tree"
>reset that most devices are reset by
> 
> Note that this does not change the need for each machine or whatever
> to use qemu_register_reset() to arrange to call cpu_reset() -- that
> is necessary because CPU objects are not on any qbus, so they don't
> get reset when the qbus tree rooted at the sysbus bus is reset, and
> this isn't being changed here.
> 
> All the changes to the files under target/ were made using the
> included Coccinelle script, except:
> 
> (1) the deletion of the now-inaccurate and not terribly useful
> "CPUClass::reset" comments was done with a perl one-liner afterwards:
>   perl -n -i -e '/ CPUClass::reset/ or print' target/*/*.c
> 
> (2) this bit of the s390 change was done by hand, because the
> Coccinelle script is not sophisticated enough to handle the
> parent_reset call being inside another function:
> 
> | @@ -96,8 +96,9 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type 
> type)
> | S390CPU *cpu = S390_CPU(s);
> | S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
> | CPUS390XState *env = >env;
> |+DeviceState *dev = DEVICE(s);
> |
> |-scc->parent_reset(s);
> |+scc->parent_reset(dev);
> | cpu->env.sigp_order = 0;
> | s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
> 
> Signed-off-by: Peter Maydell 
> ---
> Testing was by 'make check' and 'make check-acceptance'.
> 
> I need this patch as a preliminary to some arm stuff I'm
> doing, but I think it makes sense as a cleanup in its own
> right so I'm sending it out early for review. If it's not
> yet in master before I get round to finishing the stuff
> that depends on it I'll resend it as part of that series.
> ---

Reviewed-by: Richard Henderson 


r~



Re: [PATCH 4/4] target/arm: Fix some comment typos

2020-03-03 Thread Richard Henderson
On 3/3/20 9:49 AM, Peter Maydell wrote:
> Fix a couple of comment typos.
> 
> Signed-off-by: Peter Maydell 
> ---
> Noticed these while writing the other patches...
> ---
>  target/arm/helper.c| 2 +-
>  target/arm/translate.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Richard Henderson 


r~



Re: [PATCH 3/4] target/arm: Recalculate hflags correctly after writes to CONTROL

2020-03-03 Thread Richard Henderson
On 3/3/20 9:49 AM, Peter Maydell wrote:
> A write to the CONTROL register can change our current EL (by
> writing to the nPRIV bit). That means that we can't assume
> that s->current_el is still valid in trans_MSR_v7m() when
> we try to rebuild the hflags.
> 
> Add a new helper rebuild_hflags_m32_newel() which, like the
> existing rebuild_hflags_a32_newel(), recalculates the current
> EL from scratch, and use it in trans_MSR_v7m().
> 
> This fixes an assertion about an hflags mismatch when the
> guest changes privilege by writing to CONTROL.
> 
> Signed-off-by: Peter Maydell 
> ---
>  target/arm/helper.h|  1 +
>  target/arm/helper.c| 12 
>  target/arm/translate.c |  7 +++
>  3 files changed, 16 insertions(+), 4 deletions(-)

Reviewed-by: Richard Henderson 


r~



Re: [PATCH] cpu: Use DeviceClass reset instead of a special CPUClass reset

2020-03-03 Thread Peter Maydell
On Tue, 3 Mar 2020 at 18:33, Philippe Mathieu-Daudé  wrote:
> Nitpick: you don't need to include the bracket symbol in the diff:
>
>@@
>-resetfn(CPUState *cpu)
>+resetfn(DeviceState *dev)
> {
>
> (simply indent it with a space).

I think this was probably leftover from trying to get Coccinelle
to not rewrap the '{' onto the previous line, before I found
--smpl-spacing.

In general I don't find it terribly useful to spend a great
deal of time streamlining Coccinelle scripts -- I think they
are basically one-shot uses almost all of the time, so once
they're producing the right changes I prefer to move on.

thanks
-- PMM



Re: [PATCH 2/4] target/arm: Update hflags in trans_CPS_v7m()

2020-03-03 Thread Richard Henderson
On 3/3/20 9:49 AM, Peter Maydell wrote:
> For M-profile CPUs, the FAULTMASK value affects the CPU's MMU index
> (it changes the NegPri bit). We update the hflags after calls
> to the v7m_msr helper in trans_MSR_v7m() but forgot to do so
> in trans_CPS_v7m().
> 
> Signed-off-by: Peter Maydell 
> ---
>  target/arm/translate.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)

Reviewed-by: Richard Henderson 


r~



Re: [PATCH 1/4] hw/intc/armv7m_nvic: Rebuild hflags on reset

2020-03-03 Thread Richard Henderson
On 3/3/20 9:49 AM, Peter Maydell wrote:
> Some of an M-profile CPU's cached hflags state depends on state that's
> in our NVIC object. We already do an hflags rebuild when the NVIC
> registers are written, but we also need to do this on NVIC reset,
> because there's no guarantee that this will happen before the
> CPU reset.
> 
> This fixes an assertion due to mismatched hflags which happens if
> the CPU is reset from inside a HardFault handler.
> 
> Signed-off-by: Peter Maydell 
> ---
>  hw/intc/armv7m_nvic.c | 6 ++
>  1 file changed, 6 insertions(+)

Reviewed-by: Richard Henderson 


r~



Re: [PATCH] cpu: Use DeviceClass reset instead of a special CPUClass reset

2020-03-03 Thread Philippe Mathieu-Daudé

On 3/3/20 3:19 PM, Philippe Mathieu-Daudé wrote:

On 3/3/20 11:05 AM, Peter Maydell wrote:

The CPUClass has a 'reset' method.  This is a legacy from when
TYPE_CPU used not to inherit from TYPE_DEVICE.  We don't need it any
more, as we can simply use the TYPE_DEVICE reset.  The 'cpu_reset()'
function is kept as the API which most places use to reset a CPU; it
is now a wrapper which calls device_cold_reset() and then the
tracepoint function.

This change should not cause CPU objects to be reset more often
than they are at the moment, because:
  * nobody is directly calling device_cold_reset() or
    qdev_reset_all() on CPU objects
  * no CPU object is on a qbus, so they will not be reset either
    by somebody calling qbus_reset_all()/bus_cold_reset(), or
    by the main "reset sysbus and everything in the qbus tree"
    reset that most devices are reset by

Note that this does not change the need for each machine or whatever
to use qemu_register_reset() to arrange to call cpu_reset() -- that
is necessary because CPU objects are not on any qbus, so they don't
get reset when the qbus tree rooted at the sysbus bus is reset, and
this isn't being changed here.

All the changes to the files under target/ were made using the
included Coccinelle script, except:

(1) the deletion of the now-inaccurate and not terribly useful
"CPUClass::reset" comments was done with a perl one-liner afterwards:
   perl -n -i -e '/ CPUClass::reset/ or print' target/*/*.c

(2) this bit of the s390 change was done by hand, because the
Coccinelle script is not sophisticated enough to handle the
parent_reset call being inside another function:

| @@ -96,8 +96,9 @@ static void s390_cpu_reset(CPUState *s, 
cpu_reset_type type)

| S390CPU *cpu = S390_CPU(s);
| S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
| CPUS390XState *env = >env;
|+    DeviceState *dev = DEVICE(s);
|
|-    scc->parent_reset(s);
|+    scc->parent_reset(dev);
| cpu->env.sigp_order = 0;
| s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);

Signed-off-by: Peter Maydell 
---
Testing was by 'make check' and 'make check-acceptance'.

I need this patch as a preliminary to some arm stuff I'm
doing, but I think it makes sense as a cleanup in its own
right so I'm sending it out early for review. If it's not
yet in master before I get round to finishing the stuff
that depends on it I'll resend it as part of that series.


Nice cleanup, thanks.

Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 


[...]
diff --git a/scripts/coccinelle/cpu-reset.cocci 
b/scripts/coccinelle/cpu-reset.cocci

new file mode 100644
index 000..396a724e514
--- /dev/null
+++ b/scripts/coccinelle/cpu-reset.cocci
@@ -0,0 +1,47 @@
+// Convert targets using the old CPUState reset to DeviceState reset
+//
+// Copyright Linaro Ltd 2020
+// This work is licensed under the terms of the GNU GPLv2 or later.
+//
+// spatch --macro-file scripts/cocci-macro-file.h \
+//    --sp-file scripts/coccinelle/cpu-reset.cocci \
+//    --keep-comments --smpl-spacing --in-place --include-headers 
--dir target

+//
+// For simplicity we assume some things about the code we're modifying
+// that happen to be true for all our targets:
+//  * all cpu_class_set_parent_reset() callsites have a 'DeviceClass 
*dc' local

+//  * the parent reset field in the target CPU class is 'parent_reset'
+//  * no reset function already has a 'dev' local
+
+@@
+identifier cpu, x;
+typedef CPUState;
+@@
+struct x {
+...
+- void (*parent_reset)(CPUState *cpu);
++ DeviceReset parent_reset;
+...
+};
+@ rule1 @
+identifier resetfn;
+expression resetfield;
+identifier cc;
+@@
+- cpu_class_set_parent_reset(cc, resetfn, resetfield)
++ device_class_set_parent_reset(dc, resetfn, resetfield)
+@@
+identifier rule1.resetfn;
+identifier cpu, cc;
+typedef CPUState, DeviceState;
+@@
+-resetfn(CPUState *cpu)
+-{
++resetfn(DeviceState *dev)
++{


Nitpick: you don't need to include the bracket symbol in the diff:

  @@
  -resetfn(CPUState *cpu)
  +resetfn(DeviceState *dev)
   {

(simply indent it with a space).


++    CPUState *cpu = CPU(dev);
+<...
+-    cc->parent_reset(cpu);
++    cc->parent_reset(dev);
+...>
+}








[PATCH] Fixed integer overflow in e1000e

2020-03-03 Thread andrew
From: Andrew Melnychenko 

https://bugzilla.redhat.com/show_bug.cgi?id=1737400
Fixed setting max_queue_num if there are no peers in NICConf. qemu_new_nic() 
creates NICState with 1 NetClientState(index 0) without peers, set 
max_queue_num to 0 - It prevents undefined behavior and possible crashes, 
especially during pcie hotplug.

Signed-off-by: Andrew Melnychenko 
---
 hw/net/e1000e.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
index a91dbdca3c..f2cc1552c5 100644
--- a/hw/net/e1000e.c
+++ b/hw/net/e1000e.c
@@ -328,7 +328,7 @@ e1000e_init_net_peer(E1000EState *s, PCIDevice *pci_dev, 
uint8_t *macaddr)
 s->nic = qemu_new_nic(_e1000e_info, >conf,
 object_get_typename(OBJECT(s)), dev->id, s);
 
-s->core.max_queue_num = s->conf.peers.queues - 1;
+s->core.max_queue_num = s->conf.peers.queues ? s->conf.peers.queues - 1 : 
0;
 
 trace_e1000e_mac_set_permanent(MAC_ARG(macaddr));
 memcpy(s->core.permanent_mac, macaddr, sizeof(s->core.permanent_mac));
-- 
2.24.1




Re: [PATCH v3 00/33] Convert qemu-doc to rST

2020-03-03 Thread Alex Bennée


Peter Maydell  writes:

> On Fri, 28 Feb 2020 at 15:36, Peter Maydell  wrote:
>>
>> Hi; this series does a complete conversion of qemu-doc from
>> Texinfo to rST, including the hxtool-generated parts and
>> creation of the qemu.1 manpage from rST.
>>
>
> Advance notice: I would like to put these into a pull
> request at the end of this week. This is your opportunity
> to say "that would be a bad idea", "I need X more time
> to review it", etc :-)

Just merge it, we can fix things up afterwards if we need to but it's a
big step in the right direction.

>
> thanks
> -- PMM


-- 
Alex Bennée



Re: [EXTERNAL] Re: PATCH] WHPX: TSC get and set should be dependent on VM state

2020-03-03 Thread Paolo Bonzini
On 02/03/20 20:59, Sunil Muthuswamy wrote:
>> You'd be using it to include a signed tags in a pull requests; that is,
>> the git tag that you ask to pull has a cryptographic signature attached
>> to it.
> Great. Is there a link that I can use to read up on how to get the GPG key
> and how to include the signature or what process should I be following?

This guide seems good, though I haven't tried:

https://medium.com/@ryanmillerc/use-gpg-signing-keys-with-git-on-windows-10-github-4acbced49f68

You don't need the "git config --local commit.gpgsign true" command, but
you will then create a signed tag with

git tag -s -f qemu-for-upstream
# let's say "mirror" is your github repo
git push mirror +tags/for-upstream

and send it to Peter.  I really think we should document this final step
("send it to Peter") better in the wiki, because the git tools for
sending pull requests leave a lot to be desired.

Paolo



[PATCH 4/4] target/arm: Fix some comment typos

2020-03-03 Thread Peter Maydell
Fix a couple of comment typos.

Signed-off-by: Peter Maydell 
---
Noticed these while writing the other patches...
---
 target/arm/helper.c| 2 +-
 target/arm/translate.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 2eec812b80b..3fa9c0cc861 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -12347,7 +12347,7 @@ void HELPER(rebuild_hflags_m32)(CPUARMState *env, int 
el)
 
 /*
  * If we have triggered a EL state change we can't rely on the
- * translator having passed it too us, we need to recompute.
+ * translator having passed it to us, we need to recompute.
  */
 void HELPER(rebuild_hflags_a32_newel)(CPUARMState *env)
 {
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 4715ca0d2ad..9f9f4e19e04 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -7296,7 +7296,7 @@ static int disas_coproc_insn(DisasContext *s, uint32_t 
insn)
 
 if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
 /*
- * A write to any coprocessor regiser that ends a TB
+ * A write to any coprocessor register that ends a TB
  * must rebuild the hflags for the next TB.
  */
 TCGv_i32 tcg_el = tcg_const_i32(s->current_el);
-- 
2.20.1




[PATCH 1/4] hw/intc/armv7m_nvic: Rebuild hflags on reset

2020-03-03 Thread Peter Maydell
Some of an M-profile CPU's cached hflags state depends on state that's
in our NVIC object. We already do an hflags rebuild when the NVIC
registers are written, but we also need to do this on NVIC reset,
because there's no guarantee that this will happen before the
CPU reset.

This fixes an assertion due to mismatched hflags which happens if
the CPU is reset from inside a HardFault handler.

Signed-off-by: Peter Maydell 
---
 hw/intc/armv7m_nvic.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index a62587eb3f0..1ad35e55292 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2593,6 +2593,12 @@ static void armv7m_nvic_reset(DeviceState *dev)
 s->itns[i] = true;
 }
 }
+
+/*
+ * We updated state that affects the CPU's MMUidx and thus its hflags;
+ * and we can't guarantee that we run before the CPU reset function.
+ */
+arm_rebuild_hflags(>cpu->env);
 }
 
 static void nvic_systick_trigger(void *opaque, int n, int level)
-- 
2.20.1




[PATCH 0/4] target/arm: Fix hflags mismatches for M-profile

2020-03-03 Thread Peter Maydell
This patchset fixes three hflags-mismatch assertions I ran
into while doing some work on M-profile. The last patch
is just comment typos that I noticed in the process.

thanks
-- PMM

Peter Maydell (4):
  hw/intc/armv7m_nvic: Rebuild hflags on reset
  target/arm: Update hflags in trans_CPS_v7m()
  target/arm: Recalculate hflags correctly after writes to CONTROL
  target/arm: Fix some comment typos

 target/arm/helper.h|  1 +
 hw/intc/armv7m_nvic.c  |  6 ++
 target/arm/helper.c| 14 +-
 target/arm/translate.c | 14 --
 4 files changed, 28 insertions(+), 7 deletions(-)

-- 
2.20.1




[PATCH 2/4] target/arm: Update hflags in trans_CPS_v7m()

2020-03-03 Thread Peter Maydell
For M-profile CPUs, the FAULTMASK value affects the CPU's MMU index
(it changes the NegPri bit). We update the hflags after calls
to the v7m_msr helper in trans_MSR_v7m() but forgot to do so
in trans_CPS_v7m().

Signed-off-by: Peter Maydell 
---
 target/arm/translate.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index 6259064ea7c..7f0154194cf 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -10590,7 +10590,7 @@ static bool trans_CPS(DisasContext *s, arg_CPS *a)
 
 static bool trans_CPS_v7m(DisasContext *s, arg_CPS_v7m *a)
 {
-TCGv_i32 tmp, addr;
+TCGv_i32 tmp, addr, el;
 
 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
 return false;
@@ -10613,6 +10613,9 @@ static bool trans_CPS_v7m(DisasContext *s, arg_CPS_v7m 
*a)
 gen_helper_v7m_msr(cpu_env, addr, tmp);
 tcg_temp_free_i32(addr);
 }
+el = tcg_const_i32(s->current_el);
+gen_helper_rebuild_hflags_m32(cpu_env, el);
+tcg_temp_free_i32(el);
 tcg_temp_free_i32(tmp);
 gen_lookup_tb(s);
 return true;
-- 
2.20.1




[PATCH 3/4] target/arm: Recalculate hflags correctly after writes to CONTROL

2020-03-03 Thread Peter Maydell
A write to the CONTROL register can change our current EL (by
writing to the nPRIV bit). That means that we can't assume
that s->current_el is still valid in trans_MSR_v7m() when
we try to rebuild the hflags.

Add a new helper rebuild_hflags_m32_newel() which, like the
existing rebuild_hflags_a32_newel(), recalculates the current
EL from scratch, and use it in trans_MSR_v7m().

This fixes an assertion about an hflags mismatch when the
guest changes privilege by writing to CONTROL.

Signed-off-by: Peter Maydell 
---
 target/arm/helper.h|  1 +
 target/arm/helper.c| 12 
 target/arm/translate.c |  7 +++
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index fcbf5041213..a63fd5dfb73 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -90,6 +90,7 @@ DEF_HELPER_4(msr_banked, void, env, i32, i32, i32)
 DEF_HELPER_2(get_user_reg, i32, env, i32)
 DEF_HELPER_3(set_user_reg, void, env, i32, i32)
 
+DEF_HELPER_FLAGS_1(rebuild_hflags_m32_newel, TCG_CALL_NO_RWG, void, env)
 DEF_HELPER_FLAGS_2(rebuild_hflags_m32, TCG_CALL_NO_RWG, void, env, int)
 DEF_HELPER_FLAGS_1(rebuild_hflags_a32_newel, TCG_CALL_NO_RWG, void, env)
 DEF_HELPER_FLAGS_2(rebuild_hflags_a32, TCG_CALL_NO_RWG, void, env, int)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 6be9ffa09ef..2eec812b80b 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -12325,6 +12325,18 @@ void arm_rebuild_hflags(CPUARMState *env)
 env->hflags = rebuild_hflags_internal(env);
 }
 
+/*
+ * If we have triggered a EL state change we can't rely on the
+ * translator having passed it to us, we need to recompute.
+ */
+void HELPER(rebuild_hflags_m32_newel)(CPUARMState *env)
+{
+int el = arm_current_el(env);
+int fp_el = fp_exception_el(env, el);
+ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
+env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
+}
+
 void HELPER(rebuild_hflags_m32)(CPUARMState *env, int el)
 {
 int fp_el = fp_exception_el(env, el);
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 7f0154194cf..4715ca0d2ad 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -8551,7 +8551,7 @@ static bool trans_MRS_v7m(DisasContext *s, arg_MRS_v7m *a)
 
 static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
 {
-TCGv_i32 addr, reg, el;
+TCGv_i32 addr, reg;
 
 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
 return false;
@@ -8561,9 +8561,8 @@ static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
 gen_helper_v7m_msr(cpu_env, addr, reg);
 tcg_temp_free_i32(addr);
 tcg_temp_free_i32(reg);
-el = tcg_const_i32(s->current_el);
-gen_helper_rebuild_hflags_m32(cpu_env, el);
-tcg_temp_free_i32(el);
+/* If we wrote to CONTROL, the EL might have changed */
+gen_helper_rebuild_hflags_m32_newel(cpu_env);
 gen_lookup_tb(s);
 return true;
 }
-- 
2.20.1




Re: [PATCH v3 00/33] Convert qemu-doc to rST

2020-03-03 Thread Paolo Bonzini
On 03/03/20 18:35, Peter Maydell wrote:
> Advance notice: I would like to put these into a pull
> request at the end of this week. This is your opportunity
> to say "that would be a bad idea", "I need X more time
> to review it", etc :-)
> 

On the contrary, it's a great idea. :)

Paolo




Re: [PATCH v3 00/33] Convert qemu-doc to rST

2020-03-03 Thread Peter Maydell
On Fri, 28 Feb 2020 at 15:36, Peter Maydell  wrote:
>
> Hi; this series does a complete conversion of qemu-doc from
> Texinfo to rST, including the hxtool-generated parts and
> creation of the qemu.1 manpage from rST.
>

Advance notice: I would like to put these into a pull
request at the end of this week. This is your opportunity
to say "that would be a bad idea", "I need X more time
to review it", etc :-)

thanks
-- PMM



Re: [PATCH RFC 0/9] KVM: Dirty ring support (QEMU part)

2020-03-03 Thread Peter Xu
On Wed, Feb 05, 2020 at 09:17:40AM -0500, Peter Xu wrote:
> This is still RFC because the kernel counterpart is still under
> review.  However please feel free to read into the code a bit if you
> want; they've even got rich comments so not really in WIP status
> itself.  Any kind of comments are greatly welcomed.
> 
> For anyone who wants to try (we need to upgrade kernel too):
> 
> KVM branch:
>   https://github.com/xzpeter/linux/tree/kvm-dirty-ring
> 
> QEMU branch for testing:
>   https://github.com/xzpeter/qemu/tree/kvm-dirty-ring
> 
> Overview
> 
> 
> KVM dirty ring is a new interface to pass over dirty bits from kernel
> to the userspace.  Instead of using a bitmap for each memory region,
> the dirty ring contains an array of dirtied GPAs to fetch, one ring
> per vcpu.
> 
> There're a few major changes comparing to how the old dirty logging
> interface would work:
> 
> - Granularity of dirty bits
> 
>   KVM dirty ring interface does not offer memory region level
>   granularity to collect dirty bits (i.e., per KVM memory
>   slot). Instead the dirty bit is collected globally for all the vcpus
>   at once.  The major effect is on VGA part because VGA dirty tracking
>   is enabled as long as the device is created, also it was in memory
>   region granularity.  Now that operation will be amplified to a VM
>   sync.  Maybe there's smarter way to do the same thing in VGA with
>   the new interface, but so far I don't see it affects much at least
>   on regular VMs.
> 
> - Collection of dirty bits
> 
>   The old dirty logging interface collects KVM dirty bits when
>   synchronizing dirty bits.  KVM dirty ring interface instead used a
>   standalone thread to do that.  So when the other thread (e.g., the
>   migration thread) wants to synchronize the dirty bits, it simply
>   kick the thread and wait until it flushes all the dirty bits to the
>   ramblock dirty bitmap.
> 
> A new parameter "dirty-ring-size" is added to "-accel kvm".  By
> default, dirty ring is still disabled (size==0).  To enable it, we
> need to be with:
> 
>   -accel kvm,dirty-ring-size=65536
> 
> This establishes a 64K dirty ring buffer per vcpu.  Then if we
> migrate, it'll switch to dirty ring.

Ping?

I'd like to know whether there's any high level comment about all
these... Considering that the kernel counterpart is still during
review, I guess we don't need to spend much time on that much,
assuming it'll be a ring of dirty addresses.  The rest should be
irrelevant to kernel so I'd glad to know if there's comments on those
parts.

Thanks,

-- 
Peter Xu




Re: [PULL 0/2] virtiofs queue

2020-03-03 Thread Peter Maydell
On Tue, 3 Mar 2020 at 15:17, Dr. David Alan Gilbert (git)
 wrote:
>
> From: "Dr. David Alan Gilbert" 
>
> The following changes since commit 104933c4a973960dea605b06fcd5d0d478255d77:
>
>   Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into 
> staging (2020-03-03 12:03:59 +)
>
> are available in the Git repository at:
>
>   https://gitlab.com/dagrh/qemu.git tags/pull-virtiofs-20200303
>
> for you to fetch changes up to bdfd66788349acc43cd3f1298718ad491663cfcc:
>
>   virtiofsd: Fix xattr operations (2020-03-03 15:13:24 +)
>
> 
> Virtiofsd pull 2020-03-03
>
> xattr fixes from Misono.
>


Applied, thanks.

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

-- PMM



Re: [PATCH v2 00/30] Configurable policy for handling deprecated interfaces

2020-03-03 Thread Peter Maydell
On Tue, 3 Mar 2020 at 16:37, Markus Armbruster  wrote:
>
> Based-on: <20200227144531.24309-1-arm...@redhat.com>
>
> This series extends QMP introspection to cover deprecation.
> Additionally, new option -compat lets you configure what to do when
> deprecated interfaces get used.  This is intended for testing users of
> the management interfaces.  It is experimental.

How much do you think this is likely to affect the
generate-rst-from-qapi-docs series? I'd really like
that to go in for this release, but this looks like
it's shaping up to be a big conflict :-(

thanks
-- PMM



Re: [PATCH v4 07/11] monitor/hmp: move hmp_snapshot_* to block-hmp-cmds.c hmp_snapshot_blkdev is from GPLv2 version of the hmp-cmds.c thus have to change the licence to GPLv2

2020-03-03 Thread Kevin Wolf
Am 30.01.2020 um 13:34 hat Maxim Levitsky geschrieben:
> Signed-off-by: Maxim Levitsky 
> Reviewed-by: Dr. David Alan Gilbert 

Very long subject line. I suppose the license notice should be in the
body instead.

>  block/monitor/block-hmp-cmds.c | 56 --
>  include/block/block-hmp-cmds.h |  4 +++
>  include/monitor/hmp.h  |  3 --
>  monitor/hmp-cmds.c | 47 
>  4 files changed, 58 insertions(+), 52 deletions(-)
> 
> diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
> index 8e8288c2f1..b83687196f 100644
> --- a/block/monitor/block-hmp-cmds.c
> +++ b/block/monitor/block-hmp-cmds.c
> @@ -1,10 +1,13 @@
>  /*
>   * Blockdev HMP commands
>   *
> + *  Authors:
> + *  Anthony Liguori   
> + *
>   * Copyright (c) 2003-2008 Fabrice Bellard
>   *
> - * 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 work is licensed under the terms of the GNU GPL, version 2.
> + * See the COPYING file in the top-level directory.

Please also copy the next paragraph of the license header:

 * Contributions after 2012-01-13 are licensed under the terms of the
 * GNU GPL, version 2 or (at your option) any later version.

Kevin




Re: New Hardware model emulation

2020-03-03 Thread Priyamvad Acharya
 > These errors are probably due to the Makefile.objs changes in your
commit:

If I am not wrong, we need to add a rule i.e *"
common-obj-$(CONFIG_TESTPCI) += testpci.o "* in Makefile.objs to compile
custom device in Qemu.
Shall I should remove that rule to remove the errors?

On Tue, 3 Mar 2020 at 21:06, Stefan Hajnoczi  wrote:

> On Tue, Mar 3, 2020 at 12:45 PM Priyamvad Acharya
>  wrote:
> > Thanks Stefan for explaining the method.
> > After following above method when I run below command to compile my
> custom device in Qemu source code , I get the output on terminal which is
> attached in a file for your reference.
> >
> > Command:- make -j8 -C build
> >
> > Most of the lines in attached file indicate that error might be due to
> helper.c file.
> >
> > How to resolve it?
>
> These errors are probably due to the Makefile.objs changes in your commit:
>
> https://github.com/PriyamvadAcharya/virtual_prototype_qemu/commit/4c71c2759a96cf1db83a74027b93c6ceeab24bf1#diff-a8f0482bb5eda5c20e2054e1b1d263f2
>
> Stefan
>


Re: [PATCH v4 02/11] monitor/hmp: uninline add_init_drive

2020-03-03 Thread Kevin Wolf
Am 30.01.2020 um 13:34 hat Maxim Levitsky geschrieben:
> This is only used by hmp_drive_add.
> The code is just a bit shorter this way.
> 
> No functional changes
> 
> Signed-off-by: Maxim Levitsky 
> Reviewed-by: Markus Armbruster 

Shouldn't the subject say "inline" rather than "uninline"?

Kevin




Re: [PATCH v2 00/20] Add qemu-storage-daemon

2020-03-03 Thread Kevin Wolf
Am 28.02.2020 um 12:16 hat Stefan Hajnoczi geschrieben:
> On Mon, Feb 24, 2020 at 03:29:48PM +0100, Kevin Wolf wrote:
> > This series adds a new tool 'qemu-storage-daemon', which can be used to
> > export and perform operations on block devices. There is some overlap
> > between qemu-img/qemu-nbd and the new qemu-storage-daemon, but there are
> > a few important differences:
> > 
> > * The qemu-storage-daemon has QMP support. The command set is obviously
> >   restricted compared to the system emulator because there is no guest,
> >   but all of the block operations that are not tied to gues devices are
> >   present.
> > 
> >   This means that it can access advanced options or operations that the
> >   qemu-img command line doesn't expose. For example, blockdev-create is
> >   a lot more powerful than 'qemu-img create', and qemu-storage-daemon
> >   allows to execute it without starting a guest.
> > 
> >   Compared to qemu-nbd it means that, for example, block jobs can now be
> >   executed on the server side, and backing chains shared by multiple VMs
> >   can be modified this way.
> > 
> > * The existing tools all have a separately invented one-off syntax for
> >   the job at hand, which usually comes with restrictions compared to the
> >   system emulator. qemu-storage-daemon shares the same syntax with the
> >   system emulator for most options and prefers QAPI based interfaces
> >   where possible (such as --blockdev), so it should be easy to make use
> >   of in libvirt.
> > 
> >   The exception is --chardev, for which not clear design for a QAPIfied
> >   command line exists yet. We'll consider this interface unstable until
> >   we've figured out how to solve it. For now it just uses the same
> >   QemuOpts-based code as the system emulator.
> > 
> > * While this series implements only NBD exports, the storage daemon is
> >   intended to serve multiple protocols and its syntax reflects this. In
> >   the past, we had proposals to add new one-off tools for exporting over
> >   new protocols like FUSE or TCMU.
> > 
> >   With a generic storage daemon, additional export methods have a home
> >   without adding a new tool for each of them.
> > 
> > The plan is to merge qemu-storage-daemon as an experimental feature with
> > a reduced API stability promise in 5.0.
> > 
> > Kevin Wolf (20):
> >   qemu-storage-daemon: Add barebone tool
> >   stubs: Add arch_type
> >   block: Move system emulator QMP commands to block/qapi-sysemu.c
> >   block: Move common QMP commands to block-core QAPI module
> >   block: Move sysemu QMP commands to QAPI block module
> >   qemu-storage-daemon: Add --blockdev option
> >   qapi: Flatten object-add
> >   qemu-storage-daemon: Add --object option
> >   qemu-storage-daemon: Add --nbd-server option
> >   blockdev-nbd: Boxed argument type for nbd-server-add
> >   qemu-storage-daemon: Add --export option
> >   qemu-storage-daemon: Add main loop
> >   qemu-storage-daemon: Add --chardev option
> >   stubs: Update monitor stubs for qemu-storage-daemon
> >   qapi: Create 'pragma' module
> >   monitor: Create QAPIfied monitor_init()
> >   qmp: Fail gracefully if chardev is already in use
> >   hmp: Fail gracefully if chardev is already in use
> >   monitor: Add allow_hmp parameter to monitor_init()
> >   qemu-storage-daemon: Add --monitor option
> > 
> >  qapi/block-core.json | 730 +--
> >  qapi/block.json  | 512 +++
> >  qapi/control.json|  37 ++
> >  qapi/pragma.json |  24 +
> >  qapi/qapi-schema.json|  25 +-
> >  qapi/qom.json|  12 +-
> >  qapi/transaction.json|   2 +-
> >  configure|   2 +-
> >  include/block/nbd.h  |   1 +
> >  include/monitor/monitor.h|   6 +-
> >  include/qom/object_interfaces.h  |   7 +
> >  include/sysemu/arch_init.h   |   2 +
> >  block/qapi-sysemu.c  | 590 ++
> >  blockdev-nbd.c   |  40 +-
> >  blockdev.c   | 559 
> >  chardev/char.c   |   8 +-
> >  gdbstub.c|   2 +-
> >  hw/block/xen-block.c |  11 +-
> >  monitor/hmp-cmds.c   |  21 +-
> >  monitor/hmp.c|   8 +-
> >  monitor/misc.c   |   2 +
> >  monitor/monitor.c|  86 ++--
> >  monitor/qmp-cmds.c   |   2 +-
> >  monitor/qmp.c|  11 +-
> >  qemu-storage-daemon.c| 340 +
> >  qom/qom-qmp-cmds.c   |  42 +-
> >  stubs/arch_type.c|   4 +
> >  stubs/monitor-core.c |  21 +
> >  stubs/monitor.c  |  17 +-
> >  tests/test-util-sockets.c|   4 +-
> >  scripts/qapi/gen.py  |   5 

[PATCH v2 15/30] qapi/introspect: Factor out _make_tree()

2020-03-03 Thread Markus Armbruster
The value of @qmp_schema_qlit is generated from an expression tree.
Tree nodes are created in several places.  Factor out the common code
into _make_tree().  This isn't much of a win now.  It will pay off
when we add feature flags in the next few commits.

Signed-off-by: Markus Armbruster 
---
 scripts/qapi/introspect.py | 44 +-
 1 file changed, 24 insertions(+), 20 deletions(-)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index e4fc9d90f1..a3fa9865db 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -16,6 +16,18 @@ from qapi.schema import (QAPISchemaArrayType, 
QAPISchemaBuiltinType,
  QAPISchemaType)
 
 
+def _make_tree(obj, ifcond, features, extra=None):
+if extra is None:
+extra = {}
+if ifcond:
+extra['if'] = ifcond
+if features:
+obj['features'] = [(f.name, {'if': f.ifcond}) for f in features]
+if extra:
+return (obj, extra)
+return obj
+
+
 def _tree_to_qlit(obj, level=0, suppress_first_indent=False):
 
 def indent(level):
@@ -146,47 +158,38 @@ const QLitObject %(c_name)s = %(c_string)s;
 return self._name(typ.name)
 
 def _gen_tree(self, name, mtype, obj, ifcond, features):
-extra = {}
+extra = 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)
+extra = {'comment': '"%s" = %s' % (self._name(name), name)}
 name = self._name(name)
 obj['name'] = name
 obj['meta-type'] = mtype
-if features:
-obj['features'] = [(f.name, {'if': f.ifcond}) for f in features]
-if ifcond:
-extra['if'] = ifcond
-if extra:
-self._trees.append((obj, extra))
-else:
-self._trees.append(obj)
+self._trees.append(_make_tree(obj, ifcond, features, extra))
 
 def _gen_member(self, member):
-ret = {'name': member.name, 'type': self._use_type(member.type)}
+obj = {'name': member.name, 'type': self._use_type(member.type)}
 if member.optional:
-ret['default'] = None
-if member.ifcond:
-ret = (ret, {'if': member.ifcond})
-return ret
+obj['default'] = None
+return _make_tree(obj, member.ifcond, None)
 
 def _gen_variants(self, tag_name, variants):
 return {'tag': tag_name,
 'variants': [self._gen_variant(v) for v in variants]}
 
 def _gen_variant(self, variant):
-return ({'case': variant.name, 'type': self._use_type(variant.type)},
-{'if': variant.ifcond})
+obj = {'case': variant.name, 'type': self._use_type(variant.type)}
+return _make_tree(obj, variant.ifcond, None)
 
 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':
-[(m.name, {'if': m.ifcond}) for m in members]},
+   {'values': [_make_tree(m.name, m.ifcond, None)
+   for m in members]},
ifcond, features)
 
 def visit_array_type(self, name, info, ifcond, element_type):
@@ -206,7 +209,8 @@ const QLitObject %(c_name)s = %(c_string)s;
 def visit_alternate_type(self, name, info, ifcond, features, variants):
 self._gen_tree(name, 'alternate',
{'members': [
-   ({'type': self._use_type(m.type)}, {'if': m.ifcond})
+   _make_tree({'type': self._use_type(m.type)},
+  m.ifcond, None)
for m in variants.variants]},
ifcond, features)
 
-- 
2.21.1




[PATCH v2 12/30] qapi: Add feature flags to remaining definitions

2020-03-03 Thread Markus Armbruster
In v4.1.0, we added feature flags just to struct types (commit
6a8c0b5102^..f3ed93d545), to satisfy an immediate need (commit
c9d4070991 "file-posix: Add dynamic-auto-read-only QAPI feature").  In
v4.2.0, we added them to commands (commit 23394b4c39 "qapi: Add
feature flags to commands") to satisfy another immediate need (commit
d76744e65e "qapi: Allow introspecting fix for savevm's cooperation
with blockdev").

Add them to the remaining definitions: enumeration types, union types,
alternate types, and events.

Signed-off-by: Markus Armbruster 
---
 docs/devel/qapi-code-gen.txt| 54 +-
 tests/qapi-schema/doc-good.texi | 30 
 qapi/introspect.json| 20 +++---
 tests/test-qmp-cmds.c   |  6 +-
 scripts/qapi/doc.py |  6 +-
 scripts/qapi/events.py  |  2 +-
 scripts/qapi/expr.py| 11 ++-
 scripts/qapi/introspect.py  | 31 
 scripts/qapi/schema.py  | 96 ++---
 scripts/qapi/types.py   |  4 +-
 scripts/qapi/visit.py   |  4 +-
 tests/qapi-schema/alternate-base.err|  2 +-
 tests/qapi-schema/doc-good.json | 17 +
 tests/qapi-schema/doc-good.out  | 15 
 tests/qapi-schema/qapi-schema-test.json | 29 ++--
 tests/qapi-schema/qapi-schema-test.out  | 27 +--
 tests/qapi-schema/test-qapi.py  |  9 ++-
 17 files changed, 242 insertions(+), 121 deletions(-)

diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
index 297a725084..9fce78dcad 100644
--- a/docs/devel/qapi-code-gen.txt
+++ b/docs/devel/qapi-code-gen.txt
@@ -172,7 +172,8 @@ Syntax:
 ENUM = { 'enum': STRING,
  'data': [ ENUM-VALUE, ... ],
  '*prefix': STRING,
- '*if': COND }
+ '*if': COND,
+ '*features': FEATURES }
 ENUM-VALUE = STRING
| { 'name': STRING, '*if': COND }
 
@@ -207,6 +208,9 @@ the job satisfactorily.
 The optional 'if' member specifies a conditional.  See "Configuring
 the schema" below for more on this.
 
+The optional 'features' member specifies features.  See "Features"
+below for more on this.
+
 
 === Type references and array types ===
 
@@ -279,12 +283,14 @@ below for more on this.
 Syntax:
 UNION = { 'union': STRING,
   'data': BRANCHES,
-  '*if': COND }
+  '*if': COND,
+  '*features': FEATURES }
   | { 'union': STRING,
   'data': BRANCHES,
   'base': ( MEMBERS | STRING ),
   'discriminator': STRING,
-  '*if': COND }
+  '*if': COND,
+  '*features': FEATURES }
 BRANCHES = { BRANCH, ... }
 BRANCH = STRING : TYPE-REF
| STRING : { 'type': TYPE-REF, '*if': COND }
@@ -391,13 +397,17 @@ is identical on the wire to:
 The optional 'if' member specifies a conditional.  See "Configuring
 the schema" below for more on this.
 
+The optional 'features' member specifies features.  See "Features"
+below for more on this.
+
 
 === Alternate types ===
 
 Syntax:
 ALTERNATE = { 'alternate': STRING,
   'data': ALTERNATIVES,
-  '*if': COND }
+  '*if': COND,
+  '*features': FEATURES }
 ALTERNATIVES = { ALTERNATIVE, ... }
 ALTERNATIVE = STRING : TYPE-REF
 | STRING : { 'type': STRING, '*if': COND }
@@ -441,6 +451,9 @@ following example objects:
 The optional 'if' member specifies a conditional.  See "Configuring
 the schema" below for more on this.
 
+The optional 'features' member specifies features.  See "Features"
+below for more on this.
+
 
 === Commands ===
 
@@ -584,6 +597,9 @@ started with --preconfig.
 The optional 'if' member specifies a conditional.  See "Configuring
 the schema" below for more on this.
 
+The optional 'features' member specifies features.  See "Features"
+below for more on this.
+
 
 === Events ===
 
@@ -595,7 +611,8 @@ Syntax:
   'data': STRING,
   'boxed': true,
   )
-  '*if': COND }
+  '*if': COND,
+  '*features': FEATURES }
 
 Member 'event' names the event.  This is the event name used in the
 Client JSON Protocol.
@@ -628,6 +645,9 @@ complex type.  See section "Code generated for events" for 
examples.
 The optional 'if' member specifies a conditional.  See "Configuring
 the schema" below for more on this.
 
+The optional 'features' member specifies features.  See "Features"
+below for more on this.
+
 
 === Features ===
 
@@ -966,8 +986,9 @@ schema, along with the SchemaInfo type.  This text attempts 
to give an
 overview how things work.  For details you need to consult the QAPI
 schema.
 
-SchemaInfo objects have common members "name", "meta-type", and
-additional variant members depending on the value of meta-type.
+SchemaInfo objects have common members "name", 

[PATCH v2 29/30] qapi: Implement -compat deprecated-input=reject

2020-03-03 Thread Markus Armbruster
This policy makes deprecated commands fail like this:

---> {"execute": "query-cpus"}
<--- {"error": {"class": "CommandNotFound", "desc": "Deprecated command 
query-cpus disabled by policy"}}

When the command is removed, the error will change to

<--- {"error": {"class": "CommandNotFound", "desc": "The command query-cpus 
has not been found"}}

It makes commands with deprecated arguments fail like this:

---> {"execute": "block-commit", "arguments": {"device": "virtio0", "top": 
"/tmp/snap1.qcow2"}}
<--- {"error": {"class": "GenericError", "desc": "Deprecated parameter 
'top' disabled by policy"}}

When the argument is removed, the error will change to

<--- {"error": {"class": "GenericError", "desc": "Parameter 'top' is 
unexpected"}}

The policy thus permits "testing the future".

Signed-off-by: Markus Armbruster 
---
 include/qapi/qmp/dispatch.h  |  1 +
 include/qapi/qobject-input-visitor.h |  9 +
 include/qapi/visitor-impl.h  |  2 +-
 include/qapi/visitor.h   |  2 +-
 qapi/qapi-visit-core.c   |  4 +--
 qapi/qmp-dispatch.c  | 13 
 qapi/qobject-input-visitor.c | 28 
 qapi/qobject-output-visitor.c|  3 +-
 tests/test-qmp-cmds.c| 49 
 scripts/qapi/commands.py | 12 ---
 scripts/qapi/visit.py| 10 +++---
 11 files changed, 120 insertions(+), 13 deletions(-)

diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
index 9aa426a398..ef256f2bb7 100644
--- a/include/qapi/qmp/dispatch.h
+++ b/include/qapi/qmp/dispatch.h
@@ -24,6 +24,7 @@ typedef enum QmpCommandOptions
 QCO_NO_SUCCESS_RESP   =  (1U << 0),
 QCO_ALLOW_OOB =  (1U << 1),
 QCO_ALLOW_PRECONFIG   =  (1U << 2),
+QCO_DEPRECATED=  (1U << 3),
 } QmpCommandOptions;
 
 typedef struct QmpCommand
diff --git a/include/qapi/qobject-input-visitor.h 
b/include/qapi/qobject-input-visitor.h
index 95985e25e5..cbc54de4ac 100644
--- a/include/qapi/qobject-input-visitor.h
+++ b/include/qapi/qobject-input-visitor.h
@@ -58,6 +58,15 @@ typedef struct QObjectInputVisitor QObjectInputVisitor;
  */
 Visitor *qobject_input_visitor_new(QObject *obj);
 
+/*
+ * Create a QObject input visitor for @obj for use with QMP
+ *
+ * This is like qobject_input_visitor_new(), except it obeys the
+ * policy for handling deprecated management interfaces set with
+ * -compat.
+ */
+Visitor *qobject_input_visitor_new_qmp(QObject *obj);
+
 /*
  * Create a QObject input visitor for @obj for use with keyval_parse()
  *
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index a6b26b7a5b..ccc159a0d2 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -111,7 +111,7 @@ struct Visitor
 void (*optional)(Visitor *v, const char *name, bool *present);
 
 /* Optional */
-bool (*deprecated)(Visitor *v, const char *name);
+bool (*deprecated)(Visitor *v, const char *name, Error **errp);
 
 /* Must be set */
 VisitorType type;
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index c89d51b2a4..2a3c4d0407 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -456,7 +456,7 @@ bool visit_optional(Visitor *v, const char *name, bool 
*present);
  * visit_start_struct() and visit_end_struct(), since only objects
  * have deprecated members.
  */
-bool visit_deprecated(Visitor *v, const char *name);
+bool visit_deprecated(Visitor *v, const char *name, Error **errp);
 
 /*
  * Visit an enum value.
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 501b3ccdef..71e4978a6f 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -137,11 +137,11 @@ bool visit_optional(Visitor *v, const char *name, bool 
*present)
 return *present;
 }
 
-bool visit_deprecated(Visitor *v, const char *name)
+bool visit_deprecated(Visitor *v, const char *name, Error **errp)
 {
 trace_visit_deprecated(v, name);
 if (v->deprecated) {
-return v->deprecated(v, name);
+return v->deprecated(v, name, errp);
 }
 return true;
 }
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 80beab517f..516ee9b0b7 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -132,6 +132,19 @@ QDict *qmp_dispatch(QmpCommandList *cmds, QObject *request,
   "The command %s has not been found", command);
 goto out;
 }
+if (cmd->options & QCO_DEPRECATED) {
+switch (compat_policy.deprecated_input) {
+case COMPAT_POLICY_INPUT_ACCEPT:
+break;
+case COMPAT_POLICY_INPUT_REJECT:
+error_set(, ERROR_CLASS_COMMAND_NOT_FOUND,
+  "Deprecated command %s disabled by policy",
+  command);
+goto out;
+default:
+abort();
+}
+}
 if (!cmd->enabled) {
 error_set(, 

[PATCH v2 28/30] qapi: Implement -compat deprecated-output=hide

2020-03-03 Thread Markus Armbruster
This policy suppresses deprecated command results and deprecated
events, and thus permits "testing the future".

Example:

---> {"execute": "query-cpus-fast"}
<--- {"return": [{"thread-id": 9805, "props": {"core-id": 0, "thread-id": 
0, "socket-id": 0}, "qom-path": "/machine/unattached/device[0]", "cpu-index": 
0, "target": "x86_64"}]}

Note the absence of deprecated member "arch".

No QMP event is deprecated right now.

Signed-off-by: Markus Armbruster 
---
 include/qapi/qobject-output-visitor.h   |  9 ++
 include/qapi/visitor-impl.h |  3 ++
 include/qapi/visitor.h  |  9 ++
 qapi/qapi-visit-core.c  |  9 ++
 qapi/qobject-output-visitor.c   | 19 +++
 tests/test-qmp-cmds.c   | 42 ++---
 tests/test-qmp-event.c  | 19 +++
 qapi/trace-events   |  1 +
 scripts/qapi/commands.py|  2 +-
 scripts/qapi/events.py  | 14 +++--
 scripts/qapi/visit.py   | 12 +++
 tests/qapi-schema/qapi-schema-test.json | 17 +-
 tests/qapi-schema/qapi-schema-test.out  | 18 +--
 13 files changed, 149 insertions(+), 25 deletions(-)

diff --git a/include/qapi/qobject-output-visitor.h 
b/include/qapi/qobject-output-visitor.h
index 2b1726baf5..29f4ea6aad 100644
--- a/include/qapi/qobject-output-visitor.h
+++ b/include/qapi/qobject-output-visitor.h
@@ -53,4 +53,13 @@ typedef struct QObjectOutputVisitor QObjectOutputVisitor;
  */
 Visitor *qobject_output_visitor_new(QObject **result);
 
+/*
+ * Create a QObject output visitor for @obj for use with QMP
+ *
+ * This is like qobject_output_visitor_new(), except it obeys the
+ * policy for handling deprecated management interfaces set with
+ * -compat.
+ */
+Visitor *qobject_output_visitor_new_qmp(QObject **result);
+
 #endif
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 8ccb3b6c20..a6b26b7a5b 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -110,6 +110,9 @@ struct Visitor
The core takes care of the return type in the public interface. */
 void (*optional)(Visitor *v, const char *name, bool *present);
 
+/* Optional */
+bool (*deprecated)(Visitor *v, const char *name);
+
 /* Must be set */
 VisitorType type;
 
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index c5b23851a1..c89d51b2a4 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -449,6 +449,15 @@ void visit_end_alternate(Visitor *v, void **obj);
  */
 bool visit_optional(Visitor *v, const char *name, bool *present);
 
+/*
+ * Should we visit deprecated member @name?
+ *
+ * @name must not be NULL.  This function is only useful between
+ * visit_start_struct() and visit_end_struct(), since only objects
+ * have deprecated members.
+ */
+bool visit_deprecated(Visitor *v, const char *name);
+
 /*
  * Visit an enum value.
  *
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 5365561b07..501b3ccdef 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -137,6 +137,15 @@ bool visit_optional(Visitor *v, const char *name, bool 
*present)
 return *present;
 }
 
+bool visit_deprecated(Visitor *v, const char *name)
+{
+trace_visit_deprecated(v, name);
+if (v->deprecated) {
+return v->deprecated(v, name);
+}
+return true;
+}
+
 bool visit_is_input(Visitor *v)
 {
 return v->type == VISITOR_INPUT;
diff --git a/qapi/qobject-output-visitor.c b/qapi/qobject-output-visitor.c
index 26d7be5ec9..84cee17596 100644
--- a/qapi/qobject-output-visitor.c
+++ b/qapi/qobject-output-visitor.c
@@ -13,6 +13,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qapi/compat-policy.h"
 #include "qapi/qobject-output-visitor.h"
 #include "qapi/visitor-impl.h"
 #include "qemu/queue.h"
@@ -31,6 +32,8 @@ typedef struct QStackEntry {
 
 struct QObjectOutputVisitor {
 Visitor visitor;
+CompatPolicyOutput deprecated_policy;
+
 QSLIST_HEAD(, QStackEntry) stack; /* Stack of unfinished containers */
 QObject *root; /* Root of the output visit */
 QObject **result; /* User's storage location for result */
@@ -198,6 +201,13 @@ static void qobject_output_type_null(Visitor *v, const 
char *name,
 qobject_output_add(qov, name, qnull());
 }
 
+static bool qobject_output_deprecated(Visitor *v, const char *name)
+{
+QObjectOutputVisitor *qov = to_qov(v);
+
+return qov->deprecated_policy != COMPAT_POLICY_OUTPUT_HIDE;
+}
+
 /* Finish building, and return the root object.
  * The root object is never null. The caller becomes the object's
  * owner, and should use qobject_unref() when done with it.  */
@@ -247,6 +257,7 @@ Visitor *qobject_output_visitor_new(QObject **result)
 v->visitor.type_number = qobject_output_type_number;
 v->visitor.type_any = qobject_output_type_any;
 v->visitor.type_null = qobject_output_type_null;
+v->visitor.deprecated = 

[PATCH v2 18/30] qapi/schema: Rename QAPISchemaObjectType{Variant, Variants}

2020-03-03 Thread Markus Armbruster
QAPISchemaObjectTypeVariants represents both object type and alternate
type variants.  Rename to QAPISchemaVariants.

Rename QAPISchemaObjectTypeVariant the same way.

Signed-off-by: Markus Armbruster 
---
 scripts/qapi/schema.py | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
index f0fb0d1c4d..3065f8e14d 100644
--- a/scripts/qapi/schema.py
+++ b/scripts/qapi/schema.py
@@ -338,7 +338,7 @@ class QAPISchemaObjectType(QAPISchemaType):
 assert isinstance(m, QAPISchemaObjectTypeMember)
 m.set_defined_in(name)
 if variants is not None:
-assert isinstance(variants, QAPISchemaObjectTypeVariants)
+assert isinstance(variants, QAPISchemaVariants)
 variants.set_defined_in(name)
 self._base_name = base
 self.base = None
@@ -449,7 +449,7 @@ class QAPISchemaAlternateType(QAPISchemaType):
 
 def __init__(self, name, info, doc, ifcond, features, variants):
 super().__init__(name, info, doc, ifcond, features)
-assert isinstance(variants, QAPISchemaObjectTypeVariants)
+assert isinstance(variants, QAPISchemaVariants)
 assert variants.tag_member
 variants.set_defined_in(name)
 variants.tag_member.set_defined_in(self.name)
@@ -512,7 +512,7 @@ class QAPISchemaAlternateType(QAPISchemaType):
 self.name, self.info, self.ifcond, self.features, self.variants)
 
 
-class QAPISchemaObjectTypeVariants:
+class QAPISchemaVariants:
 def __init__(self, tag_name, info, tag_member, variants):
 # Flat unions pass tag_name but not tag_member.
 # Simple unions and alternates pass tag_member but not tag_name.
@@ -522,7 +522,7 @@ class QAPISchemaObjectTypeVariants:
 assert (isinstance(tag_name, str) or
 isinstance(tag_member, QAPISchemaObjectTypeMember))
 for v in variants:
-assert isinstance(v, QAPISchemaObjectTypeVariant)
+assert isinstance(v, QAPISchemaVariant)
 self._tag_name = tag_name
 self.info = info
 self.tag_member = tag_member
@@ -572,8 +572,8 @@ class QAPISchemaObjectTypeVariants:
 cases = {v.name for v in self.variants}
 for m in self.tag_member.type.members:
 if m.name not in cases:
-v = QAPISchemaObjectTypeVariant(m.name, self.info,
-'q_empty', m.ifcond)
+v = QAPISchemaVariant(m.name, self.info,
+  'q_empty', m.ifcond)
 v.set_defined_in(self.tag_member.defined_in)
 self.variants.append(v)
 if not self.variants:
@@ -681,7 +681,7 @@ class QAPISchemaObjectTypeMember(QAPISchemaMember):
 self.describe)
 
 
-class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
+class QAPISchemaVariant(QAPISchemaObjectTypeMember):
 role = 'branch'
 
 def __init__(self, name, info, typ, ifcond=None):
@@ -988,7 +988,7 @@ class QAPISchema:
 None))
 
 def _make_variant(self, case, typ, ifcond, info):
-return QAPISchemaObjectTypeVariant(case, info, typ, ifcond)
+return QAPISchemaVariant(case, info, typ, ifcond)
 
 def _make_simple_variant(self, case, typ, ifcond, info):
 if isinstance(typ, list):
@@ -997,7 +997,7 @@ class QAPISchema:
 typ = self._make_implicit_object_type(
 typ, info, self.lookup_type(typ),
 'wrapper', [self._make_member('data', typ, None, info)])
-return QAPISchemaObjectTypeVariant(case, info, typ, ifcond)
+return QAPISchemaVariant(case, info, typ, ifcond)
 
 def _def_union_type(self, expr, info, doc):
 name = expr['union']
@@ -1027,7 +1027,7 @@ class QAPISchema:
 self._def_entity(
 QAPISchemaObjectType(name, info, doc, ifcond, features,
  base, members,
- QAPISchemaObjectTypeVariants(
+ QAPISchemaVariants(
  tag_name, info, tag_member, variants)))
 
 def _def_alternate_type(self, expr, info, doc):
@@ -1041,7 +1041,7 @@ class QAPISchema:
 tag_member = QAPISchemaObjectTypeMember('type', info, 'QType', False)
 self._def_entity(
 QAPISchemaAlternateType(name, info, doc, ifcond, features,
-QAPISchemaObjectTypeVariants(
+QAPISchemaVariants(
 None, info, tag_member, variants)))
 
 def _def_command(self, expr, info, doc):
-- 
2.21.1




[PATCH v2 13/30] qapi: Consistently put @features parameter right after @ifcond

2020-03-03 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
---
 scripts/qapi/commands.py   |  6 +++---
 scripts/qapi/doc.py| 10 +-
 scripts/qapi/introspect.py | 10 +-
 scripts/qapi/schema.py | 36 --
 scripts/qapi/types.py  |  4 ++--
 scripts/qapi/visit.py  |  4 ++--
 tests/qapi-schema/test-qapi.py | 10 +-
 7 files changed, 39 insertions(+), 41 deletions(-)

diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
index 0e13e82989..bc30876c88 100644
--- a/scripts/qapi/commands.py
+++ b/scripts/qapi/commands.py
@@ -283,9 +283,9 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
   prefix=self._prefix))
 self._genc.add(gen_registry(self._regy.get_content(), self._prefix))
 
-def visit_command(self, name, info, ifcond, arg_type, ret_type, gen,
-  success_response, boxed, allow_oob, allow_preconfig,
-  features):
+def visit_command(self, name, info, ifcond, features,
+  arg_type, ret_type, gen, success_response, boxed,
+  allow_oob, allow_preconfig):
 if not gen:
 return
 # FIXME: If T is a user-defined type, the user is responsible
diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py
index 36e823338b..92f584edcf 100644
--- a/scripts/qapi/doc.py
+++ b/scripts/qapi/doc.py
@@ -249,8 +249,8 @@ class QAPISchemaGenDocVisitor(QAPISchemaVisitor):
 texi_members(doc, 'Values',
  member_func=texi_enum_value)))
 
-def visit_object_type(self, name, info, ifcond, base, members, variants,
-  features):
+def visit_object_type(self, name, info, ifcond, features,
+  base, members, variants):
 doc = self.cur_doc
 if base and base.is_implicit():
 base = None
@@ -262,9 +262,9 @@ class QAPISchemaGenDocVisitor(QAPISchemaVisitor):
 self._gen.add(texi_type('Alternate', doc, ifcond,
 texi_members(doc, 'Members')))
 
-def visit_command(self, name, info, ifcond, arg_type, ret_type, gen,
-  success_response, boxed, allow_oob, allow_preconfig,
-  features):
+def visit_command(self, name, info, ifcond, features,
+  arg_type, ret_type, gen, success_response, boxed,
+  allow_oob, allow_preconfig):
 doc = self.cur_doc
 self._gen.add(texi_msg('Command', doc, ifcond,
texi_arguments(doc,
diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index 2e9e00aa1f..b54910510d 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -193,8 +193,8 @@ const QLitObject %(c_name)s = %(c_string)s;
 self._gen_qlit('[' + element + ']', 'array', {'element-type': element},
ifcond, None)
 
-def visit_object_type_flat(self, name, info, ifcond, members, variants,
-   features):
+def visit_object_type_flat(self, name, info, ifcond, features,
+   members, variants):
 obj = {'members': [self._gen_member(m) for m in members]}
 if variants:
 obj.update(self._gen_variants(variants.tag_member.name,
@@ -209,9 +209,9 @@ const QLitObject %(c_name)s = %(c_string)s;
for m in variants.variants]},
ifcond, features)
 
-def visit_command(self, name, info, ifcond, arg_type, ret_type, gen,
-  success_response, boxed, allow_oob, allow_preconfig,
-  features):
+def visit_command(self, name, info, ifcond, features,
+  arg_type, ret_type, gen, success_response, boxed,
+  allow_oob, allow_preconfig):
 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),
diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
index 98c9f3016c..e3353989e9 100644
--- a/scripts/qapi/schema.py
+++ b/scripts/qapi/schema.py
@@ -115,20 +115,20 @@ class QAPISchemaVisitor:
 def visit_array_type(self, name, info, ifcond, element_type):
 pass
 
-def visit_object_type(self, name, info, ifcond, base, members, variants,
-  features):
+def visit_object_type(self, name, info, ifcond, features,
+  base, members, variants):
 pass
 
-def visit_object_type_flat(self, name, info, ifcond, members, variants,
-   features):
+def visit_object_type_flat(self, name, info, ifcond, features,
+   members, variants):
 pass
 
 def visit_alternate_type(self, name, info, ifcond, 

[PATCH v2 26/30] qapi: Mark deprecated QMP parts with feature 'deprecated'

2020-03-03 Thread Markus Armbruster
Add feature 'deprecated' to the deprecated QMP commands, so their
deprecation becomes visible in output of query-qmp-schema.  Looks like
this:

{"name": "query-cpus",
 "ret-type": "[164]",
 "meta-type": "command",
 "arg-type": "0",
---> "features": ["deprecated"]}

Management applications could conceivably use this for static
checking.

The deprecated commands are change, cpu-add, migrate-set-cache-size,
migrate_set_downtime, migrate_set_speed, query-cpus, query-events,
query-migrate-cache-size.

The deprecated command arguments are block-commit arguments @base and
@top, and block_set_io_throttle, blockdev-change-medium,
blockdev-close-tray, blockdev-open-tray, eject argument @device.

The deprecated command results are query-cpus-fast result @arch,
query-block result @dirty-bitmaps, query-named-block-nodes result
@encryption_key_missing and result @dirty-bitmaps's member @status.
Same for query-block result @inserted, which mirrors
query-named-block-nodes.

Signed-off-by: Markus Armbruster 
---
 qapi/block-core.json | 69 +---
 qapi/block.json  |  9 --
 qapi/control.json| 11 ---
 qapi/machine.json| 34 --
 qapi/migration.json  | 36 +++
 qapi/misc.json   | 13 +
 6 files changed, 115 insertions(+), 57 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 85e27bb61f..bade02760c 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -297,7 +297,7 @@
 #
 # @encrypted: true if the backing device is encrypted
 #
-# @encryption_key_missing: Deprecated; always false
+# @encryption_key_missing: always false
 #
 # @detect_zeroes: detect and optimize zero writes (Since 2.1)
 #
@@ -363,13 +363,19 @@
 # @dirty-bitmaps: dirty bitmaps information (only present if node
 # has one or more dirty bitmaps) (Since 4.2)
 #
+# Features:
+# @deprecated: Member @encryption_key_missing is deprecated.  It is
+# always false.
+#
 # Since: 0.14.0
 #
 ##
 { 'struct': 'BlockDeviceInfo',
   'data': { 'file': 'str', '*node-name': 'str', 'ro': 'bool', 'drv': 'str',
 '*backing_file': 'str', 'backing_file_depth': 'int',
-'encrypted': 'bool', 'encryption_key_missing': 'bool',
+'encrypted': 'bool',
+'encryption_key_missing': { 'type': 'bool',
+'features': [ 'deprecated' ] },
 'detect_zeroes': 'BlockdevDetectZeroesOptions',
 'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',
 'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int',
@@ -475,7 +481,7 @@
 #
 # @granularity: granularity of the dirty bitmap in bytes (since 1.4)
 #
-# @status: Deprecated in favor of @recording and @locked. (since 2.4)
+# @status: current status of the dirty bitmap (since 2.4)
 #
 # @recording: true if the bitmap is recording new writes from the guest.
 # Replaces `active` and `disabled` statuses. (since 4.0)
@@ -492,11 +498,17 @@
 #@busy to be false. This bitmap cannot be used. To remove
 #it, use @block-dirty-bitmap-remove. (Since 4.0)
 #
+# Features:
+# @deprecated: Member @status is deprecated.  Use @recording and
+# @locked instead.
+#
 # Since: 1.3
 ##
 { 'struct': 'BlockDirtyInfo',
   'data': {'*name': 'str', 'count': 'int', 'granularity': 'uint32',
-   'recording': 'bool', 'busy': 'bool', 'status': 'DirtyBitmapStatus',
+   'recording': 'bool', 'busy': 'bool',
+   'status': { 'type': 'DirtyBitmapStatus',
+   'features': [ 'deprecated' ] },
'persistent': 'bool', '*inconsistent': 'bool' } }
 
 ##
@@ -659,7 +671,6 @@
 #
 # @dirty-bitmaps: dirty bitmaps information (only present if the
 # driver has one or more dirty bitmaps) (Since 2.0)
-# Deprecated in 4.2; see BlockDeviceInfo instead.
 #
 # @io-status: @BlockDeviceIoStatus. Only present if the device
 # supports it and the VM is configured to stop on errors
@@ -669,13 +680,18 @@
 # @inserted: @BlockDeviceInfo describing the device if media is
 #present
 #
+# Features:
+# @deprecated: Member @dirty-bitmaps is deprecated.  Use @inserted
+# member @dirty-bitmaps instead.
+#
 # Since:  0.14.0
 ##
 { 'struct': 'BlockInfo',
   'data': {'device': 'str', '*qdev': 'str', 'type': 'str', 'removable': 'bool',
'locked': 'bool', '*inserted': 'BlockDeviceInfo',
'*tray_open': 'bool', '*io-status': 'BlockDeviceIoStatus',
-   '*dirty-bitmaps': ['BlockDirtyInfo'] } }
+   '*dirty-bitmaps': { 'type': ['BlockDirtyInfo'],
+   'features': [ 'deprecated' ] } } }
 
 ##
 # @BlockMeasureInfo:
@@ -1616,7 +1632,7 @@
 # @base: Same as @base-node, except that it is a file name rather than a node
 #name. This must be the exact filename string that was used to open the
 #node; other strings, even if addressing the 

[PATCH v2 14/30] qapi/introspect: Rename *qlit* to reduce confusion

2020-03-03 Thread Markus Armbruster
We generate the value of qmp_schema_qlit from an expression tree.  The
function doing that is named to_qlit(), and its inputs are accumulated
in QAPISchemaGenIntrospectVisitor._qlits.  We call both its input and
its output "qlit".  This is confusing.

Use "tree" for input, and "qlit" only for output: rename to_qlit() to
_tree_to_qlit(), ._qlits to ._trees, ._gen_qlit() to ._gen_tree().

Signed-off-by: Markus Armbruster 
---
 scripts/qapi/introspect.py | 35 ++-
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index b54910510d..e4fc9d90f1 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -16,7 +16,7 @@ from qapi.schema import (QAPISchemaArrayType, 
QAPISchemaBuiltinType,
  QAPISchemaType)
 
 
-def to_qlit(obj, level=0, suppress_first_indent=False):
+def _tree_to_qlit(obj, level=0, suppress_first_indent=False):
 
 def indent(level):
 return level * 4 * ' '
@@ -30,7 +30,7 @@ def to_qlit(obj, level=0, suppress_first_indent=False):
 ret += indent(level) + '/* %s */\n' % comment
 if ifcond:
 ret += gen_if(ifcond)
-ret += to_qlit(ifobj, level)
+ret += _tree_to_qlit(ifobj, level)
 if ifcond:
 ret += '\n' + gen_endif(ifcond)
 return ret
@@ -43,7 +43,7 @@ def to_qlit(obj, level=0, suppress_first_indent=False):
 elif isinstance(obj, str):
 ret += 'QLIT_QSTR(' + to_c_string(obj) + ')'
 elif isinstance(obj, list):
-elts = [to_qlit(elt, level + 1).strip('\n')
+elts = [_tree_to_qlit(elt, level + 1).strip('\n')
 for elt in obj]
 elts.append(indent(level + 1) + "{}")
 ret += 'QLIT_QLIST(((QLitObject[]) {\n'
@@ -53,7 +53,8 @@ def to_qlit(obj, level=0, suppress_first_indent=False):
 elts = []
 for key, value in sorted(obj.items()):
 elts.append(indent(level + 1) + '{ %s, %s }' %
-(to_c_string(key), to_qlit(value, level + 1, True)))
+(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'
@@ -79,7 +80,7 @@ class 
QAPISchemaGenIntrospectVisitor(QAPISchemaMonolithicCVisitor):
 ' * QAPI/QMP schema introspection', __doc__)
 self._unmask = unmask
 self._schema = None
-self._qlits = []
+self._trees = []
 self._used_types = []
 self._name_map = {}
 self._genc.add(mcgen('''
@@ -108,9 +109,9 @@ extern const QLitObject %(c_name)s;
 const QLitObject %(c_name)s = %(c_string)s;
 ''',
  c_name=c_name(name),
- c_string=to_qlit(self._qlits)))
+ c_string=_tree_to_qlit(self._trees)))
 self._schema = None
-self._qlits = []
+self._trees = []
 self._used_types = []
 self._name_map = {}
 
@@ -144,7 +145,7 @@ const QLitObject %(c_name)s = %(c_string)s;
 return '[' + self._use_type(typ.element_type) + ']'
 return self._name(typ.name)
 
-def _gen_qlit(self, name, mtype, obj, ifcond, features):
+def _gen_tree(self, name, mtype, obj, ifcond, features):
 extra = {}
 if mtype not in ('command', 'event', 'builtin', 'array'):
 if not self._unmask:
@@ -159,9 +160,9 @@ const QLitObject %(c_name)s = %(c_string)s;
 if ifcond:
 extra['if'] = ifcond
 if extra:
-self._qlits.append((obj, extra))
+self._trees.append((obj, extra))
 else:
-self._qlits.append(obj)
+self._trees.append(obj)
 
 def _gen_member(self, member):
 ret = {'name': member.name, 'type': self._use_type(member.type)}
@@ -180,17 +181,17 @@ const QLitObject %(c_name)s = %(c_string)s;
 {'if': variant.ifcond})
 
 def visit_builtin_type(self, name, info, json_type):
-self._gen_qlit(name, 'builtin', {'json-type': json_type}, [], None)
+self._gen_tree(name, 'builtin', {'json-type': json_type}, [], None)
 
 def visit_enum_type(self, name, info, ifcond, features, members, prefix):
-self._gen_qlit(name, 'enum',
+self._gen_tree(name, 'enum',
{'values':
 [(m.name, {'if': m.ifcond}) for m in members]},
ifcond, features)
 
 def visit_array_type(self, name, info, ifcond, element_type):
 element = self._use_type(element_type)
-self._gen_qlit('[' + element + ']', 'array', {'element-type': element},
+self._gen_tree('[' + element + ']', 'array', {'element-type': element},
ifcond, None)
 
 def visit_object_type_flat(self, name, info, ifcond, features,
@@ 

  1   2   3   >