Re: [PATCH v6 04/23] target/riscv: Improve delivery of guest external interrupts

2022-01-12 Thread Frank Chang
Anup Patel  於 2021年12月30日 週四 下午8:48寫道:

> From: Anup Patel 
>
> The guest external interrupts from an interrupt controller are
> delivered only when the Guest/VM is running (i.e. V=1). This means
> any guest external interrupt which is triggered while the Guest/VM
> is not running (i.e. V=0) will be missed on QEMU resulting in Guest
> with sluggish response to serial console input and other I/O events.
>
> To solve this, we check and inject interrupt after setting V=1.
>
> Signed-off-by: Anup Patel 
> Signed-off-by: Anup Patel 
> Reviewed-by: Alistair Francis 
> ---
>  target/riscv/cpu_helper.c | 13 +
>  1 file changed, 13 insertions(+)
>
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index bf50699b1f..43d6311e49 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -325,6 +325,19 @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env,
> bool enable)
>  }
>
>  env->virt = set_field(env->virt, VIRT_ONOFF, enable);
> +
> +if (enable) {
> +   /*
> +* The guest external interrupts from an interrupt controller are
> +* delivered only when the Guest/VM is running (i.e. V=1). This
> means
> +* any guest external interrupt which is triggered while the
> Guest/VM
> +* is not running (i.e. V=0) will be missed on QEMU resulting in
> guest
> +* with sluggish response to serial console input and other I/O
> events.
> +*
> +* To solve this, we check and inject interrupt after setting V=1.
> +*/
> +riscv_cpu_update_mip(env_archcpu(env), 0, 0);
> +}
>  }
>
>  bool riscv_cpu_two_stage_lookup(int mmu_idx)
> --
> 2.25.1
>
>
>
Reviewed-by: Frank Chang 


Re: [PATCH v6 20/23] hw/intc: Add RISC-V AIA IMSIC device emulation

2022-01-12 Thread Frank Chang
Anup Patel  於 2021年12月30日 週四 下午9:00寫道:

> From: Anup Patel 
>
> The RISC-V AIA (Advanced Interrupt Architecture) defines a new
> interrupt controller for MSIs (message signal interrupts) called
> IMSIC (Incoming Message Signal Interrupt Controller). The IMSIC
> is per-HART device and also suppport virtualizaiton of MSIs using
> dedicated VS-level guest interrupt files.
>
> This patch adds device emulation for RISC-V AIA IMSIC which
> supports M-level, S-level, and VS-level MSIs.
>
> Signed-off-by: Anup Patel 
> Signed-off-by: Anup Patel 
> ---
>  hw/intc/Kconfig   |   3 +
>  hw/intc/meson.build   |   1 +
>  hw/intc/riscv_imsic.c | 447 ++
>  include/hw/intc/riscv_imsic.h |  68 ++
>  4 files changed, 519 insertions(+)
>  create mode 100644 hw/intc/riscv_imsic.c
>  create mode 100644 include/hw/intc/riscv_imsic.h
>
> diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
> index 528e77b4a6..ec8d4cec29 100644
> --- a/hw/intc/Kconfig
> +++ b/hw/intc/Kconfig
> @@ -73,6 +73,9 @@ config RISCV_ACLINT
>  config RISCV_APLIC
>  bool
>
> +config RISCV_IMSIC
> +bool
> +
>  config SIFIVE_PLIC
>  bool
>
> diff --git a/hw/intc/meson.build b/hw/intc/meson.build
> index 7466024402..5caa337654 100644
> --- a/hw/intc/meson.build
> +++ b/hw/intc/meson.build
> @@ -51,6 +51,7 @@ specific_ss.add(when: 'CONFIG_S390_FLIC_KVM', if_true:
> files('s390_flic_kvm.c'))
>  specific_ss.add(when: 'CONFIG_SH_INTC', if_true: files('sh_intc.c'))
>  specific_ss.add(when: 'CONFIG_RISCV_ACLINT', if_true:
> files('riscv_aclint.c'))
>  specific_ss.add(when: 'CONFIG_RISCV_APLIC', if_true:
> files('riscv_aplic.c'))
> +specific_ss.add(when: 'CONFIG_RISCV_IMSIC', if_true:
> files('riscv_imsic.c'))
>  specific_ss.add(when: 'CONFIG_SIFIVE_PLIC', if_true:
> files('sifive_plic.c'))
>  specific_ss.add(when: 'CONFIG_XICS', if_true: files('xics.c'))
>  specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_XICS'],
> diff --git a/hw/intc/riscv_imsic.c b/hw/intc/riscv_imsic.c
> new file mode 100644
> index 00..753fa11a9c
> --- /dev/null
> +++ b/hw/intc/riscv_imsic.c
> @@ -0,0 +1,447 @@
> +/*
> + * RISC-V IMSIC (Incoming Message Signaled Interrupt Controller)
> + *
> + * Copyright (c) 2021 Western Digital Corporation or its affiliates.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License
> along with
> + * this program.  If not, see .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "qemu/log.h"
> +#include "qemu/module.h"
> +#include "qemu/error-report.h"
> +#include "qemu/bswap.h"
> +#include "exec/address-spaces.h"
> +#include "hw/sysbus.h"
> +#include "hw/pci/msi.h"
> +#include "hw/boards.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/intc/riscv_imsic.h"
> +#include "hw/irq.h"
> +#include "target/riscv/cpu.h"
> +#include "target/riscv/cpu_bits.h"
> +#include "sysemu/sysemu.h"
> +#include "migration/vmstate.h"
> +
> +#define IMSIC_MMIO_PAGE_LE 0x00
> +#define IMSIC_MMIO_PAGE_BE 0x04
> +
> +#define IMSIC_MIN_ID   ((IMSIC_EIPx_BITS * 2) - 1)
> +#define IMSIC_MAX_ID   (IMSIC_TOPEI_IID_MASK)
> +
> +#define IMSIC_EISTATE_PENDING  (1U << 0)
> +#define IMSIC_EISTATE_ENABLED  (1U << 1)
> +#define IMSIC_EISTATE_ENPEND   (IMSIC_EISTATE_ENABLED | \
> +IMSIC_EISTATE_PENDING)
> +
> +static uint32_t riscv_imsic_topei(RISCVIMSICState *imsic, uint32_t page)
> +{
> +uint32_t i, max_irq, base;
> +
> +base = page * imsic->num_irqs;
> +max_irq = (imsic->num_irqs < imsic->eithreshold[page]) ?
> +  imsic->num_irqs : imsic->eithreshold[page];
>

Do we need to exclude the case which imsic->eithreshold[page] == 0?
  The value of a *topei CSR (mtopei, stopei, or vstopei) indicates the
interrupt file’s current
  highest-priority pending-and-enabled interrupt that also exceeds the
priority threshold specified by
  its eithreshold register if eithreshold is not zero.


> +for (i = 1; i < max_irq; i++) {
> +if ((imsic->eistate[base + i] & IMSIC_EISTATE_ENPEND) ==
> +IMSIC_EISTATE_ENPEND) {
> +return (i << IMSIC_TOPEI_IID_SHIFT) | i;
> +}
> +}
> +
> +return 0;
> +}
> +
> +static void riscv_imsic_update(RISCVIMSICState *imsic, uint32_t page)
> +{
> +if (imsic->eidelivery[page] && riscv_imsic_topei(imsic, page)) {
> +

Re: [PATCH] softmmu/device_tree: Remove redundant pointer assignment

2022-01-12 Thread Thomas Huth

On 11/01/2022 04.27, Yanan Wang wrote:

The pointer assignment "const char *p = path;" in function
qemu_fdt_add_path is unnecessary. Let's remove it and just
use the "path" passed in. No functional change.

Suggested-by: Richard Henderson 
Signed-off-by: Yanan Wang 
---
Based on: softmmu/device_tree: Silence compiler warning with --enable-sanitizers
https://patchew.org/QEMU/20220107133844.145039-1-th...@redhat.com/
---
  softmmu/device_tree.c | 9 -
  1 file changed, 4 insertions(+), 5 deletions(-)


Reviewed-by: Thomas Huth 




Re: [RFC PATCH v3 7/7] gitlab-ci: Support macOS 12 via cirrus-run

2022-01-12 Thread Thomas Huth

On 10/01/2022 14.10, Philippe Mathieu-Daudé wrote:

Add support for macOS 12 build on Cirrus-CI, similarly to commit
0e103a65ba1 ("gitlab: support for ... macOS 11 via cirrus-run").

Update the lcitool repository to get the macos12 mappings,
and generate the vars file by calling 'make lcitool-refresh'.

Signed-off-by: Philippe Mathieu-Daudé 
---
Pending on libvirt-ci MR #210:
https://gitlab.com/libvirt/libvirt-ci/-/merge_requests/210
---
  .gitlab-ci.d/cirrus.yml   | 15 +++
  .gitlab-ci.d/cirrus/macos-12.vars | 16 
  tests/lcitool/libvirt-ci  |  2 +-
  tests/lcitool/refresh |  1 +
  4 files changed, 33 insertions(+), 1 deletion(-)
  create mode 100644 .gitlab-ci.d/cirrus/macos-12.vars

diff --git a/.gitlab-ci.d/cirrus.yml b/.gitlab-ci.d/cirrus.yml
index b96b22e2697..b7662959070 100644
--- a/.gitlab-ci.d/cirrus.yml
+++ b/.gitlab-ci.d/cirrus.yml
@@ -87,6 +87,21 @@ x64-macos-11-base-build:
  PKG_CONFIG_PATH: 
/usr/local/opt/curl/lib/pkgconfig:/usr/local/opt/ncurses/lib/pkgconfig:/usr/local/opt/readline/lib/pkgconfig
  TEST_TARGETS: check-unit check-block check-qapi-schema check-softfloat 
check-qtest-x86_64
  
+x64-macos-12-base-build:

+  extends: .cirrus_build_job
+  variables:
+NAME: macos-12
+CIRRUS_VM_INSTANCE_TYPE: osx_instance
+CIRRUS_VM_IMAGE_SELECTOR: image
+CIRRUS_VM_IMAGE_NAME: monterey-base
+CIRRUS_VM_CPUS: 12
+CIRRUS_VM_RAM: 24G
+UPDATE_COMMAND: brew update
+INSTALL_COMMAND: brew install
+PATH_EXTRA: /usr/local/opt/ccache/libexec:/usr/local/opt/gettext/bin
+PKG_CONFIG_PATH: 
/usr/local/opt/curl/lib/pkgconfig:/usr/local/opt/ncurses/lib/pkgconfig:/usr/local/opt/readline/lib/pkgconfig
+TEST_TARGETS: check-unit check-block check-qapi-schema check-softfloat 
check-qtest-x86_64


Since we cannot run that many Cirrus-CI jobs in parallel, I think it might 
make sense to limit the macos-11 job to manual mode now?


 Thomas





Re: [PATCH] sgx: Move sgx object from /machine/unattached to /machine

2022-01-12 Thread Yang Zhong
Hi Daniel,

On Wed, Jan 12, 2022 at 10:11:35AM +, Daniel P. Berrangé wrote:
> On Wed, Jan 12, 2022 at 11:55:17AM -0500, Yang Zhong wrote:
> > When Libvirt start, it get the vcpu's unavailable-features from
> > /machine/unattached/device[0] path by qom-get command, but in SGX
> > guest, since the sgx-epc virtual device is initialized before VCPU
> > creation(virtual sgx need set the virtual EPC info in the cpuid). This
> > /machine/unattached/device[0] is occupied by sgx-epc device, which
> > fail to get the unvailable-features from /machine/unattached/device[0].
> 
> If libvirt decides to enable SGX in a VM, then surely it knows
> that it should just query /machine/unattached/device[1] to get
> the CPU features instead. Why do we need to do anything in QEMU ?
> 

  I listed two solutions in the Qemu or Libvirt before:
  https://lists.nongnu.org/archive/html/qemu-devel/2021-11/msg05670.html

  This time, I posted this patch and hope to have a talk for this issue.

  If Libvirt side should handle this, I will drop this patch and inform
  them to do this. Thanks!


> > 
> > This patch make one new /machine/sgx object to avoid this issue.
> > (qemu) qom-list /machine/unattached/
> > device[0] (child)
> > 
> > (qemu) qom-list /machine/sgx
> > device[0] (child)
> > 
> > Signed-off-by: Yang Zhong 
> > ---
> >  hw/core/qdev.c | 12 ++--
> >  1 file changed, 10 insertions(+), 2 deletions(-)
> > 
> > diff --git a/hw/core/qdev.c b/hw/core/qdev.c
> > index 84f3019440..4154eef0d8 100644
> > --- a/hw/core/qdev.c
> > +++ b/hw/core/qdev.c
> > @@ -497,7 +497,7 @@ static void device_set_realized(Object *obj, bool 
> > value, Error **errp)
> >  NamedClockList *ncl;
> >  Error *local_err = NULL;
> >  bool unattached_parent = false;
> > -static int unattached_count;
> > +static int unattached_count, sgx_count;
> >  
> >  if (dev->hotplugged && !dc->hotpluggable) {
> >  error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
> > @@ -509,7 +509,15 @@ static void device_set_realized(Object *obj, bool 
> > value, Error **errp)
> >  goto fail;
> >  }
> >  
> > -if (!obj->parent) {
> > +if (!obj->parent && !strcmp(object_get_typename(obj), "sgx-epc")) {
> > +gchar *name = g_strdup_printf("device[%d]", sgx_count++);
> > +
> > +object_property_add_child(container_get(qdev_get_machine(),
> > +"/sgx"),
> > +  name, obj);
> > +unattached_parent = true;
> > +g_free(name);
> 
> The qdev.c file is part of our generic object code. It should not
> contain any code that is tied to very specific object types like
> this.

  Okay, thanks!

  Yang 


> 
> > +} else if (!obj->parent) {
> >  gchar *name = g_strdup_printf("device[%d]", 
> > unattached_count++);
> >  
> >  object_property_add_child(container_get(qdev_get_machine(),
> 
> Regards,
> Daniel
> -- 
> |: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org -o-https://fstop138.berrange.com :|
> |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



Re: [PATCH] hw/sensor: Add SB-TSI Temperature Sensor Interface

2022-01-12 Thread Thomas Huth

On 10/01/2022 10.35, Philippe Mathieu-Daudé wrote:

Hi Patrick,

On 1/8/22 04:04, Patrick Venture wrote:

From: Hao Wu 

SB Temperature Sensor Interface (SB-TSI) is an SMBus compatible
interface that reports AMD SoC's Ttcl (normalized temperature),
and resembles a typical 8-pin remote temperature sensor's I2C interface
to BMC.

This patch implements a basic AMD SB-TSI sensor that is
compatible with the open-source data sheet from AMD and Linux
kernel driver.

Reference:
Linux kernel driver:
https://lkml.org/lkml/2020/12/11/968
Register Map:
https://developer.amd.com/wp-content/resources/56255_3_03.PDF
(Chapter 6)

Signed-off-by: Hao Wu 
Reviewed-by: Doug Evans 
---
  hw/sensor/Kconfig|   4 +
  hw/sensor/meson.build|   1 +
  hw/sensor/tmp_sbtsi.c| 393 +++
  hw/sensor/trace-events   |   5 +
  hw/sensor/trace.h|   1 +
  meson.build  |   1 +



  tests/qtest/meson.build  |   1 +
  tests/qtest/tmp_sbtsi-test.c | 180 


Up to Thomas for qtest, but I'd rather split in 2 patches since
different set of maintainers / reviewers.


I don't mind too much - but anyway, I'd prefer if we could stick to "-" in 
file names here - mixing underscores and "-" in file names looks somewhat 
weird (I know, there are already some files like this, but I'd prefer if 
we'd not extend that list).


 Thomas





Re: [PATCH 3/3] intel-iommu: PASID support

2022-01-12 Thread Michael S. Tsirkin
On Thu, Jan 13, 2022 at 01:06:09PM +0800, Peter Xu wrote:
> On Wed, Jan 05, 2022 at 12:19:45PM +0800, Jason Wang wrote:
> > @@ -1725,11 +1780,16 @@ static bool vtd_do_iommu_translate(VTDAddressSpace 
> > *vtd_as, PCIBus *bus,
> >  cc_entry->context_cache_gen = s->context_cache_gen;
> >  }
> >  
> > +/* Try to fetch slpte form IOTLB */
> > +if ((pasid == PCI_NO_PASID) && s->root_scalable) {
> > +pasid = VTD_CE_GET_RID2PASID();
> > +}
> > +
> >  /*
> >   * We don't need to translate for pass-through context entries.
> >   * Also, let's ignore IOTLB caching as well for PT devices.
> >   */
> > -if (vtd_dev_pt_enabled(s, )) {
> > +if (vtd_dev_pt_enabled(s, , pasid)) {
> >  entry->iova = addr & VTD_PAGE_MASK_4K;
> >  entry->translated_addr = entry->iova;
> >  entry->addr_mask = ~VTD_PAGE_MASK_4K;
> > @@ -1750,14 +1810,24 @@ static bool vtd_do_iommu_translate(VTDAddressSpace 
> > *vtd_as, PCIBus *bus,
> >  return true;
> >  }
> >  
> > +iotlb_entry = vtd_lookup_iotlb(s, source_id, addr, pasid);
> > +if (iotlb_entry) {
> > +trace_vtd_iotlb_page_hit(source_id, addr, iotlb_entry->slpte,
> > + iotlb_entry->domain_id);
> > +slpte = iotlb_entry->slpte;
> > +access_flags = iotlb_entry->access_flags;
> > +page_mask = iotlb_entry->mask;
> > +goto out;
> > +}
> 
> IIUC the iotlb lookup moved down just because the pasid==NO_PASID case then
> we'll need to fetch the default pasid from the context entry.  That looks
> reasonable.
> 
> It's just a bit of pity because logically it'll slow down iotlb hits due to
> context entry operations.  When NO_PASID we could have looked up iotlb without
> checking pasid at all, assuming that "default pasid" will always match.  But
> that is a little bit hacky.

Maybe that's not a bad idea for an optimization.


> vIOMMU seems to be mostly used for assigned devices and dpdk in production in
> the future due to its slowness otherwise.. so maybe not a big deal at all.
> 
> [...]
> 
> > @@ -2011,7 +2083,52 @@ static void 
> > vtd_iotlb_page_invalidate(IntelIOMMUState *s, uint16_t domain_id,
> >  vtd_iommu_lock(s);
> >  g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_page, );
> >  vtd_iommu_unlock(s);
> > -vtd_iotlb_page_invalidate_notify(s, domain_id, addr, am);
> > +vtd_iotlb_page_invalidate_notify(s, domain_id, addr, am, PCI_NO_PASID);
> > +}
> > +
> > +static void vtd_iotlb_page_pasid_invalidate(IntelIOMMUState *s,
> > +uint16_t domain_id,
> > +hwaddr addr, uint8_t am,
> > +uint32_t pasid)
> > +{
> > +VTDIOTLBPageInvInfo info;
> > +
> > +trace_vtd_inv_desc_iotlb_pasid_pages(domain_id, addr, am, pasid);
> > +
> > +assert(am <= VTD_MAMV);
> > +info.domain_id = domain_id;
> > +info.addr = addr;
> > +info.mask = ~((1 << am) - 1);
> > +info.pasid = pasid;
> > +vtd_iommu_lock(s);
> > +g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_page_pasid, 
> > );
> > +vtd_iommu_unlock(s);
> > +vtd_iotlb_page_invalidate_notify(s, domain_id, addr, am, pasid);
> 
> Hmm, I think indeed we need a notification, but it'll be unnecessary for
> e.g. vfio map notifiers, because this is 1st level invalidation and at least 
> so
> far vfio map notifiers are rewalking only the 2nd level page table, so it'll 
> be
> destined to be a no-op and pure overhead.
> 
> > +}
> > +
> > +static void vtd_iotlb_pasid_invalidate(IntelIOMMUState *s, uint16_t 
> > domain_id,
> > +   uint32_t pasid)
> > +{
> > +VTDIOTLBPageInvInfo info;
> > +VTDAddressSpace *vtd_as;
> > +VTDContextEntry ce;
> > +
> > +trace_vtd_inv_desc_iotlb_pasid(domain_id, pasid);
> > +
> > +info.domain_id = domain_id;
> > +info.pasid = pasid;
> > +vtd_iommu_lock(s);
> > +g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_pasid, );
> > +vtd_iommu_unlock(s);
> > +
> > +QLIST_FOREACH(vtd_as, >vtd_as_with_notifiers, next) {
> > +if (!vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus),
> > +  vtd_as->devfn, ) &&
> > +domain_id == vtd_get_domain_id(s, , vtd_as->pasid) &&
> > +pasid == vtd_as->pasid) {
> > +vtd_sync_shadow_page_table(vtd_as);
> 
> Do we need to rewalk the shadow pgtable (which is the 2nd level, afaict) even
> if we got the 1st level pgtable invalidated?
> 
> > +}
> > +}
> >  }
> 
> The rest looks mostly good to me; thanks.
> 
> -- 
> Peter Xu




Re: [PATCH v7 5/5] multifd: Implement zero copy write in multifd migration (multifd-zero-copy)

2022-01-12 Thread Peter Xu
On Thu, Jan 06, 2022 at 07:13:42PM -0300, Leonardo Bras wrote:
> Implement zero copy on nocomp_send_write(), by making use of QIOChannel
> writev + flags & flush interface.
> 
> Change multifd_send_sync_main() so it can distinguish each iteration sync from
> the setup and the completion, so a flush_zero_copy() can be called
> after each iteration in order to make sure all dirty pages are sent
> before a new iteration is started.

Leo - could you remind me (since I remembered we've discussed something
similar) on why we can't simply do the sync() unconditionally for zero copy?

I remember why we need the sync(), but I can't remember what's the matter if we
simply sync() too during setup and complete of migration.

Another trivial nit here: 

> -void multifd_send_sync_main(QEMUFile *f)
> +int multifd_send_sync_main(QEMUFile *f, bool sync)

I'd name it "bool full" or anything not called "sync", because the function
already has a name that contains "sync", then it's werid to sync(sync==false).

The rest looks good to me.  Thanks.

-- 
Peter Xu




Re: [PATCH v7 4/5] migration: Add migrate_use_tls() helper

2022-01-12 Thread Peter Xu
On Thu, Jan 06, 2022 at 07:13:41PM -0300, Leonardo Bras wrote:
>  void migration_channel_process_incoming(QIOChannel *ioc)
>  {
> -MigrationState *s = migrate_get_current();
>  Error *local_err = NULL;
>  
>  trace_migration_set_incoming_channel(
>  ioc, object_get_typename(OBJECT(ioc)));
>  
> -if (s->parameters.tls_creds &&
> -*s->parameters.tls_creds &&
> +if (migrate_use_tls() &&
>  !object_dynamic_cast(OBJECT(ioc),
>   TYPE_QIO_CHANNEL_TLS)) {
> +MigrationState *s = migrate_get_current();
> +

Trivial nit: I'd rather keep the line there; as the movement offers nothing,
imho..

>  migration_tls_channel_process_incoming(s, ioc, _err);
>  } else {
>  migration_ioc_register_yank(ioc);

Reviewed-by: Peter Xu 

-- 
Peter Xu




Re: [PATCH 1/3] intel-iommu: don't warn guest errors when getting rid2pasid entry

2022-01-12 Thread Michael S. Tsirkin
On Thu, Jan 13, 2022 at 11:35:19AM +0800, Peter Xu wrote:
> On Wed, Jan 05, 2022 at 12:19:43PM +0800, Jason Wang wrote:
> > We use to warn on wrong rid2pasid entry. But this error could be
> > triggered by the guest and could happens during initialization. So
> > let's don't warn in this case.
> > 
> > Signed-off-by: Jason Wang 
> > ---
> >  hw/i386/intel_iommu.c | 6 --
> >  1 file changed, 4 insertions(+), 2 deletions(-)
> > 
> > diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> > index 4c6c016388..f2c7a23712 100644
> > --- a/hw/i386/intel_iommu.c
> > +++ b/hw/i386/intel_iommu.c
> > @@ -1524,8 +1524,10 @@ static bool vtd_dev_pt_enabled(IntelIOMMUState *s, 
> > VTDContextEntry *ce)
> >  if (s->root_scalable) {
> >  ret = vtd_ce_get_rid2pasid_entry(s, ce, );
> >  if (ret) {
> > -error_report_once("%s: vtd_ce_get_rid2pasid_entry error: 
> > %"PRId32,
> > -  __func__, ret);
> > +/*
> > + * This error is guest triggerable. We should assumt PT
> > + * not enabled for safety.
> > + */
> >  return false;
> >  }
> >  return (VTD_PE_GET_TYPE() == VTD_SM_PASID_ENTRY_PT);
> > -- 
> > 2.25.1
> > 
> 
> No strong opinion, but the thing is mostly all error_report_once() in this 
> file
> is guest triggerable.  If we remove this one then it's debatable on whether we
> want to remove all.
> 
> IMHO we used the _once() variant just for this: it won't go into any form of
> DoS, meanwhile we'll still get some information (as hypervisor) that the guest
> OS may not be trustworthy.
> 
> So from that pov it's still useful?  Or is this error very special in some 
> way?
> 
> Thanks,


Well we have LOG_GUEST_ERROR for guest errors now.

> -- 
> Peter Xu




Re: [PATCH 1/3] intel-iommu: don't warn guest errors when getting rid2pasid entry

2022-01-12 Thread Michael S. Tsirkin
On Wed, Jan 05, 2022 at 12:19:43PM +0800, Jason Wang wrote:
> We use to warn on wrong rid2pasid entry. But this error could be
> triggered by the guest and could happens during initialization. So
> let's don't warn in this case.
> 
> Signed-off-by: Jason Wang 
> ---
>  hw/i386/intel_iommu.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> index 4c6c016388..f2c7a23712 100644
> --- a/hw/i386/intel_iommu.c
> +++ b/hw/i386/intel_iommu.c
> @@ -1524,8 +1524,10 @@ static bool vtd_dev_pt_enabled(IntelIOMMUState *s, 
> VTDContextEntry *ce)
>  if (s->root_scalable) {
>  ret = vtd_ce_get_rid2pasid_entry(s, ce, );
>  if (ret) {
> -error_report_once("%s: vtd_ce_get_rid2pasid_entry error: 
> %"PRId32,
> -  __func__, ret);
> +/*
> + * This error is guest triggerable. We should assumt PT

typo

And drop "We should" pls, just use direct voice:
"Assume PT not enabled".


> + * not enabled for safety.
> + */
>  return false;
>  }
>  return (VTD_PE_GET_TYPE() == VTD_SM_PASID_ENTRY_PT);
> -- 
> 2.25.1




Re: [PATCH v7 3/5] migration: Add zero-copy parameter for QMP/HMP for Linux

2022-01-12 Thread Peter Xu
On Thu, Jan 06, 2022 at 07:13:40PM -0300, Leonardo Bras wrote:
> Add property that allows zero-copy migration of memory pages,
> and also includes a helper function migrate_use_zero_copy() to check
> if it's enabled.
> 
> No code is introduced to actually do the migration, but it allow
> future implementations to enable/disable this feature.
> 
> On non-Linux builds this parameter is compiled-out.

I feel sad every time seeing a new parameter needs to be mostly duplicated 3
times in the code. :(

> diff --git a/migration/socket.c b/migration/socket.c
> index 05705a32d8..f7a77aafd3 100644
> --- a/migration/socket.c
> +++ b/migration/socket.c
> @@ -77,6 +77,11 @@ static void socket_outgoing_migration(QIOTask *task,
>  } else {
>  trace_migration_socket_outgoing_connected(data->hostname);
>  }
> +
> +if (migrate_use_zero_copy()) {
> +error_setg(, "Zero copy not available in migration");
> +}

I got confused the 1st time looking at it..  I think this is not strongly
needed, but that's okay:

Reviewed-by: Peter Xu 

Thanks,

-- 
Peter Xu




Re: [PATCH v7 2/5] QIOChannelSocket: Implement io_writev zero copy flag & io_flush for CONFIG_LINUX

2022-01-12 Thread Peter Xu
On Thu, Jan 06, 2022 at 07:13:39PM -0300, Leonardo Bras wrote:
> @@ -558,15 +575,26 @@ static ssize_t qio_channel_socket_writev(QIOChannel 
> *ioc,
>  memcpy(CMSG_DATA(cmsg), fds, fdsize);
>  }
>  
> +if (flags & QIO_CHANNEL_WRITE_FLAG_ZERO_COPY) {
> +sflags = MSG_ZEROCOPY;
> +}
> +
>   retry:
> -ret = sendmsg(sioc->fd, , 0);
> +ret = sendmsg(sioc->fd, , sflags);
>  if (ret <= 0) {
> -if (errno == EAGAIN) {
> +switch (errno) {
> +case EAGAIN:
>  return QIO_CHANNEL_ERR_BLOCK;
> -}
> -if (errno == EINTR) {
> +case EINTR:
>  goto retry;
> +case ENOBUFS:
> +if (sflags & MSG_ZEROCOPY) {
> +error_setg_errno(errp, errno,
> + "Process can't lock enough memory for using 
> MSG_ZEROCOPY");
> +return -1;
> +}

I have no idea whether it'll make a real differnece, but - should we better add
a "break" here?  If you agree and with that fixed, feel free to add:

Reviewed-by: Peter Xu 

I also wonder whether you hit ENOBUFS in any of the environments.  On Fedora
here it's by default unlimited, but just curious when we should keep an eye.

Thanks,

-- 
Peter Xu




Re: [PATCH] configure: do not create roms/seabios/config.mak if SeaBIOS not present

2022-01-12 Thread Thomas Huth

On 07/01/2022 12.47, Paolo Bonzini wrote:

If roms/seabios/Makefile is not present, the configure script
is not creating the roms/seabios directory anymore (commit
5dce7b8d8c, "configure: remove DIRS", 2021-12-18); thus, creating
roms/seabios/config.mak fails.

The easiest thing to do is to not create the file, since it will not
be used.

Signed-off-by: Paolo Bonzini 
---
  configure | 6 --
  1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index 0026388343..e1a31fb332 100755
--- a/configure
+++ b/configure
@@ -3704,7 +3704,8 @@ export target_list source_path use_containers cpu
  $source_path/tests/tcg/configure.sh)
  
  # temporary config to build submodules

-for rom in seabios; do
+if test -f $source_path/roms/seabios/Makefile; then
+  for rom in seabios; do
  config_mak=roms/$rom/config.mak


I think you can now simply remove the "for" loop line by setting 
config_mak=roms/seabios/config.mak here.


 Thomas



  echo "# Automatically generated by configure - do not modify" > 
$config_mak
  echo "SRC_PATH=$source_path/roms/$rom" >> $config_mak
@@ -3717,7 +3718,8 @@ for rom in seabios; do
  echo "IASL=$iasl" >> $config_mak
  echo "LD=$ld" >> $config_mak
  echo "RANLIB=$ranlib" >> $config_mak
-done
+  done
+fi
  
  config_mak=pc-bios/optionrom/config.mak

  echo "# Automatically generated by configure - do not modify" > $config_mak





Re: [PATCH] hw/i386: Add the possibility to disable the 'isapc' machine

2022-01-12 Thread Thomas Huth

On 07/01/2022 19.54, Philippe Mathieu-Daudé wrote:

On 1/7/22 17:07, Thomas Huth wrote:

We already have a CONFIG_ISAPC switch - but we're not using it yet.
Add some "#ifdefs" to make it possible to disable this machine now.

Signed-off-by: Thomas Huth 
---
  hw/i386/pc_piix.c| 5 -
  tests/qtest/cdrom-test.c | 2 +-
  2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 1999190276..5147e1ee74 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -357,10 +357,12 @@ static void pc_compat_1_4_fn(MachineState *machine)
  pc_compat_1_5_fn(machine);
  }
  
+#ifdef CONFIG_ISAPC

  static void pc_init_isa(MachineState *machine)
  {
  pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, TYPE_I440FX_PCI_DEVICE);
  }
+#endif
  
  #ifdef CONFIG_XEN

  static void pc_xen_hvm_init_pci(MachineState *machine)
@@ -916,6 +918,7 @@ void igd_passthrough_isa_bridge_create(PCIBus *bus, 
uint16_t gpu_dev_id)
  pci_config_set_revision(bridge_dev->config, pch_rev_id);
  }
  
+#ifdef CONFIG_ISAPC

  static void isapc_machine_options(MachineClass *m)
  {
  PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
@@ -935,7 +938,7 @@ static void isapc_machine_options(MachineClass *m)
  
  DEFINE_PC_MACHINE(isapc, "isapc", pc_init_isa,

isapc_machine_options);
-
+#endif


Wouldn't it be cleaner to extract the isapc machine to a new C unit
(after renaming/declaring pc_init1 public)? 


That would be cleaner, of course, but that would also mean a major 
refactoring: We could rearrange the code so that it is possible to compile a 
binary that has isapc, but not i440fx... but that likely means a complete 
rework of pc_piix.c so that the code that is common between i440fx and isapc 
needs to be moved into a separate file, too. And that's likely not worth the 
effort, I guess, since people rather want to compile without isapc than 
compiling without i440fx, I think. So let's go with this low-hanging fruit 
here for now, and keep the possible clean-up in mind for later.



Reviewed-by: Philippe Mathieu-Daudé 


Thanks!

 Thomas





Re: [PATCH 1/3] intel-iommu: don't warn guest errors when getting rid2pasid entry

2022-01-12 Thread Peter Xu
On Thu, Jan 13, 2022 at 02:16:35PM +0800, Jason Wang wrote:
> On Thu, Jan 13, 2022 at 11:35 AM Peter Xu  wrote:
> >
> > On Wed, Jan 05, 2022 at 12:19:43PM +0800, Jason Wang wrote:
> > > We use to warn on wrong rid2pasid entry. But this error could be
> > > triggered by the guest and could happens during initialization. So
> > > let's don't warn in this case.
> > >
> > > Signed-off-by: Jason Wang 
> > > ---
> > >  hw/i386/intel_iommu.c | 6 --
> > >  1 file changed, 4 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> > > index 4c6c016388..f2c7a23712 100644
> > > --- a/hw/i386/intel_iommu.c
> > > +++ b/hw/i386/intel_iommu.c
> > > @@ -1524,8 +1524,10 @@ static bool vtd_dev_pt_enabled(IntelIOMMUState *s, 
> > > VTDContextEntry *ce)
> > >  if (s->root_scalable) {
> > >  ret = vtd_ce_get_rid2pasid_entry(s, ce, );
> > >  if (ret) {
> > > -error_report_once("%s: vtd_ce_get_rid2pasid_entry error: 
> > > %"PRId32,
> > > -  __func__, ret);
> > > +/*
> > > + * This error is guest triggerable. We should assumt PT
> > > + * not enabled for safety.
> > > + */
> > >  return false;
> > >  }
> > >  return (VTD_PE_GET_TYPE() == VTD_SM_PASID_ENTRY_PT);
> > > --
> > > 2.25.1
> > >
> >
> > No strong opinion, but the thing is mostly all error_report_once() in this 
> > file
> > is guest triggerable.  If we remove this one then it's debatable on whether 
> > we
> > want to remove all.
> >
> > IMHO we used the _once() variant just for this: it won't go into any form of
> > DoS, meanwhile we'll still get some information (as hypervisor) that the 
> > guest
> > OS may not be trustworthy.
> >
> > So from that pov it's still useful?  Or is this error very special in some 
> > way?
> 
> I want to be consistent with vtd_as_pt_enabled() where we don't even
> have error_report_once().

According to the comments (which, I think, left over by myself..) in
vtd_as_pt_enabled() - maybe indeed it could be triggered during guest boot.
Then I assume this can indeed a special case.

Acked-by: Peter Xu 

Thanks.

-- 
Peter Xu




Re: [PATCH v7 1/5] QIOChannel: Add flags on io_writev and introduce io_flush callback

2022-01-12 Thread Peter Xu
On Thu, Jan 06, 2022 at 07:13:38PM -0300, Leonardo Bras wrote:
> diff --git a/io/channel.c b/io/channel.c
> index e8b019dc36..904855e16e 100644
> --- a/io/channel.c
> +++ b/io/channel.c
> @@ -67,12 +67,13 @@ ssize_t qio_channel_readv_full(QIOChannel *ioc,
>  }
>  
>  
> -ssize_t qio_channel_writev_full(QIOChannel *ioc,
> -const struct iovec *iov,
> -size_t niov,
> -int *fds,
> -size_t nfds,
> -Error **errp)
> +ssize_t qio_channel_writev_full_flags(QIOChannel *ioc,
> +  const struct iovec *iov,
> +  size_t niov,
> +  int *fds,
> +  size_t nfds,
> +  int flags,
> +  Error **errp)
>  {
>  QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc);
>  
> @@ -83,7 +84,7 @@ ssize_t qio_channel_writev_full(QIOChannel *ioc,
>  return -1;
>  }

Should we better also check QIO_CHANNEL_FEATURE_WRITE_ZERO_COPY here when
QIO_CHANNEL_WRITE_FLAG_ZERO_COPY is set?  Just like what we do with:

if ((fds || nfds) &&
!qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_FD_PASS)) {
error_setg_errno(errp, EINVAL,
 "Channel does not support file descriptor passing");
return -1;
}

I still think it's better to have the caller be crystal clear when to use
zero_copy feature because it has implication on buffer lifetime.

I might have commented similar things before, but I have missed a few versions
so I could also have missed some previous discussions..

>  
> -return klass->io_writev(ioc, iov, niov, fds, nfds, errp);
> +return klass->io_writev(ioc, iov, niov, fds, nfds, flags, errp);
>  }

-- 
Peter Xu




Re: [PATCH 1/3] intel-iommu: don't warn guest errors when getting rid2pasid entry

2022-01-12 Thread Jason Wang
On Thu, Jan 13, 2022 at 11:35 AM Peter Xu  wrote:
>
> On Wed, Jan 05, 2022 at 12:19:43PM +0800, Jason Wang wrote:
> > We use to warn on wrong rid2pasid entry. But this error could be
> > triggered by the guest and could happens during initialization. So
> > let's don't warn in this case.
> >
> > Signed-off-by: Jason Wang 
> > ---
> >  hw/i386/intel_iommu.c | 6 --
> >  1 file changed, 4 insertions(+), 2 deletions(-)
> >
> > diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> > index 4c6c016388..f2c7a23712 100644
> > --- a/hw/i386/intel_iommu.c
> > +++ b/hw/i386/intel_iommu.c
> > @@ -1524,8 +1524,10 @@ static bool vtd_dev_pt_enabled(IntelIOMMUState *s, 
> > VTDContextEntry *ce)
> >  if (s->root_scalable) {
> >  ret = vtd_ce_get_rid2pasid_entry(s, ce, );
> >  if (ret) {
> > -error_report_once("%s: vtd_ce_get_rid2pasid_entry error: 
> > %"PRId32,
> > -  __func__, ret);
> > +/*
> > + * This error is guest triggerable. We should assumt PT
> > + * not enabled for safety.
> > + */
> >  return false;
> >  }
> >  return (VTD_PE_GET_TYPE() == VTD_SM_PASID_ENTRY_PT);
> > --
> > 2.25.1
> >
>
> No strong opinion, but the thing is mostly all error_report_once() in this 
> file
> is guest triggerable.  If we remove this one then it's debatable on whether we
> want to remove all.
>
> IMHO we used the _once() variant just for this: it won't go into any form of
> DoS, meanwhile we'll still get some information (as hypervisor) that the guest
> OS may not be trustworthy.
>
> So from that pov it's still useful?  Or is this error very special in some 
> way?

I want to be consistent with vtd_as_pt_enabled() where we don't even
have error_report_once().

Thanks

>
> Thanks,
>
> --
> Peter Xu
>




Re: [PATCH v1 1/2] decodetree: Add an optional predicate-function for decoding

2022-01-12 Thread Alistair Francis
On Thu, Jan 13, 2022 at 1:42 AM Philipp Tomsich
 wrote:
>
> Alistair,
>
> Do you (and the other RISC-V custodians of target/riscv) have any opinion on 
> this?
> We can go either way — and it boils down to a style and process question.

Sorry, it's a busy week!

I had a quick look over this series and left some comments below.

>
> Thanks,
> Philipp.
>
> On Mon, 10 Jan 2022 at 12:30, Philippe Mathieu-Daudé  wrote:
>>
>> On 1/10/22 12:11, Philipp Tomsich wrote:
>> > On Mon, 10 Jan 2022 at 11:03, Philippe Mathieu-Daudé > > > wrote:
>> >
>> > On 1/10/22 10:52, Philipp Tomsich wrote:
>> > > For RISC-V the opcode decode will change between different vendor
>> > > implementations of RISC-V (emulated by the same qemu binary).
>> > > Any two vendors may reuse the same opcode space, e.g., we may end
>> > up with:
>> > >
>> > > # *** RV64 Custom-3 Extension ***
>> > > {
>> > >   vt_maskc   000  . . 110 . 011 @r
>> > |has_xventanacondops_p
>> > >   vt_maskcn  000  . . 111 . 011 @r
>> > |has_xventanacondops_p
>> > >   someone_something   . 000 . 1100111 @i
>> > > |has_xsomeonesomething_p
>> > > }

I don't love this. If even a few vendors use this we could have a huge
number of instructions here

>> > >
>> > > With extensions being enabled either from the commandline
>> > > -cpu any,xventanacondops=true
>> > > or possibly even having a AMP in one emulation setup (e.g. 
>> > application
>> > > cores having one extension and power-mangement cores having a
>> > > different one — or even a conflicting one).

Agreed, an AMP configuration is entirely possible.

>> >
>> > I understand, I think this is what MIPS does, see commit 9d005392390:
>> > ("target/mips: Introduce decodetree structure for NEC Vr54xx 
>> > extension")
>> >
>> >
>> > The MIPS implementation is functionally equivalent, and I could see us
>> > doing something similar for RISC-V (although I would strongly prefer to
>> > make everything explicit via the .decode-file instead of relying on
>> > people being aware of the logic in decode_op).
>> >
>> > With the growing number of optional extensions (as of today, at least
>> > the Zb[abcs] and vector comes to mind), we would end up with a large
>> > number of decode-files that will then need to be sequentially called
>> > from decode_op(). The predicates can then move up into decode_op,
>> > predicting the auto-generated decoders from being invoked.
>> >
>> > As of today, we have predicates for at least the following:
>> >
>> >   * Zb[abcs]
>> >   * Vectors

I see your point, having a long list of decode_*() functions to call
is a hassle. On the other hand having thousands of lines in
insn32.decode is also a pain.

In saying that, having official RISC-V extensions in insn32.decode and
vendor instructions in insn.decode seems like a reasonable
compromise. Maybe even large extensions (vector maybe?) could have
their own insn.decode file, on a case by case basis.

>> >
>> > As long as we are in greenfield territory (i.e. not dealing with
>> > HINT-instructions that overlap existing opcode space), this will be fine
>> > and provide proper isolation between the .decode-tables.
>> > However, as soon as we need to implement something along the lines (I
>> > know this is a bad example, as prefetching will be a no-op on qemu) of:
>> >
>> > {
>> >   {
>> > # *** RV32 Zicbop Sandard Extension (hints in the ori-space) ***
>> > prefetch_i  ... 0 . 110 0 0010011 @cbo_pref
>> > prefetch_r  ... 1 . 110 0 0010011 @cbo_pref
>> > prefetch_w  ... 00011 . 110 0 0010011 @cbo_pref
>> >   }
>> >   ori   . 110 . 0010011 @i
>> > }
>> >
>> > we'd need to make sure that the generated decoders are called in the
>> > appropriate order (i.e. the decoder for the specialized instructions
>> > will need to be called first), which would not be apparent from looking
>> > at the individual .decode files.
>> >
>> > Let me know what direction we want to take (of course, I have a bias
>> > towards the one in the patch).
>>
>> I can't say for RISCV performance, I am myself biased toward maintenance
>> where having one compilation unit per (vendor) extension.
>> ARM and MIPS seems to go in this direction, while PPC and RISCV in the
>> other one.

I think we could do both right?

We could add the predicate support, but also isolate vendors to their
own decode file

So for example, for vendor abc

+++ b/target/riscv/insnabc.decode
+# *** Custom abc Extension ***
+{
+  vt_maskc   000  . . 110 . 011 @r |has_abc_c
+  vt_maskcn  000  . . 111 . 011 @r |has_abc_d
+}

Then there is a decode_abc(), but we support extension abc_c and abc_d

That way we can keep all the vendor code seperate, while still
allowing flexibility. 

Re: [PATCH 3/3] intel-iommu: PASID support

2022-01-12 Thread Peter Xu
On Wed, Jan 05, 2022 at 12:19:45PM +0800, Jason Wang wrote:
> @@ -1725,11 +1780,16 @@ static bool vtd_do_iommu_translate(VTDAddressSpace 
> *vtd_as, PCIBus *bus,
>  cc_entry->context_cache_gen = s->context_cache_gen;
>  }
>  
> +/* Try to fetch slpte form IOTLB */
> +if ((pasid == PCI_NO_PASID) && s->root_scalable) {
> +pasid = VTD_CE_GET_RID2PASID();
> +}
> +
>  /*
>   * We don't need to translate for pass-through context entries.
>   * Also, let's ignore IOTLB caching as well for PT devices.
>   */
> -if (vtd_dev_pt_enabled(s, )) {
> +if (vtd_dev_pt_enabled(s, , pasid)) {
>  entry->iova = addr & VTD_PAGE_MASK_4K;
>  entry->translated_addr = entry->iova;
>  entry->addr_mask = ~VTD_PAGE_MASK_4K;
> @@ -1750,14 +1810,24 @@ static bool vtd_do_iommu_translate(VTDAddressSpace 
> *vtd_as, PCIBus *bus,
>  return true;
>  }
>  
> +iotlb_entry = vtd_lookup_iotlb(s, source_id, addr, pasid);
> +if (iotlb_entry) {
> +trace_vtd_iotlb_page_hit(source_id, addr, iotlb_entry->slpte,
> + iotlb_entry->domain_id);
> +slpte = iotlb_entry->slpte;
> +access_flags = iotlb_entry->access_flags;
> +page_mask = iotlb_entry->mask;
> +goto out;
> +}

IIUC the iotlb lookup moved down just because the pasid==NO_PASID case then
we'll need to fetch the default pasid from the context entry.  That looks
reasonable.

It's just a bit of pity because logically it'll slow down iotlb hits due to
context entry operations.  When NO_PASID we could have looked up iotlb without
checking pasid at all, assuming that "default pasid" will always match.  But
that is a little bit hacky.

vIOMMU seems to be mostly used for assigned devices and dpdk in production in
the future due to its slowness otherwise.. so maybe not a big deal at all.

[...]

> @@ -2011,7 +2083,52 @@ static void vtd_iotlb_page_invalidate(IntelIOMMUState 
> *s, uint16_t domain_id,
>  vtd_iommu_lock(s);
>  g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_page, );
>  vtd_iommu_unlock(s);
> -vtd_iotlb_page_invalidate_notify(s, domain_id, addr, am);
> +vtd_iotlb_page_invalidate_notify(s, domain_id, addr, am, PCI_NO_PASID);
> +}
> +
> +static void vtd_iotlb_page_pasid_invalidate(IntelIOMMUState *s,
> +uint16_t domain_id,
> +hwaddr addr, uint8_t am,
> +uint32_t pasid)
> +{
> +VTDIOTLBPageInvInfo info;
> +
> +trace_vtd_inv_desc_iotlb_pasid_pages(domain_id, addr, am, pasid);
> +
> +assert(am <= VTD_MAMV);
> +info.domain_id = domain_id;
> +info.addr = addr;
> +info.mask = ~((1 << am) - 1);
> +info.pasid = pasid;
> +vtd_iommu_lock(s);
> +g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_page_pasid, 
> );
> +vtd_iommu_unlock(s);
> +vtd_iotlb_page_invalidate_notify(s, domain_id, addr, am, pasid);

Hmm, I think indeed we need a notification, but it'll be unnecessary for
e.g. vfio map notifiers, because this is 1st level invalidation and at least so
far vfio map notifiers are rewalking only the 2nd level page table, so it'll be
destined to be a no-op and pure overhead.

> +}
> +
> +static void vtd_iotlb_pasid_invalidate(IntelIOMMUState *s, uint16_t 
> domain_id,
> +   uint32_t pasid)
> +{
> +VTDIOTLBPageInvInfo info;
> +VTDAddressSpace *vtd_as;
> +VTDContextEntry ce;
> +
> +trace_vtd_inv_desc_iotlb_pasid(domain_id, pasid);
> +
> +info.domain_id = domain_id;
> +info.pasid = pasid;
> +vtd_iommu_lock(s);
> +g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_pasid, );
> +vtd_iommu_unlock(s);
> +
> +QLIST_FOREACH(vtd_as, >vtd_as_with_notifiers, next) {
> +if (!vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus),
> +  vtd_as->devfn, ) &&
> +domain_id == vtd_get_domain_id(s, , vtd_as->pasid) &&
> +pasid == vtd_as->pasid) {
> +vtd_sync_shadow_page_table(vtd_as);

Do we need to rewalk the shadow pgtable (which is the 2nd level, afaict) even
if we got the 1st level pgtable invalidated?

> +}
> +}
>  }

The rest looks mostly good to me; thanks.

-- 
Peter Xu




Re: [PATCH v5 13/13] target/riscv: enable riscv kvm accel

2022-01-12 Thread Anup Patel
On Wed, Jan 12, 2022 at 1:44 PM Yifei Jiang  wrote:
>
> Add riscv kvm support in meson.build file.
>
> Signed-off-by: Yifei Jiang 
> Signed-off-by: Mingwang Li 

Looks good to me.

Reviewed-by: Anup Patel 

Regards,
Anup

> ---
>  meson.build | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/meson.build b/meson.build
> index c1b1db1e28..06a5476254 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -90,6 +90,8 @@ elif cpu in ['ppc', 'ppc64']
>kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
>  elif cpu in ['mips', 'mips64']
>kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 
> 'mips64el-softmmu']
> +elif cpu in ['riscv']
> +  kvm_targets = ['riscv32-softmmu', 'riscv64-softmmu']
>  else
>kvm_targets = []
>  endif
> --
> 2.19.1
>
>
> --
> kvm-riscv mailing list
> kvm-ri...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kvm-riscv



Re: [PATCH v5 06/13] target/riscv: Support start kernel directly by KVM

2022-01-12 Thread Anup Patel
On Wed, Jan 12, 2022 at 1:43 PM Yifei Jiang  wrote:
>
> Get kernel and fdt start address in virt.c, and pass them to KVM
> when cpu reset. Add kvm_riscv.h to place riscv specific interface.
>
> In addition, PLIC is created without M-mode PLIC contexts when KVM
> is enabled.
>
> Signed-off-by: Yifei Jiang 
> Signed-off-by: Mingwang Li 
> Reviewed-by: Alistair Francis 

Looks good to me.

Reviewed-by: Anup Patel 

Regards,
Anup

> ---
>  hw/intc/sifive_plic.c| 20 +++---
>  hw/riscv/boot.c  | 16 +++-
>  hw/riscv/virt.c  | 83 
>  include/hw/riscv/boot.h  |  1 +
>  target/riscv/cpu.c   |  8 
>  target/riscv/cpu.h   |  3 ++
>  target/riscv/kvm-stub.c  | 25 
>  target/riscv/kvm.c   | 14 +++
>  target/riscv/kvm_riscv.h | 24 
>  target/riscv/meson.build |  2 +-
>  10 files changed, 164 insertions(+), 32 deletions(-)
>  create mode 100644 target/riscv/kvm-stub.c
>  create mode 100644 target/riscv/kvm_riscv.h
>
> diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
> index 746c0f0343..eebbcf33d4 100644
> --- a/hw/intc/sifive_plic.c
> +++ b/hw/intc/sifive_plic.c
> @@ -30,6 +30,7 @@
>  #include "target/riscv/cpu.h"
>  #include "migration/vmstate.h"
>  #include "hw/irq.h"
> +#include "sysemu/kvm.h"
>
>  static bool addr_between(uint32_t addr, uint32_t base, uint32_t num)
>  {
> @@ -430,7 +431,8 @@ DeviceState *sifive_plic_create(hwaddr addr, char 
> *hart_config,
>  uint32_t context_stride, uint32_t aperture_size)
>  {
>  DeviceState *dev = qdev_new(TYPE_SIFIVE_PLIC);
> -int i;
> +int i, j = 0;
> +SiFivePLICState *plic;
>
>  assert(enable_stride == (enable_stride & -enable_stride));
>  assert(context_stride == (context_stride & -context_stride));
> @@ -448,13 +450,21 @@ DeviceState *sifive_plic_create(hwaddr addr, char 
> *hart_config,
>  sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
>  sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
>
> +plic = SIFIVE_PLIC(dev);
>  for (i = 0; i < num_harts; i++) {
>  CPUState *cpu = qemu_get_cpu(hartid_base + i);
>
> -qdev_connect_gpio_out(dev, i,
> -  qdev_get_gpio_in(DEVICE(cpu), IRQ_S_EXT));
> -qdev_connect_gpio_out(dev, num_harts + i,
> -  qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
> +if (plic->addr_config[j].mode == PLICMode_M) {
> +j++;
> +qdev_connect_gpio_out(dev, num_harts + i,
> +  qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
> +}
> +
> +if (plic->addr_config[j].mode == PLICMode_S) {
> +j++;
> +qdev_connect_gpio_out(dev, i,
> +  qdev_get_gpio_in(DEVICE(cpu), IRQ_S_EXT));
> +}
>  }
>
>  return dev;
> diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
> index f67264374e..cae74fcbcd 100644
> --- a/hw/riscv/boot.c
> +++ b/hw/riscv/boot.c
> @@ -30,6 +30,7 @@
>  #include "elf.h"
>  #include "sysemu/device_tree.h"
>  #include "sysemu/qtest.h"
> +#include "sysemu/kvm.h"
>
>  #include 
>
> @@ -51,7 +52,9 @@ char *riscv_plic_hart_config_string(int hart_count)
>  CPUState *cs = qemu_get_cpu(i);
>  CPURISCVState *env = _CPU(cs)->env;
>
> -if (riscv_has_ext(env, RVS)) {
> +if (kvm_enabled()) {
> +vals[i] = "S";
> +} else if (riscv_has_ext(env, RVS)) {
>  vals[i] = "MS";
>  } else {
>  vals[i] = "M";
> @@ -324,3 +327,14 @@ void riscv_setup_rom_reset_vec(MachineState *machine, 
> RISCVHartArrayState *harts
>
>  return;
>  }
> +
> +void riscv_setup_direct_kernel(hwaddr kernel_addr, hwaddr fdt_addr)
> +{
> +CPUState *cs;
> +
> +for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
> +RISCVCPU *riscv_cpu = RISCV_CPU(cs);
> +riscv_cpu->env.kernel_addr = kernel_addr;
> +riscv_cpu->env.fdt_addr = fdt_addr;
> +}
> +}
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 3af074148e..2643c8bc37 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -38,6 +38,7 @@
>  #include "chardev/char.h"
>  #include "sysemu/device_tree.h"
>  #include "sysemu/sysemu.h"
> +#include "sysemu/kvm.h"
>  #include "hw/pci/pci.h"
>  #include "hw/pci-host/gpex.h"
>  #include "hw/display/ramfb.h"
> @@ -372,13 +373,22 @@ static void create_fdt_socket_plic(RISCVVirtState *s,
>  "sifive,plic-1.0.0", "riscv,plic0"
>  };
>
> -plic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4);
> +if (kvm_enabled()) {
> +plic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
> +} else {
> +plic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4);
> +}
>
>  for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
> -plic_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
> -plic_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_EXT);
> -plic_cells[cpu * 4 

Re: [PATCH v5 13/13] target/riscv: enable riscv kvm accel

2022-01-12 Thread Alistair Francis
On Wed, Jan 12, 2022 at 6:25 PM Yifei Jiang via  wrote:
>
> Add riscv kvm support in meson.build file.
>
> Signed-off-by: Yifei Jiang 
> Signed-off-by: Mingwang Li 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  meson.build | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/meson.build b/meson.build
> index c1b1db1e28..06a5476254 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -90,6 +90,8 @@ elif cpu in ['ppc', 'ppc64']
>kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
>  elif cpu in ['mips', 'mips64']
>kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 
> 'mips64el-softmmu']
> +elif cpu in ['riscv']
> +  kvm_targets = ['riscv32-softmmu', 'riscv64-softmmu']
>  else
>kvm_targets = []
>  endif
> --
> 2.19.1
>
>



Re: [PATCH] softmmu/device_tree: Remove redundant pointer assignment

2022-01-12 Thread Alistair Francis
On Tue, Jan 11, 2022 at 1:28 PM Yanan Wang via  wrote:
>
> The pointer assignment "const char *p = path;" in function
> qemu_fdt_add_path is unnecessary. Let's remove it and just
> use the "path" passed in. No functional change.
>
> Suggested-by: Richard Henderson 
> Signed-off-by: Yanan Wang 

Reviewed-by: Alistair Francis 

Alistair

> ---
> Based on: softmmu/device_tree: Silence compiler warning with 
> --enable-sanitizers
> https://patchew.org/QEMU/20220107133844.145039-1-th...@redhat.com/
> ---
>  softmmu/device_tree.c | 9 -
>  1 file changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/softmmu/device_tree.c b/softmmu/device_tree.c
> index 9e96f5ecd5..8897c79ea4 100644
> --- a/softmmu/device_tree.c
> +++ b/softmmu/device_tree.c
> @@ -556,7 +556,6 @@ int qemu_fdt_add_subnode(void *fdt, const char *name)
>  int qemu_fdt_add_path(void *fdt, const char *path)
>  {
>  const char *name;
> -const char *p = path;
>  int namelen, retval;
>  int parent = 0;
>
> @@ -565,9 +564,9 @@ int qemu_fdt_add_path(void *fdt, const char *path)
>  }
>
>  do {
> -name = p + 1;
> -p = strchr(name, '/');
> -namelen = p != NULL ? p - name : strlen(name);
> +name = path + 1;
> +path = strchr(name, '/');
> +namelen = path != NULL ? path - name : strlen(name);
>
>  retval = fdt_subnode_offset_namelen(fdt, parent, name, namelen);
>  if (retval < 0 && retval != -FDT_ERR_NOTFOUND) {
> @@ -584,7 +583,7 @@ int qemu_fdt_add_path(void *fdt, const char *path)
>  }
>
>  parent = retval;
> -} while (p);
> +} while (path);
>
>  return retval;
>  }
> --
> 2.27.0
>
>



Re: [PATCH 2/3] intel-iommu: drop VTDBus

2022-01-12 Thread Peter Xu
On Wed, Jan 05, 2022 at 12:19:44PM +0800, Jason Wang wrote:
> We introduce VTDBus structure as an intermediate step for searching
> the address space. This works well with SID based matching/lookup. But
> when we want to support SID plus PASID based address space lookup,
> this intermediate steps turns out to be a burden. So the patch simply
> drops the VTDBus structure and use the PCIBus and devfn as the key for
> the g_hash_table(). This simplifies the codes and the future PASID
> extension.
> 
> This may case slight slower for the vtd_find_as_from_bus_num() callers
> but since they are all called from the control path, we can afford it.

The only one I found is vtd_process_device_iotlb_desc() that may got affected
the most; the rest look mostly always traversing all the address space anyway
so shouldn't hurt.

I think dev-iotlb can be invalidated in IO path too when kernel device drivers
are used?  It shouldn't affect much when the VM has a few devices, but IIUC
it'll further slow down the kernel drivers on vIOMMU.  Maybe it's not a huge
problem either.

> 
> Signed-off-by: Jason Wang 
> ---
>  hw/i386/intel_iommu.c | 183 +-
>  include/hw/i386/intel_iommu.h |  10 +-
>  2 files changed, 69 insertions(+), 124 deletions(-)
> 
> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> index f2c7a23712..58c682097b 100644
> --- a/hw/i386/intel_iommu.c
> +++ b/hw/i386/intel_iommu.c
> @@ -61,6 +61,11 @@
>  }
>  \
>  }
>  
> +struct vtd_as_key {
> +PCIBus *bus;
> +uint8_t devfn;
> +};
> +
>  static void vtd_address_space_refresh_all(IntelIOMMUState *s);
>  static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n);
>  
> @@ -190,12 +195,18 @@ static inline gboolean 
> vtd_as_has_map_notifier(VTDAddressSpace *as)
>  /* GHashTable functions */
>  static gboolean vtd_uint64_equal(gconstpointer v1, gconstpointer v2)
>  {
> -return *((const uint64_t *)v1) == *((const uint64_t *)v2);
> +const struct vtd_as_key *key1 = v1;
> +const struct vtd_as_key *key2 = v2;
> +
> +return (key1->bus == key2->bus) && (key1->devfn == key2->devfn);
>  }
>  
>  static guint vtd_uint64_hash(gconstpointer v)
>  {
> -return (guint)*(const uint64_t *)v;
> +const struct vtd_as_key *key = v;
> +guint value = (guint)(uintptr_t)key->bus;
> +
> +return (guint)(value << 8 | key->devfn);

Note that value is a pointer to PCIBus*.  Just want to check with you that it's
intended to use this hash value (or maybe you wanted to use Source ID so it is
bus number to use not the bus pointer)?

>  }
>  
>  static gboolean vtd_hash_remove_by_domain(gpointer key, gpointer value,
> @@ -236,22 +247,14 @@ static gboolean vtd_hash_remove_by_page(gpointer key, 
> gpointer value,
>  static void vtd_reset_context_cache_locked(IntelIOMMUState *s)
>  {
>  VTDAddressSpace *vtd_as;
> -VTDBus *vtd_bus;
> -GHashTableIter bus_it;
> -uint32_t devfn_it;
> +GHashTableIter as_it;
>  
>  trace_vtd_context_cache_reset();
>  
> -g_hash_table_iter_init(_it, s->vtd_as_by_busptr);
> +g_hash_table_iter_init(_it, s->vtd_as);
>  
> -while (g_hash_table_iter_next (_it, NULL, (void**)_bus)) {
> -for (devfn_it = 0; devfn_it < PCI_DEVFN_MAX; ++devfn_it) {
> -vtd_as = vtd_bus->dev_as[devfn_it];
> -if (!vtd_as) {
> -continue;
> -}
> -vtd_as->context_cache_entry.context_cache_gen = 0;
> -}
> +while (g_hash_table_iter_next (_it, NULL, (void**)_as)) {
> +vtd_as->context_cache_entry.context_cache_gen = 0;
>  }
>  s->context_cache_gen = 1;
>  }
> @@ -986,32 +989,6 @@ static bool vtd_slpte_nonzero_rsvd(uint64_t slpte, 
> uint32_t level)
>  return slpte & rsvd_mask;
>  }
>  
> -/* Find the VTD address space associated with a given bus number */
> -static VTDBus *vtd_find_as_from_bus_num(IntelIOMMUState *s, uint8_t bus_num)
> -{
> -VTDBus *vtd_bus = s->vtd_as_by_bus_num[bus_num];
> -GHashTableIter iter;
> -
> -if (vtd_bus) {
> -return vtd_bus;
> -}
> -
> -/*
> - * Iterate over the registered buses to find the one which
> - * currently holds this bus number and update the bus_num
> - * lookup table.
> - */
> -g_hash_table_iter_init(, s->vtd_as_by_busptr);
> -while (g_hash_table_iter_next(, NULL, (void **)_bus)) {
> -if (pci_bus_num(vtd_bus->bus) == bus_num) {
> -s->vtd_as_by_bus_num[bus_num] = vtd_bus;
> -return vtd_bus;
> -}
> -}
> -
> -return NULL;
> -}
> -
>  /* Given the @iova, get relevant @slptep. @slpte_level will be the last level
>   * of the translation, can be used for deciding the size of large page.
>   */
> @@ -1604,18 +1581,12 @@ static bool vtd_switch_address_space(VTDAddressSpace 
> *as)
>  
>  static void vtd_switch_address_space_all(IntelIOMMUState *s)
>  {
> +

Re: [PATCH 1/3] intel-iommu: don't warn guest errors when getting rid2pasid entry

2022-01-12 Thread Peter Xu
On Wed, Jan 05, 2022 at 12:19:43PM +0800, Jason Wang wrote:
> We use to warn on wrong rid2pasid entry. But this error could be
> triggered by the guest and could happens during initialization. So
> let's don't warn in this case.
> 
> Signed-off-by: Jason Wang 
> ---
>  hw/i386/intel_iommu.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> index 4c6c016388..f2c7a23712 100644
> --- a/hw/i386/intel_iommu.c
> +++ b/hw/i386/intel_iommu.c
> @@ -1524,8 +1524,10 @@ static bool vtd_dev_pt_enabled(IntelIOMMUState *s, 
> VTDContextEntry *ce)
>  if (s->root_scalable) {
>  ret = vtd_ce_get_rid2pasid_entry(s, ce, );
>  if (ret) {
> -error_report_once("%s: vtd_ce_get_rid2pasid_entry error: 
> %"PRId32,
> -  __func__, ret);
> +/*
> + * This error is guest triggerable. We should assumt PT
> + * not enabled for safety.
> + */
>  return false;
>  }
>  return (VTD_PE_GET_TYPE() == VTD_SM_PASID_ENTRY_PT);
> -- 
> 2.25.1
> 

No strong opinion, but the thing is mostly all error_report_once() in this file
is guest triggerable.  If we remove this one then it's debatable on whether we
want to remove all.

IMHO we used the _once() variant just for this: it won't go into any form of
DoS, meanwhile we'll still get some information (as hypervisor) that the guest
OS may not be trustworthy.

So from that pov it's still useful?  Or is this error very special in some way?

Thanks,

-- 
Peter Xu




[Q] arm: SVE accesses at EL0 is broken with E2H+TGE?

2022-01-12 Thread Zenghui Yu via

Hi,

I've just exercised the SVE emulation in QEMU with

| `qemu-system-aarch64 -M virt,virtualization=on,gic-version=3 \
|  -cpu max -accel tcg [...]`

Since QEMU sets ID_AA64MMFR1_EL1.VH for -cpu max, the Linux guest I use
was booting with VHE enabled and running with E2H+TGE. But I've then
seen the Linux sve-probe-vls selftest [1] failure in guest which runs at
EL0 and can be described as:

1) Call prctl(PR_SVE_SET_VL, vl == 64) to set the vector length.
2) Emit RDVL instruction **but** get vl == 16. Emmm..

Looking a bit further at the way we emulate SVE in QEMU, there might be
some issues need to be addressed.

* sve_zcr_len_for_el() implementation

Per DDI 0584 B.a, when HCR_EL2.{E2H,TGE} == {1,1} and EL2 is enabled in
the current Security state, ZCR_EL1 has no effect on execution at EL0.
We should use ZCR_EL2 instead for E2H+TGE.

* CPTR_EL2 register accessors

CPTR_EL2 has diffrent layout with or without VHE, but looks like we only
take the nVHE one into account. Take sve_exception_el(env, el == 0) as
an example, we don't check CPTR_EL2.ZEN for EL0 SVE accesses and we will
never generate an exception even if needed...

... whilst Linux kernel indeed relies on a trap to EL2 to restore SVE
context appropriately for userland. SVE accesses at EL0 is broken in
that case, I guess?

Thanks,
Zenghui

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/testing/selftests/arm64/fp/sve-probe-vls.c




Re: [PATCH] ui/cocoa: capture screencast with AVAssetWriter

2022-01-12 Thread Chen Zhang
Granted that this patch might not fit for main branch, I hope this snippet 
could help someone in need.

Screen cast feature shipped with macOS does support screen recording, but only 
for whole screen or selected rectangle, not for a selected window like photo 
capture feature.

And pixels are not sourced from qemu display frame buffer. This means the 
screencast would be scaled by contentsScale (for retina screen) and window 
titlebar would be included.



Best Regards

> 2022年1月11日 下午4:31,Peter Maydell  写道:
> 
> On Tue, 11 Jan 2022 at 07:09, Zhang Chen  wrote:
>> 
>> To record screencast, AVAssetWriter APIs were called for each
>> cocoa_update call.
>> 
>> Commands for start/stop recording were added to View menu.
> 
> This seems a bit of an odd feature -- why doesn't the OS just
> permit screen recording of any application without the app
> having to have code for it specifically ?
> 
> -- PMM




[PATCH v4 5/6] target/riscv: add support for zhinx/zhinxmin

2022-01-12 Thread Weiwei Li
  - update extension check REQUIRE_ZHINX_OR_ZFH and 
REQUIRE_ZFH_OR_ZFHMIN_OR_ZHINX_OR_ZHINXMIN
  - update half float point register read/write
  - disable nanbox_h check

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
---
 target/riscv/fpu_helper.c |  89 +++---
 target/riscv/helper.h |   2 +-
 target/riscv/insn_trans/trans_rvzfh.c.inc | 332 +++---
 target/riscv/internals.h  |  16 +-
 4 files changed, 296 insertions(+), 143 deletions(-)

diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
index 63ca703459..5699c9517f 100644
--- a/target/riscv/fpu_helper.c
+++ b/target/riscv/fpu_helper.c
@@ -89,10 +89,11 @@ void helper_set_rod_rounding_mode(CPURISCVState *env)
 static uint64_t do_fmadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
uint64_t rs3, int flags)
 {
-float16 frs1 = check_nanbox_h(rs1);
-float16 frs2 = check_nanbox_h(rs2);
-float16 frs3 = check_nanbox_h(rs3);
-return nanbox_h(float16_muladd(frs1, frs2, frs3, flags, >fp_status));
+float16 frs1 = check_nanbox_h(env, rs1);
+float16 frs2 = check_nanbox_h(env, rs2);
+float16 frs3 = check_nanbox_h(env, rs3);
+return nanbox_h(env, float16_muladd(frs1, frs2, frs3, flags,
+>fp_status));
 }
 
 static uint64_t do_fmadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
@@ -417,146 +418,146 @@ target_ulong helper_fclass_d(uint64_t frs1)
 
 uint64_t helper_fadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
-float16 frs1 = check_nanbox_h(rs1);
-float16 frs2 = check_nanbox_h(rs2);
-return nanbox_h(float16_add(frs1, frs2, >fp_status));
+float16 frs1 = check_nanbox_h(env, rs1);
+float16 frs2 = check_nanbox_h(env, rs2);
+return nanbox_h(env, float16_add(frs1, frs2, >fp_status));
 }
 
 uint64_t helper_fsub_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
-float16 frs1 = check_nanbox_h(rs1);
-float16 frs2 = check_nanbox_h(rs2);
-return nanbox_h(float16_sub(frs1, frs2, >fp_status));
+float16 frs1 = check_nanbox_h(env, rs1);
+float16 frs2 = check_nanbox_h(env, rs2);
+return nanbox_h(env, float16_sub(frs1, frs2, >fp_status));
 }
 
 uint64_t helper_fmul_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
-float16 frs1 = check_nanbox_h(rs1);
-float16 frs2 = check_nanbox_h(rs2);
-return nanbox_h(float16_mul(frs1, frs2, >fp_status));
+float16 frs1 = check_nanbox_h(env, rs1);
+float16 frs2 = check_nanbox_h(env, rs2);
+return nanbox_h(env, float16_mul(frs1, frs2, >fp_status));
 }
 
 uint64_t helper_fdiv_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
-float16 frs1 = check_nanbox_h(rs1);
-float16 frs2 = check_nanbox_h(rs2);
-return nanbox_h(float16_div(frs1, frs2, >fp_status));
+float16 frs1 = check_nanbox_h(env, rs1);
+float16 frs2 = check_nanbox_h(env, rs2);
+return nanbox_h(env, float16_div(frs1, frs2, >fp_status));
 }
 
 uint64_t helper_fmin_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
-float16 frs1 = check_nanbox_h(rs1);
-float16 frs2 = check_nanbox_h(rs2);
-return nanbox_h(env->priv_ver < PRIV_VERSION_1_11_0 ?
+float16 frs1 = check_nanbox_h(env, rs1);
+float16 frs2 = check_nanbox_h(env, rs2);
+return nanbox_h(env, env->priv_ver < PRIV_VERSION_1_11_0 ?
 float16_minnum(frs1, frs2, >fp_status) :
 float16_minimum_number(frs1, frs2, >fp_status));
 }
 
 uint64_t helper_fmax_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
-float16 frs1 = check_nanbox_h(rs1);
-float16 frs2 = check_nanbox_h(rs2);
-return nanbox_h(env->priv_ver < PRIV_VERSION_1_11_0 ?
+float16 frs1 = check_nanbox_h(env, rs1);
+float16 frs2 = check_nanbox_h(env, rs2);
+return nanbox_h(env, env->priv_ver < PRIV_VERSION_1_11_0 ?
 float16_maxnum(frs1, frs2, >fp_status) :
 float16_maximum_number(frs1, frs2, >fp_status));
 }
 
 uint64_t helper_fsqrt_h(CPURISCVState *env, uint64_t rs1)
 {
-float16 frs1 = check_nanbox_h(rs1);
-return nanbox_h(float16_sqrt(frs1, >fp_status));
+float16 frs1 = check_nanbox_h(env, rs1);
+return nanbox_h(env, float16_sqrt(frs1, >fp_status));
 }
 
 target_ulong helper_fle_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
-float16 frs1 = check_nanbox_h(rs1);
-float16 frs2 = check_nanbox_h(rs2);
+float16 frs1 = check_nanbox_h(env, rs1);
+float16 frs2 = check_nanbox_h(env, rs2);
 return float16_le(frs1, frs2, >fp_status);
 }
 
 target_ulong helper_flt_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
-float16 frs1 = check_nanbox_h(rs1);
-float16 frs2 = check_nanbox_h(rs2);
+float16 frs1 = check_nanbox_h(env, rs1);
+float16 frs2 = check_nanbox_h(env, rs2);
 return float16_lt(frs1, frs2, >fp_status);
 }
 
 target_ulong helper_feq_h(CPURISCVState *env, uint64_t rs1, 

[PATCH v4 4/6] target/riscv: add support for zdinx

2022-01-12 Thread Weiwei Li
  -- update extension check REQUIRE_ZDINX_OR_D
  -- update double float point register read/write

Co-authored-by: ardxwe 
Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn_trans/trans_rvd.c.inc | 285 +---
 target/riscv/translate.c|  52 +
 2 files changed, 259 insertions(+), 78 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvd.c.inc 
b/target/riscv/insn_trans/trans_rvd.c.inc
index ed444b042a..a95d42d87e 100644
--- a/target/riscv/insn_trans/trans_rvd.c.inc
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
@@ -18,6 +18,19 @@
  * this program.  If not, see .
  */
 
+#define REQUIRE_ZDINX_OR_D(ctx) do { \
+if (!ctx->ext_zdinx) { \
+REQUIRE_EXT(ctx, RVD); \
+} \
+} while (0)
+
+#define REQUIRE_EVEN(ctx, reg) do { \
+if (ctx->ext_zdinx && (get_xl(ctx) == MXL_RV32) && \
+((reg) & 0x1)) { \
+return false; \
+} \
+} while (0)
+
 static bool trans_fld(DisasContext *ctx, arg_fld *a)
 {
 TCGv addr;
@@ -62,10 +75,17 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
 static bool trans_fmadd_d(DisasContext *ctx, arg_fmadd_d *a)
 {
 REQUIRE_FPU;
-REQUIRE_EXT(ctx, RVD);
+REQUIRE_ZDINX_OR_D(ctx);
+REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2 | a->rs3);
+
+TCGv_i64 dest = dest_fpr(ctx, a->rd);
+TCGv_i64 src1 = get_fpr_d(ctx, a->rs1);
+TCGv_i64 src2 = get_fpr_d(ctx, a->rs2);
+TCGv_i64 src3 = get_fpr_d(ctx, a->rs3);
+
 gen_set_rm(ctx, a->rm);
-gen_helper_fmadd_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
-   cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
+gen_helper_fmadd_d(dest, cpu_env, src1, src2, src3);
+gen_set_fpr_d(ctx, a->rd, dest);
 mark_fs_dirty(ctx);
 return true;
 }
@@ -73,10 +93,17 @@ static bool trans_fmadd_d(DisasContext *ctx, arg_fmadd_d *a)
 static bool trans_fmsub_d(DisasContext *ctx, arg_fmsub_d *a)
 {
 REQUIRE_FPU;
-REQUIRE_EXT(ctx, RVD);
+REQUIRE_ZDINX_OR_D(ctx);
+REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2 | a->rs3);
+
+TCGv_i64 dest = dest_fpr(ctx, a->rd);
+TCGv_i64 src1 = get_fpr_d(ctx, a->rs1);
+TCGv_i64 src2 = get_fpr_d(ctx, a->rs2);
+TCGv_i64 src3 = get_fpr_d(ctx, a->rs3);
+
 gen_set_rm(ctx, a->rm);
-gen_helper_fmsub_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
-   cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
+gen_helper_fmsub_d(dest, cpu_env, src1, src2, src3);
+gen_set_fpr_d(ctx, a->rd, dest);
 mark_fs_dirty(ctx);
 return true;
 }
@@ -84,10 +111,17 @@ static bool trans_fmsub_d(DisasContext *ctx, arg_fmsub_d 
*a)
 static bool trans_fnmsub_d(DisasContext *ctx, arg_fnmsub_d *a)
 {
 REQUIRE_FPU;
-REQUIRE_EXT(ctx, RVD);
+REQUIRE_ZDINX_OR_D(ctx);
+REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2 | a->rs3);
+
+TCGv_i64 dest = dest_fpr(ctx, a->rd);
+TCGv_i64 src1 = get_fpr_d(ctx, a->rs1);
+TCGv_i64 src2 = get_fpr_d(ctx, a->rs2);
+TCGv_i64 src3 = get_fpr_d(ctx, a->rs3);
+
 gen_set_rm(ctx, a->rm);
-gen_helper_fnmsub_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
-cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
+gen_helper_fnmsub_d(dest, cpu_env, src1, src2, src3);
+gen_set_fpr_d(ctx, a->rd, dest);
 mark_fs_dirty(ctx);
 return true;
 }
@@ -95,10 +129,17 @@ static bool trans_fnmsub_d(DisasContext *ctx, arg_fnmsub_d 
*a)
 static bool trans_fnmadd_d(DisasContext *ctx, arg_fnmadd_d *a)
 {
 REQUIRE_FPU;
-REQUIRE_EXT(ctx, RVD);
+REQUIRE_ZDINX_OR_D(ctx);
+REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2 | a->rs3);
+
+TCGv_i64 dest = dest_fpr(ctx, a->rd);
+TCGv_i64 src1 = get_fpr_d(ctx, a->rs1);
+TCGv_i64 src2 = get_fpr_d(ctx, a->rs2);
+TCGv_i64 src3 = get_fpr_d(ctx, a->rs3);
+
 gen_set_rm(ctx, a->rm);
-gen_helper_fnmadd_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
-cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
+gen_helper_fnmadd_d(dest, cpu_env, src1, src2, src3);
+gen_set_fpr_d(ctx, a->rd, dest);
 mark_fs_dirty(ctx);
 return true;
 }
@@ -106,12 +147,16 @@ static bool trans_fnmadd_d(DisasContext *ctx, 
arg_fnmadd_d *a)
 static bool trans_fadd_d(DisasContext *ctx, arg_fadd_d *a)
 {
 REQUIRE_FPU;
-REQUIRE_EXT(ctx, RVD);
+REQUIRE_ZDINX_OR_D(ctx);
+REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2);
 
-gen_set_rm(ctx, a->rm);
-gen_helper_fadd_d(cpu_fpr[a->rd], cpu_env,
-  cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+TCGv_i64 dest = dest_fpr(ctx, a->rd);
+TCGv_i64 src1 = get_fpr_d(ctx, a->rs1);
+TCGv_i64 src2 = get_fpr_d(ctx, a->rs2);
 
+gen_set_rm(ctx, a->rm);
+gen_helper_fadd_d(dest, cpu_env, src1, src2);
+gen_set_fpr_d(ctx, a->rd, dest);
 mark_fs_dirty(ctx);
 return true;
 }
@@ -119,12 +164,16 @@ static bool trans_fadd_d(DisasContext *ctx, arg_fadd_d *a)
 static bool trans_fsub_d(DisasContext *ctx, arg_fsub_d *a)
 {
 REQUIRE_FPU;
-

[PATCH v4 6/6] target/riscv: expose zfinx, zdinx, zhinx{min} properties

2022-01-12 Thread Weiwei Li
Co-authored-by: ardxwe 
Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
---
 target/riscv/cpu.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index fc3ec5bca1..d5e772b2b8 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -685,6 +685,11 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("zbc", RISCVCPU, cfg.ext_zbc, true),
 DEFINE_PROP_BOOL("zbs", RISCVCPU, cfg.ext_zbs, true),
 
+DEFINE_PROP_BOOL("Zdinx", RISCVCPU, cfg.ext_zdinx, false),
+DEFINE_PROP_BOOL("Zfinx", RISCVCPU, cfg.ext_zfinx, false),
+DEFINE_PROP_BOOL("Zhinx", RISCVCPU, cfg.ext_zhinx, false),
+DEFINE_PROP_BOOL("Zhinxmin", RISCVCPU, cfg.ext_zhinxmin, false),
+
 /* These are experimental so mark with 'x-' */
 DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
 /* ePMP 0.9.3 */
-- 
2.17.1




[PATCH v4 0/6] support subsets of Float-Point in Integer Registers extensions

2022-01-12 Thread Weiwei Li
This patchset implements RISC-V Float-Point in Integer Registers 
extensions(Version 1.0), which includes Zfinx, Zdinx, Zhinx and Zhinxmin 
extension. 

Specification:
https://github.com/riscv/riscv-zfinx/blob/main/zfinx-1.0.0.pdf

The port is available here:
https://github.com/plctlab/plct-qemu/tree/plct-zfinx-upstream-v4

To test this implementation, specify cpu argument with 'Zfinx 
=true,Zdinx=true,Zhinx=true,Zhinxmin=true' with 
'g=false,f=false,d=false,Zfh=false,Zfhmin=false'
This implementation can pass gcc tests, ci result can be found in 
https://ci.rvperf.org/job/plct-qemu-zfinx-upstream/.

v4:
* combine register pair check for rv32 zdinx
* clear mstatus.FS when RVF is disabled by write_misa

v3:
* delete unused reset for mstatus.FS
* use positive test for RVF instead of negative test for ZFINX
* replace get_ol with get_xl
* use tcg_gen_concat_tl_i64 to unify tcg_gen_concat_i32_i64 and 
tcg_gen_deposit_i64

v2:
* hardwire mstatus.FS to zero when enable zfinx
* do register-pair check at the begin of translation
* optimize partial implemention as suggested

Weiwei Li (6):
  target/riscv: add cfg properties for zfinx, zdinx and zhinx{min}
  target/riscv: hardwire mstatus.FS to zero when enable zfinx
  target/riscv: add support for zfinx
  target/riscv: add support for zdinx
  target/riscv: add support for zhinx/zhinxmin
  target/riscv: expose zfinx, zdinx, zhinx{min} properties

 target/riscv/cpu.c|  17 ++
 target/riscv/cpu.h|   4 +
 target/riscv/cpu_helper.c |   6 +-
 target/riscv/csr.c|  25 +-
 target/riscv/fpu_helper.c | 178 ++--
 target/riscv/helper.h |   4 +-
 target/riscv/insn_trans/trans_rvd.c.inc   | 285 ++-
 target/riscv/insn_trans/trans_rvf.c.inc   | 314 +---
 target/riscv/insn_trans/trans_rvzfh.c.inc | 332 +++---
 target/riscv/internals.h  |  32 ++-
 target/riscv/translate.c  | 154 ++
 11 files changed, 980 insertions(+), 371 deletions(-)

-- 
2.17.1




[PATCH v4 3/6] target/riscv: add support for zfinx

2022-01-12 Thread Weiwei Li
  - update extension check REQUIRE_ZFINX_OR_F
  - update single float point register read/write
  - disable nanbox_s check

Co-authored-by: ardxwe 
Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
---
 target/riscv/fpu_helper.c   |  89 +++
 target/riscv/helper.h   |   2 +-
 target/riscv/insn_trans/trans_rvf.c.inc | 314 
 target/riscv/internals.h|  16 +-
 target/riscv/translate.c|  90 +++
 5 files changed, 367 insertions(+), 144 deletions(-)

diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
index 4a5982d594..63ca703459 100644
--- a/target/riscv/fpu_helper.c
+++ b/target/riscv/fpu_helper.c
@@ -98,10 +98,11 @@ static uint64_t do_fmadd_h(CPURISCVState *env, uint64_t 
rs1, uint64_t rs2,
 static uint64_t do_fmadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
uint64_t rs3, int flags)
 {
-float32 frs1 = check_nanbox_s(rs1);
-float32 frs2 = check_nanbox_s(rs2);
-float32 frs3 = check_nanbox_s(rs3);
-return nanbox_s(float32_muladd(frs1, frs2, frs3, flags, >fp_status));
+float32 frs1 = check_nanbox_s(env, rs1);
+float32 frs2 = check_nanbox_s(env, rs2);
+float32 frs3 = check_nanbox_s(env, rs3);
+return nanbox_s(env, float32_muladd(frs1, frs2, frs3, flags,
+>fp_status));
 }
 
 uint64_t helper_fmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
@@ -183,124 +184,124 @@ uint64_t helper_fnmadd_h(CPURISCVState *env, uint64_t 
frs1, uint64_t frs2,
 
 uint64_t helper_fadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
-float32 frs1 = check_nanbox_s(rs1);
-float32 frs2 = check_nanbox_s(rs2);
-return nanbox_s(float32_add(frs1, frs2, >fp_status));
+float32 frs1 = check_nanbox_s(env, rs1);
+float32 frs2 = check_nanbox_s(env, rs2);
+return nanbox_s(env, float32_add(frs1, frs2, >fp_status));
 }
 
 uint64_t helper_fsub_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
-float32 frs1 = check_nanbox_s(rs1);
-float32 frs2 = check_nanbox_s(rs2);
-return nanbox_s(float32_sub(frs1, frs2, >fp_status));
+float32 frs1 = check_nanbox_s(env, rs1);
+float32 frs2 = check_nanbox_s(env, rs2);
+return nanbox_s(env, float32_sub(frs1, frs2, >fp_status));
 }
 
 uint64_t helper_fmul_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
-float32 frs1 = check_nanbox_s(rs1);
-float32 frs2 = check_nanbox_s(rs2);
-return nanbox_s(float32_mul(frs1, frs2, >fp_status));
+float32 frs1 = check_nanbox_s(env, rs1);
+float32 frs2 = check_nanbox_s(env, rs2);
+return nanbox_s(env, float32_mul(frs1, frs2, >fp_status));
 }
 
 uint64_t helper_fdiv_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
-float32 frs1 = check_nanbox_s(rs1);
-float32 frs2 = check_nanbox_s(rs2);
-return nanbox_s(float32_div(frs1, frs2, >fp_status));
+float32 frs1 = check_nanbox_s(env, rs1);
+float32 frs2 = check_nanbox_s(env, rs2);
+return nanbox_s(env, float32_div(frs1, frs2, >fp_status));
 }
 
 uint64_t helper_fmin_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
-float32 frs1 = check_nanbox_s(rs1);
-float32 frs2 = check_nanbox_s(rs2);
-return nanbox_s(env->priv_ver < PRIV_VERSION_1_11_0 ?
+float32 frs1 = check_nanbox_s(env, rs1);
+float32 frs2 = check_nanbox_s(env, rs2);
+return nanbox_s(env, env->priv_ver < PRIV_VERSION_1_11_0 ?
 float32_minnum(frs1, frs2, >fp_status) :
 float32_minimum_number(frs1, frs2, >fp_status));
 }
 
 uint64_t helper_fmax_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
-float32 frs1 = check_nanbox_s(rs1);
-float32 frs2 = check_nanbox_s(rs2);
-return nanbox_s(env->priv_ver < PRIV_VERSION_1_11_0 ?
+float32 frs1 = check_nanbox_s(env, rs1);
+float32 frs2 = check_nanbox_s(env, rs2);
+return nanbox_s(env, env->priv_ver < PRIV_VERSION_1_11_0 ?
 float32_maxnum(frs1, frs2, >fp_status) :
 float32_maximum_number(frs1, frs2, >fp_status));
 }
 
 uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t rs1)
 {
-float32 frs1 = check_nanbox_s(rs1);
-return nanbox_s(float32_sqrt(frs1, >fp_status));
+float32 frs1 = check_nanbox_s(env, rs1);
+return nanbox_s(env, float32_sqrt(frs1, >fp_status));
 }
 
 target_ulong helper_fle_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
-float32 frs1 = check_nanbox_s(rs1);
-float32 frs2 = check_nanbox_s(rs2);
+float32 frs1 = check_nanbox_s(env, rs1);
+float32 frs2 = check_nanbox_s(env, rs2);
 return float32_le(frs1, frs2, >fp_status);
 }
 
 target_ulong helper_flt_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
-float32 frs1 = check_nanbox_s(rs1);
-float32 frs2 = check_nanbox_s(rs2);
+float32 frs1 = check_nanbox_s(env, rs1);
+float32 frs2 = check_nanbox_s(env, rs2);
 return float32_lt(frs1, frs2, 

[PATCH v4 1/6] target/riscv: add cfg properties for zfinx, zdinx and zhinx{min}

2022-01-12 Thread Weiwei Li
Co-authored-by: ardxwe 
Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
---
 target/riscv/cpu.c   | 12 
 target/riscv/cpu.h   |  4 
 target/riscv/translate.c |  8 
 3 files changed, 24 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9bc25d3055..fc3ec5bca1 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -518,6 +518,11 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 cpu->cfg.ext_d = true;
 }
 
+if (cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinx ||
+cpu->cfg.ext_zhinxmin) {
+cpu->cfg.ext_zfinx = true;
+}
+
 /* Set the ISA extensions, checks should have happened above */
 if (cpu->cfg.ext_i) {
 ext |= RVI;
@@ -592,6 +597,13 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 if (cpu->cfg.ext_j) {
 ext |= RVJ;
 }
+if (cpu->cfg.ext_zfinx && ((ext & (RVF | RVD)) || cpu->cfg.ext_zfh ||
+   cpu->cfg.ext_zfhmin)) {
+error_setg(errp,
+"'Zfinx' cannot be supported together with 'F', 'D', 
'Zfh',"
+" 'Zfhmin'");
+return;
+}
 
 set_misa(env, env->misa_mxl, ext);
 }
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 4d63086765..b202bcbeff 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -327,8 +327,12 @@ struct RISCVCPU {
 bool ext_counters;
 bool ext_ifencei;
 bool ext_icsr;
+bool ext_zdinx;
 bool ext_zfh;
 bool ext_zfhmin;
+bool ext_zfinx;
+bool ext_zhinx;
+bool ext_zhinxmin;
 
 char *priv_spec;
 char *user_spec;
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 615048ec87..9687fa3e7c 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -77,8 +77,12 @@ typedef struct DisasContext {
 RISCVMXL ol;
 bool virt_enabled;
 bool ext_ifencei;
+bool ext_zdinx;
 bool ext_zfh;
 bool ext_zfhmin;
+bool ext_zfinx;
+bool ext_zhinx;
+bool ext_zhinxmin;
 bool hlsx;
 /* vector extension */
 bool vill;
@@ -892,8 +896,12 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->misa_ext = env->misa_ext;
 ctx->frm = -1;  /* unknown rounding mode */
 ctx->ext_ifencei = cpu->cfg.ext_ifencei;
+ctx->ext_zdinx = cpu->cfg.ext_zdinx;
 ctx->ext_zfh = cpu->cfg.ext_zfh;
 ctx->ext_zfhmin = cpu->cfg.ext_zfhmin;
+ctx->ext_zfinx = cpu->cfg.ext_zfinx;
+ctx->ext_zhinx = cpu->cfg.ext_zhinx;
+ctx->ext_zhinxmin = cpu->cfg.ext_zhinxmin;
 ctx->vlen = cpu->cfg.vlen;
 ctx->elen = cpu->cfg.elen;
 ctx->mstatus_hs_fs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_FS);
-- 
2.17.1




[PATCH v4 2/6] target/riscv: hardwire mstatus.FS to zero when enable zfinx

2022-01-12 Thread Weiwei Li
Co-authored-by: ardxwe 
Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/cpu_helper.c |  6 +-
 target/riscv/csr.c| 25 -
 target/riscv/translate.c  |  4 
 3 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 434a83e66a..3854acf7fe 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -222,9 +222,13 @@ bool riscv_cpu_vector_enabled(CPURISCVState *env)
 
 void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
 {
-uint64_t mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
+uint64_t mstatus_mask = MSTATUS_MXR | MSTATUS_SUM |
 MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE |
 MSTATUS64_UXL | MSTATUS_VS;
+
+if (riscv_has_ext(env, RVF)) {
+mstatus_mask |= MSTATUS_FS;
+}
 bool current_virt = riscv_cpu_virt_enabled(env);
 
 g_assert(riscv_has_ext(env, RVH));
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index adb3d4381d..f4466cba05 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -38,7 +38,8 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
 static RISCVException fs(CPURISCVState *env, int csrno)
 {
 #if !defined(CONFIG_USER_ONLY)
-if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
+if (!env->debugger && !riscv_cpu_fp_enabled(env) &&
+!RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 #endif
@@ -234,7 +235,9 @@ static RISCVException write_fflags(CPURISCVState *env, int 
csrno,
target_ulong val)
 {
 #if !defined(CONFIG_USER_ONLY)
-env->mstatus |= MSTATUS_FS;
+if (riscv_has_ext(env, RVF)) {
+env->mstatus |= MSTATUS_FS;
+}
 #endif
 riscv_cpu_set_fflags(env, val & (FSR_AEXC >> FSR_AEXC_SHIFT));
 return RISCV_EXCP_NONE;
@@ -251,7 +254,9 @@ static RISCVException write_frm(CPURISCVState *env, int 
csrno,
 target_ulong val)
 {
 #if !defined(CONFIG_USER_ONLY)
-env->mstatus |= MSTATUS_FS;
+if (riscv_has_ext(env, RVF)) {
+env->mstatus |= MSTATUS_FS;
+}
 #endif
 env->frm = val & (FSR_RD >> FSR_RD_SHIFT);
 return RISCV_EXCP_NONE;
@@ -269,7 +274,9 @@ static RISCVException write_fcsr(CPURISCVState *env, int 
csrno,
  target_ulong val)
 {
 #if !defined(CONFIG_USER_ONLY)
-env->mstatus |= MSTATUS_FS;
+if (riscv_has_ext(env, RVF)) {
+env->mstatus |= MSTATUS_FS;
+}
 #endif
 env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
 riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT);
@@ -564,10 +571,14 @@ static RISCVException write_mstatus(CPURISCVState *env, 
int csrno,
 tlb_flush(env_cpu(env));
 }
 mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
-MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM |
+MSTATUS_SPP | MSTATUS_MPRV | MSTATUS_SUM |
 MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
 MSTATUS_TW | MSTATUS_VS;
 
+if (riscv_has_ext(env, RVF)) {
+mask |= MSTATUS_FS;
+}
+
 if (riscv_cpu_mxl(env) != MXL_RV32) {
 /*
  * RV32: MPV and GVA are not in mstatus. The current plan is to
@@ -697,6 +708,10 @@ static RISCVException write_misa(CPURISCVState *env, int 
csrno,
 return RISCV_EXCP_NONE;
 }
 
+if (!(val & RVF)) {
+env->mstatus &= ~MSTATUS_FS;
+}
+
 /* flush translation cache */
 tb_flush(env_cpu(env));
 env->misa_ext = val;
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 9687fa3e7c..8f01063618 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -406,6 +406,10 @@ static void mark_fs_dirty(DisasContext *ctx)
 {
 TCGv tmp;
 
+if (!has_ext(ctx, RVF)) {
+return;
+}
+
 if (ctx->mstatus_fs != MSTATUS_FS) {
 /* Remember the state change for the rest of the TB. */
 ctx->mstatus_fs = MSTATUS_FS;
-- 
2.17.1




Re: [PATCH] migration: Add canary to VMSTATE_END_OF_LIST

2022-01-12 Thread Peter Xu
On Wed, Jan 12, 2022 at 10:56:07AM +, Peter Maydell wrote:
> We could have vmstate_register_with_alias_id() iterate through
> and assert presence of the right terminator (probably only if
> qtest enabled, or some other suitable condition). Then the
> existing tests that do the basic "check we can instantiate every
> device and initialize every board model" would run that code
> and catch most missing terminator cases, I think.

Agreed.  How about assert it even without qtest?  We do tons of assertion for
programming errors anyway in QEMU.

Thanks,

-- 
Peter Xu




[PATCH v2 4/4] dump/win_dump: add 32-bit guest Windows support

2022-01-12 Thread Viktor Prutyanov
Before this patch, 'dump-guest-memory -w' was accepting only 64-bit
dump header provided by guest through vmcoreinfo and thus was unable
to produce 32-bit guest Windows dump. So, add 32-bit guest Windows
dumping support.

Signed-off-by: Viktor Prutyanov 
---
 dump/win_dump.c | 231 +---
 1 file changed, 139 insertions(+), 92 deletions(-)

diff --git a/dump/win_dump.c b/dump/win_dump.c
index df3b432ca5..d751cd6d36 100644
--- a/dump/win_dump.c
+++ b/dump/win_dump.c
@@ -24,18 +24,18 @@
 #include "hw/misc/vmcoreinfo.h"
 #include "win_dump.h"
 
-#define WIN_DUMP_PTR_SIZE sizeof(uint64_t)
+#define WIN_DUMP_PTR_SIZE (x64 ? sizeof(uint64_t) : sizeof(uint32_t))
 
-#define _WIN_DUMP_FIELD(f) (h->f)
+#define _WIN_DUMP_FIELD(f) (x64 ? h->x64.f : h->x32.f)
 #define WIN_DUMP_FIELD(field) _WIN_DUMP_FIELD(field)
 
-#define _WIN_DUMP_FIELD_PTR(f) ((void *)>f)
+#define _WIN_DUMP_FIELD_PTR(f) (x64 ? (void *)>x64.f : (void *)>x32.f)
 #define WIN_DUMP_FIELD_PTR(field) _WIN_DUMP_FIELD_PTR(field)
 
-#define _WIN_DUMP_FIELD_SIZE(f) sizeof(h->f)
+#define _WIN_DUMP_FIELD_SIZE(f) (x64 ? sizeof(h->x64.f) : sizeof(h->x32.f))
 #define WIN_DUMP_FIELD_SIZE(field) _WIN_DUMP_FIELD_SIZE(field)
 
-#define WIN_DUMP_CTX_SIZE sizeof(WinContext64)
+#define WIN_DUMP_CTX_SIZE (x64 ? sizeof(WinContext64) : sizeof(WinContext32))
 
 static size_t write_run(uint64_t base_page, uint64_t page_count,
 int fd, Error **errp)
@@ -71,7 +71,7 @@ static size_t write_run(uint64_t base_page, uint64_t 
page_count,
 return total;
 }
 
-static void write_runs(DumpState *s, WinDumpHeader64 *h, Error **errp)
+static void write_runs(DumpState *s, WinDumpHeader *h, bool x64, Error **errp)
 {
 uint64_t BasePage, PageCount;
 Error *local_err = NULL;
@@ -88,22 +88,24 @@ static void write_runs(DumpState *s, WinDumpHeader64 *h, 
Error **errp)
 }
 }
 
-static int cpu_read_ptr(CPUState *cpu, uint64_t addr, uint64_t *ptr)
+static int cpu_read_ptr(bool x64, CPUState *cpu, uint64_t addr, uint64_t *ptr)
 {
 int ret;
+uint32_t ptr32;
 uint64_t ptr64;
 
-ret = cpu_memory_rw_debug(cpu, addr, , WIN_DUMP_PTR_SIZE, 0);
+ret = cpu_memory_rw_debug(cpu, addr, x64 ? (void *) : (void *),
+WIN_DUMP_PTR_SIZE, 0);
 
-*ptr = ptr64;
+*ptr = x64 ? ptr64 : ptr32;
 
 return ret;
 }
 
-static void patch_mm_pfn_database(WinDumpHeader64 *h, Error **errp)
+static void patch_mm_pfn_database(WinDumpHeader *h, bool x64, Error **errp)
 {
 if (cpu_memory_rw_debug(first_cpu,
-WIN_DUMP_FIELD(KdDebuggerDataBlock) + 
KDBG_MM_PFN_DATABASE_OFFSET64,
+WIN_DUMP_FIELD(KdDebuggerDataBlock) + KDBG_MM_PFN_DATABASE_OFFSET,
 WIN_DUMP_FIELD_PTR(PfnDatabase),
 WIN_DUMP_FIELD_SIZE(PfnDatabase), 0)) {
 error_setg(errp, "win-dump: failed to read MmPfnDatabase");
@@ -111,13 +113,12 @@ static void patch_mm_pfn_database(WinDumpHeader64 *h, 
Error **errp)
 }
 }
 
-static void patch_bugcheck_data(WinDumpHeader64 *h, Error **errp)
+static void patch_bugcheck_data(WinDumpHeader *h, bool x64, Error **errp)
 {
 uint64_t KiBugcheckData;
 
-if (cpu_read_ptr(first_cpu,
-WIN_DUMP_FIELD(KdDebuggerDataBlock) +
-KDBG_KI_BUGCHECK_DATA_OFFSET64,
+if (cpu_read_ptr(x64, first_cpu,
+WIN_DUMP_FIELD(KdDebuggerDataBlock) + KDBG_KI_BUGCHECK_DATA_OFFSET,
 )) {
 error_setg(errp, "win-dump: failed to read KiBugcheckData");
 return;
@@ -142,30 +143,34 @@ static void patch_bugcheck_data(WinDumpHeader64 *h, Error 
**errp)
 /*
  * This routine tries to correct mistakes in crashdump header.
  */
-static void patch_header(WinDumpHeader64 *h)
+static void patch_header(WinDumpHeader *h, bool x64)
 {
 Error *local_err = NULL;
 
-h->RequiredDumpSpace = sizeof(WinDumpHeader64) +
-(h->PhysicalMemoryBlock.NumberOfPages << TARGET_PAGE_BITS);
-h->PhysicalMemoryBlock.unused = 0;
-h->unused1 = 0;
+if (x64) {
+h->x64.RequiredDumpSpace = sizeof(WinDumpHeader64) +
+(h->x64.PhysicalMemoryBlock.NumberOfPages << TARGET_PAGE_BITS);
+h->x64.PhysicalMemoryBlock.unused = 0;
+h->x64.unused1 = 0;
+} else {
+h->x32.RequiredDumpSpace = sizeof(WinDumpHeader32) +
+(h->x32.PhysicalMemoryBlock.NumberOfPages << TARGET_PAGE_BITS);
+}
 
-patch_mm_pfn_database(h, _err);
+patch_mm_pfn_database(h, x64, _err);
 if (local_err) {
 warn_report_err(local_err);
 local_err = NULL;
 }
-patch_bugcheck_data(h, _err);
+patch_bugcheck_data(h, x64, _err);
 if (local_err) {
 warn_report_err(local_err);
 }
 }
 
-static void check_header(WinDumpHeader64 *h, Error **errp)
+static void check_header(WinDumpHeader *h, bool *x64, Error **errp)
 {
 const char Signature[] = "PAGE";
-const char ValidDump[] = "DU64";
 
 if (memcmp(h->Signature, Signature, sizeof(h->Signature))) {
 error_setg(errp, 

[PATCH v2 3/4] include/qemu: add 32-bit Windows dump structures

2022-01-12 Thread Viktor Prutyanov
These structures are required to produce 32-bit guest Windows Complete
Memory Dump. Add 32-bit Windows dump header, CPU context and physical
memory descriptor structures along with corresponding definitions.

Signed-off-by: Viktor Prutyanov 
---
 include/qemu/win_dump_defs.h | 107 +++
 1 file changed, 107 insertions(+)

diff --git a/include/qemu/win_dump_defs.h b/include/qemu/win_dump_defs.h
index 5a5e5a5e09..73a44e2408 100644
--- a/include/qemu/win_dump_defs.h
+++ b/include/qemu/win_dump_defs.h
@@ -11,11 +11,22 @@
 #ifndef QEMU_WIN_DUMP_DEFS_H
 #define QEMU_WIN_DUMP_DEFS_H
 
+typedef struct WinDumpPhyMemRun32 {
+uint32_t BasePage;
+uint32_t PageCount;
+} QEMU_PACKED WinDumpPhyMemRun32;
+
 typedef struct WinDumpPhyMemRun64 {
 uint64_t BasePage;
 uint64_t PageCount;
 } QEMU_PACKED WinDumpPhyMemRun64;
 
+typedef struct WinDumpPhyMemDesc32 {
+uint32_t NumberOfRuns;
+uint32_t NumberOfPages;
+WinDumpPhyMemRun32 Run[86];
+} QEMU_PACKED WinDumpPhyMemDesc32;
+
 typedef struct WinDumpPhyMemDesc64 {
 uint32_t NumberOfRuns;
 uint32_t unused;
@@ -33,6 +44,39 @@ typedef struct WinDumpExceptionRecord {
 uint64_t ExceptionInformation[15];
 } QEMU_PACKED WinDumpExceptionRecord;
 
+typedef struct WinDumpHeader32 {
+char Signature[4];
+char ValidDump[4];
+uint32_t MajorVersion;
+uint32_t MinorVersion;
+uint32_t DirectoryTableBase;
+uint32_t PfnDatabase;
+uint32_t PsLoadedModuleList;
+uint32_t PsActiveProcessHead;
+uint32_t MachineImageType;
+uint32_t NumberProcessors;
+union {
+struct {
+uint32_t BugcheckCode;
+uint32_t BugcheckParameter1;
+uint32_t BugcheckParameter2;
+uint32_t BugcheckParameter3;
+uint32_t BugcheckParameter4;
+};
+uint8_t BugcheckData[20];
+};
+uint8_t VersionUser[32];
+uint32_t reserved0;
+uint32_t KdDebuggerDataBlock;
+union {
+WinDumpPhyMemDesc32 PhysicalMemoryBlock;
+uint8_t PhysicalMemoryBlockBuffer[700];
+};
+uint8_t reserved1[3200];
+uint32_t RequiredDumpSpace;
+uint8_t reserved2[92];
+} QEMU_PACKED WinDumpHeader32;
+
 typedef struct WinDumpHeader64 {
 char Signature[4];
 char ValidDump[4];
@@ -81,25 +125,49 @@ typedef struct WinDumpHeader64 {
 uint8_t reserved[4018];
 } QEMU_PACKED WinDumpHeader64;
 
+typedef union WinDumpHeader {
+struct {
+char Signature[4];
+char ValidDump[4];
+};
+WinDumpHeader32 x32;
+WinDumpHeader64 x64;
+} WinDumpHeader;
+
 #define KDBG_OWNER_TAG_OFFSET64 0x10
 #define KDBG_MM_PFN_DATABASE_OFFSET64   0xC0
 #define KDBG_KI_BUGCHECK_DATA_OFFSET64  0x88
 #define KDBG_KI_PROCESSOR_BLOCK_OFFSET640x218
 #define KDBG_OFFSET_PRCB_CONTEXT_OFFSET64   0x338
 
+#define KDBG_OWNER_TAG_OFFSET   KDBG_OWNER_TAG_OFFSET64
+#define KDBG_MM_PFN_DATABASE_OFFSET KDBG_MM_PFN_DATABASE_OFFSET64
+#define KDBG_KI_BUGCHECK_DATA_OFFSETKDBG_KI_BUGCHECK_DATA_OFFSET64
+#define KDBG_KI_PROCESSOR_BLOCK_OFFSET  KDBG_KI_PROCESSOR_BLOCK_OFFSET64
+#define KDBG_OFFSET_PRCB_CONTEXT_OFFSET KDBG_OFFSET_PRCB_CONTEXT_OFFSET64
+
 #define VMCOREINFO_ELF_NOTE_HDR_SIZE24
+#define VMCOREINFO_WIN_DUMP_NOTE_SIZE64 (sizeof(WinDumpHeader64) + \
+ VMCOREINFO_ELF_NOTE_HDR_SIZE)
+#define VMCOREINFO_WIN_DUMP_NOTE_SIZE32 (sizeof(WinDumpHeader32) + \
+ VMCOREINFO_ELF_NOTE_HDR_SIZE)
 
 #define WIN_CTX_X64 0x0010L
+#define WIN_CTX_X86 0x0001L
 
 #define WIN_CTX_CTL 0x0001L
 #define WIN_CTX_INT 0x0002L
 #define WIN_CTX_SEG 0x0004L
 #define WIN_CTX_FP  0x0008L
 #define WIN_CTX_DBG 0x0010L
+#define WIN_CTX_EXT 0x0020L
 
 #define WIN_CTX64_FULL  (WIN_CTX_X64 | WIN_CTX_CTL | WIN_CTX_INT | WIN_CTX_FP)
 #define WIN_CTX64_ALL   (WIN_CTX64_FULL | WIN_CTX_SEG | WIN_CTX_DBG)
 
+#define WIN_CTX32_FULL (WIN_CTX_X86 | WIN_CTX_CTL | WIN_CTX_INT | WIN_CTX_SEG)
+#define WIN_CTX32_ALL (WIN_CTX32_FULL | WIN_CTX_FP | WIN_CTX_DBG | WIN_CTX_EXT)
+
 #define LIVE_SYSTEM_DUMP0x0161
 
 typedef struct WinM128A {
@@ -107,6 +175,40 @@ typedef struct WinM128A {
 int64_t high;
 } QEMU_ALIGNED(16) WinM128A;
 
+typedef struct WinContext32 {
+uint32_t ContextFlags;
+
+uint32_t Dr0;
+uint32_t Dr1;
+uint32_t Dr2;
+uint32_t Dr3;
+uint32_t Dr6;
+uint32_t Dr7;
+
+uint8_t  FloatSave[112];
+
+uint32_t SegGs;
+uint32_t SegFs;
+uint32_t SegEs;
+uint32_t SegDs;
+
+uint32_t Edi;
+uint32_t Esi;
+uint32_t Ebx;
+uint32_t Edx;
+uint32_t Ecx;
+uint32_t Eax;
+
+uint32_t Ebp;
+uint32_t Eip;
+uint32_t SegCs;
+uint32_t EFlags;
+uint32_t Esp;
+uint32_t SegSs;
+
+uint8_t ExtendedRegisters[512];
+} QEMU_ALIGNED(16) WinContext32;
+
 typedef struct WinContext64 {
 uint64_t PHome[6];
 
@@ -176,4 +278,9 @@ typedef struct WinContext64 {

[PATCH v2 1/4] include/qemu: rename Windows context definitions to expose bitness

2022-01-12 Thread Viktor Prutyanov
Context structure in 64-bit Windows differs from 32-bit one and it
should be reflected in its name.

Signed-off-by: Viktor Prutyanov 
---
 contrib/elf2dmp/main.c   |  6 +++---
 dump/win_dump.c  | 14 +++---
 include/qemu/win_dump_defs.h |  8 
 3 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/contrib/elf2dmp/main.c b/contrib/elf2dmp/main.c
index 20b477d582..b9fc6d230c 100644
--- a/contrib/elf2dmp/main.c
+++ b/contrib/elf2dmp/main.c
@@ -141,10 +141,10 @@ static KDDEBUGGER_DATA64 *get_kdbg(uint64_t KernBase, 
struct pdb_reader *pdb,
 return kdbg;
 }
 
-static void win_context_init_from_qemu_cpu_state(WinContext *ctx,
+static void win_context_init_from_qemu_cpu_state(WinContext64 *ctx,
 QEMUCPUState *s)
 {
-WinContext win_ctx = (WinContext){
+WinContext64 win_ctx = (WinContext64){
 .ContextFlags = WIN_CTX_X64 | WIN_CTX_INT | WIN_CTX_SEG | WIN_CTX_CTL,
 .MxCsr = INITIAL_MXCSR,
 
@@ -302,7 +302,7 @@ static int fill_context(KDDEBUGGER_DATA64 *kdbg,
 for (i = 0; i < qe->state_nr; i++) {
 uint64_t Prcb;
 uint64_t Context;
-WinContext ctx;
+WinContext64 ctx;
 QEMUCPUState *s = qe->state[i];
 
 if (va_space_rw(vs, kdbg->KiProcessorBlock + sizeof(Prcb) * i,
diff --git a/dump/win_dump.c b/dump/win_dump.c
index c5eb5a9aac..29b6e4f670 100644
--- a/dump/win_dump.c
+++ b/dump/win_dump.c
@@ -189,7 +189,7 @@ try_again:
 }
 
 struct saved_context {
-WinContext ctx;
+WinContext64 ctx;
 uint64_t addr;
 };
 
@@ -221,7 +221,7 @@ static void patch_and_save_context(WinDumpHeader64 *h,
 CPUX86State *env = _cpu->env;
 uint64_t Prcb;
 uint64_t Context;
-WinContext ctx;
+WinContext64 ctx;
 
 if (cpu_memory_rw_debug(first_cpu,
 KiProcessorBlock + i * sizeof(uint64_t),
@@ -241,8 +241,8 @@ static void patch_and_save_context(WinDumpHeader64 *h,
 
 saved_ctx[i].addr = Context;
 
-ctx = (WinContext){
-.ContextFlags = WIN_CTX_ALL,
+ctx = (WinContext64){
+.ContextFlags = WIN_CTX64_ALL,
 .MxCsr = env->mxcsr,
 
 .SegEs = env->segs[0].selector,
@@ -284,13 +284,13 @@ static void patch_and_save_context(WinDumpHeader64 *h,
 };
 
 if (cpu_memory_rw_debug(first_cpu, Context,
-(uint8_t *)_ctx[i].ctx, sizeof(WinContext), 0)) {
+(uint8_t *)_ctx[i].ctx, sizeof(WinContext64), 0)) {
 error_setg(errp, "win-dump: failed to save CPU #%d context", i);
 return;
 }
 
 if (cpu_memory_rw_debug(first_cpu, Context,
-(uint8_t *), sizeof(WinContext), 1)) {
+(uint8_t *), sizeof(WinContext64), 1)) {
 error_setg(errp, "win-dump: failed to write CPU #%d context", i);
 return;
 }
@@ -306,7 +306,7 @@ static void restore_context(WinDumpHeader64 *h,
 
 for (i = 0; i < h->NumberProcessors; i++) {
 if (cpu_memory_rw_debug(first_cpu, saved_ctx[i].addr,
-(uint8_t *)_ctx[i].ctx, sizeof(WinContext), 1)) {
+(uint8_t *)_ctx[i].ctx, sizeof(WinContext64), 1)) {
 warn_report("win-dump: failed to restore CPU #%d context", i);
 }
 }
diff --git a/include/qemu/win_dump_defs.h b/include/qemu/win_dump_defs.h
index 145096e8ee..5a5e5a5e09 100644
--- a/include/qemu/win_dump_defs.h
+++ b/include/qemu/win_dump_defs.h
@@ -97,8 +97,8 @@ typedef struct WinDumpHeader64 {
 #define WIN_CTX_FP  0x0008L
 #define WIN_CTX_DBG 0x0010L
 
-#define WIN_CTX_FULL(WIN_CTX_X64 | WIN_CTX_CTL | WIN_CTX_INT | WIN_CTX_FP)
-#define WIN_CTX_ALL (WIN_CTX_FULL | WIN_CTX_SEG | WIN_CTX_DBG)
+#define WIN_CTX64_FULL  (WIN_CTX_X64 | WIN_CTX_CTL | WIN_CTX_INT | WIN_CTX_FP)
+#define WIN_CTX64_ALL   (WIN_CTX64_FULL | WIN_CTX_SEG | WIN_CTX_DBG)
 
 #define LIVE_SYSTEM_DUMP0x0161
 
@@ -107,7 +107,7 @@ typedef struct WinM128A {
 int64_t high;
 } QEMU_ALIGNED(16) WinM128A;
 
-typedef struct WinContext {
+typedef struct WinContext64 {
 uint64_t PHome[6];
 
 uint32_t ContextFlags;
@@ -174,6 +174,6 @@ typedef struct WinContext {
 uint64_t LastBranchFromRip;
 uint64_t LastExceptionToRip;
 uint64_t LastExceptionFromRip;
-} QEMU_ALIGNED(16) WinContext;
+} QEMU_ALIGNED(16) WinContext64;
 
 #endif /* QEMU_WIN_DUMP_DEFS_H */
-- 
2.31.1




[PATCH v2 2/4] dump/win_dump: add helper macros for Windows dump header access

2022-01-12 Thread Viktor Prutyanov
Perform read access to Windows dump header fields via helper macros.
This is preparation for the next 32-bit guest Windows dump support.

Signed-off-by: Viktor Prutyanov 
---
 dump/win_dump.c | 100 +++-
 1 file changed, 65 insertions(+), 35 deletions(-)

diff --git a/dump/win_dump.c b/dump/win_dump.c
index 29b6e4f670..df3b432ca5 100644
--- a/dump/win_dump.c
+++ b/dump/win_dump.c
@@ -24,11 +24,25 @@
 #include "hw/misc/vmcoreinfo.h"
 #include "win_dump.h"
 
-static size_t write_run(WinDumpPhyMemRun64 *run, int fd, Error **errp)
+#define WIN_DUMP_PTR_SIZE sizeof(uint64_t)
+
+#define _WIN_DUMP_FIELD(f) (h->f)
+#define WIN_DUMP_FIELD(field) _WIN_DUMP_FIELD(field)
+
+#define _WIN_DUMP_FIELD_PTR(f) ((void *)>f)
+#define WIN_DUMP_FIELD_PTR(field) _WIN_DUMP_FIELD_PTR(field)
+
+#define _WIN_DUMP_FIELD_SIZE(f) sizeof(h->f)
+#define WIN_DUMP_FIELD_SIZE(field) _WIN_DUMP_FIELD_SIZE(field)
+
+#define WIN_DUMP_CTX_SIZE sizeof(WinContext64)
+
+static size_t write_run(uint64_t base_page, uint64_t page_count,
+int fd, Error **errp)
 {
 void *buf;
-uint64_t addr = run->BasePage << TARGET_PAGE_BITS;
-uint64_t size = run->PageCount << TARGET_PAGE_BITS;
+uint64_t addr = base_page << TARGET_PAGE_BITS;
+uint64_t size = page_count << TARGET_PAGE_BITS;
 uint64_t len, l;
 size_t total = 0;
 
@@ -59,13 +73,14 @@ static size_t write_run(WinDumpPhyMemRun64 *run, int fd, 
Error **errp)
 
 static void write_runs(DumpState *s, WinDumpHeader64 *h, Error **errp)
 {
-WinDumpPhyMemDesc64 *desc = >PhysicalMemoryBlock;
-WinDumpPhyMemRun64 *run = desc->Run;
+uint64_t BasePage, PageCount;
 Error *local_err = NULL;
 int i;
 
-for (i = 0; i < desc->NumberOfRuns; i++) {
-s->written_size += write_run(run + i, s->fd, _err);
+for (i = 0; i < WIN_DUMP_FIELD(PhysicalMemoryBlock.NumberOfRuns); i++) {
+BasePage = WIN_DUMP_FIELD(PhysicalMemoryBlock.Run[i].BasePage);
+PageCount = WIN_DUMP_FIELD(PhysicalMemoryBlock.Run[i].PageCount);
+s->written_size += write_run(BasePage, PageCount, s->fd, _err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
@@ -73,11 +88,24 @@ static void write_runs(DumpState *s, WinDumpHeader64 *h, 
Error **errp)
 }
 }
 
+static int cpu_read_ptr(CPUState *cpu, uint64_t addr, uint64_t *ptr)
+{
+int ret;
+uint64_t ptr64;
+
+ret = cpu_memory_rw_debug(cpu, addr, , WIN_DUMP_PTR_SIZE, 0);
+
+*ptr = ptr64;
+
+return ret;
+}
+
 static void patch_mm_pfn_database(WinDumpHeader64 *h, Error **errp)
 {
 if (cpu_memory_rw_debug(first_cpu,
-h->KdDebuggerDataBlock + KDBG_MM_PFN_DATABASE_OFFSET64,
-(uint8_t *)>PfnDatabase, sizeof(h->PfnDatabase), 0)) {
+WIN_DUMP_FIELD(KdDebuggerDataBlock) + 
KDBG_MM_PFN_DATABASE_OFFSET64,
+WIN_DUMP_FIELD_PTR(PfnDatabase),
+WIN_DUMP_FIELD_SIZE(PfnDatabase), 0)) {
 error_setg(errp, "win-dump: failed to read MmPfnDatabase");
 return;
 }
@@ -87,16 +115,17 @@ static void patch_bugcheck_data(WinDumpHeader64 *h, Error 
**errp)
 {
 uint64_t KiBugcheckData;
 
-if (cpu_memory_rw_debug(first_cpu,
-h->KdDebuggerDataBlock + KDBG_KI_BUGCHECK_DATA_OFFSET64,
-(uint8_t *), sizeof(KiBugcheckData), 0)) {
+if (cpu_read_ptr(first_cpu,
+WIN_DUMP_FIELD(KdDebuggerDataBlock) +
+KDBG_KI_BUGCHECK_DATA_OFFSET64,
+)) {
 error_setg(errp, "win-dump: failed to read KiBugcheckData");
 return;
 }
 
-if (cpu_memory_rw_debug(first_cpu,
-KiBugcheckData,
-h->BugcheckData, sizeof(h->BugcheckData), 0)) {
+if (cpu_memory_rw_debug(first_cpu, KiBugcheckData,
+WIN_DUMP_FIELD(BugcheckData),
+WIN_DUMP_FIELD_SIZE(BugcheckData), 0)) {
 error_setg(errp, "win-dump: failed to read bugcheck data");
 return;
 }
@@ -105,8 +134,8 @@ static void patch_bugcheck_data(WinDumpHeader64 *h, Error 
**errp)
  * If BugcheckCode wasn't saved, we consider guest OS as alive.
  */
 
-if (!h->BugcheckCode) {
-h->BugcheckCode = LIVE_SYSTEM_DUMP;
+if (!WIN_DUMP_FIELD(BugcheckCode)) {
+*(uint32_t *)WIN_DUMP_FIELD_PTR(BugcheckCode) = LIVE_SYSTEM_DUMP;
 }
 }
 
@@ -155,7 +184,7 @@ static void check_kdbg(WinDumpHeader64 *h, Error **errp)
 {
 const char OwnerTag[] = "KDBG";
 char read_OwnerTag[4];
-uint64_t KdDebuggerDataBlock = h->KdDebuggerDataBlock;
+uint64_t KdDebuggerDataBlock = WIN_DUMP_FIELD(KdDebuggerDataBlock);
 bool try_fallback = true;
 
 try_again:
@@ -174,7 +203,7 @@ try_again:
  * we try to use KDBG obtained by guest driver.
  */
 
-KdDebuggerDataBlock = h->BugcheckParameter1;
+KdDebuggerDataBlock = WIN_DUMP_FIELD(BugcheckParameter1);
 try_fallback = false;
 goto try_again;
 } else {
@@ 

[PATCH v2 0/4] dump: add 32-bit guest Windows support

2022-01-12 Thread Viktor Prutyanov
Since 32-bit versions of Windows still exist, there is a need to take
live and crash dumps of such guests along with 64-bit guests. So, add
an ability for 'dump-guest-memory -w' to take dumps from 32-bit guest.
When running the command QEMU consumes 32-bit Complete Memory Dump
header passed by guest driver through vmcoreinfo device as it was
previously done for 64-bit headers. 32-bit vmcoreinfo guest driver in
upstream virtio-win can fill such a header.

Changes in v2:
- no change in logic, just split patches
- first introduce WIN_DUMP_* macros for x64 in a separate patch
- rename WinContext to WinContext64 in a separate patch

Viktor Prutyanov (4):
  include/qemu: rename Windows context definitions to expose bitness
  dump/win_dump: add helper macros for Windows dump header access
  include/qemu: add 32-bit Windows dump structures
  dump/win_dump: add 32-bit guest Windows support

 contrib/elf2dmp/main.c   |   6 +-
 dump/win_dump.c  | 293 ++-
 include/qemu/win_dump_defs.h | 115 +-
 3 files changed, 299 insertions(+), 115 deletions(-)

-- 
2.31.1




[PATCH v2 1/2] hw/sensor: Add SB-TSI Temperature Sensor Interface

2022-01-12 Thread Patrick Venture
From: Hao Wu 

SB Temperature Sensor Interface (SB-TSI) is an SMBus compatible
interface that reports AMD SoC's Ttcl (normalized temperature),
and resembles a typical 8-pin remote temperature sensor's I2C interface
to BMC.

This patch implements a basic AMD SB-TSI sensor that is
compatible with the open-source data sheet from AMD and Linux
kernel driver.

Reference:
Linux kernel driver:
https://lkml.org/lkml/2020/12/11/968
Register Map:
https://developer.amd.com/wp-content/resources/56255_3_03.PDF
(Chapter 6)

Signed-off-by: Hao Wu 
Reviewed-by: Doug Evans 
---
 hw/sensor/Kconfig |   4 +
 hw/sensor/meson.build |   1 +
 hw/sensor/tmp_sbtsi.c | 365 ++
 hw/sensor/trace-events|   5 +
 hw/sensor/trace.h |   1 +
 include/hw/sensor/sbtsi.h |  50 ++
 meson.build   |   1 +
 7 files changed, 427 insertions(+)
 create mode 100644 hw/sensor/tmp_sbtsi.c
 create mode 100644 hw/sensor/trace-events
 create mode 100644 hw/sensor/trace.h
 create mode 100644 include/hw/sensor/sbtsi.h

diff --git a/hw/sensor/Kconfig b/hw/sensor/Kconfig
index 9c8a049b06..27f6f79c84 100644
--- a/hw/sensor/Kconfig
+++ b/hw/sensor/Kconfig
@@ -21,3 +21,7 @@ config ADM1272
 config MAX34451
 bool
 depends on I2C
+
+config AMDSBTSI
+bool
+depends on I2C
diff --git a/hw/sensor/meson.build b/hw/sensor/meson.build
index 059c4ca935..f7b0e645eb 100644
--- a/hw/sensor/meson.build
+++ b/hw/sensor/meson.build
@@ -4,3 +4,4 @@ softmmu_ss.add(when: 'CONFIG_DPS310', if_true: 
files('dps310.c'))
 softmmu_ss.add(when: 'CONFIG_EMC141X', if_true: files('emc141x.c'))
 softmmu_ss.add(when: 'CONFIG_ADM1272', if_true: files('adm1272.c'))
 softmmu_ss.add(when: 'CONFIG_MAX34451', if_true: files('max34451.c'))
+softmmu_ss.add(when: 'CONFIG_AMDSBTSI', if_true: files('tmp_sbtsi.c'))
diff --git a/hw/sensor/tmp_sbtsi.c b/hw/sensor/tmp_sbtsi.c
new file mode 100644
index 00..7090f69fa1
--- /dev/null
+++ b/hw/sensor/tmp_sbtsi.c
@@ -0,0 +1,365 @@
+/*
+ * AMD SBI Temperature Sensor Interface (SB-TSI)
+ *
+ * Copyright 2021 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/i2c/smbus_slave.h"
+#include "hw/sensor/sbtsi.h"
+#include "hw/irq.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "trace.h"
+
+/**
+ * SBTSIState:
+ * temperatures are in units of 0.125 degrees
+ * @temperature: Temperature
+ * @limit_low: Lowest temperature
+ * @limit_high: Highest temperature
+ * @status: The status register
+ * @config: The config register
+ * @alert_config: The config for alarm_l output.
+ * @addr: The address to read/write for the next cmd.
+ * @alarm: The alarm_l output pin (GPIO)
+ */
+typedef struct SBTSIState {
+SMBusDevice parent;
+
+uint32_t temperature;
+uint32_t limit_low;
+uint32_t limit_high;
+uint8_t status;
+uint8_t config;
+uint8_t alert_config;
+uint8_t addr;
+qemu_irq alarm;
+} SBTSIState;
+
+#define SBTSI_LIMIT_LOW_DEFAULT (0)
+#define SBTSI_LIMIT_HIGH_DEFAULT (560)
+#define SBTSI_MAN_DEFAULT (0)
+#define SBTSI_REV_DEFAULT (4)
+#define SBTSI_ALARM_L "alarm_l"
+
+/*
+ * The integer part and decimal of the temperature both 8 bits.
+ * Only the top 3 bits of the decimal parts are used.
+ * So the max temperature is (2^8-1) + (2^3-1)/8 = 255.875 degrees.
+ */
+#define SBTSI_TEMP_MAX_IN_MILLIDEGREE 255875
+
+/* The integer part of the temperature in terms of 0.125 degrees. */
+static uint8_t get_temp_int(uint32_t temp)
+{
+return temp >> 3;
+}
+
+/*
+ * The decimal part of the temperature, in terms of 0.125 degrees.
+ * H/W store it in the top 3 bits so we shift it by 5.
+ */
+static uint8_t get_temp_dec(uint32_t temp)
+{
+return (temp & 0x7) << 5;
+}
+
+/*
+ * Compute the temperature using the integer and decimal part,
+ * in terms of 0.125 degrees. The decimal part are only the top 3 bits
+ * so we shift it by 5 here.
+ */
+static uint32_t compute_temp(uint8_t integer, uint8_t decimal)
+{
+return (integer << 3) + (decimal >> 5);
+}
+
+/* Compute new temp with new int part of the temperature. */
+static uint32_t compute_temp_int(uint32_t temp, uint8_t integer)
+{
+return compute_temp(integer, get_temp_dec(temp));
+}
+
+/* Compute new temp with new dec part of the temperature. */
+static uint32_t compute_temp_dec(uint32_t temp, uint8_t decimal)
+{
+return compute_temp(get_temp_int(temp), decimal);
+}
+
+/* The 

[PATCH v2 0/2] hw/sensor: Add SB-TSI Temperature Sensor Interface

2022-01-12 Thread Patrick Venture
v2:
 * Split the commit into a separate patch for the qtest
 * Moved the common registers into the new header
 * Introduced a new header

Hao Wu (2):
  hw/sensor: Add SB-TSI Temperature Sensor Interface
  tests: add qtest for hw/sensor/sbtsi

 hw/sensor/Kconfig|   4 +
 hw/sensor/meson.build|   1 +
 hw/sensor/tmp_sbtsi.c| 365 +++
 hw/sensor/trace-events   |   5 +
 hw/sensor/trace.h|   1 +
 include/hw/sensor/sbtsi.h|  50 +
 meson.build  |   1 +
 tests/qtest/meson.build  |   1 +
 tests/qtest/tmp_sbtsi-test.c | 161 +++
 9 files changed, 589 insertions(+)
 create mode 100644 hw/sensor/tmp_sbtsi.c
 create mode 100644 hw/sensor/trace-events
 create mode 100644 hw/sensor/trace.h
 create mode 100644 include/hw/sensor/sbtsi.h
 create mode 100644 tests/qtest/tmp_sbtsi-test.c

-- 
2.34.1.575.g55b058a8bb-goog




[PATCH v2 2/2] tests: add qtest for hw/sensor/sbtsi

2022-01-12 Thread Patrick Venture
From: Hao Wu 

Reviewed-by: Doug Evanwqs 
Signed-off-by: Hao Wu 
Signed-off-by: Patrick Venture 
---
 tests/qtest/meson.build  |   1 +
 tests/qtest/tmp_sbtsi-test.c | 161 +++
 2 files changed, 162 insertions(+)
 create mode 100644 tests/qtest/tmp_sbtsi-test.c

diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 37e1eaa449..d1a8c38f74 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -254,6 +254,7 @@ qos_test_ss.add(
   'spapr-phb-test.c',
   'tmp105-test.c',
   'emc141x-test.c',
+  'tmp_sbtsi-test.c',
   'usb-hcd-ohci-test.c',
   'virtio-test.c',
   'virtio-blk-test.c',
diff --git a/tests/qtest/tmp_sbtsi-test.c b/tests/qtest/tmp_sbtsi-test.c
new file mode 100644
index 00..ff1e193739
--- /dev/null
+++ b/tests/qtest/tmp_sbtsi-test.c
@@ -0,0 +1,161 @@
+/*
+ * QTests for the SBTSI temperature sensor
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "libqtest-single.h"
+#include "libqos/qgraph.h"
+#include "libqos/i2c.h"
+#include "qapi/qmp/qdict.h"
+#include "qemu/bitops.h"
+#include "hw/sensor/sbtsi.h"
+
+#define TEST_ID   "sbtsi-test"
+#define TEST_ADDR (0x4c)
+
+/* The temperature stored are in units of 0.125 degrees. */
+#define LIMIT_LOW_IN_MILLIDEGREE (10500)
+#define LIMIT_HIGH_IN_MILLIDEGREE (55125)
+
+static uint32_t qmp_sbtsi_get_temperature(const char *id)
+{
+QDict *response;
+int ret;
+
+response = qmp("{ 'execute': 'qom-get', 'arguments': { 'path': %s, "
+   "'property': 'temperature' } }", id);
+g_assert(qdict_haskey(response, "return"));
+ret = (uint32_t)qdict_get_int(response, "return");
+qobject_unref(response);
+return ret;
+}
+
+static void qmp_sbtsi_set_temperature(const char *id, uint32_t value)
+{
+QDict *response;
+
+response = qmp("{ 'execute': 'qom-set', 'arguments': { 'path': %s, "
+   "'property': 'temperature', 'value': %d } }", id, value);
+g_assert(qdict_haskey(response, "return"));
+qobject_unref(response);
+}
+
+/*
+ * Compute the temperature using the integer and decimal part and return
+ * millidegrees. The decimal part are only the top 3 bits so we shift it by
+ * 5 here.
+ */
+static uint32_t regs_to_temp(uint8_t integer, uint8_t decimal)
+{
+return ((integer << 3) + (decimal >> 5)) * SBTSI_TEMP_UNIT_IN_MILLIDEGREE;
+}
+
+/*
+ * Compute the integer and decimal parts of the temperature in millidegrees.
+ * H/W store the decimal in the top 3 bits so we shift it by 5.
+ */
+static void temp_to_regs(uint32_t temp, uint8_t *integer, uint8_t *decimal)
+{
+temp /= SBTSI_TEMP_UNIT_IN_MILLIDEGREE;
+*integer = temp >> 3;
+*decimal = (temp & 0x7) << 5;
+}
+
+static void tx_rx(void *obj, void *data, QGuestAllocator *alloc)
+{
+uint16_t value;
+uint8_t integer, decimal;
+QI2CDevice *i2cdev = (QI2CDevice *)obj;
+
+/* Test default values */
+value = qmp_sbtsi_get_temperature(TEST_ID);
+g_assert_cmpuint(value, ==, 0);
+
+integer = i2c_get8(i2cdev, SBTSI_REG_TEMP_INT);
+decimal = i2c_get8(i2cdev, SBTSI_REG_TEMP_DEC);
+g_assert_cmpuint(regs_to_temp(integer, decimal), ==, 0);
+
+/* Test setting temperature */
+qmp_sbtsi_set_temperature(TEST_ID, 2);
+value = qmp_sbtsi_get_temperature(TEST_ID);
+g_assert_cmpuint(value, ==, 2);
+
+integer = i2c_get8(i2cdev, SBTSI_REG_TEMP_INT);
+decimal = i2c_get8(i2cdev, SBTSI_REG_TEMP_DEC);
+g_assert_cmpuint(regs_to_temp(integer, decimal), ==, 2);
+
+/* Set alert mask in config */
+i2c_set8(i2cdev, SBTSI_REG_CONFIG_WR, SBTSI_CONFIG_ALERT_MASK);
+value = i2c_get8(i2cdev, SBTSI_REG_CONFIG);
+g_assert_cmphex(value, ==, SBTSI_CONFIG_ALERT_MASK);
+/* Enable alarm_en */
+i2c_set8(i2cdev, SBTSI_REG_ALERT_CONFIG, SBTSI_ALARM_EN);
+value = i2c_get8(i2cdev, SBTSI_REG_ALERT_CONFIG);
+g_assert_cmphex(value, ==, SBTSI_ALARM_EN);
+
+/* Test setting limits */
+/* Limit low = 10.500 */
+temp_to_regs(LIMIT_LOW_IN_MILLIDEGREE, , );
+i2c_set8(i2cdev, SBTSI_REG_TEMP_LOW_INT, integer);
+i2c_set8(i2cdev, SBTSI_REG_TEMP_LOW_DEC, decimal);
+integer = i2c_get8(i2cdev, SBTSI_REG_TEMP_LOW_INT);
+decimal = i2c_get8(i2cdev, SBTSI_REG_TEMP_LOW_DEC);
+g_assert_cmpuint(
+regs_to_temp(integer, decimal), ==, LIMIT_LOW_IN_MILLIDEGREE);
+/* Limit high = 55.125 */
+temp_to_regs(LIMIT_HIGH_IN_MILLIDEGREE, , );
+i2c_set8(i2cdev, 

Re: [RFC PATCH] MAINTAINERS: Add myself to s390 I/O areas

2022-01-12 Thread Halil Pasic
On Wed, 12 Jan 2022 17:40:44 +0100
Eric Farman  wrote:

> After the recent restructuring, I'd like to volunteer to help
> in some of the s390 I/O areas.
> 
> Built on "[PATCH RFC v2] MAINTAINERS: split out s390x sections"
> 
> Signed-off-by: Eric Farman 

Acked-by: Halil Pasic 

Thanks!

> ---
>  MAINTAINERS | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 5d37b0eec5..343f43e83d 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1521,6 +1521,7 @@ S390 Machines
>  S390 Virtio-ccw
>  M: Halil Pasic 
>  M: Christian Borntraeger 
> +M: Eric Farman 
>  S: Supported
>  F: hw/s390x/
>  F: include/hw/s390x/
> @@ -1551,6 +1552,7 @@ L: qemu-s3...@nongnu.org
>  S390 channel subsystem
>  M: Halil Pasic 
>  M: Christian Borntraeger 
> +M: Eric Farman 
>  S: Supported
>  F: hw/s390x/ccw-device.[ch]
>  F: hw/s390x/css.c
> @@ -1975,6 +1977,7 @@ T: git https://github.com/stefanha/qemu.git block
>  virtio-ccw
>  M: Cornelia Huck 
>  M: Halil Pasic 
> +M: Eric Farman 
>  S: Supported
>  F: hw/s390x/virtio-ccw*.[hc]
>  F: hw/s390x/vhost-vsock-ccw.c




[PATCH 3/3] isa/piix4: Resolve global variables

2022-01-12 Thread Bernhard Beschow
Now that piix4_set_irq's opaque parameter references own PIIX4State,
piix4_dev becomes redundant and pci_irq_levels can be moved into PIIX4State.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/piix4.c| 22 +-
 include/hw/southbridge/piix.h |  2 --
 2 files changed, 9 insertions(+), 15 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index a31e9714cf..964e09cf7f 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -39,14 +39,14 @@
 #include "sysemu/runstate.h"
 #include "qom/object.h"
 
-PCIDevice *piix4_dev;
-
 struct PIIX4State {
 PCIDevice dev;
 qemu_irq cpu_intr;
 qemu_irq *isa;
 qemu_irq i8259[ISA_NUM_IRQS];
 
+int pci_irq_levels[PIIX_NUM_PIRQS];
+
 RTCState rtc;
 /* Reset Control Register */
 MemoryRegion rcr_mem;
@@ -55,24 +55,22 @@ struct PIIX4State {
 
 OBJECT_DECLARE_SIMPLE_TYPE(PIIX4State, PIIX4_PCI_DEVICE)
 
-static int pci_irq_levels[4];
-
 static void piix4_set_irq(void *opaque, int irq_num, int level)
 {
 int i, pic_irq, pic_level;
 PIIX4State *s = opaque;
 
-pci_irq_levels[irq_num] = level;
+s->pci_irq_levels[irq_num] = level;
 
 /* now we change the pic irq level according to the piix irq mappings */
 /* XXX: optimize */
-pic_irq = piix4_dev->config[PIIX_PIRQCA + irq_num];
-if (pic_irq < 16) {
+pic_irq = s->dev.config[PIIX_PIRQCA + irq_num];
+if (pic_irq < ISA_NUM_IRQS) {
 /* The pic level is the logical OR of all the PCI irqs mapped to it. */
 pic_level = 0;
-for (i = 0; i < 4; i++) {
-if (pic_irq == piix4_dev->config[PIIX_PIRQCA + i]) {
-pic_level |= pci_irq_levels[i];
+for (i = 0; i < PIIX_NUM_PIRQS; i++) {
+if (pic_irq == s->dev.config[PIIX_PIRQCA + i]) {
+pic_level |= s->pci_irq_levels[i];
 }
 }
 qemu_set_irq(s->i8259[pic_irq], pic_level);
@@ -223,8 +221,6 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 return;
 }
 isa_init_irq(ISA_DEVICE(>rtc), >rtc.irq, RTC_ISA_IRQ);
-
-piix4_dev = dev;
 }
 
 static void piix4_init(Object *obj)
@@ -323,7 +319,7 @@ DeviceState *piix4_create(PCIBus *pci_bus, ISABus 
**isa_bus, I2CBus **smbus)
NULL, 0, NULL);
 }
 
-pci_bus_irqs(pci_bus, piix4_set_irq, pci_slot_get_pirq, s, 4);
+pci_bus_irqs(pci_bus, piix4_set_irq, pci_slot_get_pirq, s, PIIX_NUM_PIRQS);
 
 for (int i = 0; i < ISA_NUM_IRQS; i++) {
 s->i8259[i] = qdev_get_gpio_in_named(dev, "isa", i);
diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index 6387f2b612..f63f83e5c6 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -70,8 +70,6 @@ typedef struct PIIXState PIIX3State;
 DECLARE_INSTANCE_CHECKER(PIIX3State, PIIX3_PCI_DEVICE,
  TYPE_PIIX3_PCI_DEVICE)
 
-extern PCIDevice *piix4_dev;
-
 PIIX3State *piix3_create(PCIBus *pci_bus, ISABus **isa_bus);
 
 DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_bus, I2CBus **smbus);
-- 
2.34.1




[PATCH 2/3] pci: Always pass own DeviceState to pci_map_irq_fn's

2022-01-12 Thread Bernhard Beschow
Passing own DeviceState rather than just the IRQs allows for resolving
global variables.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/piix4.c  | 6 +++---
 hw/pci-host/sh_pci.c| 6 +++---
 hw/pci-host/versatile.c | 6 +++---
 hw/ppc/ppc440_pcix.c| 6 +++---
 hw/ppc/ppc4xx_pci.c | 6 +++---
 5 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 5a86308689..a31e9714cf 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -60,7 +60,7 @@ static int pci_irq_levels[4];
 static void piix4_set_irq(void *opaque, int irq_num, int level)
 {
 int i, pic_irq, pic_level;
-qemu_irq *pic = opaque;
+PIIX4State *s = opaque;
 
 pci_irq_levels[irq_num] = level;
 
@@ -75,7 +75,7 @@ static void piix4_set_irq(void *opaque, int irq_num, int 
level)
 pic_level |= pci_irq_levels[i];
 }
 }
-qemu_set_irq(pic[pic_irq], pic_level);
+qemu_set_irq(s->i8259[pic_irq], pic_level);
 }
 }
 
@@ -323,7 +323,7 @@ DeviceState *piix4_create(PCIBus *pci_bus, ISABus 
**isa_bus, I2CBus **smbus)
NULL, 0, NULL);
 }
 
-pci_bus_irqs(pci_bus, piix4_set_irq, pci_slot_get_pirq, s->i8259, 4);
+pci_bus_irqs(pci_bus, piix4_set_irq, pci_slot_get_pirq, s, 4);
 
 for (int i = 0; i < ISA_NUM_IRQS; i++) {
 s->i8259[i] = qdev_get_gpio_in_named(dev, "isa", i);
diff --git a/hw/pci-host/sh_pci.c b/hw/pci-host/sh_pci.c
index 719d6ca2a6..ae0aa462b3 100644
--- a/hw/pci-host/sh_pci.c
+++ b/hw/pci-host/sh_pci.c
@@ -111,9 +111,9 @@ static int sh_pci_map_irq(PCIDevice *d, int irq_num)
 
 static void sh_pci_set_irq(void *opaque, int irq_num, int level)
 {
-qemu_irq *pic = opaque;
+SHPCIState *s = opaque;
 
-qemu_set_irq(pic[irq_num], level);
+qemu_set_irq(s->irq[irq_num], level);
 }
 
 static void sh_pci_device_realize(DeviceState *dev, Error **errp)
@@ -128,7 +128,7 @@ static void sh_pci_device_realize(DeviceState *dev, Error 
**errp)
 }
 phb->bus = pci_register_root_bus(dev, "pci",
  sh_pci_set_irq, sh_pci_map_irq,
- s->irq,
+ s,
  get_system_memory(),
  get_system_io(),
  PCI_DEVFN(0, 0), 4, TYPE_PCI_BUS);
diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
index f66384fa02..5fbcb72d7d 100644
--- a/hw/pci-host/versatile.c
+++ b/hw/pci-host/versatile.c
@@ -362,9 +362,9 @@ static int pci_vpb_rv_map_irq(PCIDevice *d, int irq_num)
 
 static void pci_vpb_set_irq(void *opaque, int irq_num, int level)
 {
-qemu_irq *pic = opaque;
+PCIVPBState *s = opaque;
 
-qemu_set_irq(pic[irq_num], level);
+qemu_set_irq(s->irq[irq_num], level);
 }
 
 static void pci_vpb_reset(DeviceState *d)
@@ -422,7 +422,7 @@ static void pci_vpb_realize(DeviceState *dev, Error **errp)
 mapfn = pci_vpb_map_irq;
 }
 
-pci_bus_irqs(>pci_bus, pci_vpb_set_irq, mapfn, s->irq, 4);
+pci_bus_irqs(>pci_bus, pci_vpb_set_irq, mapfn, s, 4);
 
 /* Our memory regions are:
  * 0 : our control registers
diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c
index 788d25514a..291c1bfbe7 100644
--- a/hw/ppc/ppc440_pcix.c
+++ b/hw/ppc/ppc440_pcix.c
@@ -431,14 +431,14 @@ static int ppc440_pcix_map_irq(PCIDevice *pci_dev, int 
irq_num)
 
 static void ppc440_pcix_set_irq(void *opaque, int irq_num, int level)
 {
-qemu_irq *pci_irq = opaque;
+PPC440PCIXState *s = opaque;
 
 trace_ppc440_pcix_set_irq(irq_num);
 if (irq_num < 0) {
 error_report("%s: PCI irq %d", __func__, irq_num);
 return;
 }
-qemu_set_irq(*pci_irq, level);
+qemu_set_irq(s->irq, level);
 }
 
 static AddressSpace *ppc440_pcix_set_iommu(PCIBus *b, void *opaque, int devfn)
@@ -492,7 +492,7 @@ static void ppc440_pcix_realize(DeviceState *dev, Error 
**errp)
 sysbus_init_irq(sbd, >irq);
 memory_region_init(>busmem, OBJECT(dev), "pci bus memory", UINT64_MAX);
 h->bus = pci_register_root_bus(dev, NULL, ppc440_pcix_set_irq,
- ppc440_pcix_map_irq, >irq, >busmem,
+ ppc440_pcix_map_irq, s, >busmem,
  get_system_io(), PCI_DEVFN(0, 0), 1, TYPE_PCI_BUS);
 
 s->dev = pci_create_simple(h->bus, PCI_DEVFN(0, 0), "ppc4xx-host-bridge");
diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c
index 5df97e6d15..f6718746a1 100644
--- a/hw/ppc/ppc4xx_pci.c
+++ b/hw/ppc/ppc4xx_pci.c
@@ -256,11 +256,11 @@ static int ppc4xx_pci_map_irq(PCIDevice *pci_dev, int 
irq_num)
 
 static void ppc4xx_pci_set_irq(void *opaque, int irq_num, int level)
 {
-qemu_irq *pci_irqs = opaque;
+PPC4xxPCIState *s = opaque;
 
 trace_ppc4xx_pci_set_irq(irq_num);
 assert(irq_num >= 0 && irq_num < PPC4xx_PCI_NUM_DEVS);
-qemu_set_irq(pci_irqs[irq_num], level);
+qemu_set_irq(s->irq[irq_num], 

[PATCH 1/3] malta: Move PCI interrupt handling from gt64xxx to piix4

2022-01-12 Thread Bernhard Beschow
Handling PCI interrupts in piix4 increases cohesion and reduces differences
between piix4 and piix3.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/piix4.c | 58 +++
 hw/mips/gt64xxx_pci.c  | 62 --
 hw/mips/malta.c|  6 +---
 include/hw/mips/mips.h |  2 +-
 4 files changed, 65 insertions(+), 63 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 0fe7b69bc4..5a86308689 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -45,6 +45,7 @@ struct PIIX4State {
 PCIDevice dev;
 qemu_irq cpu_intr;
 qemu_irq *isa;
+qemu_irq i8259[ISA_NUM_IRQS];
 
 RTCState rtc;
 /* Reset Control Register */
@@ -54,6 +55,30 @@ struct PIIX4State {
 
 OBJECT_DECLARE_SIMPLE_TYPE(PIIX4State, PIIX4_PCI_DEVICE)
 
+static int pci_irq_levels[4];
+
+static void piix4_set_irq(void *opaque, int irq_num, int level)
+{
+int i, pic_irq, pic_level;
+qemu_irq *pic = opaque;
+
+pci_irq_levels[irq_num] = level;
+
+/* now we change the pic irq level according to the piix irq mappings */
+/* XXX: optimize */
+pic_irq = piix4_dev->config[PIIX_PIRQCA + irq_num];
+if (pic_irq < 16) {
+/* The pic level is the logical OR of all the PCI irqs mapped to it. */
+pic_level = 0;
+for (i = 0; i < 4; i++) {
+if (pic_irq == piix4_dev->config[PIIX_PIRQCA + i]) {
+pic_level |= pci_irq_levels[i];
+}
+}
+qemu_set_irq(pic[pic_irq], pic_level);
+}
+}
+
 static void piix4_isa_reset(DeviceState *dev)
 {
 PIIX4State *d = PIIX4_PCI_DEVICE(dev);
@@ -248,8 +273,34 @@ static void piix4_register_types(void)
 
 type_init(piix4_register_types)
 
+static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
+{
+int slot;
+
+slot = PCI_SLOT(pci_dev->devfn);
+
+switch (slot) {
+/* PIIX4 USB */
+case 10:
+return 3;
+/* AMD 79C973 Ethernet */
+case 11:
+return 1;
+/* Crystal 4281 Sound */
+case 12:
+return 2;
+/* PCI slot 1 to 4 */
+case 18 ... 21:
+return ((slot - 18) + irq_num) & 0x03;
+/* Unknown device, don't do any translation */
+default:
+return irq_num;
+}
+}
+
 DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_bus, I2CBus **smbus)
 {
+PIIX4State *s;
 PCIDevice *pci;
 DeviceState *dev;
 int devfn = PCI_DEVFN(10, 0);
@@ -257,6 +308,7 @@ DeviceState *piix4_create(PCIBus *pci_bus, ISABus 
**isa_bus, I2CBus **smbus)
 pci = pci_create_simple_multifunction(pci_bus, devfn,  true,
   TYPE_PIIX4_PCI_DEVICE);
 dev = DEVICE(pci);
+s = PIIX4_PCI_DEVICE(pci);
 if (isa_bus) {
 *isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
 }
@@ -271,5 +323,11 @@ DeviceState *piix4_create(PCIBus *pci_bus, ISABus 
**isa_bus, I2CBus **smbus)
NULL, 0, NULL);
 }
 
+pci_bus_irqs(pci_bus, piix4_set_irq, pci_slot_get_pirq, s->i8259, 4);
+
+for (int i = 0; i < ISA_NUM_IRQS; i++) {
+s->i8259[i] = qdev_get_gpio_in_named(dev, "isa", i);
+}
+
 return dev;
 }
diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
index c7480bd019..9e23e32eff 100644
--- a/hw/mips/gt64xxx_pci.c
+++ b/hw/mips/gt64xxx_pci.c
@@ -981,56 +981,6 @@ static const MemoryRegionOps isd_mem_ops = {
 },
 };
 
-static int gt64120_pci_map_irq(PCIDevice *pci_dev, int irq_num)
-{
-int slot;
-
-slot = PCI_SLOT(pci_dev->devfn);
-
-switch (slot) {
-/* PIIX4 USB */
-case 10:
-return 3;
-/* AMD 79C973 Ethernet */
-case 11:
-return 1;
-/* Crystal 4281 Sound */
-case 12:
-return 2;
-/* PCI slot 1 to 4 */
-case 18 ... 21:
-return ((slot - 18) + irq_num) & 0x03;
-/* Unknown device, don't do any translation */
-default:
-return irq_num;
-}
-}
-
-static int pci_irq_levels[4];
-
-static void gt64120_pci_set_irq(void *opaque, int irq_num, int level)
-{
-int i, pic_irq, pic_level;
-qemu_irq *pic = opaque;
-
-pci_irq_levels[irq_num] = level;
-
-/* now we change the pic irq level according to the piix irq mappings */
-/* XXX: optimize */
-pic_irq = piix4_dev->config[PIIX_PIRQCA + irq_num];
-if (pic_irq < 16) {
-/* The pic level is the logical OR of all the PCI irqs mapped to it. */
-pic_level = 0;
-for (i = 0; i < 4; i++) {
-if (pic_irq == piix4_dev->config[PIIX_PIRQCA + i]) {
-pic_level |= pci_irq_levels[i];
-}
-}
-qemu_set_irq(pic[pic_irq], pic_level);
-}
-}
-
-
 static void gt64120_reset(DeviceState *dev)
 {
 GT64120State *s = GT64120_PCI_HOST_BRIDGE(dev);
@@ -1207,7 +1157,7 @@ static void gt64120_realize(DeviceState *dev, Error 
**errp)
   "gt64120-isd", 0x1000);
 }
 
-PCIBus *gt64120_register(qemu_irq *pic)
+PCIBus *gt64120_register(void)
 {
 

[PATCH 0/3] malta: Move PCI interrupt handling from gt64xxx to piix4

2022-01-12 Thread Bernhard Beschow
Hi,

first-time contributor here. Inspired by an article in LWN [1] I figured I'd
get my hands dirty with QEMU development. According to the article my goal is
to eliminate some "accidental complexity".

While studying the code I noticed some (accidental?) differences between piix3
and piix4 where the PCI interrupts are handled. Moreover, I noticed presence of
global variables in piix4 which probably constitute a limitation of QOM's idea
of configuration-driven machine creation. By applying piix3 concepts, i.e.
moving the interrupt handling from gt64xxx to piix4, it's possible to both
eliminate the differences and resolve the global variables.

The patch series is structured as follows: Patch 1 eliminates the differences,
patch 3 resolves the global variables. Patch 2 is a preparation for patch 3.
Some of my further comments regarding the patches are:

Patch 1:
* pci_slot_get_pirq() looks quite malta-specific. Neither gt64xxx nor piix4
  seem to be the perfect fit. So I moved it to piix4, analogous to piix3.
* The i8259 property moved from MaltaState to PIIX4State looks quite redundant
  to the isa property. Could isa be used instead, eliminating i8259?

Patch 2:
* Besides piix4, there were four further cases where the PIC array was passed
  as the opaque parameter to the pci_map_irq_fn's. AFAICS in all other cases
  the DeviceState is passed instead. With this patch, consistency is
  esablished.
* Passing PIIX4State to piix4_set_irq() paves the way for eliminating all
  global variables left in piix4.c (see patch 3).

Comments welcome.

Cheers
Bernhard

[1] https://lwn.net/Articles/872321/

Bernhard Beschow (3):
  malta: Move PCI interrupt handling from gt64xxx to piix4
  pci: Always pass own DeviceState to pci_map_irq_fn's
  isa/piix4: Resolve global variables

 hw/isa/piix4.c| 62 ---
 hw/mips/gt64xxx_pci.c | 62 +++
 hw/mips/malta.c   |  6 +---
 hw/pci-host/sh_pci.c  |  6 ++--
 hw/pci-host/versatile.c   |  6 ++--
 hw/ppc/ppc440_pcix.c  |  6 ++--
 hw/ppc/ppc4xx_pci.c   |  6 ++--
 include/hw/mips/mips.h|  2 +-
 include/hw/southbridge/piix.h |  2 --
 9 files changed, 77 insertions(+), 81 deletions(-)

-- 
2.34.1




Re: [PATCH 5/5] hw/display/artist: Fix framebuffer access for Linux

2022-01-12 Thread Philippe Mathieu-Daudé

+Sven

On 12/1/22 22:07, Helge Deller wrote:

This patch fixes two problems which prevented Linux to access the
artist graphics framebuffer:

The check if the framebuffer or the color map should be accessed was
incomplete. By using the vram_read/write_bufidx() functions we now check
correctly if ARTIST_BUFFER_CMAP should be accessed.

The second fix is to correctly calculate the X- and Y-coordinates and
check against the graphics resolution.

With this fix in place, the Linux stifb driver now works correctly,
shows the penguins at bootup and uses the stifb as graphics console.


Cool, could you add a test similar to these?

$ git grep Tux tests/avocado/
tests/avocado/machine_arm_integratorcp.py:69:Boot Linux and 
verify the Tux logo is displayed on the framebuffer.
tests/avocado/machine_mips_malta.py:44:Boot Linux kernel and 
check Tux logo is displayed on the framebuffer.



I haven't seen any negative side effects when running HP-UX.

Signed-off-by: Helge Deller 
Cc: qemu-sta...@nongnu.org
---
  hw/display/artist.c | 16 
  1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/display/artist.c b/hw/display/artist.c
index 6384076c60..fbf5525334 100644
--- a/hw/display/artist.c
+++ b/hw/display/artist.c
@@ -1186,7 +1186,7 @@ static void artist_vram_write(void *opaque, hwaddr addr, 
uint64_t val,
  unsigned int offset;
  trace_artist_vram_write(size, addr, val);

-if (s->cmap_bm_access) {
+if (vram_write_bufidx(s) == ARTIST_BUFFER_CMAP) {
  buf = >vram_buffer[ARTIST_BUFFER_CMAP];
  if (addr + 3 < buf->size) {
  *(uint32_t *)(buf->data + addr) = val;
@@ -1195,14 +1195,14 @@ static void artist_vram_write(void *opaque, hwaddr 
addr, uint64_t val,
  }

  buf = vram_write_buffer(s);
-posy = ADDR_TO_Y(addr >> 2);
-posx = ADDR_TO_X(addr >> 2);
+posy = ADDR_TO_Y(addr);
+posx = ADDR_TO_X(addr);

  if (!buf->size) {
  return;
  }

-if (posy > buf->height || posx > buf->width) {
+if (posy >= buf->height || posx >= buf->width) {
  return;
  }

@@ -1242,7 +1242,7 @@ static uint64_t artist_vram_read(void *opaque, hwaddr 
addr, unsigned size)
  uint64_t val;
  unsigned int posy, posx;

-if (s->cmap_bm_access) {
+if (vram_read_bufidx(s) == ARTIST_BUFFER_CMAP) {
  buf = >vram_buffer[ARTIST_BUFFER_CMAP];
  val = 0;
  if (addr < buf->size && addr + 3 < buf->size) {
@@ -1257,10 +1257,10 @@ static uint64_t artist_vram_read(void *opaque, hwaddr 
addr, unsigned size)
  return 0;
  }

-posy = ADDR_TO_Y(addr >> 2);
-posx = ADDR_TO_X(addr >> 2);
+posy = ADDR_TO_Y(addr);
+posx = ADDR_TO_X(addr);

-if (posy > buf->height || posx > buf->width) {
+if (posy >= buf->height || posx >= buf->width) {
  return 0;
  }

--
2.31.1







Re: [RFC qemu.qmp PATCH 00/24] Python: Fork qemu.qmp Python lib into independent repo

2022-01-12 Thread John Snow
On Thu, Dec 16, 2021 at 5:41 AM Daniel P. Berrangé  wrote:
>
> On Wed, Dec 15, 2021 at 04:06:10PM -0500, John Snow wrote:

> > (2) To ask for permission to become the maintainer of a
> > 'qemu-project/qemu.qmp' repository, where I would like to host this
> > subproject.
>
> I'd say we need 3 designated maintainers as a minimum for redundancy.

Let's see how many people we can get to volunteer. If it's part of the
qemu-project umbrella, I assume anyone with access to the entire
project as a whole can step in and re-assign permissions and do
emergency actions as needed, including stsquad, stefanha, etc. That
ought to be enough to get moving. If we want to add anyone for
operational redundancy, I'd be happy to add as many people that
volunteer :)

So: any volunteers? Cleber, Beraldo, Wainer? Anyone else?

I anticipate this to be extremely low traffic after the churn of
splitting it out is done with, it shouldn't be a big daily cost -- but
having some familiarity with the code would be good in case you need
to accept some urgent patches here and there.

--js




Re: [PATCH 1/2] block/rbd: fix handling of holes in .bdrv_co_block_status

2022-01-12 Thread Peter Lieven


> Am 12.01.2022 um 22:06 schrieb Ilya Dryomov :
> 
> On Wed, Jan 12, 2022 at 9:39 PM Peter Lieven  wrote:
>> 
>>> Am 12.01.22 um 10:05 schrieb Ilya Dryomov:
>>> On Mon, Jan 10, 2022 at 12:42 PM Peter Lieven  wrote:
 the assumption that we can't hit a hole if we do not diff against a 
 snapshot was wrong.
 
 We can see a hole in an image if we diff against base if there exists an 
 older snapshot
 of the image and we have discarded blocks in the image where the snapshot 
 has data.
 
 Fixes: 0347a8fd4c3faaedf119be04c197804be40a384b
 Cc: qemu-sta...@nongnu.org
 Signed-off-by: Peter Lieven 
 ---
 block/rbd.c | 55 +
 1 file changed, 34 insertions(+), 21 deletions(-)
 
 diff --git a/block/rbd.c b/block/rbd.c
 index def96292e0..5e9dc91d81 100644
 --- a/block/rbd.c
 +++ b/block/rbd.c
 @@ -1279,13 +1279,24 @@ static int qemu_rbd_diff_iterate_cb(uint64_t offs, 
 size_t len,
 RBDDiffIterateReq *req = opaque;
 
 assert(req->offs + req->bytes <= offs);
 -/*
 - * we do not diff against a snapshot so we should never receive a 
 callback
 - * for a hole.
 - */
 -assert(exists);
 
 -if (!req->exists && offs > req->offs) {
 +if (req->exists && offs > req->offs + req->bytes) {
 +/*
 + * we started in an allocated area and jumped over an unallocated 
 area,
 + * req->bytes contains the length of the allocated area before the
 + * unallocated area. stop further processing.
 + */
 +return QEMU_RBD_EXIT_DIFF_ITERATE2;
 +}
 +if (req->exists && !exists) {
 +/*
 + * we started in an allocated area and reached a hole. req->bytes
 + * contains the length of the allocated area before the hole.
 + * stop further processing.
 + */
 +return QEMU_RBD_EXIT_DIFF_ITERATE2;
 +}
 +if (!req->exists && exists && offs > req->offs) {
 /*
  * we started in an unallocated area and hit the first allocated
  * block. req->bytes must be set to the length of the unallocated 
 area
 @@ -1295,17 +1306,19 @@ static int qemu_rbd_diff_iterate_cb(uint64_t offs, 
 size_t len,
 return QEMU_RBD_EXIT_DIFF_ITERATE2;
 }
 
 -if (req->exists && offs > req->offs + req->bytes) {
 -/*
 - * we started in an allocated area and jumped over an unallocated 
 area,
 - * req->bytes contains the length of the allocated area before the
 - * unallocated area. stop further processing.
 - */
 -return QEMU_RBD_EXIT_DIFF_ITERATE2;
 -}
 +/*
 + * assert that we caught all cases above and allocation state has not
 + * changed during callbacks.
 + */
 +assert(exists == req->exists || !req->bytes);
 +req->exists = exists;
 
 -req->bytes += len;
 -req->exists = true;
 +/*
 + * assert that we either return an unallocated block or have got 
 callbacks
 + * for all allocated blocks present.
 + */
 +assert(!req->exists || offs == req->offs + req->bytes);
 +req->bytes = offs + len - req->offs;
 
 return 0;
 }
 @@ -1354,13 +1367,13 @@ static int coroutine_fn 
 qemu_rbd_co_block_status(BlockDriverState *bs,
 }
 assert(req.bytes <= bytes);
 if (!req.exists) {
 -if (r == 0) {
 +if (r == 0 && !req.bytes) {
 /*
 - * rbd_diff_iterate2 does not invoke callbacks for unallocated
 - * areas. This here catches the case where no callback was
 - * invoked at all (req.bytes == 0).
 + * rbd_diff_iterate2 does not invoke callbacks for 
 unallocated areas
 + * except for the case where an overlay has a hole where the 
 parent
 + * or an older snapshot of the image has not. This here 
 catches the
 + * case where no callback was invoked at all.
  */
 -assert(req.bytes == 0);
 req.bytes = bytes;
 }
 status = BDRV_BLOCK_ZERO | BDRV_BLOCK_OFFSET_VALID;
 --
 2.25.1
 
 
>>> Hi Peter,
>>> 
>>> Can we just skip these "holes" by replacing the existing assert with
>>> an if statement that would simply bail from the callback on !exists?
>>> 
>>> Just trying to keep the logic as simple as possible since as it turns
>>> out we get to contend with ages-old librbd bugs here...
>> 
>> 
>> I'm afraid I think this would not work. Consider qemu-img convert.
>> 
>> If we bail out we would immediately call get_block_status with the offset
>> 
>> where we stopped 

Re: [PULL 00/31] testing/next and other misc fixes

2022-01-12 Thread Peter Maydell
On Wed, 12 Jan 2022 at 11:27, Alex Bennée  wrote:
>
> The following changes since commit bf99e0ec9a51976868d7a8334620716df15fe7fe:
>
>   Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging 
> (2022-01-11 10:12:29 +)
>
> are available in the Git repository at:
>
>   https://github.com/stsquad/qemu.git tags/pull-for-7.0-110122-1
>
> for you to fetch changes up to dbd30b7abee963f4fb08892a7d7f920bb76ece58:
>
>   linux-user: Remove the deprecated ppc64abi32 target (2022-01-11 13:00:53 
> +)
>
> 
> Various testing and other misc updates:
>
>   - fix compiler warnings with ui and sdl
>   - update QXL/spice dependancy
>   - skip I/O tests on Alpine
>   - update fedora image to latest version
>   - integrate lcitool and regenerate docker images
>   - favour CONFIG_LINUX_USER over CONFIG_LINUX
>   - add libfuse3 dependencies to docker images
>   - add dtb-kaslr-seed control knob to virt machine
>   - fix build breakage from HMP update
>   - update docs for C standard and suffix usage
>   - add more logging for debugging user hole finding
>   - fix bug with linux-user hold calculation
>   - avoid affecting flags when printing results in float tests
>   - add float reference files for ppc64
>   - update FreeBSD to 12.3
>   - add bison dependancy to tricore images
>   - remove deprecated ppc64abi32 target

This seems to fail the ubuntu-18.04-s390x-all-linux-static job
with segfaults running linux-user binaries (not always the same
binary), eg:
https://gitlab.com/qemu-project/qemu/-/jobs/1968789446
https://gitlab.com/qemu-project/qemu/-/jobs/1968080419


thanks
-- PMM



[PATCH 4/5] hw/display/artist: Mouse cursor fixes for HP-UX

2022-01-12 Thread Helge Deller
This patch fix the behaviour and positioning of the X11 mouse cursor in HP-UX.

The current code missed to subtract the offset of the CURSOR_CTRL register from
the current mouse cursor position. The HP-UX graphics driver stores in this
register the offset of the mouse graphics compared to the current cursor
position.  Without this adjustment the mouse behaves strange at the screen
borders.

Additionally, depending on the HP-UX version, the mouse cursor position
in the cursor_pos register reports different values. To accommodate this
track the current min and max reported values and auto-adjust at runtime.

With this fix the mouse now behaves as expected on HP-UX 10 and 11.

Signed-off-by: Helge Deller 
Cc: qemu-sta...@nongnu.org
---
 hw/display/artist.c | 42 ++
 1 file changed, 34 insertions(+), 8 deletions(-)

diff --git a/hw/display/artist.c b/hw/display/artist.c
index 21b7fd1b44..6384076c60 100644
--- a/hw/display/artist.c
+++ b/hw/display/artist.c
@@ -80,6 +80,7 @@ struct ARTISTState {
 uint32_t line_pattern_skip;

 uint32_t cursor_pos;
+uint32_t cursor_cntrl;

 uint32_t cursor_height;
 uint32_t cursor_width;
@@ -328,19 +329,42 @@ static void artist_get_cursor_pos(ARTISTState *s, int *x, 
int *y)
 {
 /*
  * Don't know whether these magic offset values are configurable via
- * some register. They are the same for all resolutions, so don't
- * bother about it.
+ * some register. They seem to be the same for all resolutions.
+ * The cursor values provided in the registers are:
+ * X-value: -295 (for HP-UX 11) and 338 (for HP-UX 10.20) up to 2265
+ * Y-value: 1146 down to 0
+ * The emulated Artist graphic is like a CRX graphic, and as such
+ * it's usually fixed at 1280x1024 pixels.
+ * Because of the maximum Y-value of 1146 you can not choose a higher
+ * vertical resolution on HP-UX (unless you disable the mouse).
  */

-*y = 0x47a - artist_get_y(s->cursor_pos);
-*x = ((artist_get_x(s->cursor_pos) - 338) / 2);
+static int offset = 338;
+int lx;
+
+/* ignore if uninitialized */
+if (s->cursor_pos == 0) {
+*x = *y = 0;
+return;
+}
+
+lx = artist_get_x(s->cursor_pos);
+if (lx < offset)
+offset = lx;
+*x = (lx - offset) / 2;
+
+*y = 1146 - artist_get_y(s->cursor_pos);
+
+/* subtract cursor offset from cursor control register */
+*x -= (s->cursor_cntrl & 0xf0) >> 4;
+*y -= (s->cursor_cntrl & 0x0f);

 if (*x > s->width) {
-*x = 0;
+*x = s->width;
 }

 if (*y > s->height) {
-*y = 0;
+*y = s->height;
 }
 }

@@ -1034,6 +1058,7 @@ static void artist_reg_write(void *opaque, hwaddr addr, 
uint64_t val,
 break;

 case CURSOR_CTRL:
+combine_write_reg(addr, val, size, >cursor_cntrl);
 break;

 case IMAGE_BITMAP_OP:
@@ -1422,8 +1447,8 @@ static int vmstate_artist_post_load(void *opaque, int 
version_id)

 static const VMStateDescription vmstate_artist = {
 .name = "artist",
-.version_id = 1,
-.minimum_version_id = 1,
+.version_id = 2,
+.minimum_version_id = 2,
 .post_load = vmstate_artist_post_load,
 .fields = (VMStateField[]) {
 VMSTATE_UINT16(height, ARTISTState),
@@ -1443,6 +1468,7 @@ static const VMStateDescription vmstate_artist = {
 VMSTATE_UINT32(line_end, ARTISTState),
 VMSTATE_UINT32(line_xy, ARTISTState),
 VMSTATE_UINT32(cursor_pos, ARTISTState),
+VMSTATE_UINT32(cursor_cntrl, ARTISTState),
 VMSTATE_UINT32(cursor_height, ARTISTState),
 VMSTATE_UINT32(cursor_width, ARTISTState),
 VMSTATE_UINT32(plane_mask, ARTISTState),
--
2.31.1




[PATCH 5/5] hw/display/artist: Fix framebuffer access for Linux

2022-01-12 Thread Helge Deller
This patch fixes two problems which prevented Linux to access the
artist graphics framebuffer:

The check if the framebuffer or the color map should be accessed was
incomplete. By using the vram_read/write_bufidx() functions we now check
correctly if ARTIST_BUFFER_CMAP should be accessed.

The second fix is to correctly calculate the X- and Y-coordinates and
check against the graphics resolution.

With this fix in place, the Linux stifb driver now works correctly,
shows the penguins at bootup and uses the stifb as graphics console.
I haven't seen any negative side effects when running HP-UX.

Signed-off-by: Helge Deller 
Cc: qemu-sta...@nongnu.org
---
 hw/display/artist.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/display/artist.c b/hw/display/artist.c
index 6384076c60..fbf5525334 100644
--- a/hw/display/artist.c
+++ b/hw/display/artist.c
@@ -1186,7 +1186,7 @@ static void artist_vram_write(void *opaque, hwaddr addr, 
uint64_t val,
 unsigned int offset;
 trace_artist_vram_write(size, addr, val);

-if (s->cmap_bm_access) {
+if (vram_write_bufidx(s) == ARTIST_BUFFER_CMAP) {
 buf = >vram_buffer[ARTIST_BUFFER_CMAP];
 if (addr + 3 < buf->size) {
 *(uint32_t *)(buf->data + addr) = val;
@@ -1195,14 +1195,14 @@ static void artist_vram_write(void *opaque, hwaddr 
addr, uint64_t val,
 }

 buf = vram_write_buffer(s);
-posy = ADDR_TO_Y(addr >> 2);
-posx = ADDR_TO_X(addr >> 2);
+posy = ADDR_TO_Y(addr);
+posx = ADDR_TO_X(addr);

 if (!buf->size) {
 return;
 }

-if (posy > buf->height || posx > buf->width) {
+if (posy >= buf->height || posx >= buf->width) {
 return;
 }

@@ -1242,7 +1242,7 @@ static uint64_t artist_vram_read(void *opaque, hwaddr 
addr, unsigned size)
 uint64_t val;
 unsigned int posy, posx;

-if (s->cmap_bm_access) {
+if (vram_read_bufidx(s) == ARTIST_BUFFER_CMAP) {
 buf = >vram_buffer[ARTIST_BUFFER_CMAP];
 val = 0;
 if (addr < buf->size && addr + 3 < buf->size) {
@@ -1257,10 +1257,10 @@ static uint64_t artist_vram_read(void *opaque, hwaddr 
addr, unsigned size)
 return 0;
 }

-posy = ADDR_TO_Y(addr >> 2);
-posx = ADDR_TO_X(addr >> 2);
+posy = ADDR_TO_Y(addr);
+posx = ADDR_TO_X(addr);

-if (posy > buf->height || posx > buf->width) {
+if (posy >= buf->height || posx >= buf->width) {
 return 0;
 }

--
2.31.1




[PATCH 2/5] hw/hppa: Allow up to 16 emulated CPUs

2022-01-12 Thread Helge Deller
This brings the hppa_hardware.h file in sync with the copy in the
SeaBIOS-hppa sources.

In order to support up to 16 CPUs, it's required to move the HPA for
MEMORY_HPA out of the address space of the 16th CPU.

Signed-off-by: Helge Deller 
---
 hw/hppa/hppa_hardware.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/hppa/hppa_hardware.h b/hw/hppa/hppa_hardware.h
index bc258895c9..5edf577563 100644
--- a/hw/hppa/hppa_hardware.h
+++ b/hw/hppa/hppa_hardware.h
@@ -25,7 +25,7 @@
 #define LASI_GFX_HPA0xf800
 #define ARTIST_FB_ADDR  0xf900
 #define CPU_HPA 0xfffb
-#define MEMORY_HPA  0xfffbf000
+#define MEMORY_HPA  0xf000

 #define PCI_HPA DINO_HPA/* PCI bus */
 #define IDE_HPA 0xf900  /* Boot disc controller */
@@ -43,9 +43,10 @@
 #define PORT_SERIAL1(DINO_UART_HPA + 0x800)
 #define PORT_SERIAL2(LASI_UART_HPA + 0x800)

-#define HPPA_MAX_CPUS   8   /* max. number of SMP CPUs */
+#define HPPA_MAX_CPUS   16  /* max. number of SMP CPUs */
 #define CPU_CLOCK_MHZ   250 /* emulate a 250 MHz CPU */

 #define CPU_HPA_CR_REG  7   /* store CPU HPA in cr7 (SeaBIOS internal) */
+#define PIM_STORAGE_SIZE 600   /* storage size of pdc_pim_toc_struct (64bit) */

 #endif
--
2.31.1




[PATCH 0/5] Fixes and updates for hppa target

2022-01-12 Thread Helge Deller
This patchset fixes some important bugs in the hppa artist graphics driver:
- Fix framebuffer access for Linux
- Mouse cursor fixes for HP-UX

New qemu features for hppa:
- Allow up to 16 emulated CPUs (instead of 8)
- Add support for an emulated TOC/NMI button

A new Seabios-hppa firmware:
- Update SeaBIOS-hppa to VERSION 3
- New opt/hostid fw_cfg option to change hostid
- Add opt/console fw_cfg option to select default console
- Added 16x32 font to STI firmware

Signed-off-by: Helge Deller 

Helge Deller (5):
  seabios-hppa: Update SeaBIOS-hppa to VERSION 3
  hw/hppa: Allow up to 16 emulated CPUs
  hppa: Add support for an emulated TOC/NMI button.
  hw/display/artist: Mouse cursor fixes for HP-UX
  hw/display/artist: Fix framebuffer access for Linux

 hw/display/artist.c   |  58 +++---
 hw/hppa/hppa_hardware.h   |   5 ++--
 hw/hppa/machine.c |  35 ++-
 pc-bios/hppa-firmware.img | Bin 757144 -> 701964 bytes
 roms/seabios-hppa |   2 +-
 target/hppa/cpu.c |   2 +-
 target/hppa/cpu.h |   5 
 target/hppa/helper.h  |   1 +
 target/hppa/insns.decode  |   1 +
 target/hppa/int_helper.c  |  19 -
 target/hppa/op_helper.c   |   7 -
 target/hppa/translate.c   |  10 +++
 12 files changed, 122 insertions(+), 23 deletions(-)

-- 
2.31.1




[PATCH 3/5] hppa: Add support for an emulated TOC/NMI button.

2022-01-12 Thread Helge Deller
Almost all PA-RISC machines have either a button that is labeled with 'TOC' or
a BMC/GSP function to trigger a TOC.  TOC is a non-maskable interrupt that is
sent to the processor.  This can be used for diagnostic purposes like obtaining
a stack trace/register dump or to enter KDB/KGDB in Linux.

This patch adds support for such an emulated TOC button.

It wires up the qemu monitor "nmi" command to trigger a TOC.  For that it
provides the hppa_nmi function which is assigned to the nmi_monitor_handler
function pointer.  When called it raises the EXCP_TOC hardware interrupt in the
hppa_cpu_do_interrupt() function.  The interrupt function then calls the
architecturally defined TOC function in SeaBIOS-hppa firmware (at fixed address
0xf000).

According to the PA-RISC PDC specification, the SeaBIOS firmware then writes
the CPU registers into PIM (processor internal memmory) for later analysis.  In
order to write all registers it needs to know the contents of the CPU "shadow
registers" and the IASQ- and IAOQ-back values. The IAOQ/IASQ values are
provided by qemu in shadow registers when entering the SeaBIOS TOC function.
This patch adds a new aritificial opcode "getshadowregs" (0xfffdead2) which
restores the original values of the shadow registers. With this opcode SeaBIOS
can store those registers as well into PIM before calling an OS-provided TOC
handler.

To trigger a TOC, switch to the qemu monitor with Ctrl-A C, and type in the
command "nmi".  After the TOC started the OS-debugger, exit the qemu monitor
with Ctrl-A C.

Signed-off-by: Helge Deller 
---
 hw/hppa/machine.c| 35 ++-
 target/hppa/cpu.c|  2 +-
 target/hppa/cpu.h|  5 +
 target/hppa/helper.h |  1 +
 target/hppa/insns.decode |  1 +
 target/hppa/int_helper.c | 19 ++-
 target/hppa/op_helper.c  |  7 ++-
 target/hppa/translate.c  | 10 ++
 8 files changed, 76 insertions(+), 4 deletions(-)

diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index 2a46af5bc9..98b30e0395 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -17,6 +17,7 @@
 #include "hw/timer/i8254.h"
 #include "hw/char/serial.h"
 #include "hw/net/lasi_82596.h"
+#include "hw/nmi.h"
 #include "hppa_sys.h"
 #include "qemu/units.h"
 #include "qapi/error.h"
@@ -355,6 +356,14 @@ static void hppa_machine_reset(MachineState *ms)
 cpu[0]->env.gr[19] = FW_CFG_IO_BASE;
 }

+static void hppa_nmi(NMIState *n, int cpu_index, Error **errp)
+{
+CPUState *cs;
+
+CPU_FOREACH(cs) {
+cpu_interrupt(cs, CPU_INTERRUPT_NMI);
+}
+}

 static void machine_hppa_machine_init(MachineClass *mc)
 {
@@ -371,4 +380,28 @@ static void machine_hppa_machine_init(MachineClass *mc)
 mc->default_ram_id = "ram";
 }

-DEFINE_MACHINE("hppa", machine_hppa_machine_init)
+static void machine_hppa_machine_init_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+machine_hppa_machine_init(mc);
+
+NMIClass *nc = NMI_CLASS(oc);
+nc->nmi_monitor_handler = hppa_nmi;
+}
+
+static const TypeInfo machine_hppa_machine_init_typeinfo = {
+.name = ("hppa" "-machine"),
+.parent = "machine",
+.class_init = machine_hppa_machine_init_class_init,
+.interfaces = (InterfaceInfo[]) {
+{ TYPE_NMI },
+{ }
+},
+};
+
+static void machine_hppa_machine_init_register_types(void)
+{
+type_register_static(_hppa_machine_init_typeinfo);
+}
+
+type_init(machine_hppa_machine_init_register_types)
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 23eb254228..37b763fca0 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -62,7 +62,7 @@ static void hppa_cpu_synchronize_from_tb(CPUState *cs,

 static bool hppa_cpu_has_work(CPUState *cs)
 {
-return cs->interrupt_request & CPU_INTERRUPT_HARD;
+return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
 }

 static void hppa_cpu_disas_set_info(CPUState *cs, disassemble_info *info)
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 45fd338b02..93c119532a 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -69,6 +69,11 @@
 #define EXCP_SYSCALL 30
 #define EXCP_SYSCALL_LWS 31

+/* Emulated hardware TOC button */
+#define EXCP_TOC 32 /* TOC = Transfer of control (NMI) */
+
+#define CPU_INTERRUPT_NMI   CPU_INTERRUPT_TGT_EXT_3 /* TOC */
+
 /* Taken from Linux kernel: arch/parisc/include/asm/psw.h */
 #define PSW_I0x0001
 #define PSW_D0x0002
diff --git a/target/hppa/helper.h b/target/hppa/helper.h
index 0a629ffa7c..fe8a9ce493 100644
--- a/target/hppa/helper.h
+++ b/target/hppa/helper.h
@@ -80,6 +80,7 @@ DEF_HELPER_FLAGS_0(read_interval_timer, TCG_CALL_NO_RWG, tr)
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_1(halt, noreturn, env)
 DEF_HELPER_1(reset, noreturn, env)
+DEF_HELPER_1(getshadowregs, void, env)
 DEF_HELPER_1(rfi, void, env)
 DEF_HELPER_1(rfi_r, void, env)
 DEF_HELPER_FLAGS_2(write_interval_timer, 

Re: [PATCH 1/2] block/rbd: fix handling of holes in .bdrv_co_block_status

2022-01-12 Thread Ilya Dryomov
On Wed, Jan 12, 2022 at 9:39 PM Peter Lieven  wrote:
>
> Am 12.01.22 um 10:05 schrieb Ilya Dryomov:
> > On Mon, Jan 10, 2022 at 12:42 PM Peter Lieven  wrote:
> >> the assumption that we can't hit a hole if we do not diff against a 
> >> snapshot was wrong.
> >>
> >> We can see a hole in an image if we diff against base if there exists an 
> >> older snapshot
> >> of the image and we have discarded blocks in the image where the snapshot 
> >> has data.
> >>
> >> Fixes: 0347a8fd4c3faaedf119be04c197804be40a384b
> >> Cc: qemu-sta...@nongnu.org
> >> Signed-off-by: Peter Lieven 
> >> ---
> >>  block/rbd.c | 55 +
> >>  1 file changed, 34 insertions(+), 21 deletions(-)
> >>
> >> diff --git a/block/rbd.c b/block/rbd.c
> >> index def96292e0..5e9dc91d81 100644
> >> --- a/block/rbd.c
> >> +++ b/block/rbd.c
> >> @@ -1279,13 +1279,24 @@ static int qemu_rbd_diff_iterate_cb(uint64_t offs, 
> >> size_t len,
> >>  RBDDiffIterateReq *req = opaque;
> >>
> >>  assert(req->offs + req->bytes <= offs);
> >> -/*
> >> - * we do not diff against a snapshot so we should never receive a 
> >> callback
> >> - * for a hole.
> >> - */
> >> -assert(exists);
> >>
> >> -if (!req->exists && offs > req->offs) {
> >> +if (req->exists && offs > req->offs + req->bytes) {
> >> +/*
> >> + * we started in an allocated area and jumped over an unallocated 
> >> area,
> >> + * req->bytes contains the length of the allocated area before the
> >> + * unallocated area. stop further processing.
> >> + */
> >> +return QEMU_RBD_EXIT_DIFF_ITERATE2;
> >> +}
> >> +if (req->exists && !exists) {
> >> +/*
> >> + * we started in an allocated area and reached a hole. req->bytes
> >> + * contains the length of the allocated area before the hole.
> >> + * stop further processing.
> >> + */
> >> +return QEMU_RBD_EXIT_DIFF_ITERATE2;
> >> +}
> >> +if (!req->exists && exists && offs > req->offs) {
> >>  /*
> >>   * we started in an unallocated area and hit the first allocated
> >>   * block. req->bytes must be set to the length of the unallocated 
> >> area
> >> @@ -1295,17 +1306,19 @@ static int qemu_rbd_diff_iterate_cb(uint64_t offs, 
> >> size_t len,
> >>  return QEMU_RBD_EXIT_DIFF_ITERATE2;
> >>  }
> >>
> >> -if (req->exists && offs > req->offs + req->bytes) {
> >> -/*
> >> - * we started in an allocated area and jumped over an unallocated 
> >> area,
> >> - * req->bytes contains the length of the allocated area before the
> >> - * unallocated area. stop further processing.
> >> - */
> >> -return QEMU_RBD_EXIT_DIFF_ITERATE2;
> >> -}
> >> +/*
> >> + * assert that we caught all cases above and allocation state has not
> >> + * changed during callbacks.
> >> + */
> >> +assert(exists == req->exists || !req->bytes);
> >> +req->exists = exists;
> >>
> >> -req->bytes += len;
> >> -req->exists = true;
> >> +/*
> >> + * assert that we either return an unallocated block or have got 
> >> callbacks
> >> + * for all allocated blocks present.
> >> + */
> >> +assert(!req->exists || offs == req->offs + req->bytes);
> >> +req->bytes = offs + len - req->offs;
> >>
> >>  return 0;
> >>  }
> >> @@ -1354,13 +1367,13 @@ static int coroutine_fn 
> >> qemu_rbd_co_block_status(BlockDriverState *bs,
> >>  }
> >>  assert(req.bytes <= bytes);
> >>  if (!req.exists) {
> >> -if (r == 0) {
> >> +if (r == 0 && !req.bytes) {
> >>  /*
> >> - * rbd_diff_iterate2 does not invoke callbacks for unallocated
> >> - * areas. This here catches the case where no callback was
> >> - * invoked at all (req.bytes == 0).
> >> + * rbd_diff_iterate2 does not invoke callbacks for 
> >> unallocated areas
> >> + * except for the case where an overlay has a hole where the 
> >> parent
> >> + * or an older snapshot of the image has not. This here 
> >> catches the
> >> + * case where no callback was invoked at all.
> >>   */
> >> -assert(req.bytes == 0);
> >>  req.bytes = bytes;
> >>  }
> >>  status = BDRV_BLOCK_ZERO | BDRV_BLOCK_OFFSET_VALID;
> >> --
> >> 2.25.1
> >>
> >>
> > Hi Peter,
> >
> > Can we just skip these "holes" by replacing the existing assert with
> > an if statement that would simply bail from the callback on !exists?
> >
> > Just trying to keep the logic as simple as possible since as it turns
> > out we get to contend with ages-old librbd bugs here...
>
>
> I'm afraid I think this would not work. Consider qemu-img convert.
>
> If we bail out we would immediately call get_block_status with the offset
>
> where we stopped and hit the !exist again.

I'm suggesting bailing from the 

Re: [PATCH 1/2] block/rbd: fix handling of holes in .bdrv_co_block_status

2022-01-12 Thread Peter Lieven
Am 12.01.22 um 10:05 schrieb Ilya Dryomov:
> On Mon, Jan 10, 2022 at 12:42 PM Peter Lieven  wrote:
>> the assumption that we can't hit a hole if we do not diff against a snapshot 
>> was wrong.
>>
>> We can see a hole in an image if we diff against base if there exists an 
>> older snapshot
>> of the image and we have discarded blocks in the image where the snapshot 
>> has data.
>>
>> Fixes: 0347a8fd4c3faaedf119be04c197804be40a384b
>> Cc: qemu-sta...@nongnu.org
>> Signed-off-by: Peter Lieven 
>> ---
>>  block/rbd.c | 55 +
>>  1 file changed, 34 insertions(+), 21 deletions(-)
>>
>> diff --git a/block/rbd.c b/block/rbd.c
>> index def96292e0..5e9dc91d81 100644
>> --- a/block/rbd.c
>> +++ b/block/rbd.c
>> @@ -1279,13 +1279,24 @@ static int qemu_rbd_diff_iterate_cb(uint64_t offs, 
>> size_t len,
>>  RBDDiffIterateReq *req = opaque;
>>
>>  assert(req->offs + req->bytes <= offs);
>> -/*
>> - * we do not diff against a snapshot so we should never receive a 
>> callback
>> - * for a hole.
>> - */
>> -assert(exists);
>>
>> -if (!req->exists && offs > req->offs) {
>> +if (req->exists && offs > req->offs + req->bytes) {
>> +/*
>> + * we started in an allocated area and jumped over an unallocated 
>> area,
>> + * req->bytes contains the length of the allocated area before the
>> + * unallocated area. stop further processing.
>> + */
>> +return QEMU_RBD_EXIT_DIFF_ITERATE2;
>> +}
>> +if (req->exists && !exists) {
>> +/*
>> + * we started in an allocated area and reached a hole. req->bytes
>> + * contains the length of the allocated area before the hole.
>> + * stop further processing.
>> + */
>> +return QEMU_RBD_EXIT_DIFF_ITERATE2;
>> +}
>> +if (!req->exists && exists && offs > req->offs) {
>>  /*
>>   * we started in an unallocated area and hit the first allocated
>>   * block. req->bytes must be set to the length of the unallocated 
>> area
>> @@ -1295,17 +1306,19 @@ static int qemu_rbd_diff_iterate_cb(uint64_t offs, 
>> size_t len,
>>  return QEMU_RBD_EXIT_DIFF_ITERATE2;
>>  }
>>
>> -if (req->exists && offs > req->offs + req->bytes) {
>> -/*
>> - * we started in an allocated area and jumped over an unallocated 
>> area,
>> - * req->bytes contains the length of the allocated area before the
>> - * unallocated area. stop further processing.
>> - */
>> -return QEMU_RBD_EXIT_DIFF_ITERATE2;
>> -}
>> +/*
>> + * assert that we caught all cases above and allocation state has not
>> + * changed during callbacks.
>> + */
>> +assert(exists == req->exists || !req->bytes);
>> +req->exists = exists;
>>
>> -req->bytes += len;
>> -req->exists = true;
>> +/*
>> + * assert that we either return an unallocated block or have got 
>> callbacks
>> + * for all allocated blocks present.
>> + */
>> +assert(!req->exists || offs == req->offs + req->bytes);
>> +req->bytes = offs + len - req->offs;
>>
>>  return 0;
>>  }
>> @@ -1354,13 +1367,13 @@ static int coroutine_fn 
>> qemu_rbd_co_block_status(BlockDriverState *bs,
>>  }
>>  assert(req.bytes <= bytes);
>>  if (!req.exists) {
>> -if (r == 0) {
>> +if (r == 0 && !req.bytes) {
>>  /*
>> - * rbd_diff_iterate2 does not invoke callbacks for unallocated
>> - * areas. This here catches the case where no callback was
>> - * invoked at all (req.bytes == 0).
>> + * rbd_diff_iterate2 does not invoke callbacks for unallocated 
>> areas
>> + * except for the case where an overlay has a hole where the 
>> parent
>> + * or an older snapshot of the image has not. This here catches 
>> the
>> + * case where no callback was invoked at all.
>>   */
>> -assert(req.bytes == 0);
>>  req.bytes = bytes;
>>  }
>>  status = BDRV_BLOCK_ZERO | BDRV_BLOCK_OFFSET_VALID;
>> --
>> 2.25.1
>>
>>
> Hi Peter,
>
> Can we just skip these "holes" by replacing the existing assert with
> an if statement that would simply bail from the callback on !exists?
>
> Just trying to keep the logic as simple as possible since as it turns
> out we get to contend with ages-old librbd bugs here...


I'm afraid I think this would not work. Consider qemu-img convert.

If we bail out we would immediately call get_block_status with the offset

where we stopped and hit the !exist again.


Peter




Re: [PATCH v3 00/31] Python: delete synchronous qemu.qmp package

2022-01-12 Thread John Snow
Hi Hanna, Kevin:

I think this series is pretty close, it's mostly reviewed by Vladimir
and Beraldo. Only patches 22 and 23 touch iotests, and quite
minimally. Everything appears to test fine on my end, but I don't
wanna sneak any changes past you without an ACK.

(OK, admittedly, patch 22 is a touch hacky, and I think I will spend
some time today improving it, but I think it will be a follow-up, if
that's okay.)

Thanks,
--js

On Mon, Jan 10, 2022 at 6:33 PM John Snow  wrote:
>
>
>
> On Mon, Jan 10, 2022 at 6:29 PM John Snow  wrote:
>>
>> Based-on: <20220110232521.1922962-1-js...@redhat.com>
>>   (jsnow/python staging branch)
>
>
> Sorry, I goofed. This series accidentally re-includes these patches. You can 
> ignore the first four patches, or apply directly on top of origin/master. 
> Sorry for the inconvenience.
>
> --js
>
>>
>> GitLab: https://gitlab.com/jsnow/qemu/-/commits/python-qmp-legacy-switch
>> CI: https://gitlab.com/jsnow/qemu/-/pipelines/445163212
>>
>> Hi, this series is part of an effort to publish the qemu.qmp package on
>> PyPI. It is the first of three series to complete this work:
>>
>> --> (1) Switch the new Async QMP library in to python/qemu/qmp
>> (2) Fork python/qemu/qmp out into its own repository,
>> with updated GitLab CI/CD targets to build packages.
>> (3) Update qemu.git to install qemu.qmp from PyPI,
>> and then delete python/qemu/qmp.
>>
>> This series swaps out qemu.qmp for qemu.aqmp permanently, instead of
>> hiding it behind an environment variable toggle. This leaves us with
>> just one QMP library to worry about. It also implements the rename of
>> "qemu.aqmp" to "qemu.qmp".
>>
>> I suspect the most potential disruption to iotest and avocado
>> maintainers, as those two subsystems rely on the QMP features the
>> most. Would appreciate at least an ACK from each of those camps if
>> you're willing to give benefit-of-the-doubt on the actual Python code.
>>
>> V3:
>>  - Rebased on top of jsnow/python (For GitLab CI fixes)
>>  - Added a new patch 001 to fix a typo Vladimir found.
>>  - Tiny change in 006 due to the new patch 001
>>  - Reworded subject of patch 007
>>  - Changed import statement in patch 013 (Vladimir)
>>  - Rebase-related changes in patch 021
>>  - Removed 'aqmp' from internal variable names in 026
>>  - Added new patch to rename aqmp-tui to qmp-tui in 027
>>
>> V2:
>>  - Integrate the renaming of qemu.aqmp to qemu.qmp in this series
>>  - Minor bits and pieces.
>>
>> John Snow (30):
>>   python/aqmp: use absolute import statement
>>   Python/aqmp: fix type definitions for mypy 0.920
>>   python: update type hints for mypy 0.930
>>   python/aqmp: fix docstring typo
>>   python/aqmp: add __del__ method to legacy interface
>>   python/aqmp: handle asyncio.TimeoutError on execute()
>>   python/aqmp: copy type definitions from qmp
>>   python/aqmp: add SocketAddrT to package root
>>   python/aqmp: rename AQMPError to QMPError
>>   python/qemu-ga-client: don't use deprecated CLI syntax in usage
>> comment
>>   python/qmp: switch qemu-ga-client to AQMP
>>   python/qmp: switch qom tools to AQMP
>>   python/qmp: switch qmp-shell to AQMP
>>   python: move qmp utilities to python/qemu/utils
>>   python: move qmp-shell under the AQMP package
>>   python/machine: permanently switch to AQMP
>>   scripts/cpu-x86-uarch-abi: fix CLI parsing
>>   scripts/cpu-x86-uarch-abi: switch to AQMP
>>   scripts/render-block-graph: switch to AQMP
>>   scripts/bench-block-job: switch to AQMP
>>   iotests/mirror-top-perms: switch to AQMP
>>   iotests: switch to AQMP
>>   python: temporarily silence pylint duplicate-code warnings
>>   python/aqmp: take QMPBadPortError and parse_address from qemu.qmp
>>   python/aqmp: fully separate from qmp.QEMUMonitorProtocol
>>   python/aqmp: copy qmp docstrings to qemu.aqmp.legacy
>>   python: remove the old QMP package
>>   python: re-enable pylint duplicate-code warnings
>>   python: rename qemu.aqmp to qemu.qmp
>>   python: rename 'aqmp-tui' to 'qmp-tui'
>>
>> Stefan Weil (1):
>>   simplebench: Fix Python syntax error (reported by LGTM)
>>
>>  python/qemu/qmp/README.rst|   9 -
>>  python/qemu/aqmp/__init__.py  |  51 --
>>  python/qemu/aqmp/legacy.py| 138 --
>>  python/qemu/aqmp/py.typed |   0
>>  python/qemu/machine/machine.py|  18 +-
>>  python/qemu/machine/qtest.py  |   2 +-
>>  python/qemu/qmp/__init__.py   | 441 ++
>>  python/qemu/{aqmp => qmp}/error.py|  12 +-
>>  python/qemu/{aqmp => qmp}/events.py   |   6 +-
>>  python/qemu/qmp/legacy.py | 319 +
>>  python/qemu/{aqmp => qmp}/message.py  |   0
>>  python/qemu/{aqmp => qmp}/models.py   |   0
>>  python/qemu/{aqmp => qmp}/protocol.py |  33 +-
>>  python/qemu/{aqmp => qmp}/qmp_client.py   |  32 +-
>>  python/qemu/qmp/qmp_shell.py

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

2022-01-12 Thread Darrin M. Gorski
Unfortunately I ran out of cycles at the time.  Adding test cases seems
like it was the roadblock - I don't think I ever figured out how to
implement the needed build tests for this additional feature in chardev.
I'm not that strong of a C developer, unfortunately.

I haven't looked at picking this up in probably a year, so I don't even
remember if I was able to get *anywhere* with it.

I did end up using a patched build myself,  and it worked fine for what I
was doing which is probably why I didn't get back to it.

Sorry, I'm sure that's not the answer you were hoping for.  But the day job
takes priority ;)

- Darrin


On Wed, Jan 12, 2022 at 10:20 AM Aaro Koskinen  wrote:

> Hi,
>
> On Wed, Dec 16, 2020 at 05:06:51PM -0500, Darrin M. Gorski wrote:
> > This patch adds a 'modemctl' option to "-chardev socket" to enable
> control
> > of the socket via the guest serial port.
> > The default state of the option is disabled.
> >
> > 1. disconnect a connected socket when DTR transitions to low, also reject
> > new connections while DTR is low.
> > 2. provide socket connection status through the carrier detect line (CD
> or
> > DCD) on the guest serial port
> >
> > Buglink: https://bugs.launchpad.net/qemu/+bug/1213196
> >
> > Signed-off-by: Darrin M. Gorski 
>
> Is there any plans to continue working with this patch? Having the DCD
> status would be very useful.
>
> A.
>


Re: PyPI account

2022-01-12 Thread John Snow
On Wed, Jan 12, 2022 at 12:51 PM Daniel P. Berrangé  wrote:
>
> On Wed, Jan 12, 2022 at 12:47:01PM -0500, John Snow wrote:
> > On Wed, Jan 12, 2022 at 12:34 PM Daniel P. Berrangé  
> > wrote:
> > >
> > > On Wed, Jan 12, 2022 at 12:25:16PM -0500, John Snow wrote:
> > > > On Wed, Jan 12, 2022 at 5:56 AM Stefan Hajnoczi  
> > > > wrote:
> > > > >
> > > > > [Context: John created a PyPI QEMU user in order to publish the 
> > > > > qemu.qmp
> > > > > package. If anyone wants to publish additional Python packages from
> > > > > qemu.git, please contact him for PyPI access.]
> > > > >
> > > > > On Tue, Jan 11, 2022 at 03:42:23PM -0500, John Snow wrote:
> > > > > > Account made: https://pypi.org/user/QEMU/
> > > > > >
> > > > > > I can't update the wiki, I lack admin perms to edit
> > > > > > https://wiki.qemu.org/AdminContacts
> > > > > >
> > > > > > I assume in the event that I fall into a black hole or get launched
> > > > > > out of a cannon into the sun, any mails sent to js...@redhat.com can
> > > > > > be recovered by Red Hat in general, so there's a sufficient recourse
> > > > > > for recovering the account in that circumstance.
> > > > >
> > > > > Thanks, I have added the PyPI QEMU user and added you as the admin
> > > > > contact:
> > > > > https://wiki.qemu.org/AdminContacts#Other_resources
> > > > >
> > > > > Stefan
> > > >
> > > > Thanks, Stefan!
> > > >
> > > > As additional context, there is currently a single package that
> > > > belongs to that user, "qemu.qmp" [1]. I published it "in advance" to
> > > > be able to test integration in an RFC patch set I posted to the list
> > > > just before the winter break [2]. The package is an "alpha prerelease"
> > > > and is at a very low-risk to be installed by accident. The version
> > > > chosen here will be considered "less than" any other valid version
> > > > string chosen, and can be deleted permanently from PyPI after
> > > > consensus on list review. Please forgive the mid-review publishing.
> > > > The exact metadata, wording of the README, etc is still under review
> > > > here [3].
> > > >
> > > > As for the PyPI account itself, I have volunteered to administer it.
> > > > If anyone wants access (esp. a leadership committee member from
> > > > another employer), please contact me - I'm happy to share.
> > >
> > > As a general rule we should ensure we always have 2 nominated people
> > > with access to any account held on behalf of the QEMU project, so we
> > > have some redundancy in case of unexpected events. So we definitely
> > > ought to have a 2nd person with access to PyPI even if they do nothing
> > > with it.
> > >
> >
> > I'm perfectly fine with that. It'd increase the fault tolerance to
> > have someone from outside of RH be the paper-admin there. Any
> > volunteers?
> >
> > (I can add your email as a secondary contact to the account such that
> > you would be able to use that email to initiate an account recovery,
> > but you wouldn't receive email from PyPI concerning the comings and
> > goings of the account. Your name and email would not show up on any
> > PyPI package pages, so it should very hopefully not involve really any
> > actual maintainership on your part.)
>
> In my case I expect it could complain that my email(s) are already
> in use for other PyPI accounts of my own.

It does complain about this, but there's always the
myname+arbitr...@example.com trick, which works. I have no problem
adding you, but for the purposes of fault tolerance I'd prefer adding
someone outside of RH. If there aren't any takers after a bit, ...

--js




Re: PyPI account

2022-01-12 Thread Daniel P . Berrangé
On Wed, Jan 12, 2022 at 12:47:01PM -0500, John Snow wrote:
> On Wed, Jan 12, 2022 at 12:34 PM Daniel P. Berrangé  
> wrote:
> >
> > On Wed, Jan 12, 2022 at 12:25:16PM -0500, John Snow wrote:
> > > On Wed, Jan 12, 2022 at 5:56 AM Stefan Hajnoczi  
> > > wrote:
> > > >
> > > > [Context: John created a PyPI QEMU user in order to publish the qemu.qmp
> > > > package. If anyone wants to publish additional Python packages from
> > > > qemu.git, please contact him for PyPI access.]
> > > >
> > > > On Tue, Jan 11, 2022 at 03:42:23PM -0500, John Snow wrote:
> > > > > Account made: https://pypi.org/user/QEMU/
> > > > >
> > > > > I can't update the wiki, I lack admin perms to edit
> > > > > https://wiki.qemu.org/AdminContacts
> > > > >
> > > > > I assume in the event that I fall into a black hole or get launched
> > > > > out of a cannon into the sun, any mails sent to js...@redhat.com can
> > > > > be recovered by Red Hat in general, so there's a sufficient recourse
> > > > > for recovering the account in that circumstance.
> > > >
> > > > Thanks, I have added the PyPI QEMU user and added you as the admin
> > > > contact:
> > > > https://wiki.qemu.org/AdminContacts#Other_resources
> > > >
> > > > Stefan
> > >
> > > Thanks, Stefan!
> > >
> > > As additional context, there is currently a single package that
> > > belongs to that user, "qemu.qmp" [1]. I published it "in advance" to
> > > be able to test integration in an RFC patch set I posted to the list
> > > just before the winter break [2]. The package is an "alpha prerelease"
> > > and is at a very low-risk to be installed by accident. The version
> > > chosen here will be considered "less than" any other valid version
> > > string chosen, and can be deleted permanently from PyPI after
> > > consensus on list review. Please forgive the mid-review publishing.
> > > The exact metadata, wording of the README, etc is still under review
> > > here [3].
> > >
> > > As for the PyPI account itself, I have volunteered to administer it.
> > > If anyone wants access (esp. a leadership committee member from
> > > another employer), please contact me - I'm happy to share.
> >
> > As a general rule we should ensure we always have 2 nominated people
> > with access to any account held on behalf of the QEMU project, so we
> > have some redundancy in case of unexpected events. So we definitely
> > ought to have a 2nd person with access to PyPI even if they do nothing
> > with it.
> >
> 
> I'm perfectly fine with that. It'd increase the fault tolerance to
> have someone from outside of RH be the paper-admin there. Any
> volunteers?
> 
> (I can add your email as a secondary contact to the account such that
> you would be able to use that email to initiate an account recovery,
> but you wouldn't receive email from PyPI concerning the comings and
> goings of the account. Your name and email would not show up on any
> PyPI package pages, so it should very hopefully not involve really any
> actual maintainership on your part.)

In my case I expect it could complain that my email(s) are already
in use for other PyPI accounts of my own.

Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|




Re: PyPI account

2022-01-12 Thread John Snow
On Wed, Jan 12, 2022 at 12:34 PM Daniel P. Berrangé  wrote:
>
> On Wed, Jan 12, 2022 at 12:25:16PM -0500, John Snow wrote:
> > On Wed, Jan 12, 2022 at 5:56 AM Stefan Hajnoczi  wrote:
> > >
> > > [Context: John created a PyPI QEMU user in order to publish the qemu.qmp
> > > package. If anyone wants to publish additional Python packages from
> > > qemu.git, please contact him for PyPI access.]
> > >
> > > On Tue, Jan 11, 2022 at 03:42:23PM -0500, John Snow wrote:
> > > > Account made: https://pypi.org/user/QEMU/
> > > >
> > > > I can't update the wiki, I lack admin perms to edit
> > > > https://wiki.qemu.org/AdminContacts
> > > >
> > > > I assume in the event that I fall into a black hole or get launched
> > > > out of a cannon into the sun, any mails sent to js...@redhat.com can
> > > > be recovered by Red Hat in general, so there's a sufficient recourse
> > > > for recovering the account in that circumstance.
> > >
> > > Thanks, I have added the PyPI QEMU user and added you as the admin
> > > contact:
> > > https://wiki.qemu.org/AdminContacts#Other_resources
> > >
> > > Stefan
> >
> > Thanks, Stefan!
> >
> > As additional context, there is currently a single package that
> > belongs to that user, "qemu.qmp" [1]. I published it "in advance" to
> > be able to test integration in an RFC patch set I posted to the list
> > just before the winter break [2]. The package is an "alpha prerelease"
> > and is at a very low-risk to be installed by accident. The version
> > chosen here will be considered "less than" any other valid version
> > string chosen, and can be deleted permanently from PyPI after
> > consensus on list review. Please forgive the mid-review publishing.
> > The exact metadata, wording of the README, etc is still under review
> > here [3].
> >
> > As for the PyPI account itself, I have volunteered to administer it.
> > If anyone wants access (esp. a leadership committee member from
> > another employer), please contact me - I'm happy to share.
>
> As a general rule we should ensure we always have 2 nominated people
> with access to any account held on behalf of the QEMU project, so we
> have some redundancy in case of unexpected events. So we definitely
> ought to have a 2nd person with access to PyPI even if they do nothing
> with it.
>

I'm perfectly fine with that. It'd increase the fault tolerance to
have someone from outside of RH be the paper-admin there. Any
volunteers?

(I can add your email as a secondary contact to the account such that
you would be able to use that email to initiate an account recovery,
but you wouldn't receive email from PyPI concerning the comings and
goings of the account. Your name and email would not show up on any
PyPI package pages, so it should very hopefully not involve really any
actual maintainership on your part.)

--js




Re: [PATCH v3 14/31] python/qmp: switch qmp-shell to AQMP

2022-01-12 Thread John Snow
On Wed, Jan 12, 2022 at 8:52 AM Beraldo Leal  wrote:
>
> On Mon, Jan 10, 2022 at 06:28:53PM -0500, John Snow wrote:
> > We have a replacement for async QMP, but it doesn't have feature parity
> > yet. For now, then, port the old tool onto the new backend.
> >
> > Signed-off-by: John Snow 
> > Reviewed-by: Vladimir Sementsov-Ogievskiy 
> > ---
> >  python/qemu/aqmp/legacy.py   |  3 +++
> >  python/qemu/qmp/qmp_shell.py | 31 +--
> >  2 files changed, 20 insertions(+), 14 deletions(-)
> >
> > diff --git a/python/qemu/aqmp/legacy.py b/python/qemu/aqmp/legacy.py
> > index 27df22818a..0890f95b16 100644
> > --- a/python/qemu/aqmp/legacy.py
> > +++ b/python/qemu/aqmp/legacy.py
> > @@ -22,6 +22,9 @@
> >  from .qmp_client import QMPClient
> >
> >
> > +# (Temporarily) Re-export QMPBadPortError
> > +QMPBadPortError = qemu.qmp.QMPBadPortError
>
> Probably I'm missing something, but any reason for not using, something
> like this?
>
> from qemu.qmp import (QMPMessage, QMPReturnValue, SocketAddrT,
>   QMPBadPortError)
>

It's a declaration of intent; if I don't shuffle it into a new
assignment, mypy chirps a warning that I am using something "not
explicitly exported by the module". An alternative would be to define
an __all__ List[str], but that's even more churn for something that's
going to be deleted by the end of the series, so I went with this
little temporary hack instead.

Silly, yes.

--js




Re: [PATCH] virtiofsd: Do not support blocking flock

2022-01-12 Thread Sebastian Hasler



On 11/01/2022 19:10, Sebastian Hasler wrote:

With the current implementation, blocking flock can lead to
deadlock. Thus, it's better to return EOPNOTSUPP if a user attempts
to perform a blocking flock request.

Signed-off-by: Sebastian Hasler 
---
  tools/virtiofsd/passthrough_ll.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
index 64b5b4fbb1..f3cc307f6d 100644
--- a/tools/virtiofsd/passthrough_ll.c
+++ b/tools/virtiofsd/passthrough_ll.c
@@ -2442,6 +2442,12 @@ static void lo_flock(fuse_req_t req, fuse_ino_t ino, 
struct fuse_file_info *fi,
  int res;
  (void)ino;
  
+if (!(op & LOCK_NB)) {

+/* Blocking flock is not supported */
+fuse_reply_err(req, EOPNOTSUPP);
+return;
+}
+
  res = flock(lo_fi_fd(req, fi), op);
  
  fuse_reply_err(req, res == -1 ? errno : 0);


I tested this patch by cherry-picking it on v6.1.0 and using it with 
Kata Containers 2.3.0. The bash code


    exec 42>/lock/flock
    flock -w 120 42

outputs

    flock: 42: Operation not supported

while the bash code

    exec 42>/lock/flock
    flock --nonblock 42

still works. So it works as intended.

--
Sebastian Hasler

stuvus – Studierendenvertretung Universität Stuttgart




Re: [RFC qemu.qmp PATCH 17/24] Makefile: add build and publish targets

2022-01-12 Thread John Snow
On Wed, Jan 12, 2022 at 5:07 AM Daniel P. Berrangé  wrote:
>
> On Tue, Jan 11, 2022 at 02:48:55PM -0500, John Snow wrote:
> > On Fri, Dec 17, 2021 at 8:46 AM Daniel P. Berrangé 
> > wrote:
> >
> > > On Thu, Dec 16, 2021 at 06:35:23PM -0500, John Snow wrote:
> > > > On Thu, Dec 16, 2021 at 5:48 AM Daniel P. Berrangé 
> > > > wrote:
> > > >
> > > > > On Wed, Dec 15, 2021 at 04:06:27PM -0500, John Snow wrote:
> > > > > > Signed-off-by: John Snow 
> > > > > > ---
> > > > > >  Makefile | 32 
> > > > > >  1 file changed, 32 insertions(+)
> > > > > >
> > > > > > diff --git a/Makefile b/Makefile
> > > > > > index 97d737a..81bfca8 100644
> > > > > > --- a/Makefile
> > > > > > +++ b/Makefile
> > > > > > @@ -110,3 +110,35 @@ distclean: clean
> > > > > >   rm -f .coverage .coverage.*
> > > > > >   rm -rf htmlcov/
> > > > > >   rm -rf test-results/
> > > > > > +
> > > > > > +.PHONY: pristine
> > > > > > +pristine:
> > > > > > + @git diff-files --quiet --ignore-submodules -- || \
> > > > > > + (echo "You have unstaged changes."; exit 1)
> > > > > > + @git diff-index --cached --quiet HEAD --ignore-submodules --
> > > || \
> > > > > > + (echo "Your index contains uncommitted changes."; exit
> > > 1)
> > > > > > + @[ -z "$(shell git ls-files -o)" ] || \
> > > > > > + (echo "You have untracked files: $(shell git ls-files
> > > > > -o)"; exit 1)
> > > > > > +
> > > > > > +dist: setup.cfg setup.py Makefile README.rst
> > > > > > + python3 -m build
> > > > > > + @touch dist
> > > > > > +
> > > > > > +.PHONY: pre-publish
> > > > > > +pre-publish: pristine dist
> > > > > > + @git describe --exact-match 2>/dev/null || \
> > > > > > + (echo -e "\033[0;31mThere is no annotated tag for this
> > > > > commit.\033[0m"; exit 1)
> > > > > > + python3 -m twine check --strict dist/*
> > > > > > + git push -v --atomic --follow-tags --dry-run
> > > > > > +
> > > > > > +.PHONY: publish
> > > > > > +publish: pre-publish
> > > > > > + # Set the username via TWINE_USERNAME.
> > > > > > + # Set the password via TWINE_PASSWORD.
> > > > > > + # Set the pkg repository via TWINE_REPOSITORY.
> > > > > > + python3 -m twine upload --verbose dist/*
> > > > > > + git push -v --atomic --follow-tags
> > > > > > +
> > > > > > +.PHONY: publish-test
> > > > > > +publish-test: pre-publish
> > > > > > + python3 -m twine upload --verbose -r testpypi dist/*
> > > > >
> > > > > It doesn't feel very pythonic to have a makefile in the project.
> > > > >
> > > > > If we want some helpers for publishing releases, I would have
> > > > > expected to see a python script  eg scripts/publish.py
> > > > >
> > > > >
> > > > Eh, Python folks use Makefiles too. I've been using these little 
> > > > Makefile
> > > > targets for hobby things for a while and I had them laying around and
> > > ready
> > > > to go. I have no strong need to "upgrade" to python scripts for these
> > > right
> > > > now, unless there's some extra features you want to see.
> > >
> > > Using make means you have to worry about portability across different
> > > impls of make and different impls of shell. Using python means your
> > > python project is portable to anywhere that python runs.
> >
> >
> > I still like the idea of using a Makefile as a "canonical menu of things
> > you can do in this directory", but there's probably room for interactive
> > error checking and so on with the TWINE_USERNAME / TWINE_PASSWORD /
> > TWINE_REPOSITORY environment variables in a python script. I'll look into
> > it as a follow-up, if that's fine. (I'm worried it's a lot of polish and
> > effort on a maintainers-only interface that only I will likely use for at
> > least the next year or two.)
> >
> > Ultimately, what's likely to happen here is that I will generate some oauth
> > tokens with publish permissions and a hypothetical user would set e.g.
> > TWINE_USERNAME to "__token__", and the password would be
> > "pypi-tokengoeshere". Using the "keyring" python package, we could attempt
> > to fetch stored values from a session keyring, falling back to an
> > interactive prompt if they're unset.
>
> FWIW, don't consider this original comment of mine to be a technical
> blocker, rather it is more of a conceptual observation.  If you don't
> think it matters, I won't mind.
>

OK, thanks -- just didn't want to give the impression I was just
simply ignoring it, since I appreciate the look-over.

--js




Re: PyPI account

2022-01-12 Thread Daniel P . Berrangé
On Wed, Jan 12, 2022 at 12:25:16PM -0500, John Snow wrote:
> On Wed, Jan 12, 2022 at 5:56 AM Stefan Hajnoczi  wrote:
> >
> > [Context: John created a PyPI QEMU user in order to publish the qemu.qmp
> > package. If anyone wants to publish additional Python packages from
> > qemu.git, please contact him for PyPI access.]
> >
> > On Tue, Jan 11, 2022 at 03:42:23PM -0500, John Snow wrote:
> > > Account made: https://pypi.org/user/QEMU/
> > >
> > > I can't update the wiki, I lack admin perms to edit
> > > https://wiki.qemu.org/AdminContacts
> > >
> > > I assume in the event that I fall into a black hole or get launched
> > > out of a cannon into the sun, any mails sent to js...@redhat.com can
> > > be recovered by Red Hat in general, so there's a sufficient recourse
> > > for recovering the account in that circumstance.
> >
> > Thanks, I have added the PyPI QEMU user and added you as the admin
> > contact:
> > https://wiki.qemu.org/AdminContacts#Other_resources
> >
> > Stefan
> 
> Thanks, Stefan!
> 
> As additional context, there is currently a single package that
> belongs to that user, "qemu.qmp" [1]. I published it "in advance" to
> be able to test integration in an RFC patch set I posted to the list
> just before the winter break [2]. The package is an "alpha prerelease"
> and is at a very low-risk to be installed by accident. The version
> chosen here will be considered "less than" any other valid version
> string chosen, and can be deleted permanently from PyPI after
> consensus on list review. Please forgive the mid-review publishing.
> The exact metadata, wording of the README, etc is still under review
> here [3].
> 
> As for the PyPI account itself, I have volunteered to administer it.
> If anyone wants access (esp. a leadership committee member from
> another employer), please contact me - I'm happy to share.

As a general rule we should ensure we always have 2 nominated people
with access to any account held on behalf of the QEMU project, so we
have some redundancy in case of unexpected events. So we definitely
ought to have a 2nd person with access to PyPI even if they do nothing
with it.

Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|




[PULL 6/6] virtio: unify dataplane and non-dataplane ->handle_output()

2022-01-12 Thread Stefan Hajnoczi
Now that virtio-blk and virtio-scsi are ready, get rid of
the handle_aio_output() callback. It's no longer needed.

Signed-off-by: Stefan Hajnoczi 
Reviewed-by: Stefano Garzarella 
Message-id: 20211207132336.36627-7-stefa...@redhat.com
Signed-off-by: Stefan Hajnoczi 
---
 include/hw/virtio/virtio.h  |  4 +--
 hw/block/dataplane/virtio-blk.c | 16 ++
 hw/scsi/virtio-scsi-dataplane.c | 54 -
 hw/virtio/virtio.c  | 32 +--
 4 files changed, 26 insertions(+), 80 deletions(-)

diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index b90095628f..f095637058 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -316,8 +316,8 @@ bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev);
 EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq);
 void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled);
 void virtio_queue_host_notifier_read(EventNotifier *n);
-void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
-VirtIOHandleOutput handle_output);
+void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx);
+void virtio_queue_aio_detach_host_notifier(VirtQueue *vq, AioContext *ctx);
 VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector);
 VirtQueue *virtio_vector_next_queue(VirtQueue *vq);
 
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index a2fa407b98..49276e46f2 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -154,17 +154,6 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s)
 g_free(s);
 }
 
-static void virtio_blk_data_plane_handle_output(VirtIODevice *vdev,
-VirtQueue *vq)
-{
-VirtIOBlock *s = (VirtIOBlock *)vdev;
-
-assert(s->dataplane);
-assert(s->dataplane_started);
-
-virtio_blk_handle_vq(s, vq);
-}
-
 /* Context: QEMU global mutex held */
 int virtio_blk_data_plane_start(VirtIODevice *vdev)
 {
@@ -258,8 +247,7 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
 for (i = 0; i < nvqs; i++) {
 VirtQueue *vq = virtio_get_queue(s->vdev, i);
 
-virtio_queue_aio_set_host_notifier_handler(vq, s->ctx,
-virtio_blk_data_plane_handle_output);
+virtio_queue_aio_attach_host_notifier(vq, s->ctx);
 }
 aio_context_release(s->ctx);
 return 0;
@@ -302,7 +290,7 @@ static void virtio_blk_data_plane_stop_bh(void *opaque)
 for (i = 0; i < s->conf->num_queues; i++) {
 VirtQueue *vq = virtio_get_queue(s->vdev, i);
 
-virtio_queue_aio_set_host_notifier_handler(vq, s->ctx, NULL);
+virtio_queue_aio_detach_host_notifier(vq, s->ctx);
 }
 }
 
diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c
index 76137de67f..29575cbaf6 100644
--- a/hw/scsi/virtio-scsi-dataplane.c
+++ b/hw/scsi/virtio-scsi-dataplane.c
@@ -49,45 +49,6 @@ void virtio_scsi_dataplane_setup(VirtIOSCSI *s, Error **errp)
 }
 }
 
-static void virtio_scsi_data_plane_handle_cmd(VirtIODevice *vdev,
-  VirtQueue *vq)
-{
-VirtIOSCSI *s = VIRTIO_SCSI(vdev);
-
-virtio_scsi_acquire(s);
-if (!s->dataplane_fenced) {
-assert(s->ctx && s->dataplane_started);
-virtio_scsi_handle_cmd_vq(s, vq);
-}
-virtio_scsi_release(s);
-}
-
-static void virtio_scsi_data_plane_handle_ctrl(VirtIODevice *vdev,
-   VirtQueue *vq)
-{
-VirtIOSCSI *s = VIRTIO_SCSI(vdev);
-
-virtio_scsi_acquire(s);
-if (!s->dataplane_fenced) {
-assert(s->ctx && s->dataplane_started);
-virtio_scsi_handle_ctrl_vq(s, vq);
-}
-virtio_scsi_release(s);
-}
-
-static void virtio_scsi_data_plane_handle_event(VirtIODevice *vdev,
-VirtQueue *vq)
-{
-VirtIOSCSI *s = VIRTIO_SCSI(vdev);
-
-virtio_scsi_acquire(s);
-if (!s->dataplane_fenced) {
-assert(s->ctx && s->dataplane_started);
-virtio_scsi_handle_event_vq(s, vq);
-}
-virtio_scsi_release(s);
-}
-
 static int virtio_scsi_set_host_notifier(VirtIOSCSI *s, VirtQueue *vq, int n)
 {
 BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s)));
@@ -112,10 +73,10 @@ static void virtio_scsi_dataplane_stop_bh(void *opaque)
 VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
 int i;
 
-virtio_queue_aio_set_host_notifier_handler(vs->ctrl_vq, s->ctx, NULL);
-virtio_queue_aio_set_host_notifier_handler(vs->event_vq, s->ctx, NULL);
+virtio_queue_aio_detach_host_notifier(vs->ctrl_vq, s->ctx);
+virtio_queue_aio_detach_host_notifier(vs->event_vq, s->ctx);
 for (i = 0; i < vs->conf.num_queues; i++) {
-virtio_queue_aio_set_host_notifier_handler(vs->cmd_vqs[i], s->ctx, 
NULL);
+virtio_queue_aio_detach_host_notifier(vs->cmd_vqs[i], s->ctx);
 }
 }
 
@@ -176,14 +137,11 

[PULL 3/6] virtio-blk: drop unused virtio_blk_handle_vq() return value

2022-01-12 Thread Stefan Hajnoczi
The return value of virtio_blk_handle_vq() is no longer used. Get rid of
it. This is a step towards unifying the dataplane and non-dataplane
virtqueue handler functions.

Prepare virtio_blk_handle_output() to be used by both dataplane and
non-dataplane by making the condition for starting ioeventfd more
specific. This way it won't trigger when dataplane has already been
started.

Signed-off-by: Stefan Hajnoczi 
Reviewed-by: Stefano Garzarella 
Message-id: 20211207132336.36627-4-stefa...@redhat.com
Signed-off-by: Stefan Hajnoczi 
---
 include/hw/virtio/virtio-blk.h |  2 +-
 hw/block/virtio-blk.c  | 14 +++---
 2 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
index 29655a406d..d311c57cca 100644
--- a/include/hw/virtio/virtio-blk.h
+++ b/include/hw/virtio/virtio-blk.h
@@ -90,7 +90,7 @@ typedef struct MultiReqBuffer {
 bool is_write;
 } MultiReqBuffer;
 
-bool virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq);
+void virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq);
 void virtio_blk_process_queued_requests(VirtIOBlock *s, bool is_bh);
 
 #endif
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index f139cd7cc9..82676cdd01 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -767,12 +767,11 @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, 
MultiReqBuffer *mrb)
 return 0;
 }
 
-bool virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq)
+void virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq)
 {
 VirtIOBlockReq *req;
 MultiReqBuffer mrb = {};
 bool suppress_notifications = virtio_queue_get_notification(vq);
-bool progress = false;
 
 aio_context_acquire(blk_get_aio_context(s->blk));
 blk_io_plug(s->blk);
@@ -783,7 +782,6 @@ bool virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq)
 }
 
 while ((req = virtio_blk_get_request(s, vq))) {
-progress = true;
 if (virtio_blk_handle_request(req, )) {
 virtqueue_detach_element(req->vq, >elem, 0);
 virtio_blk_free_request(req);
@@ -802,19 +800,13 @@ bool virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq)
 
 blk_io_unplug(s->blk);
 aio_context_release(blk_get_aio_context(s->blk));
-return progress;
-}
-
-static void virtio_blk_handle_output_do(VirtIOBlock *s, VirtQueue *vq)
-{
-virtio_blk_handle_vq(s, vq);
 }
 
 static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
 {
 VirtIOBlock *s = (VirtIOBlock *)vdev;
 
-if (s->dataplane) {
+if (s->dataplane && !s->dataplane_started) {
 /* Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start
  * dataplane here instead of waiting for .set_status().
  */
@@ -823,7 +815,7 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, 
VirtQueue *vq)
 return;
 }
 }
-virtio_blk_handle_output_do(s, vq);
+virtio_blk_handle_vq(s, vq);
 }
 
 void virtio_blk_process_queued_requests(VirtIOBlock *s, bool is_bh)
-- 
2.34.1




[PULL 5/6] virtio: use ->handle_output() instead of ->handle_aio_output()

2022-01-12 Thread Stefan Hajnoczi
The difference between ->handle_output() and ->handle_aio_output() was
that ->handle_aio_output() returned a bool return value indicating
progress. This was needed by the old polling API but now that the bool
return value is gone, the two functions can be unified.

Signed-off-by: Stefan Hajnoczi 
Reviewed-by: Stefano Garzarella 
Message-id: 20211207132336.36627-6-stefa...@redhat.com
Signed-off-by: Stefan Hajnoczi 
---
 hw/virtio/virtio.c | 33 +++--
 1 file changed, 3 insertions(+), 30 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 323f549aad..e938e6513b 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -125,7 +125,6 @@ struct VirtQueue
 
 uint16_t vector;
 VirtIOHandleOutput handle_output;
-VirtIOHandleOutput handle_aio_output;
 VirtIODevice *vdev;
 EventNotifier guest_notifier;
 EventNotifier host_notifier;
@@ -2303,20 +2302,6 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, 
int align)
 }
 }
 
-static void virtio_queue_notify_aio_vq(VirtQueue *vq)
-{
-if (vq->vring.desc && vq->handle_aio_output) {
-VirtIODevice *vdev = vq->vdev;
-
-trace_virtio_queue_notify(vdev, vq - vdev->vq, vq);
-vq->handle_aio_output(vdev, vq);
-
-if (unlikely(vdev->start_on_kick)) {
-virtio_set_started(vdev, true);
-}
-}
-}
-
 static void virtio_queue_notify_vq(VirtQueue *vq)
 {
 if (vq->vring.desc && vq->handle_output) {
@@ -2395,7 +2380,6 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int 
queue_size,
 vdev->vq[i].vring.num_default = queue_size;
 vdev->vq[i].vring.align = VIRTIO_PCI_VRING_ALIGN;
 vdev->vq[i].handle_output = handle_output;
-vdev->vq[i].handle_aio_output = NULL;
 vdev->vq[i].used_elems = g_malloc0(sizeof(VirtQueueElement) *
queue_size);
 
@@ -2407,7 +2391,6 @@ void virtio_delete_queue(VirtQueue *vq)
 vq->vring.num = 0;
 vq->vring.num_default = 0;
 vq->handle_output = NULL;
-vq->handle_aio_output = NULL;
 g_free(vq->used_elems);
 vq->used_elems = NULL;
 virtio_virtqueue_reset_region_cache(vq);
@@ -3512,14 +3495,6 @@ EventNotifier *virtio_queue_get_guest_notifier(VirtQueue 
*vq)
 return >guest_notifier;
 }
 
-static void virtio_queue_host_notifier_aio_read(EventNotifier *n)
-{
-VirtQueue *vq = container_of(n, VirtQueue, host_notifier);
-if (event_notifier_test_and_clear(n)) {
-virtio_queue_notify_aio_vq(vq);
-}
-}
-
 static void virtio_queue_host_notifier_aio_poll_begin(EventNotifier *n)
 {
 VirtQueue *vq = container_of(n, VirtQueue, host_notifier);
@@ -3539,7 +3514,7 @@ static void 
virtio_queue_host_notifier_aio_poll_ready(EventNotifier *n)
 {
 VirtQueue *vq = container_of(n, VirtQueue, host_notifier);
 
-virtio_queue_notify_aio_vq(vq);
+virtio_queue_notify_vq(vq);
 }
 
 static void virtio_queue_host_notifier_aio_poll_end(EventNotifier *n)
@@ -3554,9 +3529,8 @@ void virtio_queue_aio_set_host_notifier_handler(VirtQueue 
*vq, AioContext *ctx,
 VirtIOHandleOutput handle_output)
 {
 if (handle_output) {
-vq->handle_aio_output = handle_output;
 aio_set_event_notifier(ctx, >host_notifier, true,
-   virtio_queue_host_notifier_aio_read,
+   virtio_queue_host_notifier_read,
virtio_queue_host_notifier_aio_poll,
virtio_queue_host_notifier_aio_poll_ready);
 aio_set_event_notifier_poll(ctx, >host_notifier,
@@ -3566,8 +3540,7 @@ void virtio_queue_aio_set_host_notifier_handler(VirtQueue 
*vq, AioContext *ctx,
 aio_set_event_notifier(ctx, >host_notifier, true, NULL, NULL, 
NULL);
 /* Test and clear notifier before after disabling event,
  * in case poll callback didn't have time to run. */
-virtio_queue_host_notifier_aio_read(>host_notifier);
-vq->handle_aio_output = NULL;
+virtio_queue_host_notifier_read(>host_notifier);
 }
 }
 
-- 
2.34.1




Re: [PATCH v2] block: drop BLK_PERM_GRAPH_MOD

2022-01-12 Thread Kevin Wolf
Am 02.09.2021 um 11:37 hat Vladimir Sementsov-Ogievskiy geschrieben:
> First, this permission never protected a node from being changed, as
> generic child-replacing functions don't check it.
> 
> Second, it's a strange thing: it presents a permission of parent node
> to change its child. But generally, children are replaced by different
> mechanisms, like jobs or qmp commands, not by nodes.
> 
> Graph-mod permission is hard to understand. All other permissions
> describe operations which done by parent node on its child: read,
> write, resize. Graph modification operations are something completely
> different.
> 
> The only place where BLK_PERM_GRAPH_MOD is used as "perm" (not shared
> perm) is mirror_start_job, for s->target. Still modern code should use
> bdrv_freeze_backing_chain() to protect from graph modification, if we
> don't do it somewhere it may be considered as a bug. So, it's a bit
> risky to drop GRAPH_MOD, and analyzing of possible loss of protection
> is hard. But one day we should do it, let's do it now.
> 
> One more bit of information is that locking the corresponding byte in
> file-posix doesn't make sense at all.
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy 

Thanks, applied to the block branch.

Kevin




Re: PyPI account

2022-01-12 Thread John Snow
On Wed, Jan 12, 2022 at 5:56 AM Stefan Hajnoczi  wrote:
>
> [Context: John created a PyPI QEMU user in order to publish the qemu.qmp
> package. If anyone wants to publish additional Python packages from
> qemu.git, please contact him for PyPI access.]
>
> On Tue, Jan 11, 2022 at 03:42:23PM -0500, John Snow wrote:
> > Account made: https://pypi.org/user/QEMU/
> >
> > I can't update the wiki, I lack admin perms to edit
> > https://wiki.qemu.org/AdminContacts
> >
> > I assume in the event that I fall into a black hole or get launched
> > out of a cannon into the sun, any mails sent to js...@redhat.com can
> > be recovered by Red Hat in general, so there's a sufficient recourse
> > for recovering the account in that circumstance.
>
> Thanks, I have added the PyPI QEMU user and added you as the admin
> contact:
> https://wiki.qemu.org/AdminContacts#Other_resources
>
> Stefan

Thanks, Stefan!

As additional context, there is currently a single package that
belongs to that user, "qemu.qmp" [1]. I published it "in advance" to
be able to test integration in an RFC patch set I posted to the list
just before the winter break [2]. The package is an "alpha prerelease"
and is at a very low-risk to be installed by accident. The version
chosen here will be considered "less than" any other valid version
string chosen, and can be deleted permanently from PyPI after
consensus on list review. Please forgive the mid-review publishing.
The exact metadata, wording of the README, etc is still under review
here [3].

As for the PyPI account itself, I have volunteered to administer it.
If anyone wants access (esp. a leadership committee member from
another employer), please contact me - I'm happy to share.

[1] https://pypi.org/project/qemu.qmp/
[2] https://lists.gnu.org/archive/html/qemu-devel/2021-12/msg02840.html
[3] https://lists.gnu.org/archive/html/qemu-devel/2021-12/msg02418.html




[PULL 1/6] aio-posix: split poll check from ready handler

2022-01-12 Thread Stefan Hajnoczi
Adaptive polling measures the execution time of the polling check plus
handlers called when a polled event becomes ready. Handlers can take a
significant amount of time, making it look like polling was running for
a long time when in fact the event handler was running for a long time.

For example, on Linux the io_submit(2) syscall invoked when a virtio-blk
device's virtqueue becomes ready can take 10s of microseconds. This
can exceed the default polling interval (32 microseconds) and cause
adaptive polling to stop polling.

By excluding the handler's execution time from the polling check we make
the adaptive polling calculation more accurate. As a result, the event
loop now stays in polling mode where previously it would have fallen
back to file descriptor monitoring.

The following data was collected with virtio-blk num-queues=2
event_idx=off using an IOThread. Before:

168k IOPS, IOThread syscalls:

  9837.115 ( 0.020 ms): IO iothread1/620155 io_submit(ctx_id: 140512552468480, 
nr: 16, iocbpp: 0x7fcb9f937db0)= 16
  9837.158 ( 0.002 ms): IO iothread1/620155 write(fd: 103, buf: 0x556a2ef71b88, 
count: 8) = 8
  9837.161 ( 0.001 ms): IO iothread1/620155 write(fd: 104, buf: 0x556a2ef71b88, 
count: 8) = 8
  9837.163 ( 0.001 ms): IO iothread1/620155 ppoll(ufds: 0x7fcb90002800, nfds: 
4, tsp: 0x7fcb9f1342d0, sigsetsize: 8) = 3
  9837.164 ( 0.001 ms): IO iothread1/620155 read(fd: 107, buf: 0x7fcb9f939cc0, 
count: 512)= 8
  9837.174 ( 0.001 ms): IO iothread1/620155 read(fd: 105, buf: 0x7fcb9f939cc0, 
count: 512)= 8
  9837.176 ( 0.001 ms): IO iothread1/620155 read(fd: 106, buf: 0x7fcb9f939cc0, 
count: 512)= 8
  9837.209 ( 0.035 ms): IO iothread1/620155 io_submit(ctx_id: 140512552468480, 
nr: 32, iocbpp: 0x7fca7d0cebe0)= 32

174k IOPS (+3.6%), IOThread syscalls:

  9809.566 ( 0.036 ms): IO iothread1/623061 io_submit(ctx_id: 140539805028352, 
nr: 32, iocbpp: 0x7fd0cdd62be0)= 32
  9809.625 ( 0.001 ms): IO iothread1/623061 write(fd: 103, buf: 0x5647cfba5f58, 
count: 8) = 8
  9809.627 ( 0.002 ms): IO iothread1/623061 write(fd: 104, buf: 0x5647cfba5f58, 
count: 8) = 8
  9809.663 ( 0.036 ms): IO iothread1/623061 io_submit(ctx_id: 140539805028352, 
nr: 32, iocbpp: 0x7fd0d0388b50)= 32

Notice that ppoll(2) and eventfd read(2) syscalls are eliminated because
the IOThread stays in polling mode instead of falling back to file
descriptor monitoring.

As usual, polling is not implemented on Windows so this patch ignores
the new io_poll_read() callback in aio-win32.c.

Signed-off-by: Stefan Hajnoczi 
Reviewed-by: Stefano Garzarella 
Message-id: 20211207132336.36627-2-stefa...@redhat.com

[Fixed up aio_set_event_notifier() calls in
tests/unit/test-fdmon-epoll.c added after this series was queued.
--Stefan]

Signed-off-by: Stefan Hajnoczi 
---
 include/block/aio.h   |  4 +-
 util/aio-posix.h  |  1 +
 block/curl.c  | 11 +++--
 block/export/fuse.c   |  4 +-
 block/io_uring.c  | 19 
 block/iscsi.c |  4 +-
 block/linux-aio.c | 16 ---
 block/nfs.c   |  6 +--
 block/nvme.c  | 51 +---
 block/ssh.c   |  4 +-
 block/win32-aio.c |  4 +-
 hw/virtio/virtio.c| 16 ---
 hw/xen/xen-bus.c  |  6 +--
 io/channel-command.c  |  6 ++-
 io/channel-file.c |  3 +-
 io/channel-socket.c   |  3 +-
 migration/rdma.c  |  8 ++--
 tests/unit/test-aio.c |  4 +-
 tests/unit/test-fdmon-epoll.c |  4 +-
 util/aio-posix.c  | 89 ++-
 util/aio-win32.c  |  4 +-
 util/async.c  | 10 +++-
 util/main-loop.c  |  4 +-
 util/qemu-coroutine-io.c  |  5 +-
 util/vhost-user-server.c  | 11 +++--
 25 files changed, 193 insertions(+), 104 deletions(-)

diff --git a/include/block/aio.h b/include/block/aio.h
index 47fbe9d81f..5634173b12 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -469,6 +469,7 @@ void aio_set_fd_handler(AioContext *ctx,
 IOHandler *io_read,
 IOHandler *io_write,
 AioPollFn *io_poll,
+IOHandler *io_poll_ready,
 void *opaque);
 
 /* Set polling begin/end callbacks for a file descriptor that has already been
@@ -490,7 +491,8 @@ void aio_set_event_notifier(AioContext *ctx,
 EventNotifier *notifier,
 bool is_external,
 EventNotifierHandler *io_read,
-AioPollFn *io_poll);
+AioPollFn *io_poll,
+EventNotifierHandler *io_poll_ready);
 
 /* Set polling begin/end 

[PULL 2/6] virtio: get rid of VirtIOHandleAIOOutput

2022-01-12 Thread Stefan Hajnoczi
The virtqueue host notifier API
virtio_queue_aio_set_host_notifier_handler() polls the virtqueue for new
buffers. AioContext previously required a bool progress return value
indicating whether an event was handled or not. This is no longer
necessary because the AioContext polling API has been split into a poll
check function and an event handler function. The event handler is only
run when we know there is work to do, so it doesn't return bool.

The VirtIOHandleAIOOutput function signature is now the same as
VirtIOHandleOutput. Get rid of the bool return value.

Further simplifications will be made for virtio-blk and virtio-scsi in
the next patch.

Signed-off-by: Stefan Hajnoczi 
Reviewed-by: Stefano Garzarella 
Message-id: 20211207132336.36627-3-stefa...@redhat.com
Signed-off-by: Stefan Hajnoczi 
---
 include/hw/virtio/virtio.h  |  3 +--
 hw/block/dataplane/virtio-blk.c |  4 ++--
 hw/scsi/virtio-scsi-dataplane.c | 18 ++
 hw/virtio/virtio.c  | 12 
 4 files changed, 13 insertions(+), 24 deletions(-)

diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 8bab9cfb75..b90095628f 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -175,7 +175,6 @@ void virtio_error(VirtIODevice *vdev, const char *fmt, ...) 
GCC_FMT_ATTR(2, 3);
 void virtio_device_set_child_bus_name(VirtIODevice *vdev, char *bus_name);
 
 typedef void (*VirtIOHandleOutput)(VirtIODevice *, VirtQueue *);
-typedef bool (*VirtIOHandleAIOOutput)(VirtIODevice *, VirtQueue *);
 
 VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
 VirtIOHandleOutput handle_output);
@@ -318,7 +317,7 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue 
*vq);
 void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled);
 void virtio_queue_host_notifier_read(EventNotifier *n);
 void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
-VirtIOHandleAIOOutput 
handle_output);
+VirtIOHandleOutput handle_output);
 VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector);
 VirtQueue *virtio_vector_next_queue(VirtQueue *vq);
 
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index ee5a5352dc..a2fa407b98 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -154,7 +154,7 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s)
 g_free(s);
 }
 
-static bool virtio_blk_data_plane_handle_output(VirtIODevice *vdev,
+static void virtio_blk_data_plane_handle_output(VirtIODevice *vdev,
 VirtQueue *vq)
 {
 VirtIOBlock *s = (VirtIOBlock *)vdev;
@@ -162,7 +162,7 @@ static bool 
virtio_blk_data_plane_handle_output(VirtIODevice *vdev,
 assert(s->dataplane);
 assert(s->dataplane_started);
 
-return virtio_blk_handle_vq(s, vq);
+virtio_blk_handle_vq(s, vq);
 }
 
 /* Context: QEMU global mutex held */
diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c
index 18eb824c97..76137de67f 100644
--- a/hw/scsi/virtio-scsi-dataplane.c
+++ b/hw/scsi/virtio-scsi-dataplane.c
@@ -49,49 +49,43 @@ void virtio_scsi_dataplane_setup(VirtIOSCSI *s, Error 
**errp)
 }
 }
 
-static bool virtio_scsi_data_plane_handle_cmd(VirtIODevice *vdev,
+static void virtio_scsi_data_plane_handle_cmd(VirtIODevice *vdev,
   VirtQueue *vq)
 {
-bool progress = false;
 VirtIOSCSI *s = VIRTIO_SCSI(vdev);
 
 virtio_scsi_acquire(s);
 if (!s->dataplane_fenced) {
 assert(s->ctx && s->dataplane_started);
-progress = virtio_scsi_handle_cmd_vq(s, vq);
+virtio_scsi_handle_cmd_vq(s, vq);
 }
 virtio_scsi_release(s);
-return progress;
 }
 
-static bool virtio_scsi_data_plane_handle_ctrl(VirtIODevice *vdev,
+static void virtio_scsi_data_plane_handle_ctrl(VirtIODevice *vdev,
VirtQueue *vq)
 {
-bool progress = false;
 VirtIOSCSI *s = VIRTIO_SCSI(vdev);
 
 virtio_scsi_acquire(s);
 if (!s->dataplane_fenced) {
 assert(s->ctx && s->dataplane_started);
-progress = virtio_scsi_handle_ctrl_vq(s, vq);
+virtio_scsi_handle_ctrl_vq(s, vq);
 }
 virtio_scsi_release(s);
-return progress;
 }
 
-static bool virtio_scsi_data_plane_handle_event(VirtIODevice *vdev,
+static void virtio_scsi_data_plane_handle_event(VirtIODevice *vdev,
 VirtQueue *vq)
 {
-bool progress = false;
 VirtIOSCSI *s = VIRTIO_SCSI(vdev);
 
 virtio_scsi_acquire(s);
 if (!s->dataplane_fenced) {
 assert(s->ctx && s->dataplane_started);
-progress = virtio_scsi_handle_event_vq(s, vq);
+virtio_scsi_handle_event_vq(s, vq);
 }
 virtio_scsi_release(s);
-return progress;
 }
 
 static int 

Re: [PATCH] tests: Fix typo in check-help output

2022-01-12 Thread Alex Bennée


Philippe Mathieu-Daudé  writes:

> Fix typo in 'make check-help' output.

Queued to testing/next, thanks.

-- 
Alex Bennée



[PULL 4/6] virtio-scsi: prepare virtio_scsi_handle_cmd for dataplane

2022-01-12 Thread Stefan Hajnoczi
Prepare virtio_scsi_handle_cmd() to be used by both dataplane and
non-dataplane by making the condition for starting ioeventfd more
specific. This way it won't trigger when dataplane has already been
started.

Signed-off-by: Stefan Hajnoczi 
Reviewed-by: Stefano Garzarella 
Message-id: 20211207132336.36627-5-stefa...@redhat.com
Signed-off-by: Stefan Hajnoczi 
---
 hw/scsi/virtio-scsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 51fd09522a..34a968ecfb 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -720,7 +720,7 @@ static void virtio_scsi_handle_cmd(VirtIODevice *vdev, 
VirtQueue *vq)
 /* use non-QOM casts in the data path */
 VirtIOSCSI *s = (VirtIOSCSI *)vdev;
 
-if (s->ctx) {
+if (s->ctx && !s->dataplane_started) {
 virtio_device_start_ioeventfd(vdev);
 if (!s->dataplane_fenced) {
 return;
-- 
2.34.1




[PULL 0/6] Block patches

2022-01-12 Thread Stefan Hajnoczi
The following changes since commit 91f5f7a5df1fda8c34677a7c49ee8a4bb5b56a36:

  Merge remote-tracking branch 
'remotes/lvivier-gitlab/tags/linux-user-for-7.0-pull-request' into staging 
(2022-01-12 11:51:47 +)

are available in the Git repository at:

  https://gitlab.com/stefanha/qemu.git tags/block-pull-request

for you to fetch changes up to db608fb78444c58896db69495729e4458eeaace1:

  virtio: unify dataplane and non-dataplane ->handle_output() (2022-01-12 
17:09:39 +)


Pull request



Stefan Hajnoczi (6):
  aio-posix: split poll check from ready handler
  virtio: get rid of VirtIOHandleAIOOutput
  virtio-blk: drop unused virtio_blk_handle_vq() return value
  virtio-scsi: prepare virtio_scsi_handle_cmd for dataplane
  virtio: use ->handle_output() instead of ->handle_aio_output()
  virtio: unify dataplane and non-dataplane ->handle_output()

 include/block/aio.h |  4 +-
 include/hw/virtio/virtio-blk.h  |  2 +-
 include/hw/virtio/virtio.h  |  5 +-
 util/aio-posix.h|  1 +
 block/curl.c| 11 ++--
 block/export/fuse.c |  4 +-
 block/io_uring.c| 19 ---
 block/iscsi.c   |  4 +-
 block/linux-aio.c   | 16 +++---
 block/nfs.c |  6 +--
 block/nvme.c| 51 ---
 block/ssh.c |  4 +-
 block/win32-aio.c   |  4 +-
 hw/block/dataplane/virtio-blk.c | 16 +-
 hw/block/virtio-blk.c   | 14 ++
 hw/scsi/virtio-scsi-dataplane.c | 60 +++---
 hw/scsi/virtio-scsi.c   |  2 +-
 hw/virtio/virtio.c  | 73 +--
 hw/xen/xen-bus.c|  6 +--
 io/channel-command.c|  6 ++-
 io/channel-file.c   |  3 +-
 io/channel-socket.c |  3 +-
 migration/rdma.c|  8 +--
 tests/unit/test-aio.c   |  4 +-
 tests/unit/test-fdmon-epoll.c   |  4 +-
 util/aio-posix.c| 89 +
 util/aio-win32.c|  4 +-
 util/async.c| 10 +++-
 util/main-loop.c|  4 +-
 util/qemu-coroutine-io.c|  5 +-
 util/vhost-user-server.c| 11 ++--
 31 files changed, 221 insertions(+), 232 deletions(-)

-- 
2.34.1





[PATCH v4 4/5] target/s390x: Fix shifting 32-bit values for more than 31 bits

2022-01-12 Thread Ilya Leoshkevich
According to PoP, both 32- and 64-bit shifts use lowest 6 address
bits. The current code special-cases 32-bit shifts to use only 5 bits,
which is not correct. For example, shifting by 32 bits currently
preserves the initial value, however, it's supposed zero it out
instead.

Fix by merging sh32 and sh64 and adapting CC calculation to shift
values greater than 31.

Fixes: cbe24bfa91d2 ("target-s390: Convert SHIFT, ROTATE SINGLE")
Signed-off-by: Ilya Leoshkevich 
---
 target/s390x/cpu-dump.c|  3 +--
 target/s390x/s390x-internal.h  |  3 +--
 target/s390x/tcg/cc_helper.c   | 36 +++---
 target/s390x/tcg/insn-data.def | 36 +-
 target/s390x/tcg/translate.c   | 47 --
 5 files changed, 45 insertions(+), 80 deletions(-)

diff --git a/target/s390x/cpu-dump.c b/target/s390x/cpu-dump.c
index 0f5c062994..ffa9e94d84 100644
--- a/target/s390x/cpu-dump.c
+++ b/target/s390x/cpu-dump.c
@@ -121,8 +121,7 @@ const char *cc_name(enum cc_op cc_op)
 [CC_OP_NZ_F64]= "CC_OP_NZ_F64",
 [CC_OP_NZ_F128]   = "CC_OP_NZ_F128",
 [CC_OP_ICM]   = "CC_OP_ICM",
-[CC_OP_SLA_32]= "CC_OP_SLA_32",
-[CC_OP_SLA_64]= "CC_OP_SLA_64",
+[CC_OP_SLA]   = "CC_OP_SLA",
 [CC_OP_FLOGR] = "CC_OP_FLOGR",
 [CC_OP_LCBB]  = "CC_OP_LCBB",
 [CC_OP_VC]= "CC_OP_VC",
diff --git a/target/s390x/s390x-internal.h b/target/s390x/s390x-internal.h
index 1a178aed41..6fc8cad2d5 100644
--- a/target/s390x/s390x-internal.h
+++ b/target/s390x/s390x-internal.h
@@ -193,8 +193,7 @@ enum cc_op {
 CC_OP_NZ_F128,  /* FP dst != 0 (128bit) */
 
 CC_OP_ICM,  /* insert characters under mask */
-CC_OP_SLA_32,   /* Calculate shift left signed (32bit) */
-CC_OP_SLA_64,   /* Calculate shift left signed (64bit) */
+CC_OP_SLA,  /* Calculate shift left signed */
 CC_OP_FLOGR,/* find leftmost one */
 CC_OP_LCBB, /* load count to block boundary */
 CC_OP_VC,   /* vector compare result */
diff --git a/target/s390x/tcg/cc_helper.c b/target/s390x/tcg/cc_helper.c
index c9b7b0e8c6..8d04097f78 100644
--- a/target/s390x/tcg/cc_helper.c
+++ b/target/s390x/tcg/cc_helper.c
@@ -268,34 +268,7 @@ static uint32_t cc_calc_icm(uint64_t mask, uint64_t val)
 }
 }
 
-static uint32_t cc_calc_sla_32(uint32_t src, int shift)
-{
-uint32_t mask = ((1U << shift) - 1U) << (32 - shift);
-uint32_t sign = 1U << 31;
-uint32_t match;
-int32_t r;
-
-/* Check if the sign bit stays the same.  */
-if (src & sign) {
-match = mask;
-} else {
-match = 0;
-}
-if ((src & mask) != match) {
-/* Overflow.  */
-return 3;
-}
-
-r = ((src << shift) & ~sign) | (src & sign);
-if (r == 0) {
-return 0;
-} else if (r < 0) {
-return 1;
-}
-return 2;
-}
-
-static uint32_t cc_calc_sla_64(uint64_t src, int shift)
+static uint32_t cc_calc_sla(uint64_t src, int shift)
 {
 uint64_t mask = -1ULL << (63 - shift);
 uint64_t sign = 1ULL << 63;
@@ -459,11 +432,8 @@ static uint32_t do_calc_cc(CPUS390XState *env, uint32_t 
cc_op,
 case CC_OP_ICM:
 r =  cc_calc_icm(src, dst);
 break;
-case CC_OP_SLA_32:
-r =  cc_calc_sla_32(src, dst);
-break;
-case CC_OP_SLA_64:
-r =  cc_calc_sla_64(src, dst);
+case CC_OP_SLA:
+r =  cc_calc_sla(src, dst);
 break;
 case CC_OP_FLOGR:
 r = cc_calc_flogr(dst);
diff --git a/target/s390x/tcg/insn-data.def b/target/s390x/tcg/insn-data.def
index 90c753068c..1c3e115712 100644
--- a/target/s390x/tcg/insn-data.def
+++ b/target/s390x/tcg/insn-data.def
@@ -747,8 +747,8 @@
 C(0xb9e1, POPCNT,  RRE,   PC,  0, r2_o, r1, 0, popcnt, nz64)
 
 /* ROTATE LEFT SINGLE LOGICAL */
-C(0xeb1d, RLL, RSY_a, Z,   r3_o, sh32, new, r1_32, rll32, 0)
-C(0xeb1c, RLLG,RSY_a, Z,   r3_o, sh64, r1, 0, rll64, 0)
+C(0xeb1d, RLL, RSY_a, Z,   r3_o, sh, new, r1_32, rll32, 0)
+C(0xeb1c, RLLG,RSY_a, Z,   r3_o, sh, r1, 0, rll64, 0)
 
 /* ROTATE THEN INSERT SELECTED BITS */
 C(0xec55, RISBG,   RIE_f, GIE, 0, r2, r1, 0, risbg, s64)
@@ -784,29 +784,29 @@
 C(0x0400, SPM, RR_a,  Z,   r1, 0, 0, 0, spm, 0)
 
 /* SHIFT LEFT SINGLE */
-D(0x8b00, SLA, RS_a,  Z,   r1, sh32, new, r1_32, sla, 0, 31)
-D(0xebdd, SLAK,RSY_a, DO,  r3, sh32, new, r1_32, sla, 0, 31)
-D(0xeb0b, SLAG,RSY_a, Z,   r3, sh64, r1, 0, sla, 0, 63)
+D(0x8b00, SLA, RS_a,  Z,   r1, sh, new, r1_32, sla, 0, 31)
+D(0xebdd, SLAK,RSY_a, DO,  r3, sh, new, r1_32, sla, 0, 31)
+D(0xeb0b, SLAG,RSY_a, Z,   r3, sh, r1, 0, sla, 0, 63)
 /* SHIFT LEFT SINGLE LOGICAL */
-C(0x8900, SLL, RS_a,  Z,   r1_o, sh32, new, r1_32, sll, 0)
-C(0xebdf, SLLK,RSY_a, DO,  r3_o, sh32, new, r1_32, sll, 0)
-

Re: [PATCH v11 1/7] net/vmnet: add vmnet dependency and customizable option

2022-01-12 Thread Roman Bolshakov
On Wed, Jan 12, 2022 at 03:21:44PM +0300, Vladislav Yaroshchuk wrote:
> vmnet.framework dependency is added with 'vmnet' option
> to enable or disable it. Default value is 'auto'.
> 
> vmnet features to be used are available since macOS 11.0,
> corresponding probe is created into meson.build.
> 
> Signed-off-by: Vladislav Yaroshchuk 
> ---
>  meson.build   | 23 ++-
>  meson_options.txt |  2 ++
>  scripts/meson-buildoptions.sh |  3 +++
>  3 files changed, 27 insertions(+), 1 deletion(-)
> 
> diff --git a/meson.build b/meson.build
> index c1b1db1e28..b912c9cb91 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -496,6 +496,24 @@ if cocoa.found() and get_option('gtk').enabled()
>error('Cocoa and GTK+ cannot be enabled at the same time')
>  endif
>  
> +vmnet = dependency('appleframeworks', modules: 'vmnet', required: 
> get_option('vmnet'))
> +vmnet_11_0_api = false
> +if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
> +  'VMNET_BRIDGED_MODE',
> +  dependencies: vmnet)
> +  vmnet = not_found
> +  if get_option('vmnet').enabled()
> +error('vmnet.framework API is outdated')
> +  else
> +warning('vmnet.framework API is outdated, disabling')
> +  endif
> +endif
> +if vmnet.found() and cc.has_header_symbol('vmnet/vmnet.h',
> +  'VMNET_SHARING_SERVICE_BUSY',
> +  dependencies: vmnet)
> +  vmnet_11_0_api = true
> +endif
> +
>  seccomp = not_found
>  if not get_option('seccomp').auto() or have_system or have_tools
>seccomp = dependency('libseccomp', version: '>=2.3.0',
> @@ -1492,6 +1510,8 @@ config_host_data.set('CONFIG_SECCOMP', seccomp.found())
>  config_host_data.set('CONFIG_SNAPPY', snappy.found())
>  config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
>  config_host_data.set('CONFIG_VDE', vde.found())
> +config_host_data.set('CONFIG_VMNET', vmnet.found())
> +config_host_data.set('CONFIG_VMNET_11_0_API', vmnet_11_0_api)

Hi Vladislav,

There might be more functionality coming in the next macOS versions but
we likely don't want to add them as extra CONFIG defines. Instead we
wrap new symbols/functions/code that are avaialble above Big Sur in the
code as:

#if defined(MAC_OS_VERSION_11_0) && \
MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_11_0

xpc_dictionary_set_bool(
if_desc,
vmnet_enable_isolation_key,
options->isolated
);

#endif

Please see similar thread here:
https://lists.gnu.org/archive/html/qemu-devel/2022-01/msg01915.html

Thanks,
Roman

>  config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', 
> have_vhost_user_blk_server)
>  config_host_data.set('CONFIG_VNC', vnc.found())
>  config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
> @@ -3406,7 +3426,8 @@ summary(summary_info, bool_yn: true, section: 'Crypto')
>  # Libraries
>  summary_info = {}
>  if targetos == 'darwin'
> -  summary_info += {'Cocoa support':   cocoa}
> +  summary_info += {'Cocoa support':   cocoa}
> +  summary_info += {'vmnet.framework support': vmnet}
>  endif
>  summary_info += {'SDL support':   sdl}
>  summary_info += {'SDL image support': sdl_image}
> diff --git a/meson_options.txt b/meson_options.txt
> index 921967eddb..701e1381f9 100644
> --- a/meson_options.txt
> +++ b/meson_options.txt
> @@ -151,6 +151,8 @@ option('netmap', type : 'feature', value : 'auto',
> description: 'netmap network backend support')
>  option('vde', type : 'feature', value : 'auto',
> description: 'vde network backend support')
> +option('vmnet', type : 'feature', value : 'auto',
> +   description: 'vmnet.framework network backend support')
>  option('virglrenderer', type : 'feature', value : 'auto',
> description: 'virgl rendering support')
>  option('vnc', type : 'feature', value : 'auto',
> diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
> index 50bd7bed4d..cdcece4b05 100644
> --- a/scripts/meson-buildoptions.sh
> +++ b/scripts/meson-buildoptions.sh
> @@ -84,6 +84,7 @@ meson_options_help() {
>printf "%s\n" '  u2f U2F emulation support'
>printf "%s\n" '  usb-redir   libusbredir support'
>printf "%s\n" '  vde vde network backend support'
> +  printf "%s\n" '  vmnet   vmnet.framework network backend support'
>printf "%s\n" '  vhost-user-blk-server'
>printf "%s\n" '  build vhost-user-blk server'
>printf "%s\n" '  virglrenderer   virgl rendering support'
> @@ -248,6 +249,8 @@ _meson_option_parse() {
>  --disable-usb-redir) printf "%s" -Dusb_redir=disabled ;;
>  --enable-vde) printf "%s" -Dvde=enabled ;;
>  --disable-vde) printf "%s" -Dvde=disabled ;;
> +--enable-vmnet) printf "%s" -Dvmnet=enabled ;;
> +--disable-vmnet) printf "%s" -Dvmnet=disabled ;;
>  --enable-vhost-user-blk-server) printf "%s" 
> 

[PATCH v4 2/5] target/s390x: Fix SRDA CC calculation

2022-01-12 Thread Ilya Leoshkevich
SRDA uses r1_D32 for binding the first operand and s64 for setting CC.
cout_s64() relies on o->out being the shift result, however,
wout_r1_D32() clobbers it.

Fix by using a temporary.

Fixes: a79ba3398a0a ("target-s390: Convert SHIFT DOUBLE")
Signed-off-by: Ilya Leoshkevich 
---
 target/s390x/tcg/translate.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
index f180853e7a..766b4c87b2 100644
--- a/target/s390x/tcg/translate.c
+++ b/target/s390x/tcg/translate.c
@@ -5420,9 +5420,11 @@ static void wout_r1_P32(DisasContext *s, DisasOps *o)
 static void wout_r1_D32(DisasContext *s, DisasOps *o)
 {
 int r1 = get_field(s, r1);
+TCGv_i64 t = tcg_temp_new_i64();
 store_reg32_i64(r1 + 1, o->out);
-tcg_gen_shri_i64(o->out, o->out, 32);
-store_reg32_i64(r1, o->out);
+tcg_gen_shri_i64(t, o->out, 32);
+store_reg32_i64(r1, t);
+tcg_temp_free_i64(t);
 }
 #define SPEC_wout_r1_D32 SPEC_r1_even
 
-- 
2.31.1




[PATCH v4 0/5] target/s390x: Fix shift instructions

2022-01-12 Thread Ilya Leoshkevich
v3: https://lists.nongnu.org/archive/html/qemu-devel/2022-01/msg02680.html
v3 -> v4: Simplify cc_calc_sla().
  Free temporaries.

v2: https://lists.nongnu.org/archive/html/qemu-devel/2022-01/msg02488.html
v2 -> v3: Unify CC_OP_SLA_32 and CC_OP_SLA_64.
  Add underscores to test macro parameters.
  Shift CC in test asm.
  Add a second SLAG test.
  Add tags to commit messages.

v1: https://lists.nongnu.org/archive/html/qemu-devel/2022-01/msg02035.html
v1 -> v2: Fix cc_calc_sla_32().
  Fix cc_calc_sla_64().
  Fix SLDA sign bit index.
  Inline help_l2_shift().
  Fix wout_r1_D32().
  Add all shift instructions to the test.
  Split the series.

Ilya Leoshkevich (5):
  target/s390x: Fix SLDA sign bit index
  target/s390x: Fix SRDA CC calculation
  target/s390x: Fix cc_calc_sla_64() missing overflows
  target/s390x: Fix shifting 32-bit values for more than 31 bits
  tests/tcg/s390x: Test shift instructions

 target/s390x/cpu-dump.c |   3 +-
 target/s390x/s390x-internal.h   |   3 +-
 target/s390x/tcg/cc_helper.c|  38 +
 target/s390x/tcg/insn-data.def  |  36 ++---
 target/s390x/tcg/translate.c|  53 +++
 tests/tcg/s390x/Makefile.target |   1 +
 tests/tcg/s390x/shift.c | 270 
 7 files changed, 321 insertions(+), 83 deletions(-)
 create mode 100644 tests/tcg/s390x/shift.c

-- 
2.31.1




[PATCH v4 1/5] target/s390x: Fix SLDA sign bit index

2022-01-12 Thread Ilya Leoshkevich
SLDA operates on 64-bit values, so its sign bit index should be 63,
not 31.

Fixes: a79ba3398a0a ("target-s390: Convert SHIFT DOUBLE")
Reported-by: David Hildenbrand 
Signed-off-by: Ilya Leoshkevich 
Reviewed-by: David Hildenbrand 
---
 target/s390x/tcg/insn-data.def | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/s390x/tcg/insn-data.def b/target/s390x/tcg/insn-data.def
index f0af458aee..90c753068c 100644
--- a/target/s390x/tcg/insn-data.def
+++ b/target/s390x/tcg/insn-data.def
@@ -800,7 +800,7 @@
 C(0xebde, SRLK,RSY_a, DO,  r3_32u, sh32, new, r1_32, srl, 0)
 C(0xeb0c, SRLG,RSY_a, Z,   r3_o, sh64, r1, 0, srl, 0)
 /* SHIFT LEFT DOUBLE */
-D(0x8f00, SLDA,RS_a,  Z,   r1_D32, sh64, new, r1_D32, sla, 0, 31)
+D(0x8f00, SLDA,RS_a,  Z,   r1_D32, sh64, new, r1_D32, sla, 0, 63)
 /* SHIFT LEFT DOUBLE LOGICAL */
 C(0x8d00, SLDL,RS_a,  Z,   r1_D32, sh64, new, r1_D32, sll, 0)
 /* SHIFT RIGHT DOUBLE */
-- 
2.31.1




[PATCH v4 5/5] tests/tcg/s390x: Test shift instructions

2022-01-12 Thread Ilya Leoshkevich
Add a test for each shift instruction in order to to prevent
regressions.

Signed-off-by: Ilya Leoshkevich 
---
 tests/tcg/s390x/Makefile.target |   1 +
 tests/tcg/s390x/shift.c | 270 
 2 files changed, 271 insertions(+)
 create mode 100644 tests/tcg/s390x/shift.c

diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target
index cc64dd32d2..1a7238b4eb 100644
--- a/tests/tcg/s390x/Makefile.target
+++ b/tests/tcg/s390x/Makefile.target
@@ -9,6 +9,7 @@ TESTS+=exrl-trtr
 TESTS+=pack
 TESTS+=mvo
 TESTS+=mvc
+TESTS+=shift
 TESTS+=trap
 TESTS+=signals-s390x
 
diff --git a/tests/tcg/s390x/shift.c b/tests/tcg/s390x/shift.c
new file mode 100644
index 00..29594fec5c
--- /dev/null
+++ b/tests/tcg/s390x/shift.c
@@ -0,0 +1,270 @@
+#include 
+#include 
+#include 
+
+#define DEFINE_SHIFT_SINGLE_COMMON(_name, _insn_str) \
+static uint64_t _name(uint64_t op1, uint64_t op2, uint64_t *cc) \
+{ \
+asm("sll %[cc],28\n" \
+"spm %[cc]\n" \
+"" _insn_str "\n" \
+"ipm %[cc]\n" \
+"srl %[cc],28" \
+: [op1] "+" (op1), \
+  [cc] "+" (*cc) \
+: [op2] "r" (op2) \
+: "cc"); \
+return op1; \
+}
+#define DEFINE_SHIFT_SINGLE_2(_insn, _offset) \
+DEFINE_SHIFT_SINGLE_COMMON(_insn ## _ ## _offset, \
+   #_insn " %[op1]," #_offset "(%[op2])")
+#define DEFINE_SHIFT_SINGLE_3(_insn, _offset) \
+DEFINE_SHIFT_SINGLE_COMMON(_insn ## _ ## _offset, \
+   #_insn " %[op1],%[op1]," #_offset "(%[op2])")
+#define DEFINE_SHIFT_DOUBLE(_insn, _offset) \
+static uint64_t _insn ## _ ## _offset(uint64_t op1, uint64_t op2, \
+  uint64_t *cc) \
+{ \
+uint32_t op1h = op1 >> 32; \
+uint32_t op1l = op1 & 0x; \
+register uint32_t r2 asm("2") = op1h; \
+register uint32_t r3 asm("3") = op1l; \
+\
+asm("sll %[cc],28\n" \
+"spm %[cc]\n" \
+"" #_insn " %[r2]," #_offset "(%[op2])\n" \
+"ipm %[cc]\n" \
+"srl %[cc],28" \
+: [r2] "+" (r2), \
+  [r3] "+" (r3), \
+  [cc] "+" (*cc) \
+: [op2] "r" (op2) \
+: "cc"); \
+op1h = r2; \
+op1l = r3; \
+return (((uint64_t)op1h) << 32) | op1l; \
+}
+
+DEFINE_SHIFT_SINGLE_3(rll, 0x4cf3b);
+DEFINE_SHIFT_SINGLE_3(rllg, 0x697c9);
+DEFINE_SHIFT_SINGLE_2(sla, 0x4b0);
+DEFINE_SHIFT_SINGLE_2(sla, 0xd54);
+DEFINE_SHIFT_SINGLE_3(slak, 0x2832c);
+DEFINE_SHIFT_SINGLE_3(slag, 0x66cc4);
+DEFINE_SHIFT_SINGLE_3(slag, 0xd54);
+DEFINE_SHIFT_SINGLE_2(sll, 0xd04);
+DEFINE_SHIFT_SINGLE_3(sllk, 0x2699f);
+DEFINE_SHIFT_SINGLE_3(sllg, 0x59df9);
+DEFINE_SHIFT_SINGLE_2(sra, 0x67e);
+DEFINE_SHIFT_SINGLE_3(srak, 0x60943);
+DEFINE_SHIFT_SINGLE_3(srag, 0x6b048);
+DEFINE_SHIFT_SINGLE_2(srl, 0x035);
+DEFINE_SHIFT_SINGLE_3(srlk, 0x43dfc);
+DEFINE_SHIFT_SINGLE_3(srlg, 0x27227);
+DEFINE_SHIFT_DOUBLE(slda, 0x38b);
+DEFINE_SHIFT_DOUBLE(sldl, 0x031);
+DEFINE_SHIFT_DOUBLE(srda, 0x36f);
+DEFINE_SHIFT_DOUBLE(srdl, 0x99a);
+
+struct shift_test {
+const char *name;
+uint64_t (*insn)(uint64_t, uint64_t, uint64_t *);
+uint64_t op1;
+uint64_t op2;
+uint64_t exp_result;
+uint64_t exp_cc;
+};
+
+static const struct shift_test tests[] = {
+{
+.name = "rll",
+.insn = rll_0x4cf3b,
+.op1 = 0xecbd589a45c248f5ull,
+.op2 = 0x62e5508ccb4c99fdull,
+.exp_result = 0xecbd589af545c248ull,
+.exp_cc = 0,
+},
+{
+.name = "rllg",
+.insn = rllg_0x697c9,
+.op1 = 0xaa2d54c1b729f7f4ull,
+.op2 = 0x5ffcf7465f5cd71full,
+.exp_result = 0x29f7f4aa2d54c1b7ull,
+.exp_cc = 0,
+},
+{
+.name = "sla-1",
+.insn = sla_0x4b0,
+.op1 = 0x8bf21fb67cca0e96ull,
+.op2 = 0x3ddf2f53347d3030ull,
+.exp_result = 0x8bf21fb6ull,
+.exp_cc = 3,
+},
+{
+.name = "sla-2",
+.insn = sla_0xd54,
+.op1 = 0xe4faaed5def0e926ull,
+.op2 = 0x18d586fab239cbeeull,
+.exp_result = 0xe4faaed5fbc3a498ull,
+.exp_cc = 3,
+},
+{
+.name = "slak",
+.insn = slak_0x2832c,
+.op1 = 0x7300bf78707f09f9ull,
+.op2 = 0x4d193b85bb5cb39bull,
+.exp_result = 0x7300bf783f84fc80ull,
+.exp_cc = 3,
+},
+{
+.name = "slag-1",
+.insn = slag_0x66cc4,
+.op1 = 0xe805966de1a77762ull,
+.op2 = 0x0e92953f6aa91c6bull,
+.exp_result = 0xbbb1ull,
+.exp_cc = 3,
+},
+{
+.name = "slag-2",
+.insn = slag_0xd54,
+.op1 = 0xdef0e926ull,
+.op2 = 0x18d586fab239cbeeull,
+.exp_result = 0xfbc3a498ull,
+.exp_cc = 3,
+},
+{
+

[PATCH v4 3/5] target/s390x: Fix cc_calc_sla_64() missing overflows

2022-01-12 Thread Ilya Leoshkevich
An overflow occurs for SLAG when at least one shifted bit is not equal
to sign bit. Therefore, we need to check that `shift + 1` bits are
neither all 0s nor all 1s. The current code checks only `shift` bits,
missing some overflows.

Fixes: cbe24bfa91d2 ("target-s390: Convert SHIFT, ROTATE SINGLE")
Co-developed-by: David Hildenbrand 
Signed-off-by: Ilya Leoshkevich 
---
 target/s390x/tcg/cc_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/s390x/tcg/cc_helper.c b/target/s390x/tcg/cc_helper.c
index c2c96c3a3c..c9b7b0e8c6 100644
--- a/target/s390x/tcg/cc_helper.c
+++ b/target/s390x/tcg/cc_helper.c
@@ -297,7 +297,7 @@ static uint32_t cc_calc_sla_32(uint32_t src, int shift)
 
 static uint32_t cc_calc_sla_64(uint64_t src, int shift)
 {
-uint64_t mask = ((1ULL << shift) - 1ULL) << (64 - shift);
+uint64_t mask = -1ULL << (63 - shift);
 uint64_t sign = 1ULL << 63;
 uint64_t match;
 int64_t r;
-- 
2.31.1




Re: [RFC] virtio_pmem: enable live migration support

2022-01-12 Thread Pankaj Gupta
> >  I mean, that would be fundamentally broken, because the fsync() would
> >  corrupt the file. So I assume in a sane environment, the dst could only
> >  have stale clean pagecache pages. And we'd have to get rid of these to
> >  re-read everything from file.
> > >>>
> > >>> In case of write back cache mode, we could still have stale dirty
> > >>> pages at the destination
> > >>> host and destination fsync is not the right thing to do. We need to
> > >>> invalidate these pages
> > >>> (Can we invalidate dirty pages resident in page cache with
> > >>> POSIX_FADV_DONTNEED as
> > >>> well?) man pages say, we cannot (unless i misunderstood it).
> > >>>
> > >>
> > >> I think you'd have to fsync + POSIX_FADV_DONTNEED. But I am still
> > >> confused how we could end up with dirty pagecache pages on the
> > >> destination. In my opinion, there should only be clean pagecache pages
> > >> -- can someone enlighten me? :)
> > >
> > > because of activity on the page cache pages corresponding to mmap region
> > > in the past which is not synced yet or not reclaimed yet. Maybe this
> > > is hypothetical
> > > or not possible, happy to learn?
> >
> > Right, but assume the following *sane*
> >
> > #1 H0 starts and runs VM.
> > #2 H0 migrates VM to H1.
> > #3 H1 runs VM.
> > #4 H1 migrates VM to H0.
> > #5 H0 runs VM.
> >
> > We'd expect a proper fsync during #2, writing back any dirty pages to
> > the memory backend. Otherwise, #3 would already be broken. Similarly,
> > we'd expect a proper fsync during #4.
> >
> > I assume during #4 we could find clean pagecache pages that are actually
> > invalid, because the underlying file was changed by H1. So we have to
> > make sure to invalidate all pagecache pages (all clean).
>
> Yes, you mean fsync on source host before migration starts. My point
> is something
> like another process mmap same backend file on destination host and/or
> guest/qemu
> crashing abruptly.

In that case we should not start guest if we cannot invalidate all the
corresponding
page cache pages before starting guest i.e mmaping virtio-pmem backend file.

Thank you for the discussion!

Best regards,
Pankaj



Re: [PATCH v6 16/23] hw/riscv: virt: Use AIA INTC compatible string when available

2022-01-12 Thread Frank Chang
Anup Patel  於 2021年12月30日 週四 下午8:59寫道:

> From: Anup Patel 
>
> We should use the AIA INTC compatible string in the CPU INTC
> DT nodes when the CPUs support AIA feature. This will allow
> Linux INTC driver to use AIA local interrupt CSRs.
>
> Signed-off-by: Anup Patel 
> Signed-off-by: Anup Patel 
> Reviewed-by: Alistair Francis 
> ---
>  hw/riscv/virt.c | 13 +++--
>  1 file changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 3af074148e..720641b1dd 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -211,8 +211,17 @@ static void create_fdt_socket_cpus(RISCVVirtState *s,
> int socket,
>  qemu_fdt_add_subnode(mc->fdt, intc_name);
>  qemu_fdt_setprop_cell(mc->fdt, intc_name, "phandle",
>  intc_phandles[cpu]);
> -qemu_fdt_setprop_string(mc->fdt, intc_name, "compatible",
> -"riscv,cpu-intc");
> +if (riscv_feature(>soc[socket].harts[cpu].env,
> +  RISCV_FEATURE_AIA)) {
> +static const char * const compat[2] = {
> +"riscv,cpu-intc-aia", "riscv,cpu-intc"
> +};
> +qemu_fdt_setprop_string_array(mc->fdt, intc_name,
> "compatible",
> +  (char **),
> ARRAY_SIZE(compat));
> +} else {
> +qemu_fdt_setprop_string(mc->fdt, intc_name, "compatible",
> +"riscv,cpu-intc");
> +}
>  qemu_fdt_setprop(mc->fdt, intc_name, "interrupt-controller",
> NULL, 0);
>  qemu_fdt_setprop_cell(mc->fdt, intc_name, "#interrupt-cells", 1);
>
> --
> 2.25.1
>
>
>
Reviewed-by: Frank Chang 


Re: [RFC] virtio_pmem: enable live migration support

2022-01-12 Thread Pankaj Gupta
>  I mean, that would be fundamentally broken, because the fsync() would
>  corrupt the file. So I assume in a sane environment, the dst could only
>  have stale clean pagecache pages. And we'd have to get rid of these to
>  re-read everything from file.
> >>>
> >>> In case of write back cache mode, we could still have stale dirty
> >>> pages at the destination
> >>> host and destination fsync is not the right thing to do. We need to
> >>> invalidate these pages
> >>> (Can we invalidate dirty pages resident in page cache with
> >>> POSIX_FADV_DONTNEED as
> >>> well?) man pages say, we cannot (unless i misunderstood it).
> >>>
> >>
> >> I think you'd have to fsync + POSIX_FADV_DONTNEED. But I am still
> >> confused how we could end up with dirty pagecache pages on the
> >> destination. In my opinion, there should only be clean pagecache pages
> >> -- can someone enlighten me? :)
> >
> > because of activity on the page cache pages corresponding to mmap region
> > in the past which is not synced yet or not reclaimed yet. Maybe this
> > is hypothetical
> > or not possible, happy to learn?
>
> Right, but assume the following *sane*
>
> #1 H0 starts and runs VM.
> #2 H0 migrates VM to H1.
> #3 H1 runs VM.
> #4 H1 migrates VM to H0.
> #5 H0 runs VM.
>
> We'd expect a proper fsync during #2, writing back any dirty pages to
> the memory backend. Otherwise, #3 would already be broken. Similarly,
> we'd expect a proper fsync during #4.
>
> I assume during #4 we could find clean pagecache pages that are actually
> invalid, because the underlying file was changed by H1. So we have to
> make sure to invalidate all pagecache pages (all clean).

Yes, you mean fsync on source host before migration starts. My point
is something
like another process mmap same backend file on destination host and/or
guest/qemu
crashing abruptly.



Re: [PATCH v6 14/23] target/riscv: Implement AIA xiselect and xireg CSRs

2022-01-12 Thread Frank Chang
Anup Patel  於 2021年12月30日 週四 下午8:51寫道:

> From: Anup Patel 
>
> The AIA specification defines [m|s|vs]iselect and [m|s|vs]ireg CSRs
> which allow indirect access to interrupt priority arrays and per-HART
> IMSIC registers. This patch implements AIA xiselect and xireg CSRs.
>
> Signed-off-by: Anup Patel 
> Signed-off-by: Anup Patel 
> ---
>  target/riscv/cpu.h |   7 ++
>  target/riscv/csr.c | 175 +
>  target/riscv/machine.c |   3 +
>  3 files changed, 185 insertions(+)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 721727c577..82272f99fd 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -186,6 +186,10 @@ struct CPURISCVState {
>  uint8_t miprio[64];
>  uint8_t siprio[64];
>
> +/* AIA CSRs */
> +target_ulong miselect;
> +target_ulong siselect;
> +
>  /* Hypervisor CSRs */
>  target_ulong hstatus;
>  target_ulong hedeleg;
> @@ -215,6 +219,9 @@ struct CPURISCVState {
>  target_ulong vstval;
>  target_ulong vsatp;
>
> +/* AIA VS-mode CSRs */
> +target_ulong vsiselect;
> +
>  target_ulong mtval2;
>  target_ulong mtinst;
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 5a27c3bfbb..488877e89c 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -895,6 +895,169 @@ static int read_mtopi(CPURISCVState *env, int csrno,
> target_ulong *val)
>  return RISCV_EXCP_NONE;
>  }
>
> +static int aia_xlate_vs_csrno(CPURISCVState *env, int csrno)
> +{
> +if (!riscv_cpu_virt_enabled(env)) {
> +return csrno;
> +}
> +
> +switch (csrno) {
> +case CSR_SISELECT:
> +return CSR_VSISELECT;
> +case CSR_SIREG:
> +return CSR_VSIREG;
> +default:
> +return csrno;
> +};
> +}
> +
> +static int rmw_xiselect(CPURISCVState *env, int csrno, target_ulong *val,
> +target_ulong new_val, target_ulong wr_mask)
> +{
> +target_ulong *iselect;
> +
> +/* Translate CSR number for VS-mode */
> +csrno = aia_xlate_vs_csrno(env, csrno);
> +
> +/* Find the iselect CSR based on CSR number */
> +switch (csrno) {
> +case CSR_MISELECT:
> +iselect = >miselect;
> +break;
> +case CSR_SISELECT:
> +iselect = >siselect;
> +break;
> +case CSR_VSISELECT:
> +iselect = >vsiselect;
> +break;
> +default:
> + return RISCV_EXCP_ILLEGAL_INST;
> +};
> +
> +if (val) {
> +*val = *iselect;
> +}
> +
> +wr_mask &= ISELECT_MASK;
> +if (wr_mask) {
> +*iselect = (*iselect & ~wr_mask) | (new_val & wr_mask);
> +}
> +
> +return RISCV_EXCP_NONE;
> +}
> +
> +static int rmw_iprio(target_ulong xlen,
> + target_ulong iselect, uint8_t *iprio,
> + target_ulong *val, target_ulong new_val,
> + target_ulong wr_mask, int ext_irq_no)
> +{
> +int i, firq, nirqs;
> +target_ulong old_val;
> +
> +if (iselect < ISELECT_IPRIO0 || ISELECT_IPRIO15 < iselect) {
> +return -EINVAL;
> +}
> +if (xlen != 32 && iselect & 0x1) {
> +return -EINVAL;
> +}
> +
> +nirqs = 4 * (xlen / 32);
> +firq = ((iselect - ISELECT_IPRIO0) / (xlen / 32)) * (nirqs);
> +
> +old_val = 0;
> +for (i = 0; i < nirqs; i++) {
> +old_val |= ((target_ulong)iprio[firq + i]) << (IPRIO_IRQ_BITS *
> i);
> +}
> +
> +if (val) {
> +*val = old_val;
> +}
> +
> +if (wr_mask) {
> +new_val = (old_val & ~wr_mask) | (new_val & wr_mask);
> +for (i = 0; i < nirqs; i++) {
> +/*
> + * M-level and S-level external IRQ priority always read-only
> + * zero. This means default priority order is always preferred
> + * for M-level and S-level external IRQs.
> + */
> +if ((firq + i) == ext_irq_no) {
> +continue;
> +}
> +iprio[firq + i] = (new_val >> (IPRIO_IRQ_BITS * i)) & 0xff;
> +}
> +}
> +
> +return 0;
> +}
> +
> +static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
> + target_ulong new_val, target_ulong wr_mask)
> +{
> +bool virt;
> +uint8_t *iprio;
> +int ret = -EINVAL;
> +target_ulong priv, isel, vgein;
> +
> +/* Translate CSR number for VS-mode */
> +csrno = aia_xlate_vs_csrno(env, csrno);
> +
> +/* Decode register details from CSR number */
> +virt = false;
> +switch (csrno) {
> +case CSR_MIREG:
> +iprio = env->miprio;
> +isel = env->miselect;
> +priv = PRV_M;
> +break;
> +case CSR_SIREG:
> +iprio = env->siprio;
> +isel = env->siselect;
> +priv = PRV_S;
> +break;
> +case CSR_VSIREG:
> +iprio = env->hviprio;
> +isel = env->vsiselect;
> +priv = PRV_S;
> +virt = true;
> +break;
> +default:
> + goto 

[RFC PATCH] MAINTAINERS: Add myself to s390 I/O areas

2022-01-12 Thread Eric Farman
After the recent restructuring, I'd like to volunteer to help
in some of the s390 I/O areas.

Built on "[PATCH RFC v2] MAINTAINERS: split out s390x sections"

Signed-off-by: Eric Farman 
---
 MAINTAINERS | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 5d37b0eec5..343f43e83d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1521,6 +1521,7 @@ S390 Machines
 S390 Virtio-ccw
 M: Halil Pasic 
 M: Christian Borntraeger 
+M: Eric Farman 
 S: Supported
 F: hw/s390x/
 F: include/hw/s390x/
@@ -1551,6 +1552,7 @@ L: qemu-s3...@nongnu.org
 S390 channel subsystem
 M: Halil Pasic 
 M: Christian Borntraeger 
+M: Eric Farman 
 S: Supported
 F: hw/s390x/ccw-device.[ch]
 F: hw/s390x/css.c
@@ -1975,6 +1977,7 @@ T: git https://github.com/stefanha/qemu.git block
 virtio-ccw
 M: Cornelia Huck 
 M: Halil Pasic 
+M: Eric Farman 
 S: Supported
 F: hw/s390x/virtio-ccw*.[hc]
 F: hw/s390x/vhost-vsock-ccw.c
-- 
2.32.0




Re: [PATCH v2 3/5] target/s390x: Fix cc_calc_sla_64() missing overflows

2022-01-12 Thread Ilya Leoshkevich
On Wed, 2022-01-12 at 16:45 +0100, David Hildenbrand wrote:
> > > If the sign is false, the shifted bits (mask) have to be 0.
> > > If the sign bit is true, the shifted bits (mask) have to be set.
> > 
> > IIUC this logic handles sign bit + "shift - 1" bits. So if the last
> > shifted bit is different, the overflow is not detected.
> 
> Ah, right, because of the - 1ULL ...
> 
> [...]
> 
> > > This looks like some black magic :)
> > 
> > Yeah, I felt this way too, but didn't come up with anything better
> > and
> > just left a comment warning not to simplify.
> > 
> 
> I wonder if all we want is
> 
> const uint64_t sign = 1ULL << 63;
> uint64_t mask = (-1ULL << (63 - shift)) & ~sign;
> 
> For shift =
> *  0: 000...0b
> *  1: 010...0b
> *  2: 011...0b
> * 63: 011...1b
> 
> Seems to survive your tests.

-1ULL does indeed help a lot to simplify this.
I don't think we even need to mask out the sign, since it should be
the same as the other bits anyway. So just

uint64_t mask = -1ULL << (63 - shift);

appears to be enough.



Re: [RFC] virtio_pmem: enable live migration support

2022-01-12 Thread David Hildenbrand
On 12.01.22 17:08, Pankaj Gupta wrote:
 I mean, that would be fundamentally broken, because the fsync() would
 corrupt the file. So I assume in a sane environment, the dst could only
 have stale clean pagecache pages. And we'd have to get rid of these to
 re-read everything from file.
>>>
>>> In case of write back cache mode, we could still have stale dirty
>>> pages at the destination
>>> host and destination fsync is not the right thing to do. We need to
>>> invalidate these pages
>>> (Can we invalidate dirty pages resident in page cache with
>>> POSIX_FADV_DONTNEED as
>>> well?) man pages say, we cannot (unless i misunderstood it).
>>>
>>
>> I think you'd have to fsync + POSIX_FADV_DONTNEED. But I am still
>> confused how we could end up with dirty pagecache pages on the
>> destination. In my opinion, there should only be clean pagecache pages
>> -- can someone enlighten me? :)
> 
> because of activity on the page cache pages corresponding to mmap region
> in the past which is not synced yet or not reclaimed yet. Maybe this
> is hypothetical
> or not possible, happy to learn?

Right, but assume the following *sane*

#1 H0 starts and runs VM.
#2 H0 migrates VM to H1.
#3 H1 runs VM.
#4 H1 migrates VM to H0.
#5 H0 runs VM.

We'd expect a proper fsync during #2, writing back any dirty pages to
the memory backend. Otherwise, #3 would already be broken. Similarly,
we'd expect a proper fsync during #4.

I assume during #4 we could find clean pagecache pages that are actually
invalid, because the underlying file was changed by H1. So we have to
make sure to invalidate all pagecache pages (all clean).

-- 
Thanks,

David / dhildenb




Re: [PULL 00/30] Linux user for 7.0 patches

2022-01-12 Thread Peter Maydell
On Tue, 11 Jan 2022 at 19:55, Laurent Vivier  wrote:
>
> The following changes since commit 64c01c7da449bcafc614b27ecf1325bb08031c84:
>
>   Merge remote-tracking branch 'remotes/philmd/tags/sdmmc-20220108' into 
> staging (2022-01-11 11:39:31 +)
>
> are available in the Git repository at:
>
>   https://gitlab.com/laurent_vivier/qemu.git 
> tags/linux-user-for-7.0-pull-request
>
> for you to fetch changes up to 4f4e5567f856d9b841494b3b5216a37d2952ee54:
>
>   linux-user: Implement capability prctls (2022-01-11 18:40:44 +0100)
>
> 
> linux-user pull request 20220111
> siginfo_t cleanup
> more prtctl() update
> target_struct.h cleanup
>

Applied, thanks.

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

-- PMM



Re: [PATCH] hw/timer/etraxfs_timer: Add vmstate for ETRAX timers

2022-01-12 Thread Peter Maydell
On Sat, 18 Dec 2021 at 02:28, Richard Henderson
 wrote:
> What I don't understand is how these controls get applied to qemu_irq after 
> vmload, here
> or in any other device.  It seems like we should have some post_load hook 
> that calls
> timer_update_irq, etc.

Very late answer, but: we don't need to call qemu_set_irq() on
qemu_irqs outbound from a device after a vmload, because IRQ
lines themselves have no state. The device on the other end of
the irq line also loads its own state, and typically that includes
its internal variables which it uses to track whether its input
lines are 0 or 1.

-- PMM



Re: [PATCH v3 4/5] target/s390x: Fix shifting 32-bit values for more than 31 bits

2022-01-12 Thread David Hildenbrand


>  static DisasJumpType help_goto_direct(DisasContext *s, uint64_t dest)
>  {
>  if (dest == s->pc_tmp) {
> @@ -4113,9 +4099,15 @@ static DisasJumpType op_soc(DisasContext *s, DisasOps 
> *o)
>  
>  static DisasJumpType op_sla(DisasContext *s, DisasOps *o)
>  {
> +TCGv_i64 t;
>  uint64_t sign = 1ull << s->insn->data;
> -enum cc_op cco = s->insn->data == 31 ? CC_OP_SLA_32 : CC_OP_SLA_64;
> -gen_op_update2_cc_i64(s, cco, o->in1, o->in2);
> +if (s->insn->data == 31) {
> +t = tcg_temp_new_i64();
> +tcg_gen_shli_i64(t, o->in1, 32);
> +} else {
> +t = o->in1;
> +}

Are you missing to free the temp in case you allocated one?

-- 
Thanks,

David / dhildenb




Re: [PATCH v3 0/2] Aspeed I3C device model

2022-01-12 Thread Graeme Gregory
On Wed, Jan 12, 2022 at 01:45:05PM +0100, Cédric Le Goater wrote:
> Hello Gregory,
> 
> On 1/12/22 11:57, Graeme Gregory wrote:
> > On Tue, Jan 11, 2022 at 04:45:44PM +0800, Troy Lee wrote:
> > > This series of patch introduce a dummy implemenation of aspeed i3c
> > > model, and it provide just enough information for guest machine.
> > > However, the driver probing is still failed, but it will not cause
> > > kernel panic.
> > > 
> > 
> > These patches arrived just in time for our i3c testing. This stops
> > our CI halting due to kernel panic on i3c probing.
> > 
> > Reviewed-by: Graeme Gregory 
> > Tested-by: Graeme Gregory 
> 
> Excellent !
> 
> Are you using the Aspeed image from :
> 
>  https://github.com/AspeedTech-BMC/openbmc/releases/tag/v07.02
> 
> or your custom ones ?
> 
We are using the drivers from the v5.4 based SDK currently. Hacked
into the v5.15 kernel of openbmc upstream! We needed something quick
to test a new PCB.

Graeme




Re: [PATCH v10 0/7] Add vmnet.framework based network backend

2022-01-12 Thread Roman Bolshakov
On Wed, Jan 12, 2022 at 04:23:30PM +0300, Vladislav Yaroshchuk wrote:
> ср, 12 янв. 2022 г. в 11:22, Roman Bolshakov :
> 
> > On Wed, Jan 12, 2022 at 10:50:04AM +0300, Roman Bolshakov wrote:
> > > On Wed, Jan 12, 2022 at 12:14:15AM +0300, Vladislav Yaroshchuk wrote:
> > > > v9 -> v10
> > > >  - Disable vmnet feature for macOS < 11.0: add
> > > >vmnet.framework API probe into meson.build.
> > > >This fixes QEMU building on macOS < 11.0:
> > > >
> > >
> > > Hi Vladislav,
> > >
> > > What symbols are missing on Catalina except VMNET_SHARING_BUSY?
> > >
> > > It'd be great to get the feature working there.
> > >
> > > Thanks,
> > > Roman
> > >
> >
> > Ok it turned out not that many symbols are needed for successfull
> > compilation on Catalina:
> >
> > vmnet_enable_isolation_key
> > vmnet_network_identifier_key
> > VMNET_SHARING_SERVICE_BUSY
> >
> > The compilation suceeds if they're wrappeed by ifdefs. I haven't tested
> > it yet though.
> >
> >
> New version with Catalina 10.15 support submitted as v11.
> 

Thanks!

I appreciate that.

Regards,
Roman




Re: [PATCH v2 3/5] target/s390x: Fix cc_calc_sla_64() missing overflows

2022-01-12 Thread David Hildenbrand
>> If the sign is false, the shifted bits (mask) have to be 0.
>> If the sign bit is true, the shifted bits (mask) have to be set.
> 
> IIUC this logic handles sign bit + "shift - 1" bits. So if the last
> shifted bit is different, the overflow is not detected.

Ah, right, because of the - 1ULL ...

[...]

>> This looks like some black magic :)
> 
> Yeah, I felt this way too, but didn't come up with anything better and
> just left a comment warning not to simplify.
> 

I wonder if all we want is

const uint64_t sign = 1ULL << 63;
uint64_t mask = (-1ULL << (63 - shift)) & ~sign;

For shift =
*  0: 000...0b
*  1: 010...0b
*  2: 011...0b
* 63: 011...1b

Seems to survive your tests.

-- 
Thanks,

David / dhildenb




Re: [RFC] virtio_pmem: enable live migration support

2022-01-12 Thread Pankaj Gupta
> >> I mean, that would be fundamentally broken, because the fsync() would
> >> corrupt the file. So I assume in a sane environment, the dst could only
> >> have stale clean pagecache pages. And we'd have to get rid of these to
> >> re-read everything from file.
> >
> > In case of write back cache mode, we could still have stale dirty
> > pages at the destination
> > host and destination fsync is not the right thing to do. We need to
> > invalidate these pages
> > (Can we invalidate dirty pages resident in page cache with
> > POSIX_FADV_DONTNEED as
> > well?) man pages say, we cannot (unless i misunderstood it).
> >
>
> I think you'd have to fsync + POSIX_FADV_DONTNEED. But I am still
> confused how we could end up with dirty pagecache pages on the
> destination. In my opinion, there should only be clean pagecache pages
> -- can someone enlighten me? :)

because of activity on the page cache pages corresponding to mmap region
in the past which is not synced yet or not reclaimed yet. Maybe this
is hypothetical
or not possible, happy to learn?

>
> >>
> >> IIRC, an existing mmap of the file on the dst should not really be
> >> problematic *as long as* we didn't actually access file content that way
> >> and faulted in the pages. So *maybe*, if we do the POSIX_FADV_DONTNEED
> >> on the dst before accessing file content via the mmap, there shouldn't
> >> be an issue. Unless the mmap itself is already problematic.
> >
> > mmap with shared=ON, might result in stale dirty page cache pages?
>
> But only if actually accessing memory, especially writing to it, no?

yes.


>
> >
> >>
> >> I think we can assume that once QEMU starts on the dst and wants to mmap
> >> the file that it's not mapped into any other process yet. vhost-user
> >> will only mmap *after* being told from QEMU about the mmap region and
> >> the location in GPA.
> >
> > maybe we have an old stale dirty page cache page even if there no mmap 
> > process
> > alive before mmaping virtio-pmem backend file in destination?
>
> But how could that happen in a sane environment? As I said, any
> writeback on that file from the destination would actually corrupt the
> file that has been used+modified on the source in the meantime, no?
>
>
> --
> Thanks,
>
> David / dhildenb
>



  1   2   3   4   >