Re: [PATCH v4 8/9] aspeed: Add an AST1030 eval board

2022-04-01 Thread Cédric Le Goater

On 4/1/22 05:46, Jamin Lin wrote:

The image should be supplied with ELF binary.
$ qemu-system-arm -M ast1030-evb -kernel zephyr.elf -nographic

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Signed-off-by: Steven Lee 
---
  hw/arm/aspeed.c | 97 +
  include/hw/arm/aspeed.h |  6 +--
  2 files changed, 100 insertions(+), 3 deletions(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index d205384d98..30b49d2db1 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -24,6 +24,7 @@
  #include "hw/loader.h"
  #include "qemu/error-report.h"
  #include "qemu/units.h"
+#include "hw/qdev-clock.h"
  
  static struct arm_boot_info aspeed_board_binfo = {

  .board_id = -1, /* device-tree-only board */
@@ -1361,3 +1362,99 @@ static const TypeInfo aspeed_machine_types[] = {
  };
  
  DEFINE_TYPES(aspeed_machine_types)

+
+#define AST1030_INTERNAL_FLASH_SIZE (1024 * 1024)
+/* Main SYSCLK frequency in Hz (200MHz) */
+#define SYSCLK_FRQ 2ULL
+
+static void aspeed_minibmc_machine_ast1030_evb_class_init(ObjectClass *oc,
+  void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+AspeedMachineClass *amc = ASPEED_MINIBMC_MACHINE_CLASS(oc);


I don't think we need a ASPEED_MINIBMC type (yet)


+
+mc->desc = "Aspeed AST1030 MiniBMC (Cortex-M4)";
+amc->soc_name = "ast1030-a1";
+amc->hw_strap1 = 0;
+amc->hw_strap2 = 0;
+mc->default_ram_size = 0;
+mc->default_cpus = mc->min_cpus = mc->max_cpus = 1;
+amc->fmc_model = "sst25vf032b";
+amc->spi_model = "sst25vf032b";
+amc->num_cs = 2;


In this routine, you could add :

 amc->macs_mask = 0;

Since the NICs are not modeled yet.


+}
+
+static void ast1030_machine_instance_init(Object *obj)
+{
+ASPEED_MINIBMC_MACHINE(obj)->mmio_exec = false;
+}


ast1030_machine_instance_init() is not that useful either.


+
+static void aspeed_minibmc_machine_init(MachineState *machine)
+{
+AspeedMachineState *bmc = ASPEED_MINIBMC_MACHINE(machine);
+AspeedMachineClass *amc = ASPEED_MINIBMC_MACHINE_GET_CLASS(machine);
+Clock *sysclk;
+
+sysclk = clock_new(OBJECT(machine), "SYSCLK");
+clock_set_hz(sysclk, SYSCLK_FRQ);
+
+object_initialize_child(OBJECT(machine), "soc", &bmc->soc, amc->soc_name);
+qdev_connect_clock_in(DEVICE(&bmc->soc), "sysclk", sysclk);
+
+qdev_prop_set_uint32(DEVICE(&bmc->soc), "uart-default",
+ amc->uart_default);
+qdev_realize(DEVICE(&bmc->soc), NULL, &error_abort);
+
+aspeed_board_init_flashes(&bmc->soc.fmc,
+  bmc->fmc_model ? bmc->fmc_model : amc->fmc_model,
+  amc->num_cs,
+  0);
+
+aspeed_board_init_flashes(&bmc->soc.spi[0],
+  bmc->spi_model ? bmc->spi_model : amc->spi_model,
+  amc->num_cs, amc->num_cs);
+
+aspeed_board_init_flashes(&bmc->soc.spi[1],
+  bmc->spi_model ? bmc->spi_model : amc->spi_model,
+  amc->num_cs, (amc->num_cs * 2));
+
+if (amc->i2c_init) {
+amc->i2c_init(bmc);
+}
+
+armv7m_load_kernel(ARM_CPU(first_cpu),
+   machine->kernel_filename,
+   AST1030_INTERNAL_FLASH_SIZE);
+}
+
+static void aspeed_minibmc_machine_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+AspeedMachineClass *amc = ASPEED_MINIBMC_MACHINE_CLASS(oc);
+
+mc->init = aspeed_minibmc_machine_init;
+mc->no_floppy = 1;
+mc->no_cdrom = 1;
+mc->no_parallel = 1;
+mc->default_ram_id = "ram";
+amc->uart_default = ASPEED_DEV_UART5;


This is very much like aspeed_machine_class_init()



+}
+
+static const TypeInfo aspeed_minibmc_machine_types[] = {
+{
+.name   = MACHINE_TYPE_NAME("ast1030-evb"),
+.parent = TYPE_ASPEED_MINIBMC_MACHINE,


Why don't you inherit directly from TYPE_ASPEED_MACHINE and simplify
the model by removing the duplicate TYPE_ASPEED_MINIBMC_MACHINE ?


+.class_init = aspeed_minibmc_machine_ast1030_evb_class_init,
+}, {
+.name   = TYPE_ASPEED_MINIBMC_MACHINE,
+.parent = TYPE_MACHINE,
+.instance_size  = sizeof(AspeedMachineState),
+.instance_init  = ast1030_machine_instance_init,
+.class_size= sizeof(AspeedMachineClass),
+.class_init= aspeed_minibmc_machine_class_init,
+.abstract  = true,
+}
+};
+
+DEFINE_TYPES(aspeed_minibmc_machine_types)
+
diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h
index cbeacb214c..b7411c860d 100644
--- a/include/hw/arm/aspeed.h
+++ b/include/hw/arm/aspeed.h
@@ -13,18 +13,19 @@
  #include "qom/object.h"
  
  typedef struct AspeedMachineState AspeedMachineState;

-
  #define TYPE_ASPEED_MACHINE   MACHINE_TYPE_NAME("aspeed")
+#define TYPE_ASPEED_MINIBMC_MACHIN

Re: [RFC PATCH 1/2] spapr: Report correct GTSE support via ov5

2022-04-01 Thread Aneesh Kumar K.V
David Gibson  writes:

> On Mon, Mar 14, 2022 at 07:10:10PM -0300, Fabiano Rosas wrote:
>> David Gibson  writes:
>> 
>> > On Tue, Mar 08, 2022 at 10:23:59PM -0300, Fabiano Rosas wrote:
>>

...

>> To satisfy TCG we could keep a spapr capability as ON and usually the
>> guest would pass cap-gtse=off when running with KVM. However this
>> doesn't work because this crash happens precisely because the nested
>> guest doesn't know that it needs to use cap-rpt-invalidate=on. Another
>> cap wouldn't help.
>> 
>> So I think the only way to have a spapr capability for this is if TCG
>> always defaults to ON and KVM always defaults to OFF. But then we would
>> be changing guest visible behaviour depending on host properties.
>
> Ok, I'd forgotten we already have cap-rpt-invalidate.  It still
> defaults to OFF for now, which might help us.
>
> What's clear is that we should never disable GTSE if
> cap-rpt-invalidate is off - qemu should enforce that before even
> starting the guest if at all possible.
>
> What's less clear to me is if we want to enable GTSE by default or
> not, in the cases where we're able to choose.  Would always disabling
> GTSE when cap-rpt-invalidate=on be ok?  Or do we want to be able to
> control GTSE separately.  In that case we might need a second cap, but
> it would need inverted sense, so e.g. cap-disable-gtse.


GTSE and cap-rpt-invalidate can be looked at as independent such that we
can do GTSE=1 or GTSE=0 with cap-rpt-invalidate=on. But GTSE=0 with
cap-rpt-invalidate=off is not allowed/possible. GTSE value is what is
negotiated via CAS so we should let the hypervisor inform the guest whether it
can do GTSE 0 or 1. The challenge IIUC is Qemu always assumed GTSE=1
which is not true in the case of nested virt where L1 guest that is booted
with GTSE=0.

with cap-disable-gtse how would one interpret that? Whether hypervisor
have the capability to disable gtse? 

>
> I believe a guest that is expecting GTSE==0 should work if
> LPCR[GTSE]==1, just not optimally (as long as H_RPT_INVALIDATE is
> still available, of course).  Is that right?

That is correct.

-aneesh



Re: [PATCH v1 1/2] timer: cadence_ttc: Break out header file to allow embedding

2022-04-01 Thread Luc Michel
On 00:20 Fri 01 Apr , Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" 
> 
> Break out header file to allow embedding of the the TTC.
> 
> Signed-off-by: Edgar E. Iglesias 

Reviewed-by: Luc Michel 

> ---
>  include/hw/timer/cadence_ttc.h | 54 ++
>  hw/timer/cadence_ttc.c | 32 ++--
>  2 files changed, 56 insertions(+), 30 deletions(-)
>  create mode 100644 include/hw/timer/cadence_ttc.h
> 
> diff --git a/include/hw/timer/cadence_ttc.h b/include/hw/timer/cadence_ttc.h
> new file mode 100644
> index 00..e1251383f2
> --- /dev/null
> +++ b/include/hw/timer/cadence_ttc.h
> @@ -0,0 +1,54 @@
> +/*
> + * Xilinx Zynq cadence TTC model
> + *
> + * Copyright (c) 2011 Xilinx Inc.
> + * Copyright (c) 2012 Peter A.G. Crosthwaite 
> (peter.crosthwa...@petalogix.com)
> + * Copyright (c) 2012 PetaLogix Pty Ltd.
> + * Written By Haibing Ma
> + *M. Habib
> + *
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, see .
> + */
> +#ifndef HW_TIMER_CADENCE_TTC_H
> +#define HW_TIMER_CADENCE_TTC_H
> +
> +#include "hw/sysbus.h"
> +#include "qemu/timer.h"
> +
> +typedef struct {
> +QEMUTimer *timer;
> +int freq;
> +
> +uint32_t reg_clock;
> +uint32_t reg_count;
> +uint32_t reg_value;
> +uint16_t reg_interval;
> +uint16_t reg_match[3];
> +uint32_t reg_intr;
> +uint32_t reg_intr_en;
> +uint32_t reg_event_ctrl;
> +uint32_t reg_event;
> +
> +uint64_t cpu_time;
> +unsigned int cpu_time_valid;
> +
> +qemu_irq irq;
> +} CadenceTimerState;
> +
> +#define TYPE_CADENCE_TTC "cadence_ttc"
> +OBJECT_DECLARE_SIMPLE_TYPE(CadenceTTCState, CADENCE_TTC)
> +
> +struct CadenceTTCState {
> +SysBusDevice parent_obj;
> +
> +MemoryRegion iomem;
> +CadenceTimerState timer[3];
> +};
> +
> +#endif
> diff --git a/hw/timer/cadence_ttc.c b/hw/timer/cadence_ttc.c
> index 64108241ba..e57a0f5f09 100644
> --- a/hw/timer/cadence_ttc.c
> +++ b/hw/timer/cadence_ttc.c
> @@ -24,6 +24,8 @@
>  #include "qemu/timer.h"
>  #include "qom/object.h"
>  
> +#include "hw/timer/cadence_ttc.h"
> +
>  #ifdef CADENCE_TTC_ERR_DEBUG
>  #define DB_PRINT(...) do { \
>  fprintf(stderr,  ": %s: ", __func__); \
> @@ -49,36 +51,6 @@
>  #define CLOCK_CTRL_PS_EN0x0001
>  #define CLOCK_CTRL_PS_V 0x001e
>  
> -typedef struct {
> -QEMUTimer *timer;
> -int freq;
> -
> -uint32_t reg_clock;
> -uint32_t reg_count;
> -uint32_t reg_value;
> -uint16_t reg_interval;
> -uint16_t reg_match[3];
> -uint32_t reg_intr;
> -uint32_t reg_intr_en;
> -uint32_t reg_event_ctrl;
> -uint32_t reg_event;
> -
> -uint64_t cpu_time;
> -unsigned int cpu_time_valid;
> -
> -qemu_irq irq;
> -} CadenceTimerState;
> -
> -#define TYPE_CADENCE_TTC "cadence_ttc"
> -OBJECT_DECLARE_SIMPLE_TYPE(CadenceTTCState, CADENCE_TTC)
> -
> -struct CadenceTTCState {
> -SysBusDevice parent_obj;
> -
> -MemoryRegion iomem;
> -CadenceTimerState timer[3];
> -};
> -
>  static void cadence_timer_update(CadenceTimerState *s)
>  {
>  qemu_set_irq(s->irq, !!(s->reg_intr & s->reg_intr_en));
> -- 
> 2.25.1
> 

-- 



Re: [PATCH v1 2/2] hw/arm/xlnx-zynqmp: Connect 4 TTC timers

2022-04-01 Thread Luc Michel
On 00:20 Fri 01 Apr , Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" 
> 
> Connect the 4 TTC timers on the ZynqMP.
> 
> Signed-off-by: Edgar E. Iglesias 

Reviewed-by: Luc Michel 

> ---
>  include/hw/arm/xlnx-zynqmp.h |  4 
>  hw/arm/xlnx-zynqmp.c | 22 ++
>  2 files changed, 26 insertions(+)
> 
> diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
> index 9d9a9d0bf9..85fd9f53da 100644
> --- a/include/hw/arm/xlnx-zynqmp.h
> +++ b/include/hw/arm/xlnx-zynqmp.h
> @@ -41,6 +41,7 @@
>  #include "hw/or-irq.h"
>  #include "hw/misc/xlnx-zynqmp-apu-ctrl.h"
>  #include "hw/misc/xlnx-zynqmp-crf.h"
> +#include "hw/timer/cadence_ttc.h"
>  
>  #define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
>  OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
> @@ -84,6 +85,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
>  #define XLNX_ZYNQMP_MAX_RAM_SIZE (XLNX_ZYNQMP_MAX_LOW_RAM_SIZE + \
>XLNX_ZYNQMP_MAX_HIGH_RAM_SIZE)
>  
> +#define XLNX_ZYNQMP_NUM_TTC 4
> +
>  /*
>   * Unimplemented mmio regions needed to boot some images.
>   */
> @@ -128,6 +131,7 @@ struct XlnxZynqMPState {
>  qemu_or_irq qspi_irq_orgate;
>  XlnxZynqMPAPUCtrl apu_ctrl;
>  XlnxZynqMPCRF crf;
> +CadenceTTCState ttc[XLNX_ZYNQMP_NUM_TTC];
>  
>  char *boot_cpu;
>  ARMCPU *boot_cpu_ptr;
> diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
> index 5bfe285a19..375309e68e 100644
> --- a/hw/arm/xlnx-zynqmp.c
> +++ b/hw/arm/xlnx-zynqmp.c
> @@ -68,6 +68,9 @@
>  #define APU_ADDR0xfd5c
>  #define APU_IRQ 153
>  
> +#define TTC0_ADDR   0xFF11
> +#define TTC0_IRQ36
> +
>  #define IPI_ADDR0xFF30
>  #define IPI_IRQ 64
>  
> @@ -316,6 +319,24 @@ static void xlnx_zynqmp_create_crf(XlnxZynqMPState *s, 
> qemu_irq *gic)
>  sysbus_connect_irq(sbd, 0, gic[CRF_IRQ]);
>  }
>  
> +static void xlnx_zynqmp_create_ttc(XlnxZynqMPState *s, qemu_irq *gic)
> +{
> +SysBusDevice *sbd;
> +int i, irq;
> +
> +for (i = 0; i < XLNX_ZYNQMP_NUM_TTC; i++) {
> +object_initialize_child(OBJECT(s), "ttc[*]", &s->ttc[i],
> +TYPE_CADENCE_TTC);
> +sbd = SYS_BUS_DEVICE(&s->ttc[i]);
> +
> +sysbus_realize(sbd, &error_fatal);
> +sysbus_mmio_map(sbd, 0, TTC0_ADDR + i * 0x1);
> +for (irq = 0; irq < 3; irq++) {
> +sysbus_connect_irq(sbd, irq, gic[TTC0_IRQ + i * 3 + irq]);
> +}
> +}
> +}
> +
>  static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
>  {
>  static const struct UnimpInfo {
> @@ -721,6 +742,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error 
> **errp)
>  xlnx_zynqmp_create_efuse(s, gic_spi);
>  xlnx_zynqmp_create_apu_ctrl(s, gic_spi);
>  xlnx_zynqmp_create_crf(s, gic_spi);
> +xlnx_zynqmp_create_ttc(s, gic_spi);
>  xlnx_zynqmp_create_unimp_mmio(s);
>  
>  for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
> -- 
> 2.25.1
> 

-- 



Re: [PATCH] vhost: Fix bad return of descriptors to SVQ

2022-04-01 Thread Eugenio Perez Martin
On Fri, Apr 1, 2022 at 4:30 AM Jason Wang  wrote:
>
> On Fri, Apr 1, 2022 at 2:14 AM Eugenio Pérez  wrote:
> >
> > Only the first one of them were properly enqueued back.
> >
> > Fixes: 100890f7ca ("vhost: Shadow virtqueue buffers forwarding")
> > Signed-off-by: Eugenio Pérez 
> > ---
> >  hw/virtio/vhost-shadow-virtqueue.c | 17 +++--
> >  1 file changed, 15 insertions(+), 2 deletions(-)
> >
> > diff --git a/hw/virtio/vhost-shadow-virtqueue.c 
> > b/hw/virtio/vhost-shadow-virtqueue.c
> > index b232803d1b..c17506df20 100644
> > --- a/hw/virtio/vhost-shadow-virtqueue.c
> > +++ b/hw/virtio/vhost-shadow-virtqueue.c
> > @@ -333,13 +333,25 @@ static void 
> > vhost_svq_disable_notification(VhostShadowVirtqueue *svq)
> >  svq->vring.avail->flags |= cpu_to_le16(VRING_AVAIL_F_NO_INTERRUPT);
> >  }
> >
> > +static uint16_t vhost_svq_last_desc_of_chain(VhostShadowVirtqueue *svq,
> > + uint16_t i)
> > +{
> > +vring_desc_t *descs = svq->vring.desc;
> > +
> > +while (le16_to_cpu(descs[i].flags) & VRING_DESC_F_NEXT) {
> > +i = le16_to_cpu(descs[i].next);
>
>
> This seems to be a guest trigger-able infinite loop?
>

This is the list of the SVQ vring. We could consider an infinite loop
triggable by the device if it can write the vring directly.

I can add a counter in the loop, or to maintain an internal copy of
the vring so it's completely hardened against malicious/bad devices.
It should be done for packed vring anyway.

Thanks!

> Thanks
>
>
> > +}
> > +
> > +return i;
> > +}
> > +
> >  static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq,
> > uint32_t *len)
> >  {
> >  vring_desc_t *descs = svq->vring.desc;
> >  const vring_used_t *used = svq->vring.used;
> >  vring_used_elem_t used_elem;
> > -uint16_t last_used;
> > +uint16_t last_used, last_used_chain;
> >
> >  if (!vhost_svq_more_used(svq)) {
> >  return NULL;
> > @@ -365,7 +377,8 @@ static VirtQueueElement 
> > *vhost_svq_get_buf(VhostShadowVirtqueue *svq,
> >  return NULL;
> >  }
> >
> > -descs[used_elem.id].next = svq->free_head;
> > +last_used_chain = vhost_svq_last_desc_of_chain(svq, used_elem.id);
> > +descs[last_used_chain].next = svq->free_head;
> >  svq->free_head = used_elem.id;
> >
> >  *len = used_elem.len;
> > --
> > 2.27.0
> >
>




Re: [PATCH v1 1/9] qapi: fix example of netdev_add command

2022-04-01 Thread Markus Armbruster
Victor Toso  writes:

> Example output has the optional member @dnssearch as string type. It
> should be an array of strings instead. Fix it.
>
> For reference, see NetdevUserOptions.
>
> Signed-off-by: Victor Toso 
> ---
>  qapi/net.json | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/qapi/net.json b/qapi/net.json
> index 0d4578bd07..efc0bae170 100644
> --- a/qapi/net.json
> +++ b/qapi/net.json
> @@ -51,7 +51,7 @@
>  #
>  # -> { "execute": "netdev_add",
>  #  "arguments": { "type": "user", "id": "netdev1",
> -# "dnssearch": "example.org" } }
> +# "dnssearch": [ "example.org" ] } }
>  # <- { "return": {} }
>  #
>  ##

Uh, @dnssearch is ['String']...  shouldn't this be something like

   # "dnssearch": [ { "str": "example.org" } ] } }

?




Re: [PATCH v1 2/9] qapi: fix examples: replay-break and replay-seek

2022-04-01 Thread Markus Armbruster
Victor Toso  writes:

> Both examples outputs are using @data member for the arguments. This
> is wrong. The expected member for the QMP is @arguments. Fix it.
>
> Signed-off-by: Victor Toso 
> ---
>  qapi/replay.json | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/qapi/replay.json b/qapi/replay.json
> index b4d1ba253b..351898f60d 100644
> --- a/qapi/replay.json
> +++ b/qapi/replay.json
> @@ -81,7 +81,7 @@
>  #
>  # Example:
>  #
> -# -> { "execute": "replay-break", "data": { "icount": 220414 } }
> +# -> { "execute": "replay-break", "arguments": { "icount": 220414 } }
>  #
>  ##
>  { 'command': 'replay-break', 'data': { 'icount': 'int' } }
> @@ -117,6 +117,6 @@
>  #
>  # Example:
>  #
> -# -> { "execute": "replay-seek", "data": { "icount": 220414 } }
> +# -> { "execute": "replay-seek", "arguments": { "icount": 220414 } }
>  ##
>  { 'command': 'replay-seek', 'data': { 'icount': 'int' } }

I should've flagged these when I reviewed commit b1ca53224a
"qapi/migration: Fix examples document wrong field name for arguments".

Reviewed-by: Markus Armbruster 




Re: [PATCH v1 5/9] qapi: fix example of query-vnc command

2022-04-01 Thread Markus Armbruster
Victor Toso  writes:

> The return value is missing the mandatory member @websocket. Fix it.
>
> Signed-off-by: Victor Toso 
> ---
>  qapi/ui.json | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/qapi/ui.json b/qapi/ui.json
> index c039b8b3cb..13a8bb82aa 100644
> --- a/qapi/ui.json
> +++ b/qapi/ui.json
> @@ -658,6 +658,7 @@
>  #"host":"127.0.0.1",
>  #"service":"50401",
>  #"family":"ipv4"
> +#"websocket":false,
>  # }
>  #  ]
>  #   }

Reviewed-by: Markus Armbruster 




Re: [PATCH v1 3/9] qapi: fix example of query-named-block-nodes command

2022-04-01 Thread Markus Armbruster
Victor Toso  writes:

> Example output is missing mandatory member @detect_zeroes. Fix it.
>
> Signed-off-by: Victor Toso 
> ---
>  qapi/block-core.json | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/qapi/block-core.json b/qapi/block-core.json
> index 4a7a6940a3..beeb91952a 100644
> --- a/qapi/block-core.json
> +++ b/qapi/block-core.json
> @@ -1776,6 +1776,7 @@
>  #"file":"disks/test.qcow2",
>  #"node-name": "my-node",
>  #"backing_file_depth":1,
> +#"detect_zeroes":"off",
>  #"bps":100,
>  #"bps_rd":0,
>  #"bps_wr":0,

Reviewed-by: Markus Armbruster 




Re: [RFC PATCH 0/5] Removal of AioContext lock, bs->parents and ->children: proof of concept

2022-04-01 Thread Emanuele Giuseppe Esposito



Am 31/03/2022 um 18:40 schrieb Paolo Bonzini:
> On 3/31/22 15:51, Emanuele Giuseppe Esposito wrote:
>>
>> bdrv_graph_list_wrlock <-> start_exclusive
>> bdrv_graph_list_wrunlock <-> end_exclusive
>> bdrv_graph_list_rdlock <-> cpu_exec_start
>> bdrv_graph_list_rdunlock <-> cpu_exec_end
> 
> This wouldn't protect the list but the whole graph, i.e. the parents and
> children of all BDSes.  So the functions would be:
> 
>   bdrv_graph_wrlock <-> start_exclusive
>   bdrv_graph_wrunlock <-> end_exclusive
>   bdrv_graph_rdlock <-> cpu_exec_start
>   bdrv_graph_rdunlock <-> cpu_exec_end
> 
> 
> The list itself would be used internally to implement the write-side
> lock and unlock primitives, but it would not be protected by the above
> functions.  So there would be a couple additional functions:
> 
>   bdrv_graph_list_lock <-> cpu_list_lock
>   bdrv_graph_list_unlock <-> cpu_list_unlock

The list would be graph_bdrv_states, why do we need to protect it with a
lock? Currently it is protected by BQL, and theoretically only
bdrv_graph_wrlock iterates on it. And as we defined in the assertion
below, wrlock is always in the main loop too.

> 
>> +void bdrv_graph_list_rdlock(BlockDriverState *bs);
>> +void bdrv_graph_list_rdunlock(BlockDriverState *bs);
> 
> Apart from the naming change, these two would be coroutine_fn.
> 
>> +#define BS_GRAPH_READER(bs) /* in main loop OR bs->reading_graph */
>> +#define BS_GRAPH_WRITER(bs) /* in main loop AND bs->bs_graph_pending_op
> 
> bs_graph_pending_op is not part of bs->, it is a global variable
> (corresponding to pending_cpus in cpus-common.c).  I would call it
> bs_graph_pending_reader since you have "has_writer" below.

Hmm maybe it is better to go with has_waiter and pending_op. This is
because as "pending" we always have 1 write and zero or more reads.

Rest makes sense.

Emanuele
> 
> Also, this second #define does not need an argument, and is really the
> same as assert_bdrv_graph_writable(bs).  So perhaps you can rename the
> first one to assert_bdrv_graph_readable(bs).
> 
>>
>> +    /*
>> + * If true, the main loop is modifying the graph.
>> + * bs cannot read the graph.
>> + * Protected by bs_graph_list_lock.
>> + */
>> +    bool has_writer;
> 
> Note that it's "has_waiter" in cpus-common.c. :)  has_writer is fine too.
> 
> Paolo
> 




Re: [PATCH v1 4/9] qapi: fix example of query-spice command

2022-04-01 Thread Markus Armbruster
Victor Toso  writes:

> Example output is missing mandatory members @migrated and @mouse-mode.
> Fix it.
>
> Signed-off-by: Victor Toso 
> ---
>  qapi/ui.json | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/qapi/ui.json b/qapi/ui.json
> index a810ed680c..c039b8b3cb 100644
> --- a/qapi/ui.json
> +++ b/qapi/ui.json
> @@ -324,8 +324,10 @@
>  #  "enabled": true,
>  #  "auth": "spice",
>  #  "port": 5920,
> +#  "migrated":false,
>  #  "tls-port": 5921,
>  #  "host": "0.0.0.0",
> +#  "mouse-mode":"client",
>  #  "channels": [
>  # {
>  #"port": "54924",

Reviewed-by: Markus Armbruster 




Re: [PATCH v1 6/9] qapi: fix example of query-colo-status command

2022-04-01 Thread Markus Armbruster
Victor Toso  writes:

> The example output is missing the mandatory member @last-mode in the
> return value. Fix it.
>
> Signed-off-by: Victor Toso 
> ---
>  qapi/migration.json | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/qapi/migration.json b/qapi/migration.json
> index 092a63354b..f74777608a 100644
> --- a/qapi/migration.json
> +++ b/qapi/migration.json
> @@ -1679,7 +1679,7 @@
>  # Example:
>  #
>  # -> { "execute": "query-colo-status" }
> -# <- { "return": { "mode": "primary", "reason": "request" } }
> +# <- { "return": { "mode": "primary", "last-mode": "none", "reason": 
> "request" } }
>  #
>  # Since: 3.1
>  ##

Reviewed-by: Markus Armbruster 




Re: [PATCH v1 7/9] qapi: fix example of trace-event-get-state command

2022-04-01 Thread Markus Armbruster
Victor Toso  writes:

> The example output is missing the mandatory member @vcpu. Fix it.
>
> Signed-off-by: Victor Toso 
> ---
>  qapi/trace.json | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/qapi/trace.json b/qapi/trace.json
> index 119509f565..6c6982a587 100644
> --- a/qapi/trace.json
> +++ b/qapi/trace.json
> @@ -69,7 +69,7 @@
>  #
>  # -> { "execute": "trace-event-get-state",
>  #  "arguments": { "name": "qemu_memalign" } }
> -# <- { "return": [ { "name": "qemu_memalign", "state": "disabled" } ] }
> +# <- { "return": [ { "name": "qemu_memalign", "state": "disabled", "vcpu": 
> false } ] }
>  #
>  ##
>  { 'command': 'trace-event-get-state',

Reviewed-by: Markus Armbruster 




Re: [PATCH v1 9/9] qapi: fix example of query-memdev command

2022-04-01 Thread Markus Armbruster
Victor Toso  writes:

> Example output is missing mandatory argument @share for the return
> JSON object. Add it.
>
> Signed-off-by: Victor Toso 
> ---
>  qapi/machine.json | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/qapi/machine.json b/qapi/machine.json
> index 968f912989..d25a481ce4 100644
> --- a/qapi/machine.json
> +++ b/qapi/machine.json
> @@ -839,6 +839,7 @@
>  #  "merge": false,
>  #  "dump": true,
>  #  "prealloc": false,
> +#  "share": false,
>  #  "host-nodes": [0, 1],
>  #  "policy": "bind"
>  #},
> @@ -847,6 +848,7 @@
>  #  "merge": false,
>  #  "dump": true,
>  #  "prealloc": true,
> +#  "share": false,
>  #  "host-nodes": [2, 3],
>  #  "policy": "preferred"
>  #}

Reviewed-by: Markus Armbruster 




Re: use of uninitialized variable involving visit_type_uint32() and friends

2022-04-01 Thread Paolo Bonzini
On Thu, Mar 31, 2022 at 7:35 PM Peter Maydell 
wrote:

> Coverity warns about use of uninitialized data in what seems
> to be a common pattern of use of visit_type_uint32() and similar
> functions. Here's an example from target/arm/cpu64.c:
>
> static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char
> *name,
>void *opaque, Error **errp)
> {
> ARMCPU *cpu = ARM_CPU(obj);
> uint32_t max_vq;
> if (!visit_type_uint32(v, name, &max_vq, errp)) {
> return;
> }
> [code that does something with max_vq here]
> }
>
> This doesn't initialize max_vq, on the apparent assumption
> that visit_type_uint32() will do so. But that function [...]
> reads the value of *obj (the uninitialized max_vq).
>

The visit_type_* functions are written to work for both getters and setters.
For the leaves, that means potentially reading uninitialized data.  It is
harmless but very ugly, and with respect to static analysis it was all but
a time bomb, all the time.

The best (but most intrusive) solution would be to add a parameter to all
visit_type_* functions with the expected "direction" of the visit, which
could be checked against v->type.

That is:

bool visit_type_uint32(VisitorType expected_type, Visitor *v, const char
*name, uint32_t *obj,
   Error **errp)
{
uint64_t value;
bool ok;

trace_visit_type_uint32(v, name, obj);
assert (v->type == expected_type);
if (expected_type & (VISITOR_INPUT | VISITOR_DEALLOC)) {
value = *obj;
}
ok = visit_type_uintN(v, &value, name, UINT32_MAX, "uint32_t", errp);
assert (ok || expected_type == VISITOR_INPUT);
if (expected_type & VISITOR_OUTPUT) {
*obj = value;
}
return ok;
}

Probably also renaming VISITOR_* to V_* for conciseness.  That *should*
quiesce Coverity, and also add some runtime checks.

Paolo


Re: [RFC PATCH] tests/qtest: attempt to enable tests for virtio-gpio (!working)

2022-04-01 Thread Stefan Hajnoczi
On Thu, Mar 31, 2022 at 10:52:56AM +0100, Alex Bennée wrote:
> 
> (expanding the CC list for help, anyone have a better idea about how
> vhost-user qtests should work/see obvious issues with this patch?)

This is better than no test :).

Stefan


signature.asc
Description: PGP signature


Re: [PATCH v1 8/9] qapi: fix example of query-cpus-fast command

2022-04-01 Thread Markus Armbruster
Victor Toso  writes:

> Example output contains member @arch that was removed in 445a5b4087
> "machine: remove 'arch' field from 'query-cpus-fast' QMP command". Fix
> it.
>
> Signed-off-by: Victor Toso 
> ---
>  qapi/machine.json | 2 --
>  1 file changed, 2 deletions(-)
>
> diff --git a/qapi/machine.json b/qapi/machine.json
> index 9c460ec450..968f912989 100644
> --- a/qapi/machine.json
> +++ b/qapi/machine.json
> @@ -109,7 +109,6 @@
>  # "socket-id": 0
>  # },
>  # "qom-path": "/machine/unattached/device[0]",
> -# "arch":"x86",
>  # "target":"x86_64",
>  # "cpu-index": 0
>  # },
> @@ -121,7 +120,6 @@
>  # "socket-id": 1
>  # },
>  # "qom-path": "/machine/unattached/device[2]",
> -# "arch":"x86",
>  # "target":"x86_64",
>  # "cpu-index": 1
>  # }

Reviewed-by: Markus Armbruster 




Re: [PATCH v1 1/2] timer: cadence_ttc: Break out header file to allow embedding

2022-04-01 Thread Francisco Iglesias
On [2022 Apr 01] Fri 00:20:16, Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" 
> 
> Break out header file to allow embedding of the the TTC.
> 
> Signed-off-by: Edgar E. Iglesias 

Reviewed-by: Francisco Iglesias 

> ---
>  include/hw/timer/cadence_ttc.h | 54 ++
>  hw/timer/cadence_ttc.c | 32 ++--
>  2 files changed, 56 insertions(+), 30 deletions(-)
>  create mode 100644 include/hw/timer/cadence_ttc.h
> 
> diff --git a/include/hw/timer/cadence_ttc.h b/include/hw/timer/cadence_ttc.h
> new file mode 100644
> index 00..e1251383f2
> --- /dev/null
> +++ b/include/hw/timer/cadence_ttc.h
> @@ -0,0 +1,54 @@
> +/*
> + * Xilinx Zynq cadence TTC model
> + *
> + * Copyright (c) 2011 Xilinx Inc.
> + * Copyright (c) 2012 Peter A.G. Crosthwaite 
> (peter.crosthwa...@petalogix.com)
> + * Copyright (c) 2012 PetaLogix Pty Ltd.
> + * Written By Haibing Ma
> + *M. Habib
> + *
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, see .
> + */
> +#ifndef HW_TIMER_CADENCE_TTC_H
> +#define HW_TIMER_CADENCE_TTC_H
> +
> +#include "hw/sysbus.h"
> +#include "qemu/timer.h"
> +
> +typedef struct {
> +QEMUTimer *timer;
> +int freq;
> +
> +uint32_t reg_clock;
> +uint32_t reg_count;
> +uint32_t reg_value;
> +uint16_t reg_interval;
> +uint16_t reg_match[3];
> +uint32_t reg_intr;
> +uint32_t reg_intr_en;
> +uint32_t reg_event_ctrl;
> +uint32_t reg_event;
> +
> +uint64_t cpu_time;
> +unsigned int cpu_time_valid;
> +
> +qemu_irq irq;
> +} CadenceTimerState;
> +
> +#define TYPE_CADENCE_TTC "cadence_ttc"
> +OBJECT_DECLARE_SIMPLE_TYPE(CadenceTTCState, CADENCE_TTC)
> +
> +struct CadenceTTCState {
> +SysBusDevice parent_obj;
> +
> +MemoryRegion iomem;
> +CadenceTimerState timer[3];
> +};
> +
> +#endif
> diff --git a/hw/timer/cadence_ttc.c b/hw/timer/cadence_ttc.c
> index 64108241ba..e57a0f5f09 100644
> --- a/hw/timer/cadence_ttc.c
> +++ b/hw/timer/cadence_ttc.c
> @@ -24,6 +24,8 @@
>  #include "qemu/timer.h"
>  #include "qom/object.h"
>  
> +#include "hw/timer/cadence_ttc.h"
> +
>  #ifdef CADENCE_TTC_ERR_DEBUG
>  #define DB_PRINT(...) do { \
>  fprintf(stderr,  ": %s: ", __func__); \
> @@ -49,36 +51,6 @@
>  #define CLOCK_CTRL_PS_EN0x0001
>  #define CLOCK_CTRL_PS_V 0x001e
>  
> -typedef struct {
> -QEMUTimer *timer;
> -int freq;
> -
> -uint32_t reg_clock;
> -uint32_t reg_count;
> -uint32_t reg_value;
> -uint16_t reg_interval;
> -uint16_t reg_match[3];
> -uint32_t reg_intr;
> -uint32_t reg_intr_en;
> -uint32_t reg_event_ctrl;
> -uint32_t reg_event;
> -
> -uint64_t cpu_time;
> -unsigned int cpu_time_valid;
> -
> -qemu_irq irq;
> -} CadenceTimerState;
> -
> -#define TYPE_CADENCE_TTC "cadence_ttc"
> -OBJECT_DECLARE_SIMPLE_TYPE(CadenceTTCState, CADENCE_TTC)
> -
> -struct CadenceTTCState {
> -SysBusDevice parent_obj;
> -
> -MemoryRegion iomem;
> -CadenceTimerState timer[3];
> -};
> -
>  static void cadence_timer_update(CadenceTimerState *s)
>  {
>  qemu_set_irq(s->irq, !!(s->reg_intr & s->reg_intr_en));
> -- 
> 2.25.1
> 



[PATCH 10/9] qapi: Fix calc-dirty-rate example

2022-04-01 Thread Markus Armbruster
The example shows {"command": ...}, which is wrong.  Fix it to
{"execute": ...}.

Signed-off-by: Markus Armbruster 
---
 qapi/migration.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qapi/migration.json b/qapi/migration.json
index f74777608a..27d7b28158 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1845,7 +1845,7 @@
 # Since: 5.2
 #
 # Example:
-#   {"command": "calc-dirty-rate", "arguments": {"calc-time": 1,
+#   {"execute": "calc-dirty-rate", "arguments": {"calc-time": 1,
 #'sample-pages': 512} }
 #
 ##
-- 
2.35.1




Re: [PATCH v1 2/2] hw/arm/xlnx-zynqmp: Connect 4 TTC timers

2022-04-01 Thread Francisco Iglesias
On [2022 Apr 01] Fri 00:20:17, Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" 
> 
> Connect the 4 TTC timers on the ZynqMP.
> 
> Signed-off-by: Edgar E. Iglesias 

Reviewed-by: Francisco Iglesias 

> ---
>  include/hw/arm/xlnx-zynqmp.h |  4 
>  hw/arm/xlnx-zynqmp.c | 22 ++
>  2 files changed, 26 insertions(+)
> 
> diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
> index 9d9a9d0bf9..85fd9f53da 100644
> --- a/include/hw/arm/xlnx-zynqmp.h
> +++ b/include/hw/arm/xlnx-zynqmp.h
> @@ -41,6 +41,7 @@
>  #include "hw/or-irq.h"
>  #include "hw/misc/xlnx-zynqmp-apu-ctrl.h"
>  #include "hw/misc/xlnx-zynqmp-crf.h"
> +#include "hw/timer/cadence_ttc.h"
>  
>  #define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
>  OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
> @@ -84,6 +85,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
>  #define XLNX_ZYNQMP_MAX_RAM_SIZE (XLNX_ZYNQMP_MAX_LOW_RAM_SIZE + \
>XLNX_ZYNQMP_MAX_HIGH_RAM_SIZE)
>  
> +#define XLNX_ZYNQMP_NUM_TTC 4
> +
>  /*
>   * Unimplemented mmio regions needed to boot some images.
>   */
> @@ -128,6 +131,7 @@ struct XlnxZynqMPState {
>  qemu_or_irq qspi_irq_orgate;
>  XlnxZynqMPAPUCtrl apu_ctrl;
>  XlnxZynqMPCRF crf;
> +CadenceTTCState ttc[XLNX_ZYNQMP_NUM_TTC];
>  
>  char *boot_cpu;
>  ARMCPU *boot_cpu_ptr;
> diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
> index 5bfe285a19..375309e68e 100644
> --- a/hw/arm/xlnx-zynqmp.c
> +++ b/hw/arm/xlnx-zynqmp.c
> @@ -68,6 +68,9 @@
>  #define APU_ADDR0xfd5c
>  #define APU_IRQ 153
>  
> +#define TTC0_ADDR   0xFF11
> +#define TTC0_IRQ36
> +
>  #define IPI_ADDR0xFF30
>  #define IPI_IRQ 64
>  
> @@ -316,6 +319,24 @@ static void xlnx_zynqmp_create_crf(XlnxZynqMPState *s, 
> qemu_irq *gic)
>  sysbus_connect_irq(sbd, 0, gic[CRF_IRQ]);
>  }
>  
> +static void xlnx_zynqmp_create_ttc(XlnxZynqMPState *s, qemu_irq *gic)
> +{
> +SysBusDevice *sbd;
> +int i, irq;
> +
> +for (i = 0; i < XLNX_ZYNQMP_NUM_TTC; i++) {
> +object_initialize_child(OBJECT(s), "ttc[*]", &s->ttc[i],
> +TYPE_CADENCE_TTC);
> +sbd = SYS_BUS_DEVICE(&s->ttc[i]);
> +
> +sysbus_realize(sbd, &error_fatal);
> +sysbus_mmio_map(sbd, 0, TTC0_ADDR + i * 0x1);
> +for (irq = 0; irq < 3; irq++) {
> +sysbus_connect_irq(sbd, irq, gic[TTC0_IRQ + i * 3 + irq]);
> +}
> +}
> +}
> +
>  static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
>  {
>  static const struct UnimpInfo {
> @@ -721,6 +742,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error 
> **errp)
>  xlnx_zynqmp_create_efuse(s, gic_spi);
>  xlnx_zynqmp_create_apu_ctrl(s, gic_spi);
>  xlnx_zynqmp_create_crf(s, gic_spi);
> +xlnx_zynqmp_create_ttc(s, gic_spi);
>  xlnx_zynqmp_create_unimp_mmio(s);
>  
>  for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
> -- 
> 2.25.1
> 



Re: [PATCH 7/7] vhost-vdpa: backend feature should set only once

2022-04-01 Thread Eugenio Perez Martin
On Thu, Mar 31, 2022 at 11:15 PM Si-Wei Liu  wrote:
>
>
>
> On 3/31/2022 1:02 AM, Eugenio Perez Martin wrote:
> > On Thu, Mar 31, 2022 at 1:03 AM Si-Wei Liu  wrote:
> >>
> >>
> >> On 3/30/2022 12:01 PM, Eugenio Perez Martin wrote:
> >>> On Wed, Mar 30, 2022 at 8:33 AM Si-Wei Liu  wrote:
>  The vhost_vdpa_one_time_request() branch in
>  vhost_vdpa_set_backend_cap() incorrectly sends down
>  iotls on vhost_dev with non-zero index. This may
>  end up with multiple VHOST_SET_BACKEND_FEATURES
>  ioctl calls sent down on the vhost-vdpa fd that is
>  shared between all these vhost_dev's.
> 
> >>> Not only that. This means that qemu thinks the device supports iotlb
> >>> batching as long as the device does not have cvq. If vdpa does not
> >>> support batching, it will return an error later with no possibility of
> >>> doing it ok.
> >> I think the implicit assumption here is that the caller should back off
> >> to where it was if it comes to error i.e. once the first
> >> vhost_dev_set_features call gets an error, vhost_dev_start() will fail
> >> straight.
> > Sorry, I don't follow you here, and maybe my message was not clear enough.
> >
> > What I meant is that your patch fixes another problem not stated in
> > the message: it is not possible to initialize a net vdpa device that
> > does not have cvq and does not support iotlb batches without it. Qemu
> > will assume that the device supports batching, so the write of
> > VHOST_IOTLB_BATCH_BEGIN will fail.
> This is not what I see from the code? For e.g.
> vhost_vdpa_iotlb_batch_begin_once() has the following:
>
>   140 if (v->dev->backend_cap & (0x1ULL <<
> VHOST_BACKEND_F_IOTLB_BATCH) &&
>   141 !v->iotlb_batch_begin_sent) {
>   142 vhost_vdpa_listener_begin_batch(v);
>   143 }
>
> If backend_cap doesn't contain the VHOST_BACKEND_F_IOTLB_BATCH bit, QEMU
> shouldn't send down VHOST_IOTLB_BATCH_BEGIN...
>
> Noted in vhost_vdpa_set_backend_cap(), VHOST_GET_BACKEND_FEATURES was
> supposed to get the backend capability from the kernel ahead of the
> VHOST_SET_BACKEND_FEATURES call. In which case of your concern, at least
> feature VHOST_BACKEND_F_IOTLB_MSG_V2 should be successfully returned and
> stored in the backend_cap, even if the VHOST_SET_BACKEND_FEATURES ioctl
> was missed in between. Hence the resulting backend_cap shouldn't have
> the VHOST_BACKEND_F_IOTLB_BATCH bit set. What am I missing here?
>

You're right, I missed that the GET is not skipped, thanks!

>
> >   I didn't test what happens next but
> > it probably cannot continue.
> >
> > In that regard, this commit needs to be marked as "Fixes: ...", either
> > ("a5bd058 vhost-vdpa: batch updating IOTLB mappings") or maybe better
> > ("4d191cf vhost-vdpa: classify one time request"). We have a
> > regression if we introduce both, or the second one and the support of
> > any other backend feature.
> Sure, it's not that I am unwilling to add the "Fixes" tag, though I'd
> like to make sure if the worry is real upfront. Thanks for pointing it
> out anyway.
>
> Thanks,
> -Siwei
>
> >
> >> Noted that the VHOST_SET_BACKEND_FEATURES ioctl is not per-vq
> >> and it doesn't even need to. There seems to me no possibility for it to
> >> fail in a way as thought here. The capture is that IOTLB batching is at
> >> least a vdpa device level backend feature, if not per-kernel. Same as
> >> IOTLB_MSG_V2.
> >>
> > At this moment it is per-kernel, yes. With your patch there is no need
> > to fail because of the lack of _F_IOTLB_BATCH, the code should handle
> > this case ok.
> >
> > But if VHOST_GET_BACKEND_FEATURES returns no support for
> > VHOST_BACKEND_F_IOTLB_MSG_V2, the qemu code will happily send v2
> > messages anyway. This has nothing to do with the patch, I'm just
> > noting it here.
> >
> > In that case, maybe it is better to return something like -ENOTSUP?
> >
> > Thanks!
> >
> >> -Siwei
> >>
> >>>Some open questions:
> >>>
> >>> Should we make the vdpa driver return error as long as a feature is
> >>> used but not set by qemu, or let it as undefined? I guess we have to
> >>> keep the batching at least without checking so the kernel supports old
> >>> versions of qemu.
> >>>
> >>> On the other hand, should we return an error if IOTLB_MSG_V2 is not
> >>> supported here? We're basically assuming it in other functions.
> >>>
>  To fix it, send down ioctl only once via the first
>  vhost_dev with index 0. Toggle the polarity of the
>  vhost_vdpa_one_time_request() test would do the trick.
> 
>  Signed-off-by: Si-Wei Liu 
> >>> Acked-by: Eugenio Pérez 
> >>>
>  ---
> hw/virtio/vhost-vdpa.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
> 
>  diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
>  index c5ed7a3..27ea706 100644
>  --- a/hw/virtio/vhost-vdpa.c
>  +++ b/hw/virtio/vhost-vdpa.c
>  @@ -665,7 +665,7 @@ static int vhost_vdpa_set_backend_cap(struct 
>  vhost_dev *dev)
> >>

[PATCH v5 0/9] Add support for AST1030 SoC

2022-04-01 Thread Jamin Lin
Changes from v5:
- remove TYPE_ASPEED_MINIBMC_MACHINE and ASPEED_MINIBMC_MACHINE
- remove ast1030_machine_instance_init function

Changes from v4:
- drop the ASPEED_SMC_FEATURE_WDT_CONTROL flag in hw/ssi/aspeed_smc.c

Changes from v3:
- remove AspeedMiniBmcMachineState state structure and
  AspeedMiniBmcMachineClass class
- remove redundant new line in hw/arm/aspeed_ast10xx.c
- drop the ASPEED_SMC_FEATURE_WDT_CONTROL flag in hw/ssi/aspeed_smc.c

Changes from v2:
- replace aspeed_ast1030.c with aspeed_ast10xx.c for minibmc SOCs family support
- Add "ast1030-evb" machine in aspeed.c and removes aspeed_minibmc.c

Changes from v1:
The patch series supports ADC, SCU, SMC, TIMER, and WDT for AST1030 SoC.
Add avocado test case for "ast1030-evb" machine.

Test steps:
1. Download image from
   
https://github.com/AspeedTech-BMC/zephyr/releases/download/v00.01.04/ast1030-evb-demo.zip
2. Extract the zip file to obtain zephyr.elf
3. Run ./qemu-system-arm -M ast1030-evb -kernel $PATH/zephyr.elf -nographic
4. Test IO by Zephyr command line, commands are refer to Aspeed Zephyr
   SDK User Guide below
   
https://github.com/AspeedTech-BMC/zephyr/releases/download/v00.01.04/Aspeed_Zephy_SDK_User_Guide_v00.01.04.pdf
   - ADC(channel 0):
   uart:~$ adc ADC0 resolution 10
   uart:~$ adc ADC0 calibrate 1
   uart:~$ adc ADC0 read_format 1
   uart:~$ adc ADC0 read 0
   [Result]
   read: 1416mv

   - SCU
   uart:~$ md 7e6e2040
   uart:~$ md 7e6e2080
   uart:~$ md 7e6e20d0
   uart:~$ md 7e6e2200
   uart:~$ md 7e6e2300
   uart:~$ md 7e6e25b0
   [Result]
   The register value should match the value of ast1030_a1_resets
   in aspeed_scu.c

   - Flash(fmc_cs0):
   uart:~$ flash write fmc_cs0 0 0x12345678 0x87654321 0x34127856 0x78563412
   uart:~$ flash read fmc_cs0 0 10
   [Result]
   : 78 56 34 12 21 43 65 87  56 78 12 34 12 34 56 78 |xV4.!Ce. 
Vx.4.4Vx|

   uart:~$ flash erase fmc_cs0 0
   uart:~$ flash read fmc_cs0 0 10
   [Result]
   : ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff | 
|

   - Timer(TIMER0):
   uart:~$ timer start TIMER0 -p 2000 -t 0
   TIMER0: period 2 ms, type 0
   [Result]
   timer expired after 2 seconds

   - Watchdog(WDT1):
   uart:~$ mw 7e785008 4755
   uart:~$ mw 7e78500c 1
   [Result]
   soc reset after 22 seconds

Based-on: 20220315075753.8591-3-steven_...@aspeedtech.com
([v2,2/2] hw: aspeed_scu: Introduce clkin_25Mhz attribute)

Jamin Lin (2):
  aspeed: Add an AST1030 eval board
  test/avocado/machine_aspeed.py: Add ast1030 test case

Steven Lee (7):
  aspeed/adc: Add AST1030 support
  aspeed/smc: Add AST1030 support
  aspeed/wdt: Fix ast2500/ast2600 default reload value
  aspeed/wdt: Add AST1030 support
  aspeed/timer: Add AST1030 support
  aspeed/scu: Add AST1030 support
  aspeed/soc : Add AST1030 support

 hw/adc/aspeed_adc.c  |  16 ++
 hw/arm/aspeed.c  |  66 +++
 hw/arm/aspeed_ast10xx.c  | 299 +++
 hw/arm/meson.build   |   6 +-
 hw/misc/aspeed_scu.c |  63 +++
 hw/ssi/aspeed_smc.c  | 157 
 hw/timer/aspeed_timer.c  |  17 ++
 hw/watchdog/wdt_aspeed.c |  34 +++-
 include/hw/adc/aspeed_adc.h  |   1 +
 include/hw/arm/aspeed_soc.h  |   3 +
 include/hw/misc/aspeed_scu.h |  25 +++
 include/hw/timer/aspeed_timer.h  |   1 +
 include/hw/watchdog/wdt_aspeed.h |   3 +
 tests/avocado/machine_aspeed.py  |  36 
 14 files changed, 724 insertions(+), 3 deletions(-)
 create mode 100644 hw/arm/aspeed_ast10xx.c
 create mode 100644 tests/avocado/machine_aspeed.py

-- 
2.17.1




[PATCH v5 3/9] aspeed/wdt: Fix ast2500/ast2600 default reload value

2022-04-01 Thread Jamin Lin
From: Steven Lee 

Per ast2500_2520_datasheet_v1.8 and ast2600v11.pdf, the default value of
WDT00 and WDT04 is 0x014FB180 for ast2500/ast2600.
Add default_status and default_reload_value attributes for storing
counter status and reload value as they are different from ast2400.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Signed-off-by: Steven Lee 
Reviewed-by: Cédric Le Goater 
---
 hw/watchdog/wdt_aspeed.c | 10 --
 include/hw/watchdog/wdt_aspeed.h |  2 ++
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
index 6aa6f90b66..386928e9c0 100644
--- a/hw/watchdog/wdt_aspeed.c
+++ b/hw/watchdog/wdt_aspeed.c
@@ -232,8 +232,8 @@ static void aspeed_wdt_reset(DeviceState *dev)
 AspeedWDTState *s = ASPEED_WDT(dev);
 AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(s);
 
-s->regs[WDT_STATUS] = 0x3EF1480;
-s->regs[WDT_RELOAD_VALUE] = 0x03EF1480;
+s->regs[WDT_STATUS] = awc->default_status;
+s->regs[WDT_RELOAD_VALUE] = awc->default_reload_value;
 s->regs[WDT_RESTART] = 0;
 s->regs[WDT_CTRL] = awc->sanitize_ctrl(0);
 s->regs[WDT_RESET_WIDTH] = 0xFF;
@@ -319,6 +319,8 @@ static void aspeed_2400_wdt_class_init(ObjectClass *klass, 
void *data)
 awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
 awc->wdt_reload = aspeed_wdt_reload;
 awc->sanitize_ctrl = aspeed_2400_sanitize_ctrl;
+awc->default_status = 0x03EF1480;
+awc->default_reload_value = 0x03EF1480;
 }
 
 static const TypeInfo aspeed_2400_wdt_info = {
@@ -355,6 +357,8 @@ static void aspeed_2500_wdt_class_init(ObjectClass *klass, 
void *data)
 awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
 awc->wdt_reload = aspeed_wdt_reload_1mhz;
 awc->sanitize_ctrl = aspeed_2500_sanitize_ctrl;
+awc->default_status = 0x014FB180;
+awc->default_reload_value = 0x014FB180;
 }
 
 static const TypeInfo aspeed_2500_wdt_info = {
@@ -376,6 +380,8 @@ static void aspeed_2600_wdt_class_init(ObjectClass *klass, 
void *data)
 awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
 awc->wdt_reload = aspeed_wdt_reload_1mhz;
 awc->sanitize_ctrl = aspeed_2600_sanitize_ctrl;
+awc->default_status = 0x014FB180;
+awc->default_reload_value = 0x014FB180;
 }
 
 static const TypeInfo aspeed_2600_wdt_info = {
diff --git a/include/hw/watchdog/wdt_aspeed.h b/include/hw/watchdog/wdt_aspeed.h
index f945cd6c58..0e37f39f38 100644
--- a/include/hw/watchdog/wdt_aspeed.h
+++ b/include/hw/watchdog/wdt_aspeed.h
@@ -45,6 +45,8 @@ struct AspeedWDTClass {
 void (*reset_pulse)(AspeedWDTState *s, uint32_t property);
 void (*wdt_reload)(AspeedWDTState *s);
 uint64_t (*sanitize_ctrl)(uint64_t data);
+uint32_t default_status;
+uint32_t default_reload_value;
 };
 
 #endif /* WDT_ASPEED_H */
-- 
2.17.1




[PATCH v5 1/9] aspeed/adc: Add AST1030 support

2022-04-01 Thread Jamin Lin
From: Steven Lee 

Per ast1030_v7.pdf, AST1030 ADC engine is identical to AST2600's ADC.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Signed-off-by: Steven Lee 
Reviewed-by: Cédric Le Goater 
---
 hw/adc/aspeed_adc.c | 16 
 include/hw/adc/aspeed_adc.h |  1 +
 2 files changed, 17 insertions(+)

diff --git a/hw/adc/aspeed_adc.c b/hw/adc/aspeed_adc.c
index c5fcae29f6..0d29663129 100644
--- a/hw/adc/aspeed_adc.c
+++ b/hw/adc/aspeed_adc.c
@@ -389,6 +389,15 @@ static void aspeed_2600_adc_class_init(ObjectClass *klass, 
void *data)
 aac->nr_engines = 2;
 }
 
+static void aspeed_1030_adc_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+AspeedADCClass *aac = ASPEED_ADC_CLASS(klass);
+
+dc->desc = "ASPEED 1030 ADC Controller";
+aac->nr_engines = 2;
+}
+
 static const TypeInfo aspeed_adc_info = {
 .name = TYPE_ASPEED_ADC,
 .parent = TYPE_SYS_BUS_DEVICE,
@@ -415,6 +424,12 @@ static const TypeInfo aspeed_2600_adc_info = {
 .class_init = aspeed_2600_adc_class_init,
 };
 
+static const TypeInfo aspeed_1030_adc_info = {
+.name = TYPE_ASPEED_1030_ADC,
+.parent = TYPE_ASPEED_ADC,
+.class_init = aspeed_1030_adc_class_init, /* No change since AST2600 */
+};
+
 static void aspeed_adc_register_types(void)
 {
 type_register_static(&aspeed_adc_engine_info);
@@ -422,6 +437,7 @@ static void aspeed_adc_register_types(void)
 type_register_static(&aspeed_2400_adc_info);
 type_register_static(&aspeed_2500_adc_info);
 type_register_static(&aspeed_2600_adc_info);
+type_register_static(&aspeed_1030_adc_info);
 }
 
 type_init(aspeed_adc_register_types);
diff --git a/include/hw/adc/aspeed_adc.h b/include/hw/adc/aspeed_adc.h
index 2f166e8be1..ff1d06ea91 100644
--- a/include/hw/adc/aspeed_adc.h
+++ b/include/hw/adc/aspeed_adc.h
@@ -17,6 +17,7 @@
 #define TYPE_ASPEED_2400_ADC TYPE_ASPEED_ADC "-ast2400"
 #define TYPE_ASPEED_2500_ADC TYPE_ASPEED_ADC "-ast2500"
 #define TYPE_ASPEED_2600_ADC TYPE_ASPEED_ADC "-ast2600"
+#define TYPE_ASPEED_1030_ADC TYPE_ASPEED_ADC "-ast1030"
 OBJECT_DECLARE_TYPE(AspeedADCState, AspeedADCClass, ASPEED_ADC)
 
 #define TYPE_ASPEED_ADC_ENGINE "aspeed.adc.engine"
-- 
2.17.1




[PATCH v5 5/9] aspeed/timer: Add AST1030 support

2022-04-01 Thread Jamin Lin
From: Steven Lee 

ast1030 tmc(timer controller) is identical to ast2600 tmc.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Signed-off-by: Steven Lee 
Reviewed-by: Cédric Le Goater 
---
 hw/timer/aspeed_timer.c | 17 +
 include/hw/timer/aspeed_timer.h |  1 +
 2 files changed, 18 insertions(+)

diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
index 42c47d2ce6..9c20b3d6ad 100644
--- a/hw/timer/aspeed_timer.c
+++ b/hw/timer/aspeed_timer.c
@@ -745,12 +745,29 @@ static const TypeInfo aspeed_2600_timer_info = {
 .class_init = aspeed_2600_timer_class_init,
 };
 
+static void aspeed_1030_timer_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+AspeedTimerClass *awc = ASPEED_TIMER_CLASS(klass);
+
+dc->desc = "ASPEED 1030 Timer";
+awc->read = aspeed_2600_timer_read;
+awc->write = aspeed_2600_timer_write;
+}
+
+static const TypeInfo aspeed_1030_timer_info = {
+.name = TYPE_ASPEED_1030_TIMER,
+.parent = TYPE_ASPEED_TIMER,
+.class_init = aspeed_1030_timer_class_init,
+};
+
 static void aspeed_timer_register_types(void)
 {
 type_register_static(&aspeed_timer_info);
 type_register_static(&aspeed_2400_timer_info);
 type_register_static(&aspeed_2500_timer_info);
 type_register_static(&aspeed_2600_timer_info);
+type_register_static(&aspeed_1030_timer_info);
 }
 
 type_init(aspeed_timer_register_types)
diff --git a/include/hw/timer/aspeed_timer.h b/include/hw/timer/aspeed_timer.h
index d36034a10c..07dc6b6f2c 100644
--- a/include/hw/timer/aspeed_timer.h
+++ b/include/hw/timer/aspeed_timer.h
@@ -31,6 +31,7 @@ OBJECT_DECLARE_TYPE(AspeedTimerCtrlState, AspeedTimerClass, 
ASPEED_TIMER)
 #define TYPE_ASPEED_2400_TIMER TYPE_ASPEED_TIMER "-ast2400"
 #define TYPE_ASPEED_2500_TIMER TYPE_ASPEED_TIMER "-ast2500"
 #define TYPE_ASPEED_2600_TIMER TYPE_ASPEED_TIMER "-ast2600"
+#define TYPE_ASPEED_1030_TIMER TYPE_ASPEED_TIMER "-ast1030"
 
 #define ASPEED_TIMER_NR_TIMERS 8
 
-- 
2.17.1




Re: [PATCH v4 8/9] aspeed: Add an AST1030 eval board

2022-04-01 Thread Jamin Lin
The 04/01/2022 06:59, Cédric Le Goater wrote:
> On 4/1/22 05:46, Jamin Lin wrote:
> > The image should be supplied with ELF binary.
> > $ qemu-system-arm -M ast1030-evb -kernel zephyr.elf -nographic
> > 
> > Signed-off-by: Troy Lee 
> > Signed-off-by: Jamin Lin 
> > Signed-off-by: Steven Lee 
> > ---
> >   hw/arm/aspeed.c | 97 +
> >   include/hw/arm/aspeed.h |  6 +--
> >   2 files changed, 100 insertions(+), 3 deletions(-)
> > 
> > diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> > index d205384d98..30b49d2db1 100644
> > --- a/hw/arm/aspeed.c
> > +++ b/hw/arm/aspeed.c
> > @@ -24,6 +24,7 @@
> >   #include "hw/loader.h"
> >   #include "qemu/error-report.h"
> >   #include "qemu/units.h"
> > +#include "hw/qdev-clock.h"
> >   
> >   static struct arm_boot_info aspeed_board_binfo = {
> >   .board_id = -1, /* device-tree-only board */
> > @@ -1361,3 +1362,99 @@ static const TypeInfo aspeed_machine_types[] = {
> >   };
> >   
> >   DEFINE_TYPES(aspeed_machine_types)
> > +
> > +#define AST1030_INTERNAL_FLASH_SIZE (1024 * 1024)
> > +/* Main SYSCLK frequency in Hz (200MHz) */
> > +#define SYSCLK_FRQ 2ULL
> > +
> > +static void aspeed_minibmc_machine_ast1030_evb_class_init(ObjectClass *oc,
> > +  void *data)
> > +{
> > +MachineClass *mc = MACHINE_CLASS(oc);
> > +AspeedMachineClass *amc = ASPEED_MINIBMC_MACHINE_CLASS(oc);
> 
> I don't think we need a ASPEED_MINIBMC type (yet)
>
Fixed
> > +
> > +mc->desc = "Aspeed AST1030 MiniBMC (Cortex-M4)";
> > +amc->soc_name = "ast1030-a1";
> > +amc->hw_strap1 = 0;
> > +amc->hw_strap2 = 0;
> > +mc->default_ram_size = 0;
> > +mc->default_cpus = mc->min_cpus = mc->max_cpus = 1;
> > +amc->fmc_model = "sst25vf032b";
> > +amc->spi_model = "sst25vf032b";
> > +amc->num_cs = 2;
> 
> In this routine, you could add :
> 
>   amc->macs_mask = 0;
> 
> Since the NICs are not modeled yet.
> 
Thanks for your review and suggestion. Added in v5 patch.
> > +}
> > +
> > +static void ast1030_machine_instance_init(Object *obj)
> > +{
> > +ASPEED_MINIBMC_MACHINE(obj)->mmio_exec = false;
> > +}
> 
> ast1030_machine_instance_init() is not that useful either.
> 
Fixed
> > +
> > +static void aspeed_minibmc_machine_init(MachineState *machine)
> > +{
> > +AspeedMachineState *bmc = ASPEED_MINIBMC_MACHINE(machine);
> > +AspeedMachineClass *amc = ASPEED_MINIBMC_MACHINE_GET_CLASS(machine);
> > +Clock *sysclk;
> > +
> > +sysclk = clock_new(OBJECT(machine), "SYSCLK");
> > +clock_set_hz(sysclk, SYSCLK_FRQ);
> > +
> > +object_initialize_child(OBJECT(machine), "soc", &bmc->soc, 
> > amc->soc_name);
> > +qdev_connect_clock_in(DEVICE(&bmc->soc), "sysclk", sysclk);
> > +
> > +qdev_prop_set_uint32(DEVICE(&bmc->soc), "uart-default",
> > + amc->uart_default);
> > +qdev_realize(DEVICE(&bmc->soc), NULL, &error_abort);
> > +
> > +aspeed_board_init_flashes(&bmc->soc.fmc,
> > +  bmc->fmc_model ? bmc->fmc_model : 
> > amc->fmc_model,
> > +  amc->num_cs,
> > +  0);
> > +
> > +aspeed_board_init_flashes(&bmc->soc.spi[0],
> > +  bmc->spi_model ? bmc->spi_model : 
> > amc->spi_model,
> > +  amc->num_cs, amc->num_cs);
> > +
> > +aspeed_board_init_flashes(&bmc->soc.spi[1],
> > +  bmc->spi_model ? bmc->spi_model : 
> > amc->spi_model,
> > +  amc->num_cs, (amc->num_cs * 2));
> > +
> > +if (amc->i2c_init) {
> > +amc->i2c_init(bmc);
> > +}
> > +
> > +armv7m_load_kernel(ARM_CPU(first_cpu),
> > +   machine->kernel_filename,
> > +   AST1030_INTERNAL_FLASH_SIZE);
> > +}
> > +
> > +static void aspeed_minibmc_machine_class_init(ObjectClass *oc, void *data)
> > +{
> > +MachineClass *mc = MACHINE_CLASS(oc);
> > +AspeedMachineClass *amc = ASPEED_MINIBMC_MACHINE_CLASS(oc);
> > +
> > +mc->init = aspeed_minibmc_machine_init;
> > +mc->no_floppy = 1;
> > +mc->no_cdrom = 1;
> > +mc->no_parallel = 1;
> > +mc->default_ram_id = "ram";
> > +amc->uart_default = ASPEED_DEV_UART5;
> 
> This is very much like aspeed_machine_class_init()
> 
> 
> > +}
> > +
> > +static const TypeInfo aspeed_minibmc_machine_types[] = {
> > +{
> > +.name   = MACHINE_TYPE_NAME("ast1030-evb"),
> > +.parent = TYPE_ASPEED_MINIBMC_MACHINE,
> 
> Why don't you inherit directly from TYPE_ASPEED_MACHINE and simplify
> the model by removing the duplicate TYPE_ASPEED_MINIBMC_MACHINE ?
> 
Fixed and removed TYPE_ASPEED_MINIBMC_MACHINE in v5 patch.
> > +.class_init = aspeed_minibmc_machine_ast1030_evb_class_init,
> > +}, {
> > +.name   = TYPE_ASPEED_MINIBMC_MACHINE,
> > +.parent = TYPE_MACHINE,
> > +   

[PATCH v5 2/9] aspeed/smc: Add AST1030 support

2022-04-01 Thread Jamin Lin
From: Steven Lee 

AST1030 spi controller's address decoding unit is 1MB that is identical
to ast2600, but fmc address decoding unit is 512kb.
Introduce seg_to_reg and reg_to_seg handlers for ast1030 fmc controller.
In addition, add ast1030 fmc, spi1, and spi2 class init handler.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Signed-off-by: Steven Lee 
Reviewed-by: Cédric Le Goater 
---
 hw/ssi/aspeed_smc.c | 157 
 1 file changed, 157 insertions(+)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 48305e1574..68aa697164 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -1696,6 +1696,160 @@ static const TypeInfo aspeed_2600_spi2_info = {
 .class_init = aspeed_2600_spi2_class_init,
 };
 
+/*
+ * The FMC Segment Registers of the AST1030 have a 512KB unit.
+ * Only bits [27:19] are used for decoding.
+ */
+#define AST1030_SEG_ADDR_MASK 0x0ff8
+
+static uint32_t aspeed_1030_smc_segment_to_reg(const AspeedSMCState *s,
+const AspeedSegments *seg)
+{
+uint32_t reg = 0;
+
+/* Disabled segments have a nil register */
+if (!seg->size) {
+return 0;
+}
+
+reg |= (seg->addr & AST1030_SEG_ADDR_MASK) >> 16; /* start offset */
+reg |= (seg->addr + seg->size - 1) & AST1030_SEG_ADDR_MASK; /* end offset 
*/
+return reg;
+}
+
+static void aspeed_1030_smc_reg_to_segment(const AspeedSMCState *s,
+uint32_t reg, AspeedSegments *seg)
+{
+uint32_t start_offset = (reg << 16) & AST1030_SEG_ADDR_MASK;
+uint32_t end_offset = reg & AST1030_SEG_ADDR_MASK;
+AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
+
+if (reg) {
+seg->addr = asc->flash_window_base + start_offset;
+seg->size = end_offset + (512 * KiB) - start_offset;
+} else {
+seg->addr = asc->flash_window_base;
+seg->size = 0;
+}
+}
+
+static const uint32_t aspeed_1030_fmc_resets[ASPEED_SMC_R_MAX] = {
+[R_CONF] = (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0 |
+CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1),
+};
+
+static const AspeedSegments aspeed_1030_fmc_segments[] = {
+{ 0x0, 128 * MiB }, /* start address is readonly */
+{ 128 * MiB, 128 * MiB }, /* default is disabled but needed for -kernel */
+{ 0x0, 0 }, /* disabled */
+};
+
+static void aspeed_1030_fmc_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
+
+dc->desc   = "Aspeed 1030 FMC Controller";
+asc->r_conf= R_CONF;
+asc->r_ce_ctrl = R_CE_CTRL;
+asc->r_ctrl0   = R_CTRL0;
+asc->r_timings = R_TIMINGS;
+asc->nregs_timings = 2;
+asc->conf_enable_w0= CONF_ENABLE_W0;
+asc->cs_num_max= 2;
+asc->segments  = aspeed_1030_fmc_segments;
+asc->segment_addr_mask = 0x0ff80ff8;
+asc->resets= aspeed_1030_fmc_resets;
+asc->flash_window_base = 0x8000;
+asc->flash_window_size = 0x1000;
+asc->features  = ASPEED_SMC_FEATURE_DMA;
+asc->dma_flash_mask= 0x0FFC;
+asc->dma_dram_mask = 0x000BFFFC;
+asc->nregs = ASPEED_SMC_R_MAX;
+asc->segment_to_reg= aspeed_1030_smc_segment_to_reg;
+asc->reg_to_segment= aspeed_1030_smc_reg_to_segment;
+asc->dma_ctrl  = aspeed_2600_smc_dma_ctrl;
+}
+
+static const TypeInfo aspeed_1030_fmc_info = {
+.name =  "aspeed.fmc-ast1030",
+.parent = TYPE_ASPEED_SMC,
+.class_init = aspeed_1030_fmc_class_init,
+};
+
+static const AspeedSegments aspeed_1030_spi1_segments[] = {
+{ 0x0, 128 * MiB }, /* start address is readonly */
+{ 0x0, 0 }, /* disabled */
+};
+
+static void aspeed_1030_spi1_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
+
+dc->desc   = "Aspeed 1030 SPI1 Controller";
+asc->r_conf= R_CONF;
+asc->r_ce_ctrl = R_CE_CTRL;
+asc->r_ctrl0   = R_CTRL0;
+asc->r_timings = R_TIMINGS;
+asc->nregs_timings = 2;
+asc->conf_enable_w0= CONF_ENABLE_W0;
+asc->cs_num_max= 2;
+asc->segments  = aspeed_1030_spi1_segments;
+asc->segment_addr_mask = 0x0ff00ff0;
+asc->flash_window_base = 0x9000;
+asc->flash_window_size = 0x1000;
+asc->features  = ASPEED_SMC_FEATURE_DMA;
+asc->dma_flash_mask= 0x0FFC;
+asc->dma_dram_mask = 0x000BFFFC;
+asc->nregs = ASPEED_SMC_R_MAX;
+asc->segment_to_reg= aspeed_2600_smc_segment_to_reg;
+asc->reg_to_segment= aspeed_2600_smc_reg_to_segment;
+asc->dma_ctrl  = aspeed_2600_smc_dma_ctrl;
+}
+
+static const TypeInfo aspeed_1030_spi1_info = {
+.name =  "aspeed.spi1-ast1030",
+.parent = TYPE_ASPEED_SMC,
+.class_init = aspeed_1030_spi1_class_init,
+};
+static const Aspee

[PATCH v5 4/9] aspeed/wdt: Add AST1030 support

2022-04-01 Thread Jamin Lin
From: Steven Lee 

AST1030 wdt controller is similiar to AST2600's wdt, but it has extra
registers.
Introduce ast1030 object class and increse the number of regs(offset) of
ast1030 model.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Signed-off-by: Steven Lee 
Reviewed-by: Cédric Le Goater 
---
 hw/watchdog/wdt_aspeed.c | 24 
 include/hw/watchdog/wdt_aspeed.h |  1 +
 2 files changed, 25 insertions(+)

diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
index 386928e9c0..31855afdf4 100644
--- a/hw/watchdog/wdt_aspeed.c
+++ b/hw/watchdog/wdt_aspeed.c
@@ -391,6 +391,29 @@ static const TypeInfo aspeed_2600_wdt_info = {
 .class_init = aspeed_2600_wdt_class_init,
 };
 
+static void aspeed_1030_wdt_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);
+
+dc->desc = "ASPEED 1030 Watchdog Controller";
+awc->offset = 0x80;
+awc->ext_pulse_width_mask = 0xf; /* TODO */
+awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
+awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
+awc->wdt_reload = aspeed_wdt_reload_1mhz;
+awc->sanitize_ctrl = aspeed_2600_sanitize_ctrl;
+awc->default_status = 0x014FB180;
+awc->default_reload_value = 0x014FB180;
+}
+
+static const TypeInfo aspeed_1030_wdt_info = {
+.name = TYPE_ASPEED_1030_WDT,
+.parent = TYPE_ASPEED_WDT,
+.instance_size = sizeof(AspeedWDTState),
+.class_init = aspeed_1030_wdt_class_init,
+};
+
 static void wdt_aspeed_register_types(void)
 {
 watchdog_add_model(&model);
@@ -398,6 +421,7 @@ static void wdt_aspeed_register_types(void)
 type_register_static(&aspeed_2400_wdt_info);
 type_register_static(&aspeed_2500_wdt_info);
 type_register_static(&aspeed_2600_wdt_info);
+type_register_static(&aspeed_1030_wdt_info);
 }
 
 type_init(wdt_aspeed_register_types)
diff --git a/include/hw/watchdog/wdt_aspeed.h b/include/hw/watchdog/wdt_aspeed.h
index 0e37f39f38..dfa5dfa424 100644
--- a/include/hw/watchdog/wdt_aspeed.h
+++ b/include/hw/watchdog/wdt_aspeed.h
@@ -19,6 +19,7 @@ OBJECT_DECLARE_TYPE(AspeedWDTState, AspeedWDTClass, 
ASPEED_WDT)
 #define TYPE_ASPEED_2400_WDT TYPE_ASPEED_WDT "-ast2400"
 #define TYPE_ASPEED_2500_WDT TYPE_ASPEED_WDT "-ast2500"
 #define TYPE_ASPEED_2600_WDT TYPE_ASPEED_WDT "-ast2600"
+#define TYPE_ASPEED_1030_WDT TYPE_ASPEED_WDT "-ast1030"
 
 #define ASPEED_WDT_REGS_MAX(0x20 / 4)
 
-- 
2.17.1




Re: [PATCH v5 8/9] aspeed: Add an AST1030 eval board

2022-04-01 Thread Cédric Le Goater

On 4/1/22 10:38, Jamin Lin wrote:

The image should be supplied with ELF binary.
$ qemu-system-arm -M ast1030-evb -kernel zephyr.elf -nographic

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Signed-off-by: Steven Lee 


Reviewed-by: Cédric Le Goater 

Thanks,

C.


---
  hw/arm/aspeed.c | 66 +
  1 file changed, 66 insertions(+)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index d205384d98..4e27060324 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -24,6 +24,7 @@
  #include "hw/loader.h"
  #include "qemu/error-report.h"
  #include "qemu/units.h"
+#include "hw/qdev-clock.h"
  
  static struct arm_boot_info aspeed_board_binfo = {

  .board_id = -1, /* device-tree-only board */
@@ -1292,6 +1293,67 @@ static void 
aspeed_machine_bletchley_class_init(ObjectClass *oc, void *data)
  aspeed_soc_num_cpus(amc->soc_name);
  }
  
+#define AST1030_INTERNAL_FLASH_SIZE (1024 * 1024)

+/* Main SYSCLK frequency in Hz (200MHz) */
+#define SYSCLK_FRQ 2ULL
+
+static void aspeed_minibmc_machine_init(MachineState *machine)
+{
+AspeedMachineState *bmc = ASPEED_MACHINE(machine);
+AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
+Clock *sysclk;
+
+sysclk = clock_new(OBJECT(machine), "SYSCLK");
+clock_set_hz(sysclk, SYSCLK_FRQ);
+
+object_initialize_child(OBJECT(machine), "soc", &bmc->soc, amc->soc_name);
+qdev_connect_clock_in(DEVICE(&bmc->soc), "sysclk", sysclk);
+
+qdev_prop_set_uint32(DEVICE(&bmc->soc), "uart-default",
+ amc->uart_default);
+qdev_realize(DEVICE(&bmc->soc), NULL, &error_abort);
+
+aspeed_board_init_flashes(&bmc->soc.fmc,
+  bmc->fmc_model ? bmc->fmc_model : amc->fmc_model,
+  amc->num_cs,
+  0);
+
+aspeed_board_init_flashes(&bmc->soc.spi[0],
+  bmc->spi_model ? bmc->spi_model : amc->spi_model,
+  amc->num_cs, amc->num_cs);
+
+aspeed_board_init_flashes(&bmc->soc.spi[1],
+  bmc->spi_model ? bmc->spi_model : amc->spi_model,
+  amc->num_cs, (amc->num_cs * 2));
+
+if (amc->i2c_init) {
+amc->i2c_init(bmc);
+}
+
+armv7m_load_kernel(ARM_CPU(first_cpu),
+   machine->kernel_filename,
+   AST1030_INTERNAL_FLASH_SIZE);
+}
+
+static void aspeed_minibmc_machine_ast1030_evb_class_init(ObjectClass *oc,
+  void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
+
+mc->desc = "Aspeed AST1030 MiniBMC (Cortex-M4)";
+amc->soc_name = "ast1030-a1";
+amc->hw_strap1 = 0;
+amc->hw_strap2 = 0;
+mc->init = aspeed_minibmc_machine_init;
+mc->default_ram_size = 0;
+mc->default_cpus = mc->min_cpus = mc->max_cpus = 1;
+amc->fmc_model = "sst25vf032b";
+amc->spi_model = "sst25vf032b";
+amc->num_cs = 2;
+amc->macs_mask = 0;
+}
+
  static const TypeInfo aspeed_machine_types[] = {
  {
  .name  = MACHINE_TYPE_NAME("palmetto-bmc"),
@@ -1349,6 +1411,10 @@ static const TypeInfo aspeed_machine_types[] = {
  .name  = MACHINE_TYPE_NAME("bletchley-bmc"),
  .parent= TYPE_ASPEED_MACHINE,
  .class_init= aspeed_machine_bletchley_class_init,
+}, {
+.name   = MACHINE_TYPE_NAME("ast1030-evb"),
+.parent = TYPE_ASPEED_MACHINE,
+.class_init = aspeed_minibmc_machine_ast1030_evb_class_init,
  }, {
  .name  = TYPE_ASPEED_MACHINE,
  .parent= TYPE_MACHINE,





[PATCH v5 8/9] aspeed: Add an AST1030 eval board

2022-04-01 Thread Jamin Lin
The image should be supplied with ELF binary.
$ qemu-system-arm -M ast1030-evb -kernel zephyr.elf -nographic

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Signed-off-by: Steven Lee 
---
 hw/arm/aspeed.c | 66 +
 1 file changed, 66 insertions(+)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index d205384d98..4e27060324 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -24,6 +24,7 @@
 #include "hw/loader.h"
 #include "qemu/error-report.h"
 #include "qemu/units.h"
+#include "hw/qdev-clock.h"
 
 static struct arm_boot_info aspeed_board_binfo = {
 .board_id = -1, /* device-tree-only board */
@@ -1292,6 +1293,67 @@ static void 
aspeed_machine_bletchley_class_init(ObjectClass *oc, void *data)
 aspeed_soc_num_cpus(amc->soc_name);
 }
 
+#define AST1030_INTERNAL_FLASH_SIZE (1024 * 1024)
+/* Main SYSCLK frequency in Hz (200MHz) */
+#define SYSCLK_FRQ 2ULL
+
+static void aspeed_minibmc_machine_init(MachineState *machine)
+{
+AspeedMachineState *bmc = ASPEED_MACHINE(machine);
+AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
+Clock *sysclk;
+
+sysclk = clock_new(OBJECT(machine), "SYSCLK");
+clock_set_hz(sysclk, SYSCLK_FRQ);
+
+object_initialize_child(OBJECT(machine), "soc", &bmc->soc, amc->soc_name);
+qdev_connect_clock_in(DEVICE(&bmc->soc), "sysclk", sysclk);
+
+qdev_prop_set_uint32(DEVICE(&bmc->soc), "uart-default",
+ amc->uart_default);
+qdev_realize(DEVICE(&bmc->soc), NULL, &error_abort);
+
+aspeed_board_init_flashes(&bmc->soc.fmc,
+  bmc->fmc_model ? bmc->fmc_model : amc->fmc_model,
+  amc->num_cs,
+  0);
+
+aspeed_board_init_flashes(&bmc->soc.spi[0],
+  bmc->spi_model ? bmc->spi_model : amc->spi_model,
+  amc->num_cs, amc->num_cs);
+
+aspeed_board_init_flashes(&bmc->soc.spi[1],
+  bmc->spi_model ? bmc->spi_model : amc->spi_model,
+  amc->num_cs, (amc->num_cs * 2));
+
+if (amc->i2c_init) {
+amc->i2c_init(bmc);
+}
+
+armv7m_load_kernel(ARM_CPU(first_cpu),
+   machine->kernel_filename,
+   AST1030_INTERNAL_FLASH_SIZE);
+}
+
+static void aspeed_minibmc_machine_ast1030_evb_class_init(ObjectClass *oc,
+  void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
+
+mc->desc = "Aspeed AST1030 MiniBMC (Cortex-M4)";
+amc->soc_name = "ast1030-a1";
+amc->hw_strap1 = 0;
+amc->hw_strap2 = 0;
+mc->init = aspeed_minibmc_machine_init;
+mc->default_ram_size = 0;
+mc->default_cpus = mc->min_cpus = mc->max_cpus = 1;
+amc->fmc_model = "sst25vf032b";
+amc->spi_model = "sst25vf032b";
+amc->num_cs = 2;
+amc->macs_mask = 0;
+}
+
 static const TypeInfo aspeed_machine_types[] = {
 {
 .name  = MACHINE_TYPE_NAME("palmetto-bmc"),
@@ -1349,6 +1411,10 @@ static const TypeInfo aspeed_machine_types[] = {
 .name  = MACHINE_TYPE_NAME("bletchley-bmc"),
 .parent= TYPE_ASPEED_MACHINE,
 .class_init= aspeed_machine_bletchley_class_init,
+}, {
+.name   = MACHINE_TYPE_NAME("ast1030-evb"),
+.parent = TYPE_ASPEED_MACHINE,
+.class_init = aspeed_minibmc_machine_ast1030_evb_class_init,
 }, {
 .name  = TYPE_ASPEED_MACHINE,
 .parent= TYPE_MACHINE,
-- 
2.17.1




[PATCH v5 9/9] test/avocado/machine_aspeed.py: Add ast1030 test case

2022-04-01 Thread Jamin Lin
Add test case to test "ast1030-evb" machine with zephyr os

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Signed-off-by: Steven Lee 
Reviewed-by: Cédric Le Goater 
---
 tests/avocado/machine_aspeed.py | 36 +
 1 file changed, 36 insertions(+)
 create mode 100644 tests/avocado/machine_aspeed.py

diff --git a/tests/avocado/machine_aspeed.py b/tests/avocado/machine_aspeed.py
new file mode 100644
index 00..33090af199
--- /dev/null
+++ b/tests/avocado/machine_aspeed.py
@@ -0,0 +1,36 @@
+# Functional test that boots the ASPEED SoCs with firmware
+#
+# Copyright (C) 2022 ASPEED Technology Inc
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later.  See the COPYING file in the top-level directory.
+
+from avocado_qemu import QemuSystemTest
+from avocado_qemu import wait_for_console_pattern
+from avocado_qemu import exec_command_and_wait_for_pattern
+from avocado.utils import archive
+
+
+class AST1030Machine(QemuSystemTest):
+"""Boots the zephyr os and checks that the console is operational"""
+
+timeout = 10
+
+def test_ast1030_zephyros(self):
+"""
+:avocado: tags=arch:arm
+:avocado: tags=machine:ast1030-evb
+"""
+tar_url = ('https://github.com/AspeedTech-BMC'
+   '/zephyr/releases/download/v00.01.04/ast1030-evb-demo.zip')
+tar_hash = '4c6a8ce3a8ba76ef1a65dae419ae3409343c4b20'
+tar_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
+archive.extract(tar_path, self.workdir)
+kernel_file = self.workdir + "/ast1030-evb-demo/zephyr.elf"
+self.vm.set_console()
+self.vm.add_args('-kernel', kernel_file,
+ '-nographic')
+self.vm.launch()
+wait_for_console_pattern(self, "Booting Zephyr OS")
+exec_command_and_wait_for_pattern(self, "help",
+  "Available commands")
-- 
2.17.1




[PATCH v5 6/9] aspeed/scu: Add AST1030 support

2022-04-01 Thread Jamin Lin
From: Steven Lee 

Per ast1030_v07.pdf, AST1030 SOC doesn't have SCU300, the pclk divider
selection is defined in SCU310[11:8].
Add a get_apb_freq function and a class init handler for ast1030.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Signed-off-by: Steven Lee 
Reviewed-by: Cédric Le Goater 
---
 hw/misc/aspeed_scu.c | 63 
 include/hw/misc/aspeed_scu.h | 25 ++
 2 files changed, 88 insertions(+)

diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
index 150567f98a..19b03471fc 100644
--- a/hw/misc/aspeed_scu.c
+++ b/hw/misc/aspeed_scu.c
@@ -235,6 +235,15 @@ static uint32_t 
aspeed_2600_scu_get_apb_freq(AspeedSCUState *s)
 / asc->apb_divider;
 }
 
+static uint32_t aspeed_1030_scu_get_apb_freq(AspeedSCUState *s)
+{
+AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
+uint32_t hpll = asc->calc_hpll(s, s->regs[AST2600_HPLL_PARAM]);
+
+return hpll / (SCU_AST1030_CLK_GET_PCLK_DIV(s->regs[AST2600_CLK_SEL4]) + 1)
+/ asc->apb_divider;
+}
+
 static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
 {
 AspeedSCUState *s = ASPEED_SCU(opaque);
@@ -482,6 +491,8 @@ static uint32_t aspeed_silicon_revs[] = {
 AST2600_A1_SILICON_REV,
 AST2600_A2_SILICON_REV,
 AST2600_A3_SILICON_REV,
+AST1030_A0_SILICON_REV,
+AST1030_A1_SILICON_REV,
 };
 
 bool is_supported_silicon_rev(uint32_t silicon_rev)
@@ -770,12 +781,64 @@ static const TypeInfo aspeed_2600_scu_info = {
 .class_init = aspeed_2600_scu_class_init,
 };
 
+static const uint32_t ast1030_a1_resets[ASPEED_AST2600_SCU_NR_REGS] = {
+[AST2600_SYS_RST_CTRL]  = 0xFFC3FED8,
+[AST2600_SYS_RST_CTRL2] = 0x09FC,
+[AST2600_CLK_STOP_CTRL] = 0x7F8A,
+[AST2600_CLK_STOP_CTRL2]= 0xFFF0FFF0,
+[AST2600_DEBUG_CTRL2]   = 0x,
+[AST2600_HPLL_PARAM]= 0x10004077,
+[AST2600_HPLL_EXT]  = 0x0031,
+[AST2600_CLK_SEL4]  = 0x43F90900,
+[AST2600_CLK_SEL5]  = 0x4000,
+[AST2600_CHIP_ID0]  = 0xDEADBEEF,
+[AST2600_CHIP_ID1]  = 0x0BADCAFE,
+};
+
+static void aspeed_ast1030_scu_reset(DeviceState *dev)
+{
+AspeedSCUState *s = ASPEED_SCU(dev);
+AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(dev);
+
+memcpy(s->regs, asc->resets, asc->nr_regs * 4);
+
+s->regs[AST2600_SILICON_REV] = AST1030_A1_SILICON_REV;
+s->regs[AST2600_SILICON_REV2] = s->silicon_rev;
+s->regs[AST2600_HW_STRAP1] = s->hw_strap1;
+s->regs[AST2600_HW_STRAP2] = s->hw_strap2;
+s->regs[PROT_KEY] = s->hw_prot_key;
+}
+
+static void aspeed_1030_scu_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+AspeedSCUClass *asc = ASPEED_SCU_CLASS(klass);
+
+dc->desc = "ASPEED 1030 System Control Unit";
+dc->reset = aspeed_ast1030_scu_reset;
+asc->resets = ast1030_a1_resets;
+asc->calc_hpll = aspeed_2600_scu_calc_hpll;
+asc->get_apb = aspeed_1030_scu_get_apb_freq;
+asc->apb_divider = 2;
+asc->nr_regs = ASPEED_AST2600_SCU_NR_REGS;
+asc->clkin_25Mhz = true;
+asc->ops = &aspeed_ast2600_scu_ops;
+}
+
+static const TypeInfo aspeed_1030_scu_info = {
+.name = TYPE_ASPEED_1030_SCU,
+.parent = TYPE_ASPEED_SCU,
+.instance_size = sizeof(AspeedSCUState),
+.class_init = aspeed_1030_scu_class_init,
+};
+
 static void aspeed_scu_register_types(void)
 {
 type_register_static(&aspeed_scu_info);
 type_register_static(&aspeed_2400_scu_info);
 type_register_static(&aspeed_2500_scu_info);
 type_register_static(&aspeed_2600_scu_info);
+type_register_static(&aspeed_1030_scu_info);
 }
 
 type_init(aspeed_scu_register_types);
diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h
index fdc721846c..d71aa66e40 100644
--- a/include/hw/misc/aspeed_scu.h
+++ b/include/hw/misc/aspeed_scu.h
@@ -19,6 +19,7 @@ OBJECT_DECLARE_TYPE(AspeedSCUState, AspeedSCUClass, 
ASPEED_SCU)
 #define TYPE_ASPEED_2400_SCU TYPE_ASPEED_SCU "-ast2400"
 #define TYPE_ASPEED_2500_SCU TYPE_ASPEED_SCU "-ast2500"
 #define TYPE_ASPEED_2600_SCU TYPE_ASPEED_SCU "-ast2600"
+#define TYPE_ASPEED_1030_SCU TYPE_ASPEED_SCU "-ast1030"
 
 #define ASPEED_SCU_NR_REGS (0x1A8 >> 2)
 #define ASPEED_AST2600_SCU_NR_REGS (0xE20 >> 2)
@@ -45,6 +46,8 @@ struct AspeedSCUState {
 #define AST2600_A1_SILICON_REV   0x05010303U
 #define AST2600_A2_SILICON_REV   0x05020303U
 #define AST2600_A3_SILICON_REV   0x05030303U
+#define AST1030_A0_SILICON_REV   0x8000U
+#define AST1030_A1_SILICON_REV   0x8001U
 
 #define ASPEED_IS_AST2500(si_rev) si_rev) >> 24) & 0xff) == 0x04)
 
@@ -335,4 +338,26 @@ uint32_t aspeed_scu_get_apb_freq(AspeedSCUState *s);
 #define SCU_AST2600_H_PLL_BYPASS_EN(0x1 << 24)
 #define SCU_AST2600_H_PLL_OFF  (0x1 << 23)
 
+/*
+ * SCU310   Clock Selection Register Set 4 (for Aspeed AST1030 SOC)
+ *
+ *  31 I3C Clock Source selection
+ *  30:2

[PATCH] build-sys: drop ntddscsi.h check

2022-04-01 Thread marcandre . lureau
From: Marc-André Lureau 

The header has been part of MinGW-w64 since the introduction of the
project (2007). While on MinGW(32), the legacy project, it was imported
in 2014 from w32api-3.17 (commit e4803e0da2).

According to build-platform.rst and our CI coverage, we only support
building with MinGW-w64 (from Debian/Fedora).

Signed-off-by: Marc-André Lureau 
---
 meson.build  | 17 -
 qga/commands-win32.c | 19 ---
 qga/meson.build  |  6 ++
 3 files changed, 2 insertions(+), 40 deletions(-)

diff --git a/meson.build b/meson.build
index c06fe5e02737..46b5e938b196 100644
--- a/meson.build
+++ b/meson.build
@@ -2019,22 +2019,6 @@ if targetos == 'windows' and link_language == 'cpp'
 endif
 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
 
-have_ntddscsi = false
-if targetos == 'windows'
-  have_ntddscsi = cc.compiles('''
-#include 
-#include 
-int main(void) {
-#if !defined(IOCTL_SCSI_GET_ADDRESS)
-#error Missing required ioctl definitions
-#endif
-  SCSI_ADDRESS addr = { .Lun = 0, .TargetId = 0, .PathId = 0 };
-  return addr.Lun;
-}
-''')
-endif
-config_host_data.set('HAVE_NTDDSCSI', have_ntddscsi)
-
 ignored = ['CONFIG_QEMU_INTERP_PREFIX', # actually per-target
 'HAVE_GDB_BIN']
 arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
@@ -3722,7 +3706,6 @@ summary_info += {'libnfs support':libnfs}
 if targetos == 'windows'
   if have_ga
 summary_info += {'QGA VSS support':   have_qga_vss}
-summary_info += {'QGA w32 disk info': have_ntddscsi}
   endif
 endif
 summary_info += {'seccomp support':   seccomp}
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 3c428213db0a..ebec5536340a 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -18,10 +18,8 @@
 #include 
 #include 
 #include 
-#ifdef HAVE_NTDDSCSI
 #include 
 #include 
-#endif
 #include 
 #include 
 #include 
@@ -474,8 +472,6 @@ void qmp_guest_file_flush(int64_t handle, Error **errp)
 }
 }
 
-#ifdef HAVE_NTDDSCSI
-
 static GuestDiskBusType win2qemu[] = {
 [BusTypeUnknown] = GUEST_DISK_BUS_TYPE_UNKNOWN,
 [BusTypeScsi] = GUEST_DISK_BUS_TYPE_SCSI,
@@ -1098,21 +1094,6 @@ GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
 return ret;
 }
 
-#else
-
-static GuestDiskAddressList *build_guest_disk_info(char *guid, Error **errp)
-{
-return NULL;
-}
-
-GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
-{
-error_setg(errp, QERR_UNSUPPORTED);
-return NULL;
-}
-
-#endif /* HAVE_NTDDSCSI */
-
 static GuestFilesystemInfo *build_guest_fsinfo(char *guid, Error **errp)
 {
 DWORD info_size;
diff --git a/qga/meson.build b/qga/meson.build
index 4d5de843abf6..40a7baabfde3 100644
--- a/qga/meson.build
+++ b/qga/meson.build
@@ -83,14 +83,12 @@ qga_ss = qga_ss.apply(config_host, strict: false)
 gen_tlb = []
 qga_libs = []
 if targetos == 'windows'
-  qga_libs += ['-lws2_32', '-lwinmm', '-lpowrprof', '-lwtsapi32', '-lwininet', 
'-liphlpapi', '-lnetapi32']
+  qga_libs += ['-lws2_32', '-lwinmm', '-lpowrprof', '-lwtsapi32', '-lwininet', 
'-liphlpapi', '-lnetapi32',
+   '-lsetupapi', '-lcfgmgr32']
   if have_qga_vss
 qga_libs += ['-lole32', '-loleaut32', '-lshlwapi', '-lstdc++', 
'-Wl,--enable-stdcall-fixup']
 subdir('vss-win32')
   endif
-  if have_ntddscsi
-qga_libs += ['-lsetupapi', '-lcfgmgr32']
-  endif
 endif
 
 qga = executable('qemu-ga', qga_ss.sources(),
-- 
2.35.1.693.g805e0a68082a




[PATCH v5 7/9] aspeed/soc : Add AST1030 support

2022-04-01 Thread Jamin Lin
From: Steven Lee 

The embedded core of AST1030 SoC is ARM Coretex M4.
It is hard to be integrated in the common Aspeed Soc framework.
We introduce a new ast1030 class with instance_init and realize
handlers.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Signed-off-by: Steven Lee 
Reviewed-by: Cédric Le Goater 
---
 hw/arm/aspeed_ast10xx.c | 299 
 hw/arm/meson.build  |   6 +-
 include/hw/arm/aspeed_soc.h |   3 +
 3 files changed, 307 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/aspeed_ast10xx.c

diff --git a/hw/arm/aspeed_ast10xx.c b/hw/arm/aspeed_ast10xx.c
new file mode 100644
index 00..0567527671
--- /dev/null
+++ b/hw/arm/aspeed_ast10xx.c
@@ -0,0 +1,299 @@
+/*
+ * ASPEED AST10xx SoC
+ *
+ * Copyright (C) 2022 ASPEED Technology Inc.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ * Implementation extracted from the AST2600 and adapted for AST10xx.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "exec/address-spaces.h"
+#include "sysemu/sysemu.h"
+#include "hw/qdev-clock.h"
+#include "hw/misc/unimp.h"
+#include "hw/char/serial.h"
+#include "hw/arm/aspeed_soc.h"
+
+#define ASPEED_SOC_IOMEM_SIZE 0x0020
+
+static const hwaddr aspeed_soc_ast1030_memmap[] = {
+[ASPEED_DEV_SRAM]  = 0x,
+[ASPEED_DEV_SBC]   = 0x7900,
+[ASPEED_DEV_IOMEM] = 0x7E60,
+[ASPEED_DEV_PWM]   = 0x7E61,
+[ASPEED_DEV_FMC]   = 0x7E62,
+[ASPEED_DEV_SPI1]  = 0x7E63,
+[ASPEED_DEV_SPI2]  = 0x7E64,
+[ASPEED_DEV_SCU]   = 0x7E6E2000,
+[ASPEED_DEV_ADC]   = 0x7E6E9000,
+[ASPEED_DEV_SBC]   = 0x7E6F2000,
+[ASPEED_DEV_GPIO]  = 0x7E78,
+[ASPEED_DEV_TIMER1]= 0x7E782000,
+[ASPEED_DEV_UART5] = 0x7E784000,
+[ASPEED_DEV_WDT]   = 0x7E785000,
+[ASPEED_DEV_LPC]   = 0x7E789000,
+[ASPEED_DEV_I2C]   = 0x7E7B,
+};
+
+static const int aspeed_soc_ast1030_irqmap[] = {
+[ASPEED_DEV_UART5] = 8,
+[ASPEED_DEV_GPIO]  = 11,
+[ASPEED_DEV_TIMER1]= 16,
+[ASPEED_DEV_TIMER2]= 17,
+[ASPEED_DEV_TIMER3]= 18,
+[ASPEED_DEV_TIMER4]= 19,
+[ASPEED_DEV_TIMER5]= 20,
+[ASPEED_DEV_TIMER6]= 21,
+[ASPEED_DEV_TIMER7]= 22,
+[ASPEED_DEV_TIMER8]= 23,
+[ASPEED_DEV_WDT]   = 24,
+[ASPEED_DEV_LPC]   = 35,
+[ASPEED_DEV_FMC]   = 39,
+[ASPEED_DEV_PWM]   = 44,
+[ASPEED_DEV_ADC]   = 46,
+[ASPEED_DEV_SPI1]  = 65,
+[ASPEED_DEV_SPI2]  = 66,
+[ASPEED_DEV_I2C]   = 110, /* 110 ~ 123 */
+[ASPEED_DEV_KCS]   = 138, /* 138 -> 142 */
+};
+
+static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl)
+{
+AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+
+return qdev_get_gpio_in(DEVICE(&s->armv7m), sc->irqmap[ctrl]);
+}
+
+static void aspeed_soc_ast1030_init(Object *obj)
+{
+AspeedSoCState *s = ASPEED_SOC(obj);
+AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+char socname[8];
+char typename[64];
+int i;
+
+if (sscanf(sc->name, "%7s", socname) != 1) {
+g_assert_not_reached();
+}
+
+object_initialize_child(obj, "armv7m", &s->armv7m, TYPE_ARMV7M);
+
+s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0);
+
+snprintf(typename, sizeof(typename), "aspeed.scu-%s", socname);
+object_initialize_child(obj, "scu", &s->scu, typename);
+qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev", sc->silicon_rev);
+
+object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu), "hw-strap1");
+object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu), "hw-strap2");
+
+snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
+object_initialize_child(obj, "timerctrl", &s->timerctrl, typename);
+
+snprintf(typename, sizeof(typename), "aspeed.adc-%s", socname);
+object_initialize_child(obj, "adc", &s->adc, typename);
+
+snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname);
+object_initialize_child(obj, "fmc", &s->fmc, typename);
+
+for (i = 0; i < sc->spis_num; i++) {
+snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, 
socname);
+object_initialize_child(obj, "spi[*]", &s->spi[i], typename);
+}
+
+object_initialize_child(obj, "lpc", &s->lpc, TYPE_ASPEED_LPC);
+
+object_initialize_child(obj, "sbc", &s->sbc, TYPE_ASPEED_SBC);
+
+for (i = 0; i < sc->wdts_num; i++) {
+snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
+object_initialize_child(obj, "wdt[*]", &s->wdt[i], typename);
+}
+}
+
+static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
+{
+AspeedSoCState *s = ASPEED_SOC(dev_soc);
+AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+MemoryRegion *system_memory = get_system_memory();
+DeviceState *armv7m;
+Error *err = N

Re: [PATCH 2/2] NVDIMM: Init vNVDIMM's LSA index block if it hasn't been

2022-04-01 Thread Igor Mammedov
On Fri, 01 Apr 2022 12:07:56 +0800
Robert Hoo  wrote:

> On Thu, 2022-03-31 at 16:41 +0200, Igor Mammedov wrote:
> > On Thu, 31 Mar 2022 21:08:12 +0800
> > Robert Hoo  wrote:
> >
> > > > 
> > > > Can user initialize/format LSA from guest using ndctl/some other
> > > > tool?
> > > > 
> > > 
> > > Yes, he can. But when guest Kernel already told him this is a dimm
> > > without label capability, dare/should he take this dangerous
> > > action?;-)  
> > 
> > I don't think this feature belongs to QEMU (i.e. hw emulation).
> > It's task that is usually accomplished by firmware or OS
> > (in context of QEMU its guest's responsibility).
> >   
> 
> Thanks Igor.
> Actually before I compose this patch, I was pondering on this as well:
> whose obligation to fulfill this function, i.e. initialize the LSA.
> 
> So I asked around (and still asking), knowing these about native usage,
> (correct me if I'm wrong), which we virtualization should mimic in
> principle:
> 
> a) before user start to use NVDIMM, he's supposed to ipmctl[0] create
> goal firstly, to determine 2LM mode or app direct mode, which usually
> initializes the LSA. So user doesn't necessarily to explicit 'ndctl
> init-label' although he can do this to init LSA again.
> 
> b) I heard that, perhaps, even when DIMMs are sent out from factory, it
> has LSA initialized (not quite certain about this, I'm still
> confirming).
if you find a NVDIMM that implements initialization in hardware,
then it could be considered. But QEMU isn't a factory, it's rather
a component within factory that perform specific task while other
components manage it (including storage it consumes, see libguestfs
project which is similar to what you are trying to do, but deals
with conventional storage).

> What specs say
> ---
> In NVDIMM Namespace spec[1], Chap 2 "Namespaces": 
> "NVDIMM vendors define the size of their label storage area and,
> therefor, the number of labels it holds."
one does define size and lsa size on QEMU command line,
how it will be consumed is the business of firmware/operating system
that runs within VM though.

> I think: In QEMU context, it's QEMU who's the vNVDIMM's vendor.
> 
> In UEFI spec [2], "13.19 NVDIMM Label Protocol", page 640:
> "Before Index Blocks and labels can be utilized, the software managing
> the Label Storage Area must determine the total number of labels that
> will be supported and utilizing the description above, calculate the
> size of the Index Blocks required."
> 
> I think: In QEMU context, it's QEMU who emulates LSA and therefore the
> management software of it.
> 
> What's real limitation on QEMU vNVDIMM implementation
> ---
> In VM:
> ipmctl isn't supported.
> Only app direct mode is supported. (i.e. no bother to ipmctl create
> goal first).
> vNVDIMM is actually presented to user in a ready-to-use initial state.
> We never tell user you must 'ndctl init-label' then can use it.
> Nor tell user that you should 'ipmctl create-goal' first, because in
> fact ipmctl isn't available at all.

ipmictl isn't hardware, it's tool to connect to firmware
running on BMC. In virt world it corresponds to guest code running
within VM or some mgmt app outside QEMU that can implement IPMI
interface. You can try to generalize this utility and extend EDKII
to support it, which would benefit not only QEMU but other
consumers of EDKII.
wrt IPMI, I'm not familiar with BMC support in QEMU, but looks
there are at least some (see hw/ipmi folder) implementations.

As for [b] point, QEMU is not software managing NVDIMM, it's
hardware emulator. Duplicating irrelevant features in QEMU
will just bloat it and make project unmanageable.
Point [b] to me looks more like a separate utility that could
initialize vNVDIMM for further consumption (I'd ask libguestfs
or ndctl folks if they would like to add support for 'out of band'
vNVDIMM management, but likely outcome to this would be what
libguestfs is doing currently with disks, start VM appliance
and run ndctl within it to initialize vNVDIMM).
 
> That's all the story and thoughts before I compose this patch:)
> 
> [0] https://docs.pmem.io/ipmctl-user-guide/ (and, ipmctl is for Intel
> Optane PMEM only)
> [1] https://pmem.io/documents/NVDIMM_Namespace_Spec.pdf
> [2] 
> https://uefi.org/sites/default/files/resources/UEFI_Spec_2_9_2021_03_18.pdf
> 
> > 
> > PS:
> > It's true that QEMU caries some 'firmware' code, like composing
> > ACPI tables but we do it only to reduce QEMU<->firmware ABI
> > necessary for hardware description and that's pretty much it.
> > Unfortunately this series doesn't fit the bill.
> >   
> Yeah, I've seen this part of code, but a little difficult to comprehend
> them, especially for me a stranger to ACPI. Where can I find related
> design document?
> I now only find a valuable doc: docs/specs/acpi_nvdimm.rst.
> >   
> 




Re: [PATCH v5 0/9] Add support for AST1030 SoC

2022-04-01 Thread Cédric Le Goater

Hello Jamin,

Thanks for these new models and machine. They are queued for QEMU 7.1.
There are a couple of patchsets adding support for the AST1030 GPIO
controller and the I2C new mode that would be good extensions but
they need review first.

What are the next steps? any plans for network ? The NIC should be a
FTGMAC100 if I am correct.

Thanks,

C.


 On 4/1/22 10:38, Jamin Lin wrote:

Changes from v5:
- remove TYPE_ASPEED_MINIBMC_MACHINE and ASPEED_MINIBMC_MACHINE
- remove ast1030_machine_instance_init function

Changes from v4:
- drop the ASPEED_SMC_FEATURE_WDT_CONTROL flag in hw/ssi/aspeed_smc.c

Changes from v3:
- remove AspeedMiniBmcMachineState state structure and
   AspeedMiniBmcMachineClass class
- remove redundant new line in hw/arm/aspeed_ast10xx.c
- drop the ASPEED_SMC_FEATURE_WDT_CONTROL flag in hw/ssi/aspeed_smc.c

Changes from v2:
- replace aspeed_ast1030.c with aspeed_ast10xx.c for minibmc SOCs family support
- Add "ast1030-evb" machine in aspeed.c and removes aspeed_minibmc.c

Changes from v1:
The patch series supports ADC, SCU, SMC, TIMER, and WDT for AST1030 SoC.
Add avocado test case for "ast1030-evb" machine.

Test steps:
1. Download image from

https://github.com/AspeedTech-BMC/zephyr/releases/download/v00.01.04/ast1030-evb-demo.zip
2. Extract the zip file to obtain zephyr.elf
3. Run ./qemu-system-arm -M ast1030-evb -kernel $PATH/zephyr.elf -nographic
4. Test IO by Zephyr command line, commands are refer to Aspeed Zephyr
SDK User Guide below

https://github.com/AspeedTech-BMC/zephyr/releases/download/v00.01.04/Aspeed_Zephy_SDK_User_Guide_v00.01.04.pdf
- ADC(channel 0):
uart:~$ adc ADC0 resolution 10
uart:~$ adc ADC0 calibrate 1
uart:~$ adc ADC0 read_format 1
uart:~$ adc ADC0 read 0
[Result]
read: 1416mv

- SCU
uart:~$ md 7e6e2040
uart:~$ md 7e6e2080
uart:~$ md 7e6e20d0
uart:~$ md 7e6e2200
uart:~$ md 7e6e2300
uart:~$ md 7e6e25b0
[Result]
The register value should match the value of ast1030_a1_resets
in aspeed_scu.c

- Flash(fmc_cs0):
uart:~$ flash write fmc_cs0 0 0x12345678 0x87654321 0x34127856 
0x78563412
uart:~$ flash read fmc_cs0 0 10
[Result]
: 78 56 34 12 21 43 65 87  56 78 12 34 12 34 56 78 |xV4.!Ce. 
Vx.4.4Vx|

uart:~$ flash erase fmc_cs0 0
uart:~$ flash read fmc_cs0 0 10
[Result]
: ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff | 
|

- Timer(TIMER0):
uart:~$ timer start TIMER0 -p 2000 -t 0
TIMER0: period 2 ms, type 0
[Result]
timer expired after 2 seconds

- Watchdog(WDT1):
uart:~$ mw 7e785008 4755
uart:~$ mw 7e78500c 1
[Result]
soc reset after 22 seconds

Based-on: 20220315075753.8591-3-steven_...@aspeedtech.com
([v2,2/2] hw: aspeed_scu: Introduce clkin_25Mhz attribute)

Jamin Lin (2):
   aspeed: Add an AST1030 eval board
   test/avocado/machine_aspeed.py: Add ast1030 test case

Steven Lee (7):
   aspeed/adc: Add AST1030 support
   aspeed/smc: Add AST1030 support
   aspeed/wdt: Fix ast2500/ast2600 default reload value
   aspeed/wdt: Add AST1030 support
   aspeed/timer: Add AST1030 support
   aspeed/scu: Add AST1030 support
   aspeed/soc : Add AST1030 support

  hw/adc/aspeed_adc.c  |  16 ++
  hw/arm/aspeed.c  |  66 +++
  hw/arm/aspeed_ast10xx.c  | 299 +++
  hw/arm/meson.build   |   6 +-
  hw/misc/aspeed_scu.c |  63 +++
  hw/ssi/aspeed_smc.c  | 157 
  hw/timer/aspeed_timer.c  |  17 ++
  hw/watchdog/wdt_aspeed.c |  34 +++-
  include/hw/adc/aspeed_adc.h  |   1 +
  include/hw/arm/aspeed_soc.h  |   3 +
  include/hw/misc/aspeed_scu.h |  25 +++
  include/hw/timer/aspeed_timer.h  |   1 +
  include/hw/watchdog/wdt_aspeed.h |   3 +
  tests/avocado/machine_aspeed.py  |  36 
  14 files changed, 724 insertions(+), 3 deletions(-)
  create mode 100644 hw/arm/aspeed_ast10xx.c
  create mode 100644 tests/avocado/machine_aspeed.py






Re: [PULL 19/35] ppc/pnv: Add models for POWER9 PHB4 PCIe Host bridge

2022-04-01 Thread Frederic Barrat




On 01/04/2022 03:59, Benjamin Herrenschmidt wrote:

This one:

#define PHB4_PEC_PCI_REGS_COUNT 0x2

Should be

#define PHB4_PEC_PCI_REGS_COUNT 0x3

There is no register at 0x1 though.



Patch on the way

  Fred



Re: [RFC PATCH 0/4] hw/i2c: i2c slave mode support

2022-04-01 Thread Damien Hedde



On 4/1/22 08:29, Klaus Jensen wrote:

On Mar 31 15:32, Corey Minyard wrote:

On Thu, Mar 31, 2022 at 06:57:33PM +0200, Klaus Jensen wrote:

From: Klaus Jensen 

Hi all,

This RFC series adds I2C "slave mode" support for the Aspeed I2C
controller as well as the necessary infrastructure in the i2c core to
support this.


I've been wondering when this would happen :).  I had put some thought
into how this would work, but hadn't come up with anything good.

The big disadvantage of this is you are adding an interface that is
incompatible with the current masters and slaves.  So you are using the
same I2C bus, but slaves written this way cannot talk to existing
masters, and masters written this way cannot talk to existing slave.
You could adapt the masters to be able to work either way, and I suppose
some slaves that could do it could have both an async send and a normal
send.


Would it make sense to introduce a QOM Interface to differentiate
between the slave/master types?



Probably.

I expect a normal slave-only I2C device will be compatible with any 
master (having or having not this feature) in real life ?


It would be great if the compatibility between "a I2C slave requiring 
the slave-mode from the bus" and the bus could be checked during the 
device plug.


--
Damien



Re: use of uninitialized variable involving visit_type_uint32() and friends

2022-04-01 Thread Markus Armbruster
Paolo Bonzini  writes:

> On Thu, Mar 31, 2022 at 7:35 PM Peter Maydell 
> wrote:
>
>> Coverity warns about use of uninitialized data in what seems
>> to be a common pattern of use of visit_type_uint32() and similar
>> functions. Here's an example from target/arm/cpu64.c:
>>
>> static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char
>> *name,
>>void *opaque, Error **errp)
>> {
>> ARMCPU *cpu = ARM_CPU(obj);
>> uint32_t max_vq;
>> if (!visit_type_uint32(v, name, &max_vq, errp)) {
>> return;
>> }
>> [code that does something with max_vq here]
>> }
>>
>> This doesn't initialize max_vq, on the apparent assumption
>> that visit_type_uint32() will do so. But that function [...]
>> reads the value of *obj (the uninitialized max_vq).
>>
>
> The visit_type_* functions are written to work for both getters and setters.

Yes.

This is convenient for uses that are actually visitor-agnostic, such as
the generated qapi-visit-FOO.c

It can be really ugly for output-only uses.  In particular for strings,
where we have to pass a char ** instead of a const char *.

> For the leaves, that means potentially reading uninitialized data.  It is
> harmless but very ugly, and with respect to static analysis it was all but
> a time bomb, all the time.
>
> The best (but most intrusive) solution would be to add a parameter to all
> visit_type_* functions with the expected "direction" of the visit, which
> could be checked against v->type.
>
> That is:
>
> bool visit_type_uint32(VisitorType expected_type, Visitor *v, const char
> *name, uint32_t *obj,
>Error **errp)
> {
> uint64_t value;
> bool ok;
>
> trace_visit_type_uint32(v, name, obj);
> assert (v->type == expected_type);
> if (expected_type & (VISITOR_INPUT | VISITOR_DEALLOC)) {
> value = *obj;
> }
> ok = visit_type_uintN(v, &value, name, UINT32_MAX, "uint32_t", errp);
> assert (ok || expected_type == VISITOR_INPUT);
> if (expected_type & VISITOR_OUTPUT) {
> *obj = value;
> }
> return ok;
> }

As diff -w:

 -bool visit_type_uint32(Visitor *v, const char *name, uint32_t *obj,
 +bool visit_type_uint32(VisitorType expected_type, Visitor *v, const char
 +*name, uint32_t *obj,
 Error **errp)
  {
  uint64_t value;
  bool ok;

  trace_visit_type_uint32(v, name, obj);
 +assert (v->type == expected_type);
 +if (expected_type & (VISITOR_INPUT | VISITOR_DEALLOC)) {

Backwards.

With an input visitor @v,

visit_type_uint32(v, "name", &val, errp)

stores to @val without looking at it first.  In other words,
uninitialized @val is fine, just like for val = ...

Note: you don't actually need VISITOR_DEALLOC here, because a
deallocation visitor isn't going to do anything for non-pointer values.

With an output visitor @v,

visit_type_uint32(v, "name", &val, errp)

reads from @val without changing it.

  value = *obj;
 +}
  ok = visit_type_uintN(v, &value, name, UINT32_MAX, "uint32_t", errp);
 +assert (ok || expected_type == VISITOR_INPUT);
 +if (expected_type & VISITOR_OUTPUT) {

Also backwards.  

  *obj = value;
 +}
  return ok;
  }

Two changes:

* Skip copying to and from full-width buffer @value:

  - Skip @value = *obj when we're going to overwrite @value without
reading it first.

This leaves @value uninitialized instead of initializing it from a
(commonly) uninitialized variable.

I'm not sure how this helps static analysis, but if it does...

  - Skip *obj = @value when value must be *obj anyway.

Should have no observable effect.

Again, I'm not sure how this helps static analysis.

  Note that only the functions for types narrower than 64 bits have such
  copying code.  Skipping the assignments creates a tiny inconsistency
  between narrow and fill-width visits.

* Pass visitor type in addition to the visitor.  Can you explain why
  that's useful?

> Probably also renaming VISITOR_* to V_* for conciseness.  That *should*
> quiesce Coverity, and also add some runtime checks.
>
> Paolo




[PATCH] ppc/pnv: Fix number of registers in the PCIe controller on POWER9

2022-04-01 Thread Frederic Barrat
The spec defines 3 registers, even though only index 0 and 2 are valid
on POWER9. The same model is used on POWER10. Register 1 is defined
there but we currently don't use it in skiboot. So we can keep
reporting an error on write.

Reported by Coverity (CID 1487176).

Fixes: 4f9924c4d4cf ("ppc/pnv: Add models for POWER9 PHB4 PCIe Host bridge")
Suggested-by: Benjamin Herrenschmidt 
Signed-off-by: Frederic Barrat 
---
 include/hw/pci-host/pnv_phb4.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/hw/pci-host/pnv_phb4.h b/include/hw/pci-host/pnv_phb4.h
index b02ecdceaa..19dcbd6f87 100644
--- a/include/hw/pci-host/pnv_phb4.h
+++ b/include/hw/pci-host/pnv_phb4.h
@@ -180,7 +180,7 @@ struct PnvPhb4PecState {
 MemoryRegion nest_regs_mr;
 
 /* PCI registers, excluding per-stack */
-#define PHB4_PEC_PCI_REGS_COUNT 0x2
+#define PHB4_PEC_PCI_REGS_COUNT 0x3
 uint64_t pci_regs[PHB4_PEC_PCI_REGS_COUNT];
 MemoryRegion pci_regs_mr;
 
-- 
2.35.1




[PATCH v2 2/7] block/copy-before-write: add on-cbw-error open parameter

2022-04-01 Thread Vladimir Sementsov-Ogievskiy
Currently, behavior on copy-before-write operation failure is simple:
report error to the guest.

Let's implement alternative behavior: break the whole copy-before-write
process (and corresponding backup job or NBD client) but keep guest
working. It's needed if we consider guest stability as more important.

The realisation is simple: on copy-before-write failure we immediately
continue guest write operation and set s->snapshot_ret variable which
will lead to all further and in-flight snapshot-API requests failure.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 block/copy-before-write.c | 62 ++-
 qapi/block-core.json  | 27 -
 2 files changed, 81 insertions(+), 8 deletions(-)

diff --git a/block/copy-before-write.c b/block/copy-before-write.c
index 394e73b094..0614c3d08b 100644
--- a/block/copy-before-write.c
+++ b/block/copy-before-write.c
@@ -41,6 +41,7 @@
 typedef struct BDRVCopyBeforeWriteState {
 BlockCopyState *bcs;
 BdrvChild *target;
+OnCbwError on_cbw_error;
 
 /*
  * @lock: protects access to @access_bitmap, @done_bitmap and
@@ -65,6 +66,14 @@ typedef struct BDRVCopyBeforeWriteState {
  * node. These areas must not be rewritten by guest.
  */
 BlockReqList frozen_read_reqs;
+
+/*
+ * @snapshot_error is normally zero. But on first copy-before-write failure
+ * when @on_cbw_error == ON_CBW_ERROR_BREAK_SNAPSHOT, @snapshot_error takes
+ * value of this error (<0). After that all in-flight and further
+ * snaoshot-API requests will fail with that error.
+ */
+int snapshot_error;
 } BDRVCopyBeforeWriteState;
 
 static coroutine_fn int cbw_co_preadv(
@@ -99,11 +108,25 @@ static coroutine_fn int 
cbw_do_copy_before_write(BlockDriverState *bs,
 end = QEMU_ALIGN_UP(offset + bytes, cluster_size);
 
 ret = block_copy(s->bcs, off, end - off, true);
-if (ret < 0) {
+if (ret < 0 && s->on_cbw_error == ON_CBW_ERROR_BREAK_GUEST_WRITE) {
 return ret;
 }
 
 WITH_QEMU_LOCK_GUARD(&s->lock) {
+if (ret < 0) {
+assert(s->on_cbw_error == ON_CBW_ERROR_BREAK_SNAPSHOT);
+if (!s->snapshot_error) {
+s->snapshot_error = ret;
+}
+/*
+ * No need to wait for s->frozen_read_reqs: they will fail anyway,
+ * as s->snapshot_error is set.
+ *
+ * We return 0, as error is handled. Guest operation should be
+ * continued.
+ */
+return 0;
+}
 bdrv_set_dirty_bitmap(s->done_bitmap, off, end - off);
 reqlist_wait_all(&s->frozen_read_reqs, off, end - off, &s->lock);
 }
@@ -176,6 +199,11 @@ static BlockReq *cbw_snapshot_read_lock(BlockDriverState 
*bs,
 
 QEMU_LOCK_GUARD(&s->lock);
 
+if (s->snapshot_error) {
+g_free(req);
+return NULL;
+}
+
 if (bdrv_dirty_bitmap_next_zero(s->access_bitmap, offset, bytes) != -1) {
 g_free(req);
 return NULL;
@@ -198,19 +226,26 @@ static BlockReq *cbw_snapshot_read_lock(BlockDriverState 
*bs,
 return req;
 }
 
-static void cbw_snapshot_read_unlock(BlockDriverState *bs, BlockReq *req)
+static int cbw_snapshot_read_unlock(BlockDriverState *bs, BlockReq *req)
 {
 BDRVCopyBeforeWriteState *s = bs->opaque;
 
 if (req->offset == -1 && req->bytes == -1) {
 g_free(req);
-return;
+/*
+ * No real need to read snapshot_error under mutex here: we are 
actually
+ * safe to ignore it and return 0, as this request was to s->target, 
and
+ * can't be influenced by guest write. But if we can new read negative
+ * s->snapshot_error let's return it, so that backup failed earlier.
+ */
+return s->snapshot_error;
 }
 
 QEMU_LOCK_GUARD(&s->lock);
 
 reqlist_remove_req(req);
 g_free(req);
+return s->snapshot_error;
 }
 
 static coroutine_fn int
@@ -219,7 +254,7 @@ cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t 
offset, int64_t bytes,
 {
 BlockReq *req;
 BdrvChild *file;
-int ret;
+int ret, ret2;
 
 /* TODO: upgrade to async loop using AioTask */
 while (bytes) {
@@ -232,10 +267,13 @@ cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t 
offset, int64_t bytes,
 
 ret = bdrv_co_preadv_part(file, offset, cur_bytes,
   qiov, qiov_offset, 0);
-cbw_snapshot_read_unlock(bs, req);
+ret2 = cbw_snapshot_read_unlock(bs, req);
 if (ret < 0) {
 return ret;
 }
+if (ret2 < 0) {
+return ret2;
+}
 
 bytes -= cur_bytes;
 offset += cur_bytes;
@@ -253,7 +291,7 @@ cbw_co_snapshot_block_status(BlockDriverState *bs,
 {
 BDRVCopyBeforeWriteState *s = bs->opaque;
 BlockReq *req;
-int ret;
+int ret, ret2;
 int64_t cur_bytes;
 BdrvChild *child;
 
@@ -273,7 +311,14 @@ cbw_co_snapshot_block_status(BlockDr

[PATCH v2 3/7] iotests: add copy-before-write: on-cbw-error tests

2022-04-01 Thread Vladimir Sementsov-Ogievskiy
Add tests for new option of copy-before-write filter: on-cbw-error.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 tests/qemu-iotests/tests/copy-before-write| 128 ++
 .../qemu-iotests/tests/copy-before-write.out  |   5 +
 2 files changed, 133 insertions(+)
 create mode 100755 tests/qemu-iotests/tests/copy-before-write
 create mode 100644 tests/qemu-iotests/tests/copy-before-write.out

diff --git a/tests/qemu-iotests/tests/copy-before-write 
b/tests/qemu-iotests/tests/copy-before-write
new file mode 100755
index 00..a32608f597
--- /dev/null
+++ b/tests/qemu-iotests/tests/copy-before-write
@@ -0,0 +1,128 @@
+#!/usr/bin/env python3
+# group: auto backup
+#
+# Copyright (c) 2022 Virtuozzo International GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
+#
+
+import os
+import re
+
+import iotests
+from iotests import qemu_img_create, qemu_io
+
+
+temp_img = os.path.join(iotests.test_dir, 'temp')
+source_img = os.path.join(iotests.test_dir, 'source')
+size = '1M'
+
+
+class TestCbwError(iotests.QMPTestCase):
+def tearDown(self):
+self.vm.shutdown()
+os.remove(temp_img)
+os.remove(source_img)
+
+def setUp(self):
+qemu_img_create('-f', iotests.imgfmt, source_img, size)
+qemu_img_create('-f', iotests.imgfmt, temp_img, size)
+qemu_io('-c', 'write 0 1M', source_img)
+
+self.vm = iotests.VM()
+self.vm.launch()
+
+def do_cbw_error(self, on_cbw_error):
+result = self.vm.qmp('blockdev-add', {
+'node-name': 'cbw',
+'driver': 'copy-before-write',
+'on-cbw-error': on_cbw_error,
+'file': {
+'driver': iotests.imgfmt,
+'file': {
+'driver': 'file',
+'filename': source_img,
+}
+},
+'target': {
+'driver': iotests.imgfmt,
+'file': {
+'driver': 'blkdebug',
+'image': {
+'driver': 'file',
+'filename': temp_img
+},
+'inject-error': [
+{
+'event': 'write_aio',
+'errno': 5,
+'immediately': False,
+'once': True
+}
+]
+}
+}
+})
+self.assert_qmp(result, 'return', {})
+
+result = self.vm.qmp('blockdev-add', {
+'node-name': 'access',
+'driver': 'snapshot-access',
+'file': 'cbw'
+})
+self.assert_qmp(result, 'return', {})
+
+result = self.vm.hmp_qemu_io('cbw', 'write 0 1M')
+self.assert_qmp(result, 'return', '')
+
+result = self.vm.hmp_qemu_io('access', 'read 0 1M')
+self.assert_qmp(result, 'return', '')
+
+self.vm.shutdown()
+log = self.vm.get_log()
+log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log)
+log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log)
+log = iotests.filter_qemu_io(log)
+return log
+
+def test_break_snapshot_on_cbw_error(self):
+"""break-snapshot behavior:
+Guest write succeed, but further snapshot-read fails, as snapshot is
+broken.
+"""
+log = self.do_cbw_error('break-snapshot')
+
+self.assertEqual(log, """\
+wrote 1048576/1048576 bytes at offset 0
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read failed: Permission denied
+""")
+
+def test_break_guest_write_on_cbw_error(self):
+"""break-guest-write behavior:
+Guest write fails, but snapshot-access continues working and further
+snapshot-read succeeds.
+"""
+log = self.do_cbw_error('break-guest-write')
+
+self.assertEqual(log, """\
+write failed: Input/output error
+read 1048576/1048576 bytes at offset 0
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+""")
+
+
+if __name__ == '__main__':
+iotests.main(supported_fmts=['qcow2'],
+ supported_protocols=['file'])
diff --git a/tests/qemu-iotests/tests/copy-before-write.out 
b/tests/qemu-iotests/tests/copy-before-write.out
new file mode 100644
index 00..fbc63e62f8
--- /dev/null
+++ b/tests/qemu-iotests

[PATCH v2 0/7] copy-before-write: on-cbw-error and cbw-timeout

2022-04-01 Thread Vladimir Sementsov-Ogievskiy
Hi all!

Here are two new options for copy-before-write filter:

on-cbw-error allows to alter the behavior on copy-before-write operation
failure: not break guest write but break the snapshot (and therefore
backup process)

cbw-timeout allows to limit cbw operation by some timeout.

So, for example, using cbw-timeout=60 and on-cbw-error=break-snapshot
you can be sure that guest write will not stuck for more than 60
seconds and will never fail due to backup problems.

This series unites and fixes my
"[PATCH 0/3] block: copy-before-write: on-cbw-error behavior" and
"[PATCH 0/4] block: copy-before-write: cbw-timeout"

Supersedes: <20220301205929.2006041-1-vsement...@openvz.org>
Supersedes: <20220302162442.2052461-1-vsement...@openvz.org>

Vladimir Sementsov-Ogievskiy (7):
  block/copy-before-write: refactor option parsing
  block/copy-before-write: add on-cbw-error open parameter
  iotests: add copy-before-write: on-cbw-error tests
  util: add qemu-co-timeout
  block/block-copy: block_copy(): add timeout_ns parameter
  block/copy-before-write: implement cbw-timeout option
  iotests: copy-before-write: add cases for cbw-timeout option

 block/block-copy.c|  26 ++-
 block/copy-before-write.c | 136 +---
 include/block/block-copy.h|   2 +-
 include/qemu/coroutine.h  |  13 ++
 qapi/block-core.json  |  30 ++-
 tests/qemu-iotests/tests/copy-before-write| 206 ++
 .../qemu-iotests/tests/copy-before-write.out  |   5 +
 util/meson.build  |   1 +
 util/qemu-co-timeout.c|  89 
 9 files changed, 464 insertions(+), 44 deletions(-)
 create mode 100755 tests/qemu-iotests/tests/copy-before-write
 create mode 100644 tests/qemu-iotests/tests/copy-before-write.out
 create mode 100644 util/qemu-co-timeout.c

-- 
2.35.1




[PATCH v2 6/7] block/copy-before-write: implement cbw-timeout option

2022-04-01 Thread Vladimir Sementsov-Ogievskiy
In some scenarios, when copy-before-write operations lasts too long
time, it's better to cancel it.

Most useful would be to use the new option together with
on-cbw-error=break-snapshot: this way if cbw operation takes too long
time we'll just cancel backup process but do not disturb the guest too
much.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 block/copy-before-write.c | 6 +-
 qapi/block-core.json  | 5 -
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/block/copy-before-write.c b/block/copy-before-write.c
index 7ef3f9f4c1..0ea5506f77 100644
--- a/block/copy-before-write.c
+++ b/block/copy-before-write.c
@@ -42,6 +42,7 @@ typedef struct BDRVCopyBeforeWriteState {
 BlockCopyState *bcs;
 BdrvChild *target;
 OnCbwError on_cbw_error;
+uint32_t cbw_timeout_ns;
 
 /*
  * @lock: protects access to @access_bitmap, @done_bitmap and
@@ -107,7 +108,7 @@ static coroutine_fn int 
cbw_do_copy_before_write(BlockDriverState *bs,
 off = QEMU_ALIGN_DOWN(offset, cluster_size);
 end = QEMU_ALIGN_UP(offset + bytes, cluster_size);
 
-ret = block_copy(s->bcs, off, end - off, true, 0);
+ret = block_copy(s->bcs, off, end - off, true, s->cbw_timeout_ns);
 if (ret < 0 && s->on_cbw_error == ON_CBW_ERROR_BREAK_GUEST_WRITE) {
 return ret;
 }
@@ -412,6 +413,7 @@ static BlockdevOptionsCbw *cbw_parse_options(QDict 
*options, Error **errp)
  */
 qdict_extract_subqdict(options, NULL, "bitmap");
 qdict_del(options, "on-cbw-error");
+qdict_del(options, "cbw-timeout");
 
 out:
 visit_free(v);
@@ -455,6 +457,8 @@ static int cbw_open(BlockDriverState *bs, QDict *options, 
int flags,
 }
 s->on_cbw_error = opts->has_on_cbw_error ? opts->on_cbw_error :
 ON_CBW_ERROR_BREAK_GUEST_WRITE;
+s->cbw_timeout_ns = opts->has_cbw_timeout ?
+opts->cbw_timeout * NANOSECONDS_PER_SECOND : 0;
 
 bs->total_sectors = bs->file->bs->total_sectors;
 bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 3f08025114..e077506e0f 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -4207,12 +4207,15 @@
 # @on-cbw-error: Behavior on failure of copy-before-write operation.
 #Default is @break-guest-write. (Since 7.0)
 #
+# @cbw-timeout: Zero means no limit. Non-zero sets the timeout in seconds
+#   for copy-before-write operation. Default 0. (Since 7.0)
+#
 # Since: 6.2
 ##
 { 'struct': 'BlockdevOptionsCbw',
   'base': 'BlockdevOptionsGenericFormat',
   'data': { 'target': 'BlockdevRef', '*bitmap': 'BlockDirtyBitmap',
-'*on-cbw-error': 'OnCbwError' } }
+'*on-cbw-error': 'OnCbwError', '*cbw-timeout': 'uint32' } }
 
 ##
 # @BlockdevOptions:
-- 
2.35.1




Re: [RFC PATCH 0/4] hw/i2c: i2c slave mode support

2022-04-01 Thread Klaus Jensen
On Apr  1 10:58, Damien Hedde wrote:
> 
> On 4/1/22 08:29, Klaus Jensen wrote:
> > On Mar 31 15:32, Corey Minyard wrote:
> > > On Thu, Mar 31, 2022 at 06:57:33PM +0200, Klaus Jensen wrote:
> > > > From: Klaus Jensen 
> > > > 
> > > > Hi all,
> > > > 
> > > > This RFC series adds I2C "slave mode" support for the Aspeed I2C
> > > > controller as well as the necessary infrastructure in the i2c core to
> > > > support this.
> > > 
> > > I've been wondering when this would happen :).  I had put some thought
> > > into how this would work, but hadn't come up with anything good.
> > > 
> > > The big disadvantage of this is you are adding an interface that is
> > > incompatible with the current masters and slaves.  So you are using the
> > > same I2C bus, but slaves written this way cannot talk to existing
> > > masters, and masters written this way cannot talk to existing slave.
> > > You could adapt the masters to be able to work either way, and I suppose
> > > some slaves that could do it could have both an async send and a normal
> > > send.
> > 
> > Would it make sense to introduce a QOM Interface to differentiate
> > between the slave/master types?
> > 
> 
> Probably.
> 
> I expect a normal slave-only I2C device will be compatible with any master
> (having or having not this feature) in real life ?
> 

Yeah, it's just that currently in the i2c core we cannot "suspend" the
sending of the ACK.

> It would be great if the compatibility between "a I2C slave requiring the
> slave-mode from the bus" and the bus could be checked during the device
> plug.
> 

Makes sense, I'll see what I can come up with for a v2 :)

Thanks!


signature.asc
Description: PGP signature


[PATCH v2 4/7] util: add qemu-co-timeout

2022-04-01 Thread Vladimir Sementsov-Ogievskiy
Add new API, to make a time limited call of the coroutine.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 include/qemu/coroutine.h | 13 ++
 util/meson.build |  1 +
 util/qemu-co-timeout.c   | 89 
 3 files changed, 103 insertions(+)
 create mode 100644 util/qemu-co-timeout.c

diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
index c828a95ee0..8704b05da8 100644
--- a/include/qemu/coroutine.h
+++ b/include/qemu/coroutine.h
@@ -316,6 +316,19 @@ static inline void coroutine_fn 
qemu_co_sleep_ns(QEMUClockType type, int64_t ns)
 qemu_co_sleep_ns_wakeable(&w, type, ns);
 }
 
+typedef void CleanupFunc(void *opaque);
+/**
+ * Run entry in a coroutine and start timer. Wait for entry to finish or for
+ * timer to elapse, what happen first. If entry finished, return 0, if timer
+ * elapsed earlier, return -ETIMEDOUT.
+ *
+ * Be careful, entry execution is not canceled, user should handle it somehow.
+ * If @clean is provided, it's called after coroutine finish if timeout
+ * happened.
+ */
+int coroutine_fn qemu_co_timeout(CoroutineEntry *entry, void *opaque,
+ uint64_t timeout_ns, CleanupFunc clean);
+
 /**
  * Wake a coroutine if it is sleeping in qemu_co_sleep_ns. The timer will be
  * deleted. @sleep_state must be the variable whose address was given to
diff --git a/util/meson.build b/util/meson.build
index f6ee74ad0c..249891db72 100644
--- a/util/meson.build
+++ b/util/meson.build
@@ -83,6 +83,7 @@ if have_block
   util_ss.add(files('block-helpers.c'))
   util_ss.add(files('qemu-coroutine-sleep.c'))
   util_ss.add(files('qemu-co-shared-resource.c'))
+  util_ss.add(files('qemu-co-timeout.c'))
   util_ss.add(files('thread-pool.c', 'qemu-timer.c'))
   util_ss.add(files('readline.c'))
   util_ss.add(files('throttle.c'))
diff --git a/util/qemu-co-timeout.c b/util/qemu-co-timeout.c
new file mode 100644
index 00..00cd335649
--- /dev/null
+++ b/util/qemu-co-timeout.c
@@ -0,0 +1,89 @@
+/*
+ * Helper functionality for distributing a fixed total amount of
+ * an abstract resource among multiple coroutines.
+ *
+ * Copyright (c) 2022 Virtuozzo International GmbH
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/coroutine.h"
+#include "block/aio.h"
+
+typedef struct QemuCoTimeoutState {
+CoroutineEntry *entry;
+void *opaque;
+QemuCoSleep sleep_state;
+bool marker;
+CleanupFunc *clean;
+} QemuCoTimeoutState;
+
+static void coroutine_fn qemu_co_timeout_entry(void *opaque)
+{
+QemuCoTimeoutState *s = opaque;
+
+s->entry(s->opaque);
+
+if (s->marker) {
+assert(!s->sleep_state.to_wake);
+/* .marker set by qemu_co_timeout, it have been failed */
+if (s->clean) {
+s->clean(s->opaque);
+}
+g_free(s);
+} else {
+s->marker = true;
+qemu_co_sleep_wake(&s->sleep_state);
+}
+}
+
+int coroutine_fn qemu_co_timeout(CoroutineEntry *entry, void *opaque,
+ uint64_t timeout_ns, CleanupFunc clean)
+{
+QemuCoTimeoutState *s;
+Coroutine *co;
+
+if (timeout_ns == 0) {
+entry(opaque);
+return 0;
+}
+
+s = g_new(QemuCoTimeoutState, 1);
+*s = (QemuCoTimeoutState) {
+.entry = entry,
+.opaque = opaque,
+.clean = clean
+};
+
+co = qemu_coroutine_create(qemu_co_timeout_entry, s);
+
+aio_co_enter(qemu_get_current_aio_context(), co);
+qemu_co_sleep_ns_wakeable(&s->sleep_state, QEMU_CLOCK_REALTIME, 
timeout_ns);
+
+if (s->marker) {
+/* .marker set by qemu_co_timeout_entry, success */
+g_free(s);
+return 0;
+}
+
+/* Don't free s, as we can't cancel qemu_co_timeout_entry execution */
+s->marker = true;
+return -ETIMEDOUT;
+}
-- 
2.35.1




[PATCH v2 5/7] block/block-copy: block_copy(): add timeout_ns parameter

2022-04-01 Thread Vladimir Sementsov-Ogievskiy
Add possibility to limit block_copy() call in time. To be used in the
next commit.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 block/block-copy.c | 26 +++---
 block/copy-before-write.c  |  2 +-
 include/block/block-copy.h |  2 +-
 3 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/block/block-copy.c b/block/block-copy.c
index ec46775ea5..b47cb188dd 100644
--- a/block/block-copy.c
+++ b/block/block-copy.c
@@ -883,10 +883,18 @@ static int coroutine_fn 
block_copy_common(BlockCopyCallState *call_state)
 return ret;
 }
 
+static void coroutine_fn block_copy_async_co_entry(void *opaque)
+{
+block_copy_common(opaque);
+}
+
 int coroutine_fn block_copy(BlockCopyState *s, int64_t start, int64_t bytes,
-bool ignore_ratelimit)
+bool ignore_ratelimit, uint64_t timeout_ns)
 {
-BlockCopyCallState call_state = {
+int ret;
+BlockCopyCallState *call_state = g_new(BlockCopyCallState, 1);
+
+*call_state = (BlockCopyCallState) {
 .s = s,
 .offset = start,
 .bytes = bytes,
@@ -894,12 +902,16 @@ int coroutine_fn block_copy(BlockCopyState *s, int64_t 
start, int64_t bytes,
 .max_workers = BLOCK_COPY_MAX_WORKERS,
 };
 
-return block_copy_common(&call_state);
-}
+ret = qemu_co_timeout(block_copy_async_co_entry, call_state, timeout_ns,
+  g_free);
+if (ret < 0) {
+/* Timeout. call_state will be freed by running coroutine. */
+return ret;
+}
 
-static void coroutine_fn block_copy_async_co_entry(void *opaque)
-{
-block_copy_common(opaque);
+ret = call_state->ret;
+
+return ret;
 }
 
 BlockCopyCallState *block_copy_async(BlockCopyState *s,
diff --git a/block/copy-before-write.c b/block/copy-before-write.c
index 0614c3d08b..7ef3f9f4c1 100644
--- a/block/copy-before-write.c
+++ b/block/copy-before-write.c
@@ -107,7 +107,7 @@ static coroutine_fn int 
cbw_do_copy_before_write(BlockDriverState *bs,
 off = QEMU_ALIGN_DOWN(offset, cluster_size);
 end = QEMU_ALIGN_UP(offset + bytes, cluster_size);
 
-ret = block_copy(s->bcs, off, end - off, true);
+ret = block_copy(s->bcs, off, end - off, true, 0);
 if (ret < 0 && s->on_cbw_error == ON_CBW_ERROR_BREAK_GUEST_WRITE) {
 return ret;
 }
diff --git a/include/block/block-copy.h b/include/block/block-copy.h
index 68bbd344b2..1c9616cdee 100644
--- a/include/block/block-copy.h
+++ b/include/block/block-copy.h
@@ -40,7 +40,7 @@ int64_t block_copy_reset_unallocated(BlockCopyState *s,
  int64_t offset, int64_t *count);
 
 int coroutine_fn block_copy(BlockCopyState *s, int64_t offset, int64_t bytes,
-bool ignore_ratelimit);
+bool ignore_ratelimit, uint64_t timeout_ns);
 
 /*
  * Run block-copy in a coroutine, create corresponding BlockCopyCallState
-- 
2.35.1




[PATCH v4 0/4] util/thread-pool: Expose minimun and maximum size

2022-04-01 Thread Nicolas Saenz Julienne
As discussed on the previous RFC[1] the thread-pool's dynamic thread
management doesn't play well with real-time and latency sensitive
systems. This series introduces a set of controls that'll permit
achieving more deterministic behaviours, for example by fixing the
pool's size.

We first introduce a new common interface to event loop configuration by
moving iothread's already available properties into an abstract class
called 'EventLooopBackend' and have both 'IOThread' and the newly
created 'MainLoop' inherit the properties from that class.

With this new configuration interface in place it's relatively simple to
introduce new options to fix the even loop's thread pool sizes. The
resulting QAPI looks like this:

-object main-loop,id=main-loop,thread-pool-min=1,thread-pool-max=1

Note that all patches are bisect friendly and pass all the tests.

[1] 
https://patchwork.ozlabs.org/project/qemu-devel/patch/20220202175234.656711-1-nsaen...@redhat.com/

@Stefan I kept your Signed-off-by, since the changes trivial/not
thread-pool related

---
Changes since v3:
 - Avoid duplication in qom.json by creating EventLoopBaseProperties.
 - Fix failures on first compilation due to race between
   event-loop-base.o and qapi header generation.

Changes since v2:
 - Get rid of wrong locking/waiting
 - Fix qapi versioning
 - Better commit messages

Changes since v1:
 - Address all Stefan's comments
 - Introduce new fix

Nicolas Saenz Julienne (3):
  Introduce event-loop-base abstract class
  util/main-loop: Introduce the main loop into QOM
  util/event-loop-base: Introduce options to set the thread pool size

 event-loop-base.c| 140 +++
 include/block/aio.h  |  10 +++
 include/block/thread-pool.h  |   3 +
 include/qemu/main-loop.h |  10 +++
 include/sysemu/event-loop-base.h |  41 +
 include/sysemu/iothread.h|   6 +-
 iothread.c   |  68 +--
 meson.build  |  26 +++---
 qapi/qom.json|  40 +++--
 util/aio-posix.c |   1 +
 util/async.c |  20 +
 util/main-loop.c |  65 ++
 util/thread-pool.c   |  55 +++-
 13 files changed, 416 insertions(+), 69 deletions(-)
 create mode 100644 event-loop-base.c
 create mode 100644 include/sysemu/event-loop-base.h

-- 
2.35.1




[PATCH v4 2/3] util/main-loop: Introduce the main loop into QOM

2022-04-01 Thread Nicolas Saenz Julienne
'event-loop-base' provides basic property handling for all 'AioContext'
based event loops. So let's define a new 'MainLoopClass' that inherits
from it. This will permit tweaking the main loop's properties through
qapi as well as through the command line using the '-object' keyword[1].
Only one instance of 'MainLoopClass' might be created at any time.

'EventLoopBaseClass' learns a new callback, 'can_be_deleted()' so as to
mark 'MainLoop' as non-deletable.

[1] For example:
  -object main-loop,id=main-loop,aio-max-batch=

Signed-off-by: Nicolas Saenz Julienne 
Reviewed-by: Stefan Hajnoczi 
---
Changes since v3:
 - Rework qom.json

Changes since v2:
 - Fix mainloop's qapi versioning

Changes since v1:
 - Fix json files to differentiate between iothread and main-loop
 - Use OBJECT_DECLARE_TYPE()
 - Fix build dependencies

 event-loop-base.c| 13 
 include/qemu/main-loop.h | 10 ++
 include/sysemu/event-loop-base.h |  1 +
 meson.build  |  3 +-
 qapi/qom.json| 32 +++---
 util/main-loop.c | 56 
 6 files changed, 109 insertions(+), 6 deletions(-)

diff --git a/event-loop-base.c b/event-loop-base.c
index a924c73a7c..e7f99a6ec8 100644
--- a/event-loop-base.c
+++ b/event-loop-base.c
@@ -73,10 +73,23 @@ static void event_loop_base_complete(UserCreatable *uc, 
Error **errp)
 }
 }
 
+static bool event_loop_base_can_be_deleted(UserCreatable *uc)
+{
+EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc);
+EventLoopBase *backend = EVENT_LOOP_BASE(uc);
+
+if (bc->can_be_deleted) {
+return bc->can_be_deleted(backend);
+}
+
+return true;
+}
+
 static void event_loop_base_class_init(ObjectClass *klass, void *class_data)
 {
 UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass);
 ucc->complete = event_loop_base_complete;
+ucc->can_be_deleted = event_loop_base_can_be_deleted;
 
 object_class_property_add(klass, "aio-max-batch", "int",
   event_loop_base_get_param,
diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
index d3750c8e76..20c9387654 100644
--- a/include/qemu/main-loop.h
+++ b/include/qemu/main-loop.h
@@ -26,9 +26,19 @@
 #define QEMU_MAIN_LOOP_H
 
 #include "block/aio.h"
+#include "qom/object.h"
+#include "sysemu/event-loop-base.h"
 
 #define SIG_IPI SIGUSR1
 
+#define TYPE_MAIN_LOOP  "main-loop"
+OBJECT_DECLARE_TYPE(MainLoop, MainLoopClass, MAIN_LOOP)
+
+struct MainLoop {
+EventLoopBase parent_obj;
+};
+typedef struct MainLoop MainLoop;
+
 /**
  * qemu_init_main_loop: Set up the process so that it can run the main loop.
  *
diff --git a/include/sysemu/event-loop-base.h b/include/sysemu/event-loop-base.h
index 8e77d8b69f..fced4c9fea 100644
--- a/include/sysemu/event-loop-base.h
+++ b/include/sysemu/event-loop-base.h
@@ -25,6 +25,7 @@ struct EventLoopBaseClass {
 
 void (*init)(EventLoopBase *base, Error **errp);
 void (*update_params)(EventLoopBase *base, Error **errp);
+bool (*can_be_deleted)(EventLoopBase *base);
 };
 
 struct EventLoopBase {
diff --git a/meson.build b/meson.build
index 89aa3a2518..b8046b5b35 100644
--- a/meson.build
+++ b/meson.build
@@ -2830,7 +2830,8 @@ libqemuutil = static_library('qemuutil',
  sources: util_ss.sources() + stub_ss.sources() + 
genh,
  dependencies: [util_ss.dependencies(), libm, 
threads, glib, socket, malloc, pixman])
 qemuutil = declare_dependency(link_with: libqemuutil,
-  sources: genh + version_res)
+  sources: genh + version_res,
+  dependencies: [event_loop_base])
 
 if have_system or have_user
   decodetree = generator(find_program('scripts/decodetree.py'),
diff --git a/qapi/qom.json b/qapi/qom.json
index eeb5395ff3..e5f31c4469 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -499,6 +499,17 @@
 '*repeat': 'bool',
 '*grab-toggle': 'GrabToggleKeys' } }
 
+##
+# @EventLoopBaseProperties:
+#
+# Common properties for objects derived from EventLoopBase
+#
+# @aio-max-batch: maximum number of requests in a batch for the AIO engine,
+# 0 means that the engine will use its default.
+##
+{ 'struct': 'EventLoopBaseProperties',
+  'data': { '*aio-max-batch': 'int' } }
+
 ##
 # @IothreadProperties:
 #
@@ -516,17 +527,26 @@
 #   algorithm detects it is spending too long polling without
 #   encountering events. 0 selects a default behaviour (default: 0)
 #
-# @aio-max-batch: maximum number of requests in a batch for the AIO engine,
-# 0 means that the engine will use its default
-# (default:0, since 6.1)
+# The @aio-max-batch option is available since 6.1.
 #
 # Since: 2.0
 ##
 { 'struct': 'IothreadProperties',
+  'base': 'EventLoopBaseProperties',
   'data': { '*poll-max-ns': 'int',
 '*poll-grow': 'i

Re: [PATCH] build-sys: drop ntddscsi.h check

2022-04-01 Thread Konstantin Kostiuk
Reviewed-by: Konstantin Kostiuk 

On Fri, Apr 1, 2022 at 11:51 AM  wrote:

> From: Marc-André Lureau 
>
> The header has been part of MinGW-w64 since the introduction of the
> project (2007). While on MinGW(32), the legacy project, it was imported
> in 2014 from w32api-3.17 (commit e4803e0da2).
>
> According to build-platform.rst and our CI coverage, we only support
> building with MinGW-w64 (from Debian/Fedora).
>
> Signed-off-by: Marc-André Lureau 
> ---
>  meson.build  | 17 -
>  qga/commands-win32.c | 19 ---
>  qga/meson.build  |  6 ++
>  3 files changed, 2 insertions(+), 40 deletions(-)
>
> diff --git a/meson.build b/meson.build
> index c06fe5e02737..46b5e938b196 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -2019,22 +2019,6 @@ if targetos == 'windows' and link_language == 'cpp'
>  endif
>  config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
>
> -have_ntddscsi = false
> -if targetos == 'windows'
> -  have_ntddscsi = cc.compiles('''
> -#include 
> -#include 
> -int main(void) {
> -#if !defined(IOCTL_SCSI_GET_ADDRESS)
> -#error Missing required ioctl definitions
> -#endif
> -  SCSI_ADDRESS addr = { .Lun = 0, .TargetId = 0, .PathId = 0 };
> -  return addr.Lun;
> -}
> -''')
> -endif
> -config_host_data.set('HAVE_NTDDSCSI', have_ntddscsi)
> -
>  ignored = ['CONFIG_QEMU_INTERP_PREFIX', # actually per-target
>  'HAVE_GDB_BIN']
>  arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
> @@ -3722,7 +3706,6 @@ summary_info += {'libnfs support':libnfs}
>  if targetos == 'windows'
>if have_ga
>  summary_info += {'QGA VSS support':   have_qga_vss}
> -summary_info += {'QGA w32 disk info': have_ntddscsi}
>endif
>  endif
>  summary_info += {'seccomp support':   seccomp}
> diff --git a/qga/commands-win32.c b/qga/commands-win32.c
> index 3c428213db0a..ebec5536340a 100644
> --- a/qga/commands-win32.c
> +++ b/qga/commands-win32.c
> @@ -18,10 +18,8 @@
>  #include 
>  #include 
>  #include 
> -#ifdef HAVE_NTDDSCSI
>  #include 
>  #include 
> -#endif
>  #include 
>  #include 
>  #include 
> @@ -474,8 +472,6 @@ void qmp_guest_file_flush(int64_t handle, Error **errp)
>  }
>  }
>
> -#ifdef HAVE_NTDDSCSI
> -
>  static GuestDiskBusType win2qemu[] = {
>  [BusTypeUnknown] = GUEST_DISK_BUS_TYPE_UNKNOWN,
>  [BusTypeScsi] = GUEST_DISK_BUS_TYPE_SCSI,
> @@ -1098,21 +1094,6 @@ GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
>  return ret;
>  }
>
> -#else
> -
> -static GuestDiskAddressList *build_guest_disk_info(char *guid, Error
> **errp)
> -{
> -return NULL;
> -}
> -
> -GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
> -{
> -error_setg(errp, QERR_UNSUPPORTED);
> -return NULL;
> -}
> -
> -#endif /* HAVE_NTDDSCSI */
> -
>  static GuestFilesystemInfo *build_guest_fsinfo(char *guid, Error **errp)
>  {
>  DWORD info_size;
> diff --git a/qga/meson.build b/qga/meson.build
> index 4d5de843abf6..40a7baabfde3 100644
> --- a/qga/meson.build
> +++ b/qga/meson.build
> @@ -83,14 +83,12 @@ qga_ss = qga_ss.apply(config_host, strict: false)
>  gen_tlb = []
>  qga_libs = []
>  if targetos == 'windows'
> -  qga_libs += ['-lws2_32', '-lwinmm', '-lpowrprof', '-lwtsapi32',
> '-lwininet', '-liphlpapi', '-lnetapi32']
> +  qga_libs += ['-lws2_32', '-lwinmm', '-lpowrprof', '-lwtsapi32',
> '-lwininet', '-liphlpapi', '-lnetapi32',
> +   '-lsetupapi', '-lcfgmgr32']
>if have_qga_vss
>  qga_libs += ['-lole32', '-loleaut32', '-lshlwapi', '-lstdc++',
> '-Wl,--enable-stdcall-fixup']
>  subdir('vss-win32')
>endif
> -  if have_ntddscsi
> -qga_libs += ['-lsetupapi', '-lcfgmgr32']
> -  endif
>  endif
>
>  qga = executable('qemu-ga', qga_ss.sources(),
> --
> 2.35.1.693.g805e0a68082a
>
>


[PATCH v4 1/3] Introduce event-loop-base abstract class

2022-04-01 Thread Nicolas Saenz Julienne
Introduce the 'event-loop-base' abstract class, it'll hold the
properties common to all event loops and provide the necessary hooks for
their creation and maintenance. Then have iothread inherit from it.

EventLoopBaseClass is defined as user creatable and provides a hook for
its children to attach themselves to the user creatable class 'complete'
function. It also provides an update_params() callback to propagate
property changes onto its children.

The new 'event-loop-base' class will live in the root directory. It is
built on its own using the 'link_whole' option (there are no direct
function dependencies between the class and its children, it all happens
trough 'constructor' magic). And also imposes new compilation
dependencies:

qom <- event-loop-base <- blockdev (iothread.c)

And in subsequent patches:

qom <- event-loop-base <- qemuutil (util/main-loop.c)

All this forced some amount of reordering in meson.build:

 - Moved qom build definition before qemuutil. Doing it the other way
   around (i.e. moving qemuutil after qom) isn't possible as a lot of
   core libraries that live in between the two depend on it.

 - Process the 'hw' subdir earlier, as it introduces files into the
   'qom' source set.

No functional changes intended.

Signed-off-by: Nicolas Saenz Julienne 
Reviewed-by: Stefan Hajnoczi 

---
Changes since v3:
 - Fix event-loop-base compilation so it depends on qapi header
   generation (note the '+ genh' in event_loop_base).

Changes since v2:
 - reword commit message to better explain compilation dependencies.

Changes since v1:
 - Rename to event-loop-base
 - Move event-loop-base into root directory
 - Build event-loop-base on its own, use link_whole to avoid the problem
   of the object file not being linked due to lacking direct calls from
   dependencies.
 - Move poll parameters into iothread, as main loop can't poll
 - Update Authorship (I took what iothread.c had and added myself, I
   hope that's fine)
 - Introduce update_params() callback

 event-loop-base.c| 104 +++
 include/sysemu/event-loop-base.h |  36 +++
 include/sysemu/iothread.h|   6 +-
 iothread.c   |  65 ++-
 meson.build  |  23 ---
 5 files changed, 175 insertions(+), 59 deletions(-)
 create mode 100644 event-loop-base.c
 create mode 100644 include/sysemu/event-loop-base.h

diff --git a/event-loop-base.c b/event-loop-base.c
new file mode 100644
index 00..a924c73a7c
--- /dev/null
+++ b/event-loop-base.c
@@ -0,0 +1,104 @@
+/*
+ * QEMU event-loop base
+ *
+ * Copyright (C) 2022 Red Hat Inc
+ *
+ * Authors:
+ *  Stefan Hajnoczi 
+ *  Nicolas Saenz Julienne 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qom/object_interfaces.h"
+#include "qapi/error.h"
+#include "sysemu/event-loop-base.h"
+
+typedef struct {
+const char *name;
+ptrdiff_t offset; /* field's byte offset in EventLoopBase struct */
+} EventLoopBaseParamInfo;
+
+static EventLoopBaseParamInfo aio_max_batch_info = {
+"aio-max-batch", offsetof(EventLoopBase, aio_max_batch),
+};
+
+static void event_loop_base_get_param(Object *obj, Visitor *v,
+const char *name, void *opaque, Error **errp)
+{
+EventLoopBase *event_loop_base = EVENT_LOOP_BASE(obj);
+EventLoopBaseParamInfo *info = opaque;
+int64_t *field = (void *)event_loop_base + info->offset;
+
+visit_type_int64(v, name, field, errp);
+}
+
+static void event_loop_base_set_param(Object *obj, Visitor *v,
+const char *name, void *opaque, Error **errp)
+{
+EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(obj);
+EventLoopBase *base = EVENT_LOOP_BASE(obj);
+EventLoopBaseParamInfo *info = opaque;
+int64_t *field = (void *)base + info->offset;
+int64_t value;
+
+if (!visit_type_int64(v, name, &value, errp)) {
+return;
+}
+
+if (value < 0) {
+error_setg(errp, "%s value must be in range [0, %" PRId64 "]",
+   info->name, INT64_MAX);
+return;
+}
+
+*field = value;
+
+if (bc->update_params) {
+bc->update_params(base, errp);
+}
+
+return;
+}
+
+static void event_loop_base_complete(UserCreatable *uc, Error **errp)
+{
+EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc);
+EventLoopBase *base = EVENT_LOOP_BASE(uc);
+
+if (bc->init) {
+bc->init(base, errp);
+}
+}
+
+static void event_loop_base_class_init(ObjectClass *klass, void *class_data)
+{
+UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass);
+ucc->complete = event_loop_base_complete;
+
+object_class_property_add(klass, "aio-max-batch", "int",
+  event_loop_base_get_param,
+  event_loop_base_set_param,
+  NULL, &aio_max_batch_info);
+}
+
+static 

Re: [PATCH v5 1/4] hw/arm/realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'

2022-04-01 Thread Peter Maydell
On Thu, 24 Mar 2022 at 18:16, Zongyuan Li  wrote:
>
> Signed-off-by: Zongyuan Li 
> ---
>  hw/arm/realview.c | 33 -
>  1 file changed, 24 insertions(+), 9 deletions(-)
>

Reviewed-by: Peter Maydell 

thanks
-- PMM



Re: [PATCH] intel-iommu: correct the value used for error_setg_errno()

2022-04-01 Thread Peter Maydell
On Fri, 1 Apr 2022 at 03:29, Jason Wang  wrote:
>
> error_setg_errno() expects a normal errno value, not a negated
> one, so we should use ENOTSUP instead of -ENOSUP.
>
> Fixes: Coverity CID 1487174
> Fixes: ("intel_iommu: support snoop control")
> Signed-off-by: Jason Wang 
> ---
>  hw/i386/intel_iommu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> index c64aa81a83..e05d69a2c0 100644
> --- a/hw/i386/intel_iommu.c
> +++ b/hw/i386/intel_iommu.c
> @@ -3032,7 +3032,7 @@ static int 
> vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
>
>  /* TODO: add support for VFIO and vhost users */
>  if (s->snoop_control) {
> -error_setg_errno(errp, -ENOTSUP,
> +error_setg_errno(errp, ENOTSUP,
>   "Snoop Control with vhost or VFIO is not 
> supported");
>  return -ENOTSUP;
>  }
> --
> 2.25.1

Reviewed-by: Peter Maydell 

thanks
-- PMM



Re: [PATCH v5 2/4] hw/arm/stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'

2022-04-01 Thread Peter Maydell
On Thu, 24 Mar 2022 at 18:16, Zongyuan Li  wrote:
>
> Signed-off-by: Zongyuan Li 
> ---
>  hw/arm/stellaris.c | 15 +--
>  1 file changed, 13 insertions(+), 2 deletions(-)

Reviewed-by: Peter Maydell 

thanks
-- PMM



[PATCH v2 1/7] block/copy-before-write: refactor option parsing

2022-04-01 Thread Vladimir Sementsov-Ogievskiy
We are going to add one more option of enum type. Let's refactor option
parsing so that we can simply work with BlockdevOptionsCbw object.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 block/copy-before-write.c | 68 +++
 1 file changed, 41 insertions(+), 27 deletions(-)

diff --git a/block/copy-before-write.c b/block/copy-before-write.c
index a8a06fdc09..394e73b094 100644
--- a/block/copy-before-write.c
+++ b/block/copy-before-write.c
@@ -24,6 +24,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qapi/qmp/qjson.h"
 
 #include "sysemu/block-backend.h"
 #include "qemu/cutils.h"
@@ -328,46 +329,49 @@ static void cbw_child_perm(BlockDriverState *bs, 
BdrvChild *c,
 }
 }
 
-static bool cbw_parse_bitmap_option(QDict *options, BdrvDirtyBitmap **bitmap,
-Error **errp)
+static BlockdevOptionsCbw *cbw_parse_options(QDict *options, Error **errp)
 {
-QDict *bitmap_qdict = NULL;
-BlockDirtyBitmap *bmp_param = NULL;
+QDict *cbw_qdict = NULL;
+BlockdevOptionsCbw *opts = NULL;
 Visitor *v = NULL;
-bool ret = false;
 
-*bitmap = NULL;
+cbw_qdict = qdict_clone_shallow(options);
 
-qdict_extract_subqdict(options, &bitmap_qdict, "bitmap.");
-if (!qdict_size(bitmap_qdict)) {
-ret = true;
-goto out;
-}
-
-v = qobject_input_visitor_new_flat_confused(bitmap_qdict, errp);
+/*
+ * Delete BlockdevOptions base fields, that are not part of
+ * BlockdevOptionsCbw.
+ */
+qdict_del(cbw_qdict, "driver");
+qdict_del(cbw_qdict, "node-name");
+qdict_del(cbw_qdict, "discard");
+qdict_del(cbw_qdict, "cache");
+qdict_extract_subqdict(cbw_qdict, NULL, "cache.");
+qdict_del(cbw_qdict, "read-only");
+qdict_del(cbw_qdict, "auto-read-only");
+qdict_del(cbw_qdict, "force-share");
+qdict_del(cbw_qdict, "detect-zeroes");
+
+v = qobject_input_visitor_new_flat_confused(cbw_qdict, errp);
 if (!v) {
 goto out;
 }
 
-visit_type_BlockDirtyBitmap(v, NULL, &bmp_param, errp);
-if (!bmp_param) {
-goto out;
-}
-
-*bitmap = block_dirty_bitmap_lookup(bmp_param->node, bmp_param->name, NULL,
-errp);
-if (!*bitmap) {
+visit_type_BlockdevOptionsCbw(v, NULL, &opts, errp);
+if (!opts) {
 goto out;
 }
 
-ret = true;
+/*
+ * Delete options which we are going to parse through BlockdevOptionsCbw
+ * object for original options.
+ */
+qdict_extract_subqdict(options, NULL, "bitmap");
 
 out:
-qapi_free_BlockDirtyBitmap(bmp_param);
 visit_free(v);
-qobject_unref(bitmap_qdict);
+qobject_unref(cbw_qdict);
 
-return ret;
+return opts;
 }
 
 static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
@@ -376,6 +380,12 @@ static int cbw_open(BlockDriverState *bs, QDict *options, 
int flags,
 BDRVCopyBeforeWriteState *s = bs->opaque;
 BdrvDirtyBitmap *bitmap = NULL;
 int64_t cluster_size;
+g_autoptr(BlockdevOptionsCbw) opts = NULL;
+
+opts = cbw_parse_options(options, errp);
+if (!opts) {
+return -EINVAL;
+}
 
 bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
@@ -390,8 +400,12 @@ static int cbw_open(BlockDriverState *bs, QDict *options, 
int flags,
 return -EINVAL;
 }
 
-if (!cbw_parse_bitmap_option(options, &bitmap, errp)) {
-return -EINVAL;
+if (opts->has_bitmap) {
+bitmap = block_dirty_bitmap_lookup(opts->bitmap->node,
+   opts->bitmap->name, NULL, errp);
+if (!bitmap) {
+return -EINVAL;
+}
 }
 
 bs->total_sectors = bs->file->bs->total_sectors;
-- 
2.35.1




[PATCH v4 3/3] util/event-loop-base: Introduce options to set the thread pool size

2022-04-01 Thread Nicolas Saenz Julienne
The thread pool regulates itself: when idle, it kills threads until
empty, when in demand, it creates new threads until full. This behaviour
doesn't play well with latency sensitive workloads where the price of
creating a new thread is too high. For example, when paired with qemu's
'-mlock', or using safety features like SafeStack, creating a new thread
has been measured take multiple milliseconds.

In order to mitigate this let's introduce a new 'EventLoopBase'
property to set the thread pool size. The threads will be created during
the pool's initialization or upon updating the property's value, remain
available during its lifetime regardless of demand, and destroyed upon
freeing it. A properly characterized workload will then be able to
configure the pool to avoid any latency spikes.

Signed-off-by: Nicolas Saenz Julienne 
Reviewed-by: Stefan Hajnoczi 
---

Changes since v3:
 - Rework qom.json to avoid duplication

Changes since v2:
 - Don't wait when decreasing pool size
 - Fix qapi versioning

Changes since v1:
 - Add INT_MAX check
 - Have copy of thread pool sizes in AioContext to properly decouple
   both instances
 - More coherent variable naming
 - Handle case where max_threads decreases
 - Code comments

 event-loop-base.c| 23 +
 include/block/aio.h  | 10 ++
 include/block/thread-pool.h  |  3 ++
 include/sysemu/event-loop-base.h |  4 +++
 iothread.c   |  3 ++
 qapi/qom.json| 10 +-
 util/aio-posix.c |  1 +
 util/async.c | 20 
 util/main-loop.c |  9 ++
 util/thread-pool.c   | 55 +---
 10 files changed, 133 insertions(+), 5 deletions(-)

diff --git a/event-loop-base.c b/event-loop-base.c
index e7f99a6ec8..d5be4dc6fc 100644
--- a/event-loop-base.c
+++ b/event-loop-base.c
@@ -14,6 +14,7 @@
 #include "qemu/osdep.h"
 #include "qom/object_interfaces.h"
 #include "qapi/error.h"
+#include "block/thread-pool.h"
 #include "sysemu/event-loop-base.h"
 
 typedef struct {
@@ -21,9 +22,22 @@ typedef struct {
 ptrdiff_t offset; /* field's byte offset in EventLoopBase struct */
 } EventLoopBaseParamInfo;
 
+static void event_loop_base_instance_init(Object *obj)
+{
+EventLoopBase *base = EVENT_LOOP_BASE(obj);
+
+base->thread_pool_max = THREAD_POOL_MAX_THREADS_DEFAULT;
+}
+
 static EventLoopBaseParamInfo aio_max_batch_info = {
 "aio-max-batch", offsetof(EventLoopBase, aio_max_batch),
 };
+static EventLoopBaseParamInfo thread_pool_min_info = {
+"thread-pool-min", offsetof(EventLoopBase, thread_pool_min),
+};
+static EventLoopBaseParamInfo thread_pool_max_info = {
+"thread-pool-max", offsetof(EventLoopBase, thread_pool_max),
+};
 
 static void event_loop_base_get_param(Object *obj, Visitor *v,
 const char *name, void *opaque, Error **errp)
@@ -95,12 +109,21 @@ static void event_loop_base_class_init(ObjectClass *klass, 
void *class_data)
   event_loop_base_get_param,
   event_loop_base_set_param,
   NULL, &aio_max_batch_info);
+object_class_property_add(klass, "thread-pool-min", "int",
+  event_loop_base_get_param,
+  event_loop_base_set_param,
+  NULL, &thread_pool_min_info);
+object_class_property_add(klass, "thread-pool-max", "int",
+  event_loop_base_get_param,
+  event_loop_base_set_param,
+  NULL, &thread_pool_max_info);
 }
 
 static const TypeInfo event_loop_base_info = {
 .name = TYPE_EVENT_LOOP_BASE,
 .parent = TYPE_OBJECT,
 .instance_size = sizeof(EventLoopBase),
+.instance_init = event_loop_base_instance_init,
 .class_size = sizeof(EventLoopBaseClass),
 .class_init = event_loop_base_class_init,
 .abstract = true,
diff --git a/include/block/aio.h b/include/block/aio.h
index 5634173b12..d128558f1d 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -192,6 +192,8 @@ struct AioContext {
 QSLIST_HEAD(, Coroutine) scheduled_coroutines;
 QEMUBH *co_schedule_bh;
 
+int thread_pool_min;
+int thread_pool_max;
 /* Thread pool for performing work and receiving completion callbacks.
  * Has its own locking.
  */
@@ -769,4 +771,12 @@ void aio_context_set_poll_params(AioContext *ctx, int64_t 
max_ns,
 void aio_context_set_aio_params(AioContext *ctx, int64_t max_batch,
 Error **errp);
 
+/**
+ * aio_context_set_thread_pool_params:
+ * @ctx: the aio context
+ * @min: min number of threads to have readily available in the thread pool
+ * @min: max number of threads the thread pool can contain
+ */
+void aio_context_set_thread_pool_params(AioContext *ctx, int64_t min,
+int64_t max, Error **errp);
 #endif
diff 

[PATCH v2 7/7] iotests: copy-before-write: add cases for cbw-timeout option

2022-04-01 Thread Vladimir Sementsov-Ogievskiy
Add two simple test-cases: timeout failure with
break-snapshot-on-cbw-error behavior and similar with
break-guest-write-on-cbw-error behavior.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 tests/qemu-iotests/tests/copy-before-write| 78 +++
 .../qemu-iotests/tests/copy-before-write.out  |  4 +-
 2 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/tests/qemu-iotests/tests/copy-before-write 
b/tests/qemu-iotests/tests/copy-before-write
index a32608f597..265299957c 100755
--- a/tests/qemu-iotests/tests/copy-before-write
+++ b/tests/qemu-iotests/tests/copy-before-write
@@ -122,6 +122,84 @@ read 1048576/1048576 bytes at offset 0
 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 """)
 
+def do_cbw_timeout(self, on_cbw_error):
+result = self.vm.qmp('object-add', {
+'qom-type': 'throttle-group',
+'id': 'group0',
+'limits': {'bps-write': 1}
+})
+self.assert_qmp(result, 'return', {})
+
+result = self.vm.qmp('blockdev-add', {
+'node-name': 'cbw',
+'driver': 'copy-before-write',
+'on-cbw-error': on_cbw_error,
+'cbw-timeout': 1,
+'file': {
+'driver': iotests.imgfmt,
+'file': {
+'driver': 'file',
+'filename': source_img,
+}
+},
+'target': {
+'driver': 'throttle',
+'throttle-group': 'group0',
+'file': {
+'driver': 'qcow2',
+'file': {
+'driver': 'file',
+'filename': temp_img
+}
+}
+}
+})
+self.assert_qmp(result, 'return', {})
+
+result = self.vm.qmp('blockdev-add', {
+'node-name': 'access',
+'driver': 'snapshot-access',
+'file': 'cbw'
+})
+self.assert_qmp(result, 'return', {})
+
+result = self.vm.hmp_qemu_io('cbw', 'write 0 512K')
+self.assert_qmp(result, 'return', '')
+
+# We need second write to trigger throttling
+result = self.vm.hmp_qemu_io('cbw', 'write 512K 512K')
+self.assert_qmp(result, 'return', '')
+
+result = self.vm.hmp_qemu_io('access', 'read 0 1M')
+self.assert_qmp(result, 'return', '')
+
+self.vm.shutdown()
+log = self.vm.get_log()
+log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log)
+log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log)
+log = iotests.filter_qemu_io(log)
+return log
+
+def test_timeout_break_guest(self):
+log = self.do_cbw_timeout('break-guest-write')
+self.assertEqual(log, """\
+wrote 524288/524288 bytes at offset 0
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+write failed: Connection timed out
+read 1048576/1048576 bytes at offset 0
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+""")
+
+def test_timeout_break_snapshot(self):
+log = self.do_cbw_timeout('break-snapshot')
+self.assertEqual(log, """\
+wrote 524288/524288 bytes at offset 0
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 524288/524288 bytes at offset 524288
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read failed: Permission denied
+""")
+
 
 if __name__ == '__main__':
 iotests.main(supported_fmts=['qcow2'],
diff --git a/tests/qemu-iotests/tests/copy-before-write.out 
b/tests/qemu-iotests/tests/copy-before-write.out
index fbc63e62f8..89968f35d7 100644
--- a/tests/qemu-iotests/tests/copy-before-write.out
+++ b/tests/qemu-iotests/tests/copy-before-write.out
@@ -1,5 +1,5 @@
-..
+
 --
-Ran 2 tests
+Ran 4 tests
 
 OK
-- 
2.35.1




RE: [PATCH v5 0/9] Add support for AST1030 SoC

2022-04-01 Thread Jamin Lin
Hi Cedric,
One more question, what is the progress about SFDP patch, 
https://patchwork.kernel.org/project/qemu-devel/list/?series=342081&archive=both
 
We need these patches for future SPI support.
Thanks-Jamin

* Email Confidentiality Notice 
DISCLAIMER:
This message (and any attachments) may contain legally privileged and/or other 
confidential information. If you have received it in error, please notify the 
sender by reply e-mail and immediately delete the e-mail and any attachments 
without copying or disclosing the contents. Thank you.

-Original Message-
From: Jamin Lin  
Sent: Friday, April 1, 2022 5:24 PM
To: Cédric Le Goater ; Alistair Francis 
; Peter Maydell ; Andrew 
Jeffery ; Joel Stanley ; Cleber Rosa 
; Philippe Mathieu-Daudé ; Wainer dos Santos 
Moschetta ; Beraldo Leal ; open 
list:STM32F205 ; open list:All patches CC here 
; Jamin Lin 
Cc: Steven Lee ; Troy Lee 
Subject: RE: [PATCH v5 0/9] Add support for AST1030 SoC

Hi Cedric, Joel and Andrew
First all, thanks for all your kindly support and review. We are so glad that 
QEMU v7.1 will support AST1030 model.

1. The ast1030 and ast2600 HACE controller are identical. 
  Steven submitted the patch to support HACE ACC mode. Once his patch accept. 
We will submit patch to support ast1030 model.
2. I submitted the patch to support GOIO index mode because ast1030 driver was 
implement by index mode. I am waiting for review and any suggestion will be 
appreciated.
3. Troy submitted the patch to support I2C new model which included ast1030 
model.
4. As for NIC plan, once AST1030 NIC driver ready, we will upstream, too.
BTW, do you have a plan to upstream it, 
https://github.com/openbmc/qemu/blob/master/hw/misc/aspeed_pwm.c

Thanks again - Jamin

* Email Confidentiality Notice 
DISCLAIMER:
This message (and any attachments) may contain legally privileged and/or other 
confidential information. If you have received it in error, please notify the 
sender by reply e-mail and immediately delete the e-mail and any attachments 
without copying or disclosing the contents. Thank you.

-Original Message-
From: Cédric Le Goater 
Sent: Friday, April 1, 2022 4:55 PM
To: Jamin Lin ; Alistair Francis 
; Peter Maydell ; Andrew 
Jeffery ; Joel Stanley ; Cleber Rosa 
; Philippe Mathieu-Daudé ; Wainer dos Santos 
Moschetta ; Beraldo Leal ; open 
list:STM32F205 ; open list:All patches CC here 

Cc: Steven Lee ; Troy Lee 
Subject: Re: [PATCH v5 0/9] Add support for AST1030 SoC

Hello Jamin,

Thanks for these new models and machine. They are queued for QEMU 7.1.
There are a couple of patchsets adding support for the AST1030 GPIO controller 
and the I2C new mode that would be good extensions but they need review first.

What are the next steps? any plans for network ? The NIC should be a
FTGMAC100 if I am correct.

Thanks,

C.


  On 4/1/22 10:38, Jamin Lin wrote:
> Changes from v5:
> - remove TYPE_ASPEED_MINIBMC_MACHINE and ASPEED_MINIBMC_MACHINE
> - remove ast1030_machine_instance_init function
> 
> Changes from v4:
> - drop the ASPEED_SMC_FEATURE_WDT_CONTROL flag in hw/ssi/aspeed_smc.c
> 
> Changes from v3:
> - remove AspeedMiniBmcMachineState state structure and
>AspeedMiniBmcMachineClass class
> - remove redundant new line in hw/arm/aspeed_ast10xx.c
> - drop the ASPEED_SMC_FEATURE_WDT_CONTROL flag in hw/ssi/aspeed_smc.c
> 
> Changes from v2:
> - replace aspeed_ast1030.c with aspeed_ast10xx.c for minibmc SOCs 
> family support
> - Add "ast1030-evb" machine in aspeed.c and removes aspeed_minibmc.c
> 
> Changes from v1:
> The patch series supports ADC, SCU, SMC, TIMER, and WDT for AST1030 SoC.
> Add avocado test case for "ast1030-evb" machine.
> 
> Test steps:
> 1. Download image from
> 
> https://github.com/AspeedTech-BMC/zephyr/releases/download/v00.01.04/a
> st1030-evb-demo.zip 2. Extract the zip file to obtain zephyr.elf 3. 
> Run ./qemu-system-arm -M ast1030-evb -kernel $PATH/zephyr.elf 
> -nographic 4. Test IO by Zephyr command line, commands are refer to Aspeed 
> Zephyr
> SDK User Guide below
> 
> https://github.com/AspeedTech-BMC/zephyr/releases/download/v00.01.04/Aspeed_Zephy_SDK_User_Guide_v00.01.04.pdf
> - ADC(channel 0):
> uart:~$ adc ADC0 resolution 10
> uart:~$ adc ADC0 calibrate 1
> uart:~$ adc ADC0 read_format 1
> uart:~$ adc ADC0 read 0
> [Result]
> read: 1416mv
> 
> - SCU
> uart:~$ md 7e6e2040
> uart:~$ md 7e6e2080
> uart:~$ md 7e6e20d0
> uart:~$ md 7e6e2200
> uart:~$ md 7e6e2300
> uart:~$ md 7e6e25b0
> [Result]
> The register value should match the value of ast1030_a1_resets
> in aspeed_scu.c
> 
> - Flash(fmc_cs0):
> uart:~$ flash write fmc_cs0 0 0x12345678 0x87654321 0x34127856 
> 0x78563412
> uart:~$ flash read fmc_cs0 0 10
> [Result]
> : 78 56 34 12 21 43 65 87  56 78 12 34 12 

RE: [PATCH v5 0/9] Add support for AST1030 SoC

2022-04-01 Thread Jamin Lin
Hi Cedric, Joel and Andrew
First all, thanks for all your kindly support and review. We are so glad that 
QEMU v7.1 will support AST1030 model.

1. The ast1030 and ast2600 HACE controller are identical. 
  Steven submitted the patch to support HACE ACC mode. Once his patch accept. 
We will submit patch to support ast1030 model.
2. I submitted the patch to support GOIO index mode because ast1030 driver was 
implement by index mode. I am waiting for review and any suggestion will be 
appreciated.
3. Troy submitted the patch to support I2C new model which included ast1030 
model.
4. As for NIC plan, once AST1030 NIC driver ready, we will upstream, too.
BTW, do you have a plan to upstream it, 
https://github.com/openbmc/qemu/blob/master/hw/misc/aspeed_pwm.c

Thanks again - Jamin

* Email Confidentiality Notice 
DISCLAIMER:
This message (and any attachments) may contain legally privileged and/or other 
confidential information. If you have received it in error, please notify the 
sender by reply e-mail and immediately delete the e-mail and any attachments 
without copying or disclosing the contents. Thank you.

-Original Message-
From: Cédric Le Goater  
Sent: Friday, April 1, 2022 4:55 PM
To: Jamin Lin ; Alistair Francis 
; Peter Maydell ; Andrew 
Jeffery ; Joel Stanley ; Cleber Rosa 
; Philippe Mathieu-Daudé ; Wainer dos Santos 
Moschetta ; Beraldo Leal ; open 
list:STM32F205 ; open list:All patches CC here 

Cc: Steven Lee ; Troy Lee 
Subject: Re: [PATCH v5 0/9] Add support for AST1030 SoC

Hello Jamin,

Thanks for these new models and machine. They are queued for QEMU 7.1.
There are a couple of patchsets adding support for the AST1030 GPIO controller 
and the I2C new mode that would be good extensions but they need review first.

What are the next steps? any plans for network ? The NIC should be a
FTGMAC100 if I am correct.

Thanks,

C.


  On 4/1/22 10:38, Jamin Lin wrote:
> Changes from v5:
> - remove TYPE_ASPEED_MINIBMC_MACHINE and ASPEED_MINIBMC_MACHINE
> - remove ast1030_machine_instance_init function
> 
> Changes from v4:
> - drop the ASPEED_SMC_FEATURE_WDT_CONTROL flag in hw/ssi/aspeed_smc.c
> 
> Changes from v3:
> - remove AspeedMiniBmcMachineState state structure and
>AspeedMiniBmcMachineClass class
> - remove redundant new line in hw/arm/aspeed_ast10xx.c
> - drop the ASPEED_SMC_FEATURE_WDT_CONTROL flag in hw/ssi/aspeed_smc.c
> 
> Changes from v2:
> - replace aspeed_ast1030.c with aspeed_ast10xx.c for minibmc SOCs 
> family support
> - Add "ast1030-evb" machine in aspeed.c and removes aspeed_minibmc.c
> 
> Changes from v1:
> The patch series supports ADC, SCU, SMC, TIMER, and WDT for AST1030 SoC.
> Add avocado test case for "ast1030-evb" machine.
> 
> Test steps:
> 1. Download image from
> 
> https://github.com/AspeedTech-BMC/zephyr/releases/download/v00.01.04/a
> st1030-evb-demo.zip 2. Extract the zip file to obtain zephyr.elf 3. 
> Run ./qemu-system-arm -M ast1030-evb -kernel $PATH/zephyr.elf 
> -nographic 4. Test IO by Zephyr command line, commands are refer to Aspeed 
> Zephyr
> SDK User Guide below
> 
> https://github.com/AspeedTech-BMC/zephyr/releases/download/v00.01.04/Aspeed_Zephy_SDK_User_Guide_v00.01.04.pdf
> - ADC(channel 0):
> uart:~$ adc ADC0 resolution 10
> uart:~$ adc ADC0 calibrate 1
> uart:~$ adc ADC0 read_format 1
> uart:~$ adc ADC0 read 0
> [Result]
> read: 1416mv
> 
> - SCU
> uart:~$ md 7e6e2040
> uart:~$ md 7e6e2080
> uart:~$ md 7e6e20d0
> uart:~$ md 7e6e2200
> uart:~$ md 7e6e2300
> uart:~$ md 7e6e25b0
> [Result]
> The register value should match the value of ast1030_a1_resets
> in aspeed_scu.c
> 
> - Flash(fmc_cs0):
> uart:~$ flash write fmc_cs0 0 0x12345678 0x87654321 0x34127856 
> 0x78563412
> uart:~$ flash read fmc_cs0 0 10
> [Result]
> : 78 56 34 12 21 43 65 87  56 78 12 34 12 34 56 78 
> |xV4.!Ce. Vx.4.4Vx|
> 
> uart:~$ flash erase fmc_cs0 0
> uart:~$ flash read fmc_cs0 0 10
> [Result]
> : ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff 
> | |
> 
> - Timer(TIMER0):
> uart:~$ timer start TIMER0 -p 2000 -t 0
> TIMER0: period 2 ms, type 0
> [Result]
> timer expired after 2 seconds
> 
> - Watchdog(WDT1):
> uart:~$ mw 7e785008 4755
> uart:~$ mw 7e78500c 1
> [Result]
> soc reset after 22 seconds
> 
> Based-on: 20220315075753.8591-3-steven_...@aspeedtech.com
> ([v2,2/2] hw: aspeed_scu: Introduce clkin_25Mhz attribute)
> 
> Jamin Lin (2):
>aspeed: Add an AST1030 eval board
>test/avocado/machine_aspeed.py: Add ast1030 test case
> 
> Steven Lee (7):
>aspeed/adc: Add AST1030 support
>aspeed/smc: Add AST1030 support
>aspeed/wdt: Fix ast2500/ast2600 default reload value
>aspeed/wdt: Add AST1030 support
>   

[PATCH v3 2/3] block: improve block_dirty_bitmap_merge(): don't allocate extra bitmap

2022-04-01 Thread Vladimir Sementsov-Ogievskiy
We don't need extra bitmap. All we need is to backup the original
bitmap when we do first merge. So, drop extra temporary bitmap and work
directly with target and backup.

Still to keep old semantics, that on failure target is unchanged and
user don't need to restore, we need a local_backup variable and do
restore ourselves on failure path.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 block/monitor/bitmap-qmp-cmds.c | 39 -
 1 file changed, 19 insertions(+), 20 deletions(-)

diff --git a/block/monitor/bitmap-qmp-cmds.c b/block/monitor/bitmap-qmp-cmds.c
index 4db704c015..07d0da323b 100644
--- a/block/monitor/bitmap-qmp-cmds.c
+++ b/block/monitor/bitmap-qmp-cmds.c
@@ -261,8 +261,9 @@ BdrvDirtyBitmap *block_dirty_bitmap_merge(const char *node, 
const char *target,
   HBitmap **backup, Error **errp)
 {
 BlockDriverState *bs;
-BdrvDirtyBitmap *dst, *src, *anon;
+BdrvDirtyBitmap *dst, *src;
 BlockDirtyBitmapMergeSourceList *lst;
+HBitmap *local_backup = NULL;
 
 GLOBAL_STATE_CODE();
 
@@ -271,12 +272,6 @@ BdrvDirtyBitmap *block_dirty_bitmap_merge(const char 
*node, const char *target,
 return NULL;
 }
 
-anon = bdrv_create_dirty_bitmap(bs, bdrv_dirty_bitmap_granularity(dst),
-NULL, errp);
-if (!anon) {
-return NULL;
-}
-
 for (lst = bms; lst; lst = lst->next) {
 switch (lst->value->type) {
 const char *name, *node;
@@ -285,8 +280,7 @@ BdrvDirtyBitmap *block_dirty_bitmap_merge(const char *node, 
const char *target,
 src = bdrv_find_dirty_bitmap(bs, name);
 if (!src) {
 error_setg(errp, "Dirty bitmap '%s' not found", name);
-dst = NULL;
-goto out;
+goto fail;
 }
 break;
 case QTYPE_QDICT:
@@ -294,29 +288,34 @@ BdrvDirtyBitmap *block_dirty_bitmap_merge(const char 
*node, const char *target,
 name = lst->value->u.external.name;
 src = block_dirty_bitmap_lookup(node, name, NULL, errp);
 if (!src) {
-dst = NULL;
-goto out;
+goto fail;
 }
 break;
 default:
 abort();
 }
 
-if (!bdrv_merge_dirty_bitmap(anon, src, NULL, errp)) {
-dst = NULL;
-goto out;
+/* We do backup only for first merge operation */
+if (!bdrv_merge_dirty_bitmap(dst, src,
+ local_backup ? NULL : &local_backup,
+ errp))
+{
+goto fail;
 }
 }
 
-/* Merge into dst; dst is unchanged on failure. */
-if (!bdrv_merge_dirty_bitmap(dst, anon, backup, errp)) {
-dst = NULL;
-goto out;
+if (backup) {
+*backup = local_backup;
 }
 
- out:
-bdrv_release_dirty_bitmap(anon);
 return dst;
+
+fail:
+if (local_backup) {
+bdrv_restore_dirty_bitmap(dst, local_backup);
+}
+
+return NULL;
 }
 
 void qmp_block_dirty_bitmap_merge(const char *node, const char *target,
-- 
2.35.1




[PATCH v3 1/3] block: block_dirty_bitmap_merge(): fix error path

2022-04-01 Thread Vladimir Sementsov-Ogievskiy
At the end we ignore failure of bdrv_merge_dirty_bitmap() and report
success. And still set errp. That's wrong.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Nikita Lapshin 
---
 block/monitor/bitmap-qmp-cmds.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/block/monitor/bitmap-qmp-cmds.c b/block/monitor/bitmap-qmp-cmds.c
index 8e35616c2e..4db704c015 100644
--- a/block/monitor/bitmap-qmp-cmds.c
+++ b/block/monitor/bitmap-qmp-cmds.c
@@ -309,7 +309,10 @@ BdrvDirtyBitmap *block_dirty_bitmap_merge(const char 
*node, const char *target,
 }
 
 /* Merge into dst; dst is unchanged on failure. */
-bdrv_merge_dirty_bitmap(dst, anon, backup, errp);
+if (!bdrv_merge_dirty_bitmap(dst, anon, backup, errp)) {
+dst = NULL;
+goto out;
+}
 
  out:
 bdrv_release_dirty_bitmap(anon);
-- 
2.35.1




[PATCH v3 0/3] block/dirty-bitmaps: fix and improve bitmap merge

2022-04-01 Thread Vladimir Sementsov-Ogievskiy
v3: rebase on master, one patch is already merged.

Vladimir Sementsov-Ogievskiy (3):
  block: block_dirty_bitmap_merge(): fix error path
  block: improve block_dirty_bitmap_merge(): don't allocate extra bitmap
  block: simplify handling of try to merge different sized bitmaps

 include/block/block_int-io.h|  2 +-
 include/qemu/hbitmap.h  | 15 ++---
 block/backup.c  |  6 ++
 block/dirty-bitmap.c| 26 ++
 block/monitor/bitmap-qmp-cmds.c | 38 +
 util/hbitmap.c  | 25 ++
 6 files changed, 43 insertions(+), 69 deletions(-)

-- 
2.35.1




[PATCH v3 3/3] block: simplify handling of try to merge different sized bitmaps

2022-04-01 Thread Vladimir Sementsov-Ogievskiy
We have too much logic to simply check that bitmaps are of the same
size. Let's just define that hbitmap_merge() and
bdrv_dirty_bitmap_merge_internal() require their argument bitmaps be of
same size, this simplifies things.

Let's look through the callers:

For backup_init_bcs_bitmap() we already assert that merge can't fail.

In bdrv_reclaim_dirty_bitmap_locked() we gracefully handle the error
that can't happen: successor always has same size as its parent, drop
this logic.

In bdrv_merge_dirty_bitmap() we already has assertion and separate
check. Make the check explicit and improve error message.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Nikita Lapshin 
---
 include/block/block_int-io.h |  2 +-
 include/qemu/hbitmap.h   | 15 ++-
 block/backup.c   |  6 ++
 block/dirty-bitmap.c | 26 +++---
 util/hbitmap.c   | 25 +++--
 5 files changed, 23 insertions(+), 51 deletions(-)

diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h
index bb454200e5..ded29e7494 100644
--- a/include/block/block_int-io.h
+++ b/include/block/block_int-io.h
@@ -102,7 +102,7 @@ bool blk_dev_is_tray_open(BlockBackend *blk);
 void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes);
 
 void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out);
-bool bdrv_dirty_bitmap_merge_internal(BdrvDirtyBitmap *dest,
+void bdrv_dirty_bitmap_merge_internal(BdrvDirtyBitmap *dest,
   const BdrvDirtyBitmap *src,
   HBitmap **backup, bool lock);
 
diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h
index 5bd986aa44..af4e4ab746 100644
--- a/include/qemu/hbitmap.h
+++ b/include/qemu/hbitmap.h
@@ -76,20 +76,9 @@ void hbitmap_truncate(HBitmap *hb, uint64_t size);
  *
  * Store result of merging @a and @b into @result.
  * @result is allowed to be equal to @a or @b.
- *
- * Return true if the merge was successful,
- *false if it was not attempted.
- */
-bool hbitmap_merge(const HBitmap *a, const HBitmap *b, HBitmap *result);
-
-/**
- * hbitmap_can_merge:
- *
- * hbitmap_can_merge(a, b) && hbitmap_can_merge(a, result) is sufficient and
- * necessary for hbitmap_merge will not fail.
- *
+ * All bitmaps must have same size.
  */
-bool hbitmap_can_merge(const HBitmap *a, const HBitmap *b);
+void hbitmap_merge(const HBitmap *a, const HBitmap *b, HBitmap *result);
 
 /**
  * hbitmap_empty:
diff --git a/block/backup.c b/block/backup.c
index 5cfd0b999c..b2b649e305 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -228,15 +228,13 @@ out:
 
 static void backup_init_bcs_bitmap(BackupBlockJob *job)
 {
-bool ret;
 uint64_t estimate;
 BdrvDirtyBitmap *bcs_bitmap = block_copy_dirty_bitmap(job->bcs);
 
 if (job->sync_mode == MIRROR_SYNC_MODE_BITMAP) {
 bdrv_clear_dirty_bitmap(bcs_bitmap, NULL);
-ret = bdrv_dirty_bitmap_merge_internal(bcs_bitmap, job->sync_bitmap,
-   NULL, true);
-assert(ret);
+bdrv_dirty_bitmap_merge_internal(bcs_bitmap, job->sync_bitmap, NULL,
+ true);
 } else if (job->sync_mode == MIRROR_SYNC_MODE_TOP) {
 /*
  * We can't hog the coroutine to initialize this thoroughly.
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index da1b91166f..bf3dc0512a 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -309,10 +309,7 @@ BdrvDirtyBitmap 
*bdrv_reclaim_dirty_bitmap_locked(BdrvDirtyBitmap *parent,
 return NULL;
 }
 
-if (!hbitmap_merge(parent->bitmap, successor->bitmap, parent->bitmap)) {
-error_setg(errp, "Merging of parent and successor bitmap failed");
-return NULL;
-}
+hbitmap_merge(parent->bitmap, successor->bitmap, parent->bitmap);
 
 parent->disabled = successor->disabled;
 parent->busy = false;
@@ -912,13 +909,15 @@ bool bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const 
BdrvDirtyBitmap *src,
 goto out;
 }
 
-if (!hbitmap_can_merge(dest->bitmap, src->bitmap)) {
-error_setg(errp, "Bitmaps are incompatible and can't be merged");
+if (bdrv_dirty_bitmap_size(src) != bdrv_dirty_bitmap_size(dest)) {
+error_setg(errp, "Bitmaps are of different sizes (destination size is 
%"
+   PRId64 ", source size is %" PRId64 ") and can't be merged",
+   bdrv_dirty_bitmap_size(dest), bdrv_dirty_bitmap_size(src));
 goto out;
 }
 
-ret = bdrv_dirty_bitmap_merge_internal(dest, src, backup, false);
-assert(ret);
+bdrv_dirty_bitmap_merge_internal(dest, src, backup, false);
+ret = true;
 
 out:
 bdrv_dirty_bitmaps_unlock(dest->bs);
@@ -932,17 +931,16 @@ out:
 /**
  * bdrv_dirty_bitmap_merge_internal: merge src into dest.
  * Does NOT check bitmap permissions; not suitable for use as public API.
+ * @dest, @src and @backup (if n

Re: [PATCH] build-sys: drop ntddscsi.h check

2022-04-01 Thread Paolo Bonzini
Queued, thanks.

Paolo





Re: [PATCH] virtio-net: use g_memdup2() instead of unsafe g_memdup()

2022-04-01 Thread Philippe Mathieu-Daudé

On 1/4/22 04:31, Jason Wang wrote:

On Fri, Apr 1, 2022 at 2:29 AM Eugenio Pérez  wrote:


Fixing that literal checkpatch.pl because it will complain when we modify the 
file


See https://www.mail-archive.com/qemu-devel@nongnu.org/msg834178.html


Signed-off-by: Eugenio Pérez 


Acked-by: Jason Wang 


---
  hw/net/virtio-net.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 1067e72b39..e4748a7e6c 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1443,7 +1443,8 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, 
VirtQueue *vq)
  }

  iov_cnt = elem->out_num;
-iov2 = iov = g_memdup(elem->out_sg, sizeof(struct iovec) * 
elem->out_num);
+iov2 = iov = g_memdup2(elem->out_sg,
+   sizeof(struct iovec) * elem->out_num);
  s = iov_to_buf(iov, iov_cnt, 0, &ctrl, sizeof(ctrl));
  iov_discard_front(&iov, &iov_cnt, sizeof(ctrl));
  if (s != sizeof(ctrl)) {
--
2.27.0







Re: [PATCH 2/3] i386: factor out x86_firmware_configure()

2022-04-01 Thread Philippe Mathieu-Daudé

On 1/4/22 07:28, Xiaoyao Li wrote:

On 4/1/2022 1:08 PM, Gerd Hoffmann wrote:

   if (sev_enabled()) {


 ^^^



Can we remove the SEV check ...



+    pc_system_parse_ovmf_flash(ptr, size);
+
+    if (sev_enabled()) {


... because we are still checking SEV here.


Well, the two checks have slightly different purposes.  The first check
will probably become "if (sev || tdx)" soon, 


Not soon for TDX since the hacky pflash interface to load TDVF is rejected.


You can still convince us you need a pflash for TDX, and particularly
"a pflash that doesn't behave like pflash". Also, see the comment in
the next patch of this series:

+ * [...] there is no need to register
+ * the firmware as rom to properly re-initialize on reset.
+ * Just go for a straight file load instead.
+ */


whereas the second will
become "if (sev) { ... } if (tdx) { ... }".

We could remove the first.  pc_system_parse_ovmf_flash() would run
unconditionally then.  Not needed, but should not have any bad side
effects.


OK, then:
Reviewed-by: Philippe Mathieu-Daudé 





Re: [PATCH v2 1/7] block/copy-before-write: refactor option parsing

2022-04-01 Thread Hanna Reitz

On 01.04.22 11:19, Vladimir Sementsov-Ogievskiy wrote:

We are going to add one more option of enum type. Let's refactor option
parsing so that we can simply work with BlockdevOptionsCbw object.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
  block/copy-before-write.c | 68 +++
  1 file changed, 41 insertions(+), 27 deletions(-)

diff --git a/block/copy-before-write.c b/block/copy-before-write.c
index a8a06fdc09..394e73b094 100644
--- a/block/copy-before-write.c
+++ b/block/copy-before-write.c
@@ -24,6 +24,7 @@
   */
  
  #include "qemu/osdep.h"

+#include "qapi/qmp/qjson.h"
  
  #include "sysemu/block-backend.h"

  #include "qemu/cutils.h"
@@ -328,46 +329,49 @@ static void cbw_child_perm(BlockDriverState *bs, 
BdrvChild *c,
  }
  }
  
-static bool cbw_parse_bitmap_option(QDict *options, BdrvDirtyBitmap **bitmap,

-Error **errp)
+static BlockdevOptionsCbw *cbw_parse_options(QDict *options, Error **errp)
  {
-QDict *bitmap_qdict = NULL;
-BlockDirtyBitmap *bmp_param = NULL;
+QDict *cbw_qdict = NULL;
+BlockdevOptionsCbw *opts = NULL;
  Visitor *v = NULL;
-bool ret = false;
  
-*bitmap = NULL;

+cbw_qdict = qdict_clone_shallow(options);
  
-qdict_extract_subqdict(options, &bitmap_qdict, "bitmap.");

-if (!qdict_size(bitmap_qdict)) {
-ret = true;
-goto out;
-}
-
-v = qobject_input_visitor_new_flat_confused(bitmap_qdict, errp);
+/*
+ * Delete BlockdevOptions base fields, that are not part of
+ * BlockdevOptionsCbw.
+ */
+qdict_del(cbw_qdict, "driver");
+qdict_del(cbw_qdict, "node-name");
+qdict_del(cbw_qdict, "discard");
+qdict_del(cbw_qdict, "cache");
+qdict_extract_subqdict(cbw_qdict, NULL, "cache.");
+qdict_del(cbw_qdict, "read-only");
+qdict_del(cbw_qdict, "auto-read-only");
+qdict_del(cbw_qdict, "force-share");
+qdict_del(cbw_qdict, "detect-zeroes");


Works in practice now, but seems a bit fragile.  If new fields are added 
to the base class, this will break.  (And I don’t know whether people 
will think of updating this when new fields are added to the base class.)


Would there be a problem if instead we parsed the full BlockdevOptions 
object here, asserting that .driver is BLOCKDEV_DRIVER_COPY_BEFORE_WRITE?



+
+v = qobject_input_visitor_new_flat_confused(cbw_qdict, errp);
  if (!v) {
  goto out;
  }
  
-visit_type_BlockDirtyBitmap(v, NULL, &bmp_param, errp);

-if (!bmp_param) {
-goto out;
-}
-
-*bitmap = block_dirty_bitmap_lookup(bmp_param->node, bmp_param->name, NULL,
-errp);
-if (!*bitmap) {
+visit_type_BlockdevOptionsCbw(v, NULL, &opts, errp);
+if (!opts) {
  goto out;
  }





Re: [RFC PATCH v3 19/28] hw/virtio: Replace g_memdup() by g_memdup2()

2022-04-01 Thread Eugenio Perez Martin
On Fri, Sep 3, 2021 at 8:11 PM Philippe Mathieu-Daudé  wrote:
>
> Per 
> https://discourse.gnome.org/t/port-your-module-from-g-memdup-to-g-memdup2-now/5538
>
>   The old API took the size of the memory to duplicate as a guint,
>   whereas most memory functions take memory sizes as a gsize. This
>   made it easy to accidentally pass a gsize to g_memdup(). For large
>   values, that would lead to a silent truncation of the size from 64
>   to 32 bits, and result in a heap area being returned which is
>   significantly smaller than what the caller expects. This can likely
>   be exploited in various modules to cause a heap buffer overflow.
>
> Replace g_memdup() by the safer g_memdup2() wrapper.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
> Should we check in_num/out_num in range?

I'd say it is not needed to check: virtqueue_pop fills them by
iterating through the descriptor chain so the range is restricted to
[0, 1024].

Acked-by: Eugenio Pérez 


> ---
>  hw/net/virtio-net.c   | 3 ++-
>  hw/virtio/virtio-crypto.c | 6 +++---
>  2 files changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index 16d20cdee52..338fbeb8c57 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -1449,7 +1449,8 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, 
> VirtQueue *vq)
>  }
>
>  iov_cnt = elem->out_num;
> -iov2 = iov = g_memdup(elem->out_sg, sizeof(struct iovec) * 
> elem->out_num);
> +iov2 = iov = g_memdup2(elem->out_sg,
> +   sizeof(struct iovec) * elem->out_num);
>  s = iov_to_buf(iov, iov_cnt, 0, &ctrl, sizeof(ctrl));
>  iov_discard_front(&iov, &iov_cnt, sizeof(ctrl));
>  if (s != sizeof(ctrl)) {
> diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
> index 54f9bbb789c..59886c1790d 100644
> --- a/hw/virtio/virtio-crypto.c
> +++ b/hw/virtio/virtio-crypto.c
> @@ -242,7 +242,7 @@ static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, 
> VirtQueue *vq)
>  }
>
>  out_num = elem->out_num;
> -out_iov_copy = g_memdup(elem->out_sg, sizeof(out_iov[0]) * out_num);
> +out_iov_copy = g_memdup2(elem->out_sg, sizeof(out_iov[0]) * out_num);
>  out_iov = out_iov_copy;
>
>  in_num = elem->in_num;
> @@ -605,11 +605,11 @@ virtio_crypto_handle_request(VirtIOCryptoReq *request)
>  }
>
>  out_num = elem->out_num;
> -out_iov_copy = g_memdup(elem->out_sg, sizeof(out_iov[0]) * out_num);
> +out_iov_copy = g_memdup2(elem->out_sg, sizeof(out_iov[0]) * out_num);
>  out_iov = out_iov_copy;
>
>  in_num = elem->in_num;
> -in_iov_copy = g_memdup(elem->in_sg, sizeof(in_iov[0]) * in_num);
> +in_iov_copy = g_memdup2(elem->in_sg, sizeof(in_iov[0]) * in_num);
>  in_iov = in_iov_copy;
>
>  if (unlikely(iov_to_buf(out_iov, out_num, 0, &req, sizeof(req))
> --
> 2.31.1
>
>




Re: [PATCH] virtio-net: use g_memdup2() instead of unsafe g_memdup()

2022-04-01 Thread Eugenio Perez Martin
On Fri, Apr 1, 2022 at 12:31 PM Philippe Mathieu-Daudé
 wrote:
>
> On 1/4/22 04:31, Jason Wang wrote:
> > On Fri, Apr 1, 2022 at 2:29 AM Eugenio Pérez  wrote:
> >>
> >> Fixing that literal checkpatch.pl because it will complain when we modify 
> >> the file
>
> See https://www.mail-archive.com/qemu-devel@nongnu.org/msg834178.html
>

Sorry I missed that series. It performs more replacements so regarding
virtio it's better to push yours.

Thanks!

> >> Signed-off-by: Eugenio Pérez 
> >
> > Acked-by: Jason Wang 
> >
> >> ---
> >>   hw/net/virtio-net.c | 3 ++-
> >>   1 file changed, 2 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> >> index 1067e72b39..e4748a7e6c 100644
> >> --- a/hw/net/virtio-net.c
> >> +++ b/hw/net/virtio-net.c
> >> @@ -1443,7 +1443,8 @@ static void virtio_net_handle_ctrl(VirtIODevice 
> >> *vdev, VirtQueue *vq)
> >>   }
> >>
> >>   iov_cnt = elem->out_num;
> >> -iov2 = iov = g_memdup(elem->out_sg, sizeof(struct iovec) * 
> >> elem->out_num);
> >> +iov2 = iov = g_memdup2(elem->out_sg,
> >> +   sizeof(struct iovec) * elem->out_num);
> >>   s = iov_to_buf(iov, iov_cnt, 0, &ctrl, sizeof(ctrl));
> >>   iov_discard_front(&iov, &iov_cnt, sizeof(ctrl));
> >>   if (s != sizeof(ctrl)) {
> >> --
> >> 2.27.0
> >>
> >
>




Re: [PATCH v1 1/9] qapi: fix example of netdev_add command

2022-04-01 Thread Victor Toso
Hi,

On Fri, Apr 01, 2022 at 09:56:40AM +0200, Markus Armbruster wrote:
> Victor Toso  writes:
> 
> > Example output has the optional member @dnssearch as string type. It
> > should be an array of strings instead. Fix it.
> >
> > For reference, see NetdevUserOptions.
> >
> > Signed-off-by: Victor Toso 
> > ---
> >  qapi/net.json | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/qapi/net.json b/qapi/net.json
> > index 0d4578bd07..efc0bae170 100644
> > --- a/qapi/net.json
> > +++ b/qapi/net.json
> > @@ -51,7 +51,7 @@
> >  #
> >  # -> { "execute": "netdev_add",
> >  #  "arguments": { "type": "user", "id": "netdev1",
> > -# "dnssearch": "example.org" } }
> > +# "dnssearch": [ "example.org" ] } }
> >  # <- { "return": {} }
> >  #
> >  ##
> 
> Uh, @dnssearch is ['String']...  shouldn't this be something like
> 
># "dnssearch": [ { "str": "example.org" } ] } }
> 
> ?

Yes, my mistake. Thanks for spotting it.
I'll resend this patch shortly.

Cheers,
Victor


signature.asc
Description: PGP signature


Re: [PATCH 10/9] qapi: Fix calc-dirty-rate example

2022-04-01 Thread Victor Toso
On Fri, Apr 01, 2022 at 10:20:28AM +0200, Markus Armbruster wrote:
> The example shows {"command": ...}, which is wrong.  Fix it to
> {"execute": ...}.
> 
> Signed-off-by: Markus Armbruster 
> ---
>  qapi/migration.json | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/qapi/migration.json b/qapi/migration.json
> index f74777608a..27d7b28158 100644
> --- a/qapi/migration.json
> +++ b/qapi/migration.json
> @@ -1845,7 +1845,7 @@
>  # Since: 5.2
>  #
>  # Example:
> -#   {"command": "calc-dirty-rate", "arguments": {"calc-time": 1,
> +#   {"execute": "calc-dirty-rate", "arguments": {"calc-time": 1,
>  #'sample-pages': 512} }
>  #
>  ##
> -- 
> 2.35.1

Reviewed-by: Victor Toso 

Cheers,
Victor


signature.asc
Description: PGP signature


Re: [PATCH v2] 9p: move P9_XATTR_SIZE_MAX from 9p.h to 9p.c

2022-04-01 Thread Thomas Huth

On 31/03/2022 22.06, Will Cohen wrote:
On Thu, Mar 31, 2022 at 4:00 PM Peter Maydell > wrote:


On Thu, 31 Mar 2022 at 19:27, Will Cohen mailto:wwco...@gmail.com>> wrote:
 >
 > The patch set adding 9p functionality to darwin introduced an issue
 > where limits.h, which defines XATTR_SIZE_MAX, is included in 9p.c,
 > though the referenced constant is needed in 9p.h. This commit fixes that
 > issue by moving the definition of P9_XATTR_SIZE_MAX, which uses
 > XATTR_SIZE_MAX, to also be in 9p.c.
 >
 > Additionally, this commit moves the location of the system headers
 > include in 9p.c to occur before the project headers.
 >
 > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/950

 > Fixes: 38d7fd68b0 ("9p: darwin: Move XATTR_SIZE_MAX->P9_XATTR_SIZE_MAX")
 >
 > Signed-off-by: Will Cohen mailto:wwco...@gmail.com>>
 > ---
 >  hw/9pfs/9p.c | 28 +++-
 >  hw/9pfs/9p.h | 18 --
 >  2 files changed, 23 insertions(+), 23 deletions(-)
 >
 > diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
 > index dcaa602d4c..b9152c7882 100644
 > --- a/hw/9pfs/9p.c
 > +++ b/hw/9pfs/9p.c
 > @@ -16,6 +16,11 @@
 >   * https://wiki.qemu.org/Documentation/9p

 >   */
 >
 > +#ifdef CONFIG_LINUX
 > +#include 
 > +#else
 > +#include 
 > +#endif
 >  #include "qemu/osdep.h"

osdep.h must always be the first include line in any .c file.

Understood, apologies -- if there's other changes for a v3 I can resubmit 
accordingly, but if this otherwise looks okay then I would be fine with a 
QEMU maintainer adjusting the header placement as needed when preparing for 
submission to the main tree.


Makes sense. I'm currently assembling a pull req with some misc fixes for 
7.0 ... if Christian & Greg do not have any other patches pending right now, 
I could throw this in, with the osdep.h location fixed.


 Thomas




Re: [RFC PATCH 0/5] Removal of AioContext lock, bs->parents and ->children: proof of concept

2022-04-01 Thread Paolo Bonzini

On 4/1/22 10:05, Emanuele Giuseppe Esposito wrote:

The list itself would be used internally to implement the write-side
lock and unlock primitives, but it would not be protected by the above
functions.  So there would be a couple additional functions:

   bdrv_graph_list_lock <-> cpu_list_lock
   bdrv_graph_list_unlock <-> cpu_list_unlock


The list would be graph_bdrv_states, why do we need to protect it with a
lock? Currently it is protected by BQL, and theoretically only
bdrv_graph_wrlock iterates on it. And as we defined in the assertion
below, wrlock is always in the main loop too.


You're right, CPU_FOREACH only appears in start_exclusive; so likewise 
you only need to walk the list in bdrv_graph_wrlock, i.e. only under BQL.


My thought was that, within the implementation, you'll need a mutex to 
protect has_waiter, and protecting the list with the same mutex made 
sense to me.  But indeed it's not necessary.


Paolo


+void bdrv_graph_list_rdlock(BlockDriverState *bs);
+void bdrv_graph_list_rdunlock(BlockDriverState *bs);


Apart from the naming change, these two would be coroutine_fn.


+#define BS_GRAPH_READER(bs) /* in main loop OR bs->reading_graph */
+#define BS_GRAPH_WRITER(bs) /* in main loop AND bs->bs_graph_pending_op


bs_graph_pending_op is not part of bs->, it is a global variable
(corresponding to pending_cpus in cpus-common.c).  I would call it
bs_graph_pending_reader since you have "has_writer" below.




[PATCH v1.1 1/9] qapi: fix example of netdev_add command

2022-04-01 Thread Victor Toso
Example output has the optional member @dnssearch as string type. It
should be an array of strings instead. Fix it.

For reference, see NetdevUserOptions.

Signed-off-by: Victor Toso 
---
 qapi/net.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qapi/net.json b/qapi/net.json
index 0d4578bd07..b92f3f5fb4 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -51,7 +51,7 @@
 #
 # -> { "execute": "netdev_add",
 #  "arguments": { "type": "user", "id": "netdev1",
-# "dnssearch": "example.org" } }
+# "dnssearch": [ { "str": "example.org" } ] } }
 # <- { "return": {} }
 #
 ##
-- 
2.35.1




[PATCH 1/3] vhost: Refactor vhost_reset_device() in VhostOps

2022-04-01 Thread Michael Qiu
Currently in vhost framwork, vhost_reset_device() is misnamed.
Actually, it should be vhost_reset_owner().

In vhost user, it make compatible with reset device ops, but
vhost kernel does not compatible with it, for vhost vdpa, it
only implement reset device action.

So we need seperate the function into vhost_reset_owner() and
vhost_reset_device(). So that different backend could use the
correct function.

Signde-off-by: Michael Qiu 
---
 hw/scsi/vhost-user-scsi.c |  6 +-
 hw/virtio/vhost-backend.c |  4 ++--
 hw/virtio/vhost-user.c| 22 ++
 include/hw/virtio/vhost-backend.h |  2 ++
 4 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index 1b2f7ee..f179626 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -80,8 +80,12 @@ static void vhost_user_scsi_reset(VirtIODevice *vdev)
 return;
 }
 
-if (dev->vhost_ops->vhost_reset_device) {
+if (virtio_has_feature(dev->protocol_features,
+   VHOST_USER_PROTOCOL_F_RESET_DEVICE) &&
+   dev->vhost_ops->vhost_reset_device) {
 dev->vhost_ops->vhost_reset_device(dev);
+} else if (dev->vhost_ops->vhost_reset_owner) {
+dev->vhost_ops->vhost_reset_owner(dev);
 }
 }
 
diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index e409a86..abbaa8b 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -191,7 +191,7 @@ static int vhost_kernel_set_owner(struct vhost_dev *dev)
 return vhost_kernel_call(dev, VHOST_SET_OWNER, NULL);
 }
 
-static int vhost_kernel_reset_device(struct vhost_dev *dev)
+static int vhost_kernel_reset_owner(struct vhost_dev *dev)
 {
 return vhost_kernel_call(dev, VHOST_RESET_OWNER, NULL);
 }
@@ -317,7 +317,7 @@ const VhostOps kernel_ops = {
 .vhost_get_features = vhost_kernel_get_features,
 .vhost_set_backend_cap = vhost_kernel_set_backend_cap,
 .vhost_set_owner = vhost_kernel_set_owner,
-.vhost_reset_device = vhost_kernel_reset_device,
+.vhost_reset_owner = vhost_kernel_reset_owner,
 .vhost_get_vq_index = vhost_kernel_get_vq_index,
 #ifdef CONFIG_VHOST_VSOCK
 .vhost_vsock_set_guest_cid = vhost_kernel_vsock_set_guest_cid,
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 6abbc9d..4412008 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -1475,16 +1475,29 @@ static int vhost_user_get_max_memslots(struct vhost_dev 
*dev,
 return 0;
 }
 
+static int vhost_user_reset_owner(struct vhost_dev *dev)
+{
+VhostUserMsg msg = {
+.hdr.request = VHOST_USER_RESET_OWNER,
+.hdr.flags = VHOST_USER_VERSION,
+};
+
+return vhost_user_write(dev, &msg, NULL, 0);
+}
+
 static int vhost_user_reset_device(struct vhost_dev *dev)
 {
 VhostUserMsg msg = {
+.hdr.request = VHOST_USER_RESET_DEVICE,
 .hdr.flags = VHOST_USER_VERSION,
 };
 
-msg.hdr.request = virtio_has_feature(dev->protocol_features,
- VHOST_USER_PROTOCOL_F_RESET_DEVICE)
-? VHOST_USER_RESET_DEVICE
-: VHOST_USER_RESET_OWNER;
+/* Caller must ensure the backend has VHOST_USER_PROTOCOL_F_RESET_DEVICE
+ * support */
+if (!virtio_has_feature(dev->protocol_features,
+   VHOST_USER_PROTOCOL_F_RESET_DEVICE)) {
+return -EPERM;
+}
 
 return vhost_user_write(dev, &msg, NULL, 0);
 }
@@ -2548,6 +2561,7 @@ const VhostOps user_ops = {
 .vhost_set_features = vhost_user_set_features,
 .vhost_get_features = vhost_user_get_features,
 .vhost_set_owner = vhost_user_set_owner,
+.vhost_reset_owner = vhost_user_reset_owner,
 .vhost_reset_device = vhost_user_reset_device,
 .vhost_get_vq_index = vhost_user_get_vq_index,
 .vhost_set_vring_enable = vhost_user_set_vring_enable,
diff --git a/include/hw/virtio/vhost-backend.h 
b/include/hw/virtio/vhost-backend.h
index 81bf310..affeeb0 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -77,6 +77,7 @@ typedef int (*vhost_get_features_op)(struct vhost_dev *dev,
  uint64_t *features);
 typedef int (*vhost_set_backend_cap_op)(struct vhost_dev *dev);
 typedef int (*vhost_set_owner_op)(struct vhost_dev *dev);
+typedef int (*vhost_reset_owner_op)(struct vhost_dev *dev);
 typedef int (*vhost_reset_device_op)(struct vhost_dev *dev);
 typedef int (*vhost_get_vq_index_op)(struct vhost_dev *dev, int idx);
 typedef int (*vhost_set_vring_enable_op)(struct vhost_dev *dev,
@@ -150,6 +151,7 @@ typedef struct VhostOps {
 vhost_get_features_op vhost_get_features;
 vhost_set_backend_cap_op vhost_set_backend_cap;
 vhost_set_owner_op vhost_set_owner;
+vhost_reset_owner_op vhost_reset_owner;
 vhost_reset_device_op vhost_reset_device;
 vhost_get_vq_index_op vhos

[PATCH 2/3] vhost: add vhost_dev_reset()

2022-04-01 Thread Michael Qiu
Not all vhost-user backends support ops->vhost_reset_device(). Instead
of adding backend check and call backend ops directly, it's better to
implement a function in vhost framework, so that it could hide vhost_ops
details.

SIgned-off-by: Michael Qiu 
---
 hw/virtio/vhost.c | 14 ++
 include/hw/virtio/vhost.h |  1 +
 2 files changed, 15 insertions(+)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index b643f42..26667ae 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1854,3 +1854,17 @@ int vhost_net_set_backend(struct vhost_dev *hdev,
 
 return -ENOSYS;
 }
+
+int vhost_dev_reset(struct vhost_dev *hdev)
+{
+int ret = 0;
+
+/* should only be called after backend is connected */
+assert(hdev->vhost_ops);
+
+if (hdev->vhost_ops->vhost_reset_device) {
+ret = hdev->vhost_ops->vhost_reset_device(hdev);
+}
+
+return ret;
+}
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 58a73e7..b8b7c20 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -114,6 +114,7 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
 void vhost_dev_cleanup(struct vhost_dev *hdev);
 int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
 void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev);
+int vhost_dev_reset(struct vhost_dev *hdev);
 int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
 void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
 
-- 
1.8.3.1





[PATCH 3/3 v5] vdpa: reset the backend device in the end of vhost_net_stop()

2022-04-01 Thread Michael Qiu
Currently, when VM poweroff, it will trigger vdpa
device(such as mlx bluefield2 VF) reset many times(with 1 datapath
queue pair and one control queue, triggered 3 times), this
leads to below issue:

vhost VQ 2 ring restore failed: -22: Invalid argument (22)

This because in vhost_net_stop(), it will stop all vhost device bind to
this virtio device, and in vhost_dev_stop(), qemu tries to stop the device
, then stop the queue: vhost_virtqueue_stop().

In vhost_dev_stop(), it resets the device, which clear some flags
in low level driver, and in next loop(stop other vhost backends),
qemu try to stop the queue corresponding to the vhost backend,
 the driver finds that the VQ is invalied, this is the root cause.

To solve the issue, vdpa should set vring unready, and
remove reset ops in device stop: vhost_dev_start(hdev, false).

and implement a new function vhost_dev_reset, only reset backend
device after all vhost(per-queue) stopped.

Signed-off-by: Michael Qiu
Acked-by: Jason Wang 
---
v5 --> v4:
move vhost_dev_reset() call after set_guest_notifiers

remove implementation of vhost_dev_reset()

remove backend check for VHOST_BACKEND_TYPE_VDPA

v4 --> v3:
Nothing changed, becasue of issue with mimecast,
when the From: tag is different from the sender,
the some mail client will take the patch as an
attachment, RESEND v3 does not work, So resend
the patch as v4

v3 --> v2:
Call vhost_dev_reset() at the end of vhost_net_stop().

Since the vDPA device need re-add the status bit 
VIRTIO_CONFIG_S_ACKNOWLEDGE and VIRTIO_CONFIG_S_DRIVER,
simply, add them inside vhost_vdpa_reset_device, and
the only way calling vhost_vdpa_reset_device is in
vhost_net_stop(), so it keeps the same behavior as before.

v2 --> v1:
   Implement a new function vhost_dev_reset,
   reset the backend kernel device at last.

---
 hw/net/vhost_net.c | 22 +++---
 hw/virtio/vhost-vdpa.c | 15 +--
 2 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 30379d2..30c76ca 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -325,7 +325,7 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
 int total_notifiers = data_queue_pairs * 2 + cvq;
 VirtIONet *n = VIRTIO_NET(dev);
 int nvhosts = data_queue_pairs + cvq;
-struct vhost_net *net;
+struct vhost_net *net = NULL;
 int r, e, i, index_end = data_queue_pairs * 2;
 NetClientState *peer;
 
@@ -391,13 +391,21 @@ int vhost_net_start(VirtIODevice *dev, NetClientState 
*ncs,
 err_start:
 while (--i >= 0) {
 peer = qemu_get_peer(ncs , i);
-vhost_net_stop_one(get_vhost_net(peer), dev);
+
+net = get_vhost_net(peer);
+
+vhost_net_stop_one(net, dev);
 }
+
 e = k->set_guest_notifiers(qbus->parent, total_notifiers, false);
 if (e < 0) {
 fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", e);
 fflush(stderr);
 }
+
+if (net) {
+vhost_dev_reset(&net->dev);
+}
 err:
 return r;
 }
@@ -410,6 +418,7 @@ void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs,
 VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
 VirtIONet *n = VIRTIO_NET(dev);
 NetClientState *peer;
+struct vhost_net *net = NULL;
 int total_notifiers = data_queue_pairs * 2 + cvq;
 int nvhosts = data_queue_pairs + cvq;
 int i, r;
@@ -420,7 +429,10 @@ void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs,
 } else {
 peer = qemu_get_peer(ncs, n->max_queue_pairs);
 }
-vhost_net_stop_one(get_vhost_net(peer), dev);
+
+net = get_vhost_net(peer);
+
+vhost_net_stop_one(net, dev);
 }
 
 r = k->set_guest_notifiers(qbus->parent, total_notifiers, false);
@@ -429,6 +441,10 @@ void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs,
 fflush(stderr);
 }
 assert(r >= 0);
+
+if (net) {
+vhost_dev_reset(&net->dev);
+}
 }
 
 void vhost_net_cleanup(struct vhost_net *net)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index c5ed7a3..3ef0199 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -708,6 +708,11 @@ static int vhost_vdpa_reset_device(struct vhost_dev *dev)
 
 ret = vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &status);
 trace_vhost_vdpa_reset_device(dev, status);
+
+/* Add back this status, so that the device could work next time*/
+vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
+   VIRTIO_CONFIG_S_DRIVER);
+
 return ret;
 }
 
@@ -719,14 +724,14 @@ static int vhost_vdpa_get_vq_index(struct vhost_dev *dev, 
int idx)
 return idx;
 }
 
-static int vhost_vdpa_set_vring_ready(struct vhost_dev *dev)
+static int vhost_vdpa_set_vring_ready(struct vhost_dev *dev, unsigned int 
ready)
 {
 int i;
 trace_vhost_vdpa_set_vring_ready(dev);
 for (i = 0; i < dev->nvqs; ++i) {
  

Re: use of uninitialized variable involving visit_type_uint32() and friends

2022-04-01 Thread Paolo Bonzini

On 4/1/22 11:15, Markus Armbruster wrote:

  +assert (v->type == expected_type);
  +if (expected_type & (VISITOR_INPUT | VISITOR_DEALLOC)) {

Backwards.


Yes, I always get input vs output wrong.


With an input visitor @v,

 visit_type_uint32(v, "name", &val, errp)

stores to @val without looking at it first.  In other words,
uninitialized @val is fine, just like for val = ...

Note: you don't actually need VISITOR_DEALLOC here, because a
deallocation visitor isn't going to do anything for non-pointer values.


There's a philosophical question on whether other deallocation visitors 
can exist than "the" deallocation visitor, but it's not particularly 
germane to the topic.



Two changes:

* Skip copying to and from full-width buffer @value:

   - Skip @value = *obj when we're going to overwrite @value without
 reading it first.

 This leaves @value uninitialized instead of initializing it from a
 (commonly) uninitialized variable.

 I'm not sure how this helps static analysis, but if it does...


If it can do really serious interprocedural analysis, it _might_ be able 
to see through the visitor constructor and know that the "value = *obj" 
is not initialized (e.g. "all callers of object_property_set use an 
input visitor").  I doubt that honestly, but a man can dream.


If the conditionals are enough to shut it up, then we won the battle 
(for now).


If the conditionals are not enough to shut it up, then you have a bit 
more confidence when marking the false positives.



   - Skip *obj = @value when value must be *obj anyway.

 Should have no observable effect.

 Again, I'm not sure how this helps static analysis.


Mostly consistency, could also be changed to an assert(*obj == value); 
/* output visitors don't really need obj to be passed by reference */



* Pass visitor type in addition to the visitor.  Can you explain why
   that's useful?


Because it communicates what the caller expects: "I have left this 
uninitialized because I expect my "v" argument to be the kind of visitor 
that fills it in".  It's this argument that gives me the confidence 
needed to shut up Coverity's false positives.


Embedding the visitor type in the signature makes it impossible not to 
pass it, unlike e.g. an assertion in every getter or setter.


Paolo



Re: [PATCH v4 2/2] Added parameter to take screenshot with screendump as PNG

2022-04-01 Thread Markus Armbruster
Dave, please have a look at the HMP compatibility issue in
hmp-command.hx below.

Kshitij Suri  writes:

> Currently screendump only supports PPM format, which is un-compressed and not
> standard.

If "standard" means "have to pay a standards organization $$$ to access
the spec", PPM is not standard.  If it means "widely supported", it
certainly is.  I'd drop "and not standard".  Suggestion, not demand.

>   Added a "format" parameter to qemu monitor screendump capabilites
> to support PNG image capture using libpng. The param was added in QAPI schema
> of screendump present in ui.json along with png_save() function which converts
> pixman_image to PNG. HMP command equivalent was also modified to support the
> feature.

Suggest to use imperative mood to describe the commit, and omit details
that aren't necessary here:

Add a "format" parameter to QMP and HMP screendump command
  to support PNG image capture using libpng.

>
> Example usage:
> { "execute": "screendump", "arguments": { "filename": "/tmp/image",
> "format":"png" } }

Providing an example in the commit message is always nice, thanks!

>
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/718
>
> Signed-off-by: Kshitij Suri 
>
> Reviewed-by: Daniel P. Berrangé 
> ---
>  hmp-commands.hx|  11 ++---
>  monitor/hmp-cmds.c |  12 +-
>  qapi/ui.json   |  24 +--
>  ui/console.c   | 101 +++--
>  4 files changed, 136 insertions(+), 12 deletions(-)
>
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 8476277aa9..19b7cab595 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -244,11 +244,12 @@ ERST
>  
>  {
>  .name   = "screendump",
> -.args_type  = "filename:F,device:s?,head:i?",
> -.params = "filename [device [head]]",
> -.help   = "save screen from head 'head' of display device 
> 'device' "
> -  "into PPM image 'filename'",
> -.cmd= hmp_screendump,
> +.args_type  = "filename:F,format:s?,device:s?,head:i?",

Incompatible change: meaning of "screendump ONE TWO" changes from
filename=ONE, device=TWO to filename=ONE, format=TWO.

As HMP is not a stable interface, incompatible change is permissible.
But is this one wise?

Could we add the new argument at the end instead?

.args_type  = "filename:F,device:s?,head:i?,format:s?",

Could we do *without* an argument, and derive the format from the
filename extension?  .png means format=png, anything else format=ppm.
Would be a bad idea for QMP.  Okay for HMP?

> +.params = "filename [format] [device [head]]",

This tells us that parameter format can be omitted like so

screendump foo.ppm device-id

which isn't true.  Better: "filename [format [device [head]]".

> +.help   = "save screen from head 'head' of display device 
> 'device'"
> +  "in specified format 'format' as image 'filename'."
> +  "Currently only 'png' and 'ppm' formats are 
> supported.",
> + .cmd= hmp_screendump,
>  .coroutine  = true,
>  },
>  
> diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
> index 634968498b..2442bfa989 100644
> --- a/monitor/hmp-cmds.c
> +++ b/monitor/hmp-cmds.c
> @@ -1720,9 +1720,19 @@ hmp_screendump(Monitor *mon, const QDict *qdict)
>  const char *filename = qdict_get_str(qdict, "filename");
>  const char *id = qdict_get_try_str(qdict, "device");
>  int64_t head = qdict_get_try_int(qdict, "head", 0);
> +const char *input_format  = qdict_get_try_str(qdict, "format");
>  Error *err = NULL;
> +ImageFormat format;
>  
> -qmp_screendump(filename, id != NULL, id, id != NULL, head, &err);
> +format = qapi_enum_parse(&ImageFormat_lookup, input_format,
> +  IMAGE_FORMAT_PPM, &err);
> +if (err) {
> +goto end;
> +}
> +
> +qmp_screendump(filename, id != NULL, id, id != NULL, head,
> +   input_format != NULL, format, &err);
> +end:
>  hmp_handle_error(mon, err);
>  }
>  
> diff --git a/qapi/ui.json b/qapi/ui.json
> index 664da9e462..24371fce05 100644
> --- a/qapi/ui.json
> +++ b/qapi/ui.json
> @@ -157,12 +157,27 @@
>  ##
>  { 'command': 'expire_password', 'boxed': true, 'data': 
> 'ExpirePasswordOptions' }
>  
> +##
> +# @ImageFormat:
> +#
> +# Supported image format types.
> +#
> +# @png: PNG format
> +#
> +# @ppm: PPM format
> +#
> +# Since: 7.1
> +#
> +##
> +{ 'enum': 'ImageFormat',
> +  'data': ['ppm', 'png'] }
> +
>  ##
>  # @screendump:
>  #
> -# Write a PPM of the VGA screen to a file.
> +# Capture the contents of a screen and write it to a file.
>  #
> -# @filename: the path of a new PPM file to store the image
> +# @filename: the path of a new file to store the image
>  #
>  # @device: ID of the display device that should be dumped. If this parameter
>  #  is missing, the primary display will be used. (Since 2.12)
>

[PATCH 0/3] Refactor vhost device reset

2022-04-01 Thread Michael Qiu
Now adays, vhost framework does a misnamed for
vhost_reset_device(), actually we need seperate vhost_reset_device()
and vhost_reset_owner(), this patchset refactor it, and make different
backend call the right function.

Base on those work, fix an issue of vdpa device reset for several times.

Test with kernel vhost, vhost-vdpa, DPDK vhost-user(vdpa), with shutdown
,reboot, and load/unload virtio_net driver in guest.

Michael Qiu (3):
  vhost: Refactor vhost_reset_device() in VhostOps
  vhost: add vhost_dev_reset()
  vdpa: reset the backend device in the end of vhost_net_stop()

 hw/net/vhost_net.c| 22 +++---
 hw/scsi/vhost-user-scsi.c |  6 +-
 hw/virtio/vhost-backend.c |  4 ++--
 hw/virtio/vhost-user.c| 22 ++
 hw/virtio/vhost-vdpa.c| 15 +--
 hw/virtio/vhost.c | 14 ++
 include/hw/virtio/vhost-backend.h |  2 ++
 include/hw/virtio/vhost.h |  1 +
 8 files changed, 70 insertions(+), 16 deletions(-)

-- 
1.8.3.1





Re: [PATCH v2] 9p: move P9_XATTR_SIZE_MAX from 9p.h to 9p.c

2022-04-01 Thread Christian Schoenebeck
On Freitag, 1. April 2022 13:01:31 CEST Thomas Huth wrote:
> On 31/03/2022 22.06, Will Cohen wrote:
> > On Thu, Mar 31, 2022 at 4:00 PM Peter Maydell  > 
> > > wrote:
> > On Thu, 31 Mar 2022 at 19:27, Will Cohen  > 
> > > wrote:
> >  > The patch set adding 9p functionality to darwin introduced an issue
> >  > where limits.h, which defines XATTR_SIZE_MAX, is included in 9p.c,
> >  > though the referenced constant is needed in 9p.h. This commit fixes
> >  > that
> >  > issue by moving the definition of P9_XATTR_SIZE_MAX, which uses
> >  > XATTR_SIZE_MAX, to also be in 9p.c.
> >  > 
> >  > Additionally, this commit moves the location of the system headers
> >  > include in 9p.c to occur before the project headers.
> >  > 
> >  > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/950
> > 
> > 
> > 
> >  > Fixes: 38d7fd68b0 ("9p: darwin: Move
> >  > XATTR_SIZE_MAX->P9_XATTR_SIZE_MAX")
> >  > 
> >  > Signed-off-by: Will Cohen  >  > >
> >  > ---
> >  >
> >  >  hw/9pfs/9p.c | 28 +++-
> >  >  hw/9pfs/9p.h | 18 --
> >  >  2 files changed, 23 insertions(+), 23 deletions(-)
> >  >
> >  > diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
> >  > index dcaa602d4c..b9152c7882 100644
> >  > --- a/hw/9pfs/9p.c
> >  > +++ b/hw/9pfs/9p.c
> >  > @@ -16,6 +16,11 @@
> >  >
> >  >   * https://wiki.qemu.org/Documentation/9p
> > 
> > 
> > 
> >  >   */
> >  >
> >  > +#ifdef CONFIG_LINUX
> >  > +#include 
> >  > +#else
> >  > +#include 
> >  > +#endif
> >  >
> >  >  #include "qemu/osdep.h"
> > 
> > osdep.h must always be the first include line in any .c file.
> > 
> > Understood, apologies -- if there's other changes for a v3 I can resubmit
> > accordingly, but if this otherwise looks okay then I would be fine with a
> > QEMU maintainer adjusting the header placement as needed when preparing
> > for
> > submission to the main tree.
> 
> Makes sense. I'm currently assembling a pull req with some misc fixes for
> 7.0 ... if Christian & Greg do not have any other patches pending right now,
> I could throw this in, with the osdep.h location fixed.
> 
>   Thomas

That would be appreciated, nothing else for 7.0 at this point. Thanks Thomas!

Best regards,
Christian Schoenebeck





[PATCH] build-sys: simplify AF_VSOCK check

2022-04-01 Thread marcandre . lureau
From: Marc-André Lureau 

The current test checks more than AF_VSOCK availability, and doesn't
need to be that long.

Since its introduction in Linux in 2013, AF_VSOCK came with
linux/vm_sockets.h for sockaddr_vm, let's check that.

We could even go back to the initial configure-less approach
proposed by Stefan Hajnoczi, since Michael Roth added the configure-time
check back then to satisfy glibc in Ubuntu 14. See:
https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg08208.html

Signed-off-by: Marc-André Lureau 
---
 meson.build | 23 ---
 1 file changed, 4 insertions(+), 19 deletions(-)

diff --git a/meson.build b/meson.build
index 46b5e938b196..e8c4f5255a3b 100644
--- a/meson.build
+++ b/meson.build
@@ -1988,25 +1988,10 @@ have_afalg = get_option('crypto_afalg') \
   '''), error_message: 'AF_ALG requested but could not be detected').allowed()
 config_host_data.set('CONFIG_AF_ALG', have_afalg)
 
-config_host_data.set('CONFIG_AF_VSOCK', cc.compiles(gnu_source_prefix + '''
-  #include 
-  #include 
-  #include 
-  #if !defined(AF_VSOCK)
-  # error missing AF_VSOCK flag
-  #endif
-  #include 
-  int main(void) {
-int sock, ret;
-struct sockaddr_vm svm;
-socklen_t len = sizeof(svm);
-sock = socket(AF_VSOCK, SOCK_STREAM, 0);
-ret = getpeername(sock, (struct sockaddr *)&svm, &len);
-if ((ret == -1) && (errno == ENOTCONN)) {
-return 0;
-}
-return -1;
-  }'''))
+config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
+  'linux/vm_sockets.h', 'AF_VSOCK',
+  prefix: '#include ',
+))
 
 have_vss = false
 have_vss_sdk = false # old xp/2003 SDK
-- 
2.35.1.693.g805e0a68082a




Re: [PATCH] build-sys: simplify AF_VSOCK check

2022-04-01 Thread Paolo Bonzini
Queued, thanks.

Paolo





Re: [PATCH v2 2/7] block/copy-before-write: add on-cbw-error open parameter

2022-04-01 Thread Hanna Reitz

On 01.04.22 11:19, Vladimir Sementsov-Ogievskiy wrote:

Currently, behavior on copy-before-write operation failure is simple:
report error to the guest.

Let's implement alternative behavior: break the whole copy-before-write
process (and corresponding backup job or NBD client) but keep guest
working. It's needed if we consider guest stability as more important.

The realisation is simple: on copy-before-write failure we immediately
continue guest write operation and set s->snapshot_ret variable which
will lead to all further and in-flight snapshot-API requests failure.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
  block/copy-before-write.c | 62 ++-
  qapi/block-core.json  | 27 -
  2 files changed, 81 insertions(+), 8 deletions(-)

diff --git a/block/copy-before-write.c b/block/copy-before-write.c
index 394e73b094..0614c3d08b 100644
--- a/block/copy-before-write.c
+++ b/block/copy-before-write.c
@@ -41,6 +41,7 @@
  typedef struct BDRVCopyBeforeWriteState {
  BlockCopyState *bcs;
  BdrvChild *target;
+OnCbwError on_cbw_error;
  
  /*

   * @lock: protects access to @access_bitmap, @done_bitmap and
@@ -65,6 +66,14 @@ typedef struct BDRVCopyBeforeWriteState {
   * node. These areas must not be rewritten by guest.
   */
  BlockReqList frozen_read_reqs;
+
+/*
+ * @snapshot_error is normally zero. But on first copy-before-write failure
+ * when @on_cbw_error == ON_CBW_ERROR_BREAK_SNAPSHOT, @snapshot_error takes
+ * value of this error (<0). After that all in-flight and further
+ * snaoshot-API requests will fail with that error.


*snapshot


+ */
+int snapshot_error;
  } BDRVCopyBeforeWriteState;
  
  static coroutine_fn int cbw_co_preadv(

@@ -99,11 +108,25 @@ static coroutine_fn int 
cbw_do_copy_before_write(BlockDriverState *bs,
  end = QEMU_ALIGN_UP(offset + bytes, cluster_size);


Wouldn’t it make sense to completely cease CBW if snapshot_error is 
non-zero?  (I.e. always returning 0 here, skipping block_copy().) You 
can’t read from it anyway anymore.  (Except from below the 
copy-before-write node, but users shouldn’t be doing this, because they 
can’t know which areas are valid to read and which aren’t.)



  ret = block_copy(s->bcs, off, end - off, true);
-if (ret < 0) {
+if (ret < 0 && s->on_cbw_error == ON_CBW_ERROR_BREAK_GUEST_WRITE) {
  return ret;
  }
  
  WITH_QEMU_LOCK_GUARD(&s->lock) {

+if (ret < 0) {
+assert(s->on_cbw_error == ON_CBW_ERROR_BREAK_SNAPSHOT);
+if (!s->snapshot_error) {
+s->snapshot_error = ret;
+}
+/*
+ * No need to wait for s->frozen_read_reqs: they will fail anyway,
+ * as s->snapshot_error is set.
+ *
+ * We return 0, as error is handled. Guest operation should be
+ * continued.
+ */
+return 0;


Hm, OK.  Naively, it looks to me like we could save us this explanation 
and simplify the code just by unconditionally waiting here (I guess we 
could skip the wait if snapshot_error was non-zero before) and not 
checking snapshot_error in cbw_snapshot_read_unlock().  I don’t think 
not waiting here meaningfully saves time.



+}
  bdrv_set_dirty_bitmap(s->done_bitmap, off, end - off);
  reqlist_wait_all(&s->frozen_read_reqs, off, end - off, &s->lock);
  }
@@ -176,6 +199,11 @@ static BlockReq *cbw_snapshot_read_lock(BlockDriverState 
*bs,
  
  QEMU_LOCK_GUARD(&s->lock);
  
+if (s->snapshot_error) {

+g_free(req);
+return NULL;
+}
+
  if (bdrv_dirty_bitmap_next_zero(s->access_bitmap, offset, bytes) != -1) {
  g_free(req);
  return NULL;
@@ -198,19 +226,26 @@ static BlockReq *cbw_snapshot_read_lock(BlockDriverState 
*bs,
  return req;
  }
  
-static void cbw_snapshot_read_unlock(BlockDriverState *bs, BlockReq *req)

+static int cbw_snapshot_read_unlock(BlockDriverState *bs, BlockReq *req)
  {
  BDRVCopyBeforeWriteState *s = bs->opaque;
  
  if (req->offset == -1 && req->bytes == -1) {

  g_free(req);
-return;
+/*
+ * No real need to read snapshot_error under mutex here: we are 
actually
+ * safe to ignore it and return 0, as this request was to s->target, 
and
+ * can't be influenced by guest write. But if we can new read negative
+ * s->snapshot_error let's return it, so that backup failed earlier.
+ */
+return s->snapshot_error;
  }
  
  QEMU_LOCK_GUARD(&s->lock);
  
  reqlist_remove_req(req);

  g_free(req);
+return s->snapshot_error;
  }
  
  static coroutine_fn int

@@ -219,7 +254,7 @@ cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t 
offset, int64_t bytes,
  {
  BlockReq *req;
  BdrvChild *file;
-int ret;
+int ret, ret2;
  
  /* TODO: upgrade to async loop using AioTask */


Re: [PATCH v2 1/7] block/copy-before-write: refactor option parsing

2022-04-01 Thread Vladimir Sementsov-Ogievskiy

01.04.2022 13:50, Hanna Reitz wrote:

On 01.04.22 11:19, Vladimir Sementsov-Ogievskiy wrote:

We are going to add one more option of enum type. Let's refactor option
parsing so that we can simply work with BlockdevOptionsCbw object.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
  block/copy-before-write.c | 68 +++
  1 file changed, 41 insertions(+), 27 deletions(-)

diff --git a/block/copy-before-write.c b/block/copy-before-write.c
index a8a06fdc09..394e73b094 100644
--- a/block/copy-before-write.c
+++ b/block/copy-before-write.c
@@ -24,6 +24,7 @@
   */
  #include "qemu/osdep.h"
+#include "qapi/qmp/qjson.h"
  #include "sysemu/block-backend.h"
  #include "qemu/cutils.h"
@@ -328,46 +329,49 @@ static void cbw_child_perm(BlockDriverState *bs, 
BdrvChild *c,
  }
  }
-static bool cbw_parse_bitmap_option(QDict *options, BdrvDirtyBitmap **bitmap,
-    Error **errp)
+static BlockdevOptionsCbw *cbw_parse_options(QDict *options, Error **errp)
  {
-    QDict *bitmap_qdict = NULL;
-    BlockDirtyBitmap *bmp_param = NULL;
+    QDict *cbw_qdict = NULL;
+    BlockdevOptionsCbw *opts = NULL;
  Visitor *v = NULL;
-    bool ret = false;
-    *bitmap = NULL;
+    cbw_qdict = qdict_clone_shallow(options);
-    qdict_extract_subqdict(options, &bitmap_qdict, "bitmap.");
-    if (!qdict_size(bitmap_qdict)) {
-    ret = true;
-    goto out;
-    }
-
-    v = qobject_input_visitor_new_flat_confused(bitmap_qdict, errp);
+    /*
+ * Delete BlockdevOptions base fields, that are not part of
+ * BlockdevOptionsCbw.
+ */
+    qdict_del(cbw_qdict, "driver");
+    qdict_del(cbw_qdict, "node-name");
+    qdict_del(cbw_qdict, "discard");
+    qdict_del(cbw_qdict, "cache");
+    qdict_extract_subqdict(cbw_qdict, NULL, "cache.");
+    qdict_del(cbw_qdict, "read-only");
+    qdict_del(cbw_qdict, "auto-read-only");
+    qdict_del(cbw_qdict, "force-share");
+    qdict_del(cbw_qdict, "detect-zeroes");


Works in practice now, but seems a bit fragile.  If new fields are added to the 
base class, this will break.  (And I don’t know whether people will think of 
updating this when new fields are added to the base class.)

Would there be a problem if instead we parsed the full BlockdevOptions object 
here, asserting that .driver is BLOCKDEV_DRIVER_COPY_BEFORE_WRITE?


Hmm. Thanks! Yes there is a problem with it,  as some options are already absorbed in 
bdrv_open_common(). But good news is that the only necessary absorbed option is 
"driver".

So, instead of asserting .driver, we temporary add "driver"="copy-before-write" 
into options, and then we can natively parse them as BlockdevOptions.

The following works for me (applied on the top of the series), will merge into 
v3:



diff --git a/block/copy-before-write.c b/block/copy-before-write.c
index 0ea5506f77..3d6c9fc055 100644
--- a/block/copy-before-write.c
+++ b/block/copy-before-write.c
@@ -375,40 +375,25 @@ static void cbw_child_perm(BlockDriverState *bs, 
BdrvChild *c,
 }
 }
 
-static BlockdevOptionsCbw *cbw_parse_options(QDict *options, Error **errp)

+static BlockdevOptions *cbw_parse_options(QDict *options, Error **errp)
 {
-QDict *cbw_qdict = NULL;
-BlockdevOptionsCbw *opts = NULL;
+BlockdevOptions *opts = NULL;
 Visitor *v = NULL;
 
-cbw_qdict = qdict_clone_shallow(options);

+qdict_put_str(options, "driver", "copy-before-write");
 
-/*

- * Delete BlockdevOptions base fields, that are not part of
- * BlockdevOptionsCbw.
- */
-qdict_del(cbw_qdict, "driver");
-qdict_del(cbw_qdict, "node-name");
-qdict_del(cbw_qdict, "discard");
-qdict_del(cbw_qdict, "cache");
-qdict_extract_subqdict(cbw_qdict, NULL, "cache.");
-qdict_del(cbw_qdict, "read-only");
-qdict_del(cbw_qdict, "auto-read-only");
-qdict_del(cbw_qdict, "force-share");
-qdict_del(cbw_qdict, "detect-zeroes");
-
-v = qobject_input_visitor_new_flat_confused(cbw_qdict, errp);
+v = qobject_input_visitor_new_flat_confused(options, errp);
 if (!v) {
 goto out;
 }
 
-visit_type_BlockdevOptionsCbw(v, NULL, &opts, errp);

+visit_type_BlockdevOptions(v, NULL, &opts, errp);
 if (!opts) {
 goto out;
 }
 
 /*

- * Delete options which we are going to parse through BlockdevOptionsCbw
+ * Delete options which we are going to parse through BlockdevOptions
  * object for original options.
  */
 qdict_extract_subqdict(options, NULL, "bitmap");
@@ -417,7 +402,7 @@ static BlockdevOptionsCbw *cbw_parse_options(QDict 
*options, Error **errp)
 
 out:

 visit_free(v);
-qobject_unref(cbw_qdict);
+qdict_del(options, "driver");
 
 return opts;

 }
@@ -428,12 +413,14 @@ static int cbw_open(BlockDriverState *bs, QDict *options, 
int flags,
 BDRVCopyBeforeWriteState *s = bs->opaque;
 BdrvDirtyBitmap *bitmap = NULL;
 int64_t cluster_size;
-g_autoptr(BlockdevOptionsCbw) opts = NULL;
+g

Re: [PATCH] intel-iommu: correct the value used for error_setg_errno()

2022-04-01 Thread Peter Xu
On Fri, Apr 01, 2022 at 10:28:24AM +0800, Jason Wang wrote:
> error_setg_errno() expects a normal errno value, not a negated
> one, so we should use ENOTSUP instead of -ENOSUP.
> 
> Fixes: Coverity CID 1487174
> Fixes: ("intel_iommu: support snoop control")
> Signed-off-by: Jason Wang 

Reviewed-by: Peter Xu 

-- 
Peter Xu




Re: [PATCH v2 2/7] block/copy-before-write: add on-cbw-error open parameter

2022-04-01 Thread Vladimir Sementsov-Ogievskiy

01.04.2022 14:58, Hanna Reitz wrote:

On 01.04.22 11:19, Vladimir Sementsov-Ogievskiy wrote:

Currently, behavior on copy-before-write operation failure is simple:
report error to the guest.

Let's implement alternative behavior: break the whole copy-before-write
process (and corresponding backup job or NBD client) but keep guest
working. It's needed if we consider guest stability as more important.

The realisation is simple: on copy-before-write failure we immediately
continue guest write operation and set s->snapshot_ret variable which
will lead to all further and in-flight snapshot-API requests failure.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
  block/copy-before-write.c | 62 ++-
  qapi/block-core.json  | 27 -
  2 files changed, 81 insertions(+), 8 deletions(-)

diff --git a/block/copy-before-write.c b/block/copy-before-write.c
index 394e73b094..0614c3d08b 100644
--- a/block/copy-before-write.c
+++ b/block/copy-before-write.c
@@ -41,6 +41,7 @@
  typedef struct BDRVCopyBeforeWriteState {
  BlockCopyState *bcs;
  BdrvChild *target;
+    OnCbwError on_cbw_error;
  /*
   * @lock: protects access to @access_bitmap, @done_bitmap and
@@ -65,6 +66,14 @@ typedef struct BDRVCopyBeforeWriteState {
   * node. These areas must not be rewritten by guest.
   */
  BlockReqList frozen_read_reqs;
+
+    /*
+ * @snapshot_error is normally zero. But on first copy-before-write failure
+ * when @on_cbw_error == ON_CBW_ERROR_BREAK_SNAPSHOT, @snapshot_error takes
+ * value of this error (<0). After that all in-flight and further
+ * snaoshot-API requests will fail with that error.


*snapshot


+ */
+    int snapshot_error;
  } BDRVCopyBeforeWriteState;
  static coroutine_fn int cbw_co_preadv(
@@ -99,11 +108,25 @@ static coroutine_fn int 
cbw_do_copy_before_write(BlockDriverState *bs,
  end = QEMU_ALIGN_UP(offset + bytes, cluster_size);


Wouldn’t it make sense to completely cease CBW if snapshot_error is non-zero?  
(I.e. always returning 0 here, skipping block_copy().) You can’t read from it 
anyway anymore.  (Except from below the copy-before-write node, but users 
shouldn’t be doing this, because they can’t know which areas are valid to read 
and which aren’t.)


Agree, will do.




  ret = block_copy(s->bcs, off, end - off, true);
-    if (ret < 0) {
+    if (ret < 0 && s->on_cbw_error == ON_CBW_ERROR_BREAK_GUEST_WRITE) {
  return ret;
  }
  WITH_QEMU_LOCK_GUARD(&s->lock) {
+    if (ret < 0) {
+    assert(s->on_cbw_error == ON_CBW_ERROR_BREAK_SNAPSHOT);
+    if (!s->snapshot_error) {
+    s->snapshot_error = ret;
+    }
+    /*
+ * No need to wait for s->frozen_read_reqs: they will fail anyway,
+ * as s->snapshot_error is set.
+ *
+ * We return 0, as error is handled. Guest operation should be
+ * continued.
+ */
+    return 0;


Hm, OK.  Naively, it looks to me like we could save us this explanation and 
simplify the code just by unconditionally waiting here (I guess we could skip 
the wait if snapshot_error was non-zero before) and not checking snapshot_error 
in cbw_snapshot_read_unlock().  I don’t think not waiting here meaningfully 
saves time.


Hmm. I tend to agree, this optimization doesn't seem to worth the complexity. 
Will drop it, we can implement it later if really needed.




+    }
  bdrv_set_dirty_bitmap(s->done_bitmap, off, end - off);
  reqlist_wait_all(&s->frozen_read_reqs, off, end - off, &s->lock);
  }
@@ -176,6 +199,11 @@ static BlockReq *cbw_snapshot_read_lock(BlockDriverState 
*bs,
  QEMU_LOCK_GUARD(&s->lock);
+    if (s->snapshot_error) {
+    g_free(req);
+    return NULL;
+    }
+
  if (bdrv_dirty_bitmap_next_zero(s->access_bitmap, offset, bytes) != -1) {
  g_free(req);
  return NULL;
@@ -198,19 +226,26 @@ static BlockReq *cbw_snapshot_read_lock(BlockDriverState 
*bs,
  return req;
  }
-static void cbw_snapshot_read_unlock(BlockDriverState *bs, BlockReq *req)
+static int cbw_snapshot_read_unlock(BlockDriverState *bs, BlockReq *req)
  {
  BDRVCopyBeforeWriteState *s = bs->opaque;
  if (req->offset == -1 && req->bytes == -1) {
  g_free(req);
-    return;
+    /*
+ * No real need to read snapshot_error under mutex here: we are 
actually
+ * safe to ignore it and return 0, as this request was to s->target, 
and
+ * can't be influenced by guest write. But if we can new read negative
+ * s->snapshot_error let's return it, so that backup failed earlier.
+ */
+    return s->snapshot_error;
  }
  QEMU_LOCK_GUARD(&s->lock);
  reqlist_remove_req(req);
  g_free(req);
+    return s->snapshot_error;
  }
  static coroutine_fn int
@@ -219,7 +254,7 @@ cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t 
offs

[PATCH v3] hw/riscv: virt: Exit if the user provided -bios in combination with KVM

2022-04-01 Thread Ralf Ramsauer
The -bios option is silently ignored if used in combination with -enable-kvm.
The reason is that the machine starts in S-Mode, and the bios typically runs in
M-Mode.

Better exit in that case to not confuse the user.

Signed-off-by: Ralf Ramsauer 
---
 hw/riscv/virt.c | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index da50cbed43..09609c96e8 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1308,12 +1308,18 @@ static void virt_machine_init(MachineState *machine)
 
 /*
  * Only direct boot kernel is currently supported for KVM VM,
- * so the "-bios" parameter is ignored and treated like "-bios none"
- * when KVM is enabled.
+ * so the "-bios" parameter is not supported when KVM is enabled.
  */
 if (kvm_enabled()) {
-g_free(machine->firmware);
-machine->firmware = g_strdup("none");
+if (machine->firmware) {
+if (strcmp(machine->firmware, "none")) {
+error_report("Machine mode firmware is not supported in "
+ "combination with KVM.");
+exit(1);
+}
+} else {
+machine->firmware = g_strdup("none");
+}
 }
 
 if (riscv_is_32bit(&s->soc[0])) {
-- 
2.32.0




[PATCH] target/riscv: Fix incorrect PTE merge in walk_pte

2022-04-01 Thread Ralf Ramsauer
Two non-subsequent PTEs can be mapped to subsequent paddrs. In this
case, walk_pte will erroneously merge them.

Enforce the split up, by tracking the virtual base address.

Let's say we have the mapping:
0x8120 -> 0x89623000 (4K)
0x8120f000 -> 0x89624000 (4K)

Before, walk_pte would have shown:

vaddrpaddrsize attr
   ---
8120 89623000 2000 rwxu-ad

as it only checks for subsequent paddrs. With this patch, it becomes:

vaddrpaddrsize attr
   ---
8120 89623000 1000 rwxu-ad
8120f000 89624000 1000 rwxu-ad

Signed-off-by: Ralf Ramsauer 
---
 target/riscv/monitor.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c
index 7efb4b62c1..60e3edd0ad 100644
--- a/target/riscv/monitor.c
+++ b/target/riscv/monitor.c
@@ -84,6 +84,7 @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong 
start,
 {
 hwaddr pte_addr;
 hwaddr paddr;
+target_ulong last_start = -1;
 target_ulong pgsize;
 target_ulong pte;
 int ptshift;
@@ -116,13 +117,15 @@ static void walk_pte(Monitor *mon, hwaddr base, 
target_ulong start,
  * contiguous mapped block details.
  */
 if ((*last_attr != attr) ||
-(*last_paddr + *last_size != paddr)) {
+(*last_paddr + *last_size != paddr) ||
+(last_start + *last_size != start)) {
 print_pte(mon, va_bits, *vbase, *pbase,
   *last_paddr + *last_size - *pbase, *last_attr);
 
 *vbase = start;
 *pbase = paddr;
 *last_attr = attr;
+last_start = start;
 }
 
 *last_paddr = paddr;
-- 
2.35.1




Re: [PATCH v2] target/riscv: Call probe_write() before atomic operations

2022-04-01 Thread Richard Henderson

On 3/31/22 19:49, Alistair Francis wrote:

+void helper_atomic_check(CPURISCVState *env, target_ulong address,
+ int mmu_idx)
+{
+#ifndef CONFIG_USER_ONLY
+void *phost;
+int ret = probe_access_flags(env, address, MMU_DATA_STORE, mmu_idx, false,
+ &phost, GETPC());
+
+if (ret & TLB_MMIO) {
+env->amo_store_fault = true;
+}
+#endif
+}


You've got to turn this off somewhere too.

I've got a better solution for you, using TARGET_INSN_START_EXTRA_WORDS, which will handle 
I/O regions as well.  I'll send it separately in a minute.



r~



[PATCH 0/2] target/riscv: Annotate atomic operations

2022-04-01 Thread Richard Henderson
If an atomic operation fails on RISC-V, we want to generate
a store/amo fault and not a load fault.

Annotate amo insns, so that we can recognize them after unwinding.
Transform the implementation access type to store/amo for reporting.


r~


Richard Henderson (2):
  target/riscv: Use cpu_loop_exit_restore directly from mmu faults
  target/riscv: Mark amo insns during translation

 target/riscv/cpu.h  | 15 ++
 target/riscv/cpu.c  |  3 ++
 target/riscv/cpu_helper.c   | 62 +
 target/riscv/translate.c|  9 
 target/riscv/insn_trans/trans_rva.c.inc | 11 -
 5 files changed, 79 insertions(+), 21 deletions(-)

-- 
2.25.1




[PATCH 1/2] target/riscv: Use cpu_loop_exit_restore directly from mmu faults

2022-04-01 Thread Richard Henderson
The riscv_raise_exception function stores its argument into
exception_index and then exits to the main loop.  When we
have already set exception_index, we can just exit directly.

Signed-off-by: Richard Henderson 
---
 target/riscv/cpu_helper.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 1c60fb2e80..126251d5da 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -1150,7 +1150,7 @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr 
physaddr,
 env->badaddr = addr;
 env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
 riscv_cpu_two_stage_lookup(mmu_idx);
-riscv_raise_exception(&cpu->env, cs->exception_index, retaddr);
+cpu_loop_exit_restore(cs, retaddr);
 }
 
 void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
@@ -1175,7 +1175,7 @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr 
addr,
 env->badaddr = addr;
 env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
 riscv_cpu_two_stage_lookup(mmu_idx);
-riscv_raise_exception(env, cs->exception_index, retaddr);
+cpu_loop_exit_restore(cs, retaddr);
 }
 
 bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
@@ -1311,7 +1311,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 first_stage_error,
 riscv_cpu_virt_enabled(env) ||
 riscv_cpu_two_stage_lookup(mmu_idx));
-riscv_raise_exception(env, cs->exception_index, retaddr);
+cpu_loop_exit_restore(cs, retaddr);
 }
 
 return true;
-- 
2.25.1




[PATCH 2/2] target/riscv: Mark amo insns during translation

2022-04-01 Thread Richard Henderson
Atomic memory operations perform both reads and writes as part
of their implementation, but always raise write faults.

Use TARGET_INSN_START_EXTRA_WORDS to mark amo insns in the
opcode stream, and force the access type to write at the
point of raising the exception.

Signed-off-by: Richard Henderson 
---
 target/riscv/cpu.h  | 15 ++
 target/riscv/cpu.c  |  3 ++
 target/riscv/cpu_helper.c   | 62 +
 target/riscv/translate.c|  9 
 target/riscv/insn_trans/trans_rva.c.inc | 11 -
 5 files changed, 79 insertions(+), 21 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index c069fe85fa..3de4da3fa1 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -290,6 +290,13 @@ struct CPUArchState {
 /* True if in debugger mode.  */
 bool debugger;
 
+/*
+ * True if unwinding through an amo insn.  Used to transform a
+ * read fault into a store_amo fault; only valid immediately
+ * after cpu_restore_state().
+ */
+bool unwind_amo;
+
 /*
  * CSRs for PointerMasking extension
  */
@@ -517,6 +524,14 @@ FIELD(TB_FLAGS, XL, 20, 2)
 FIELD(TB_FLAGS, PM_MASK_ENABLED, 22, 1)
 FIELD(TB_FLAGS, PM_BASE_ENABLED, 23, 1)
 
+#ifndef CONFIG_USER_ONLY
+/*
+ * RISC-V-specific extra insn start words:
+ * 1: True if the instruction is AMO, false otherwise.
+ */
+#define TARGET_INSN_START_EXTRA_WORDS 1
+#endif
+
 #ifdef TARGET_RISCV32
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
 #else
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index ddda4906ff..3818d5ba80 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -396,6 +396,9 @@ void restore_state_to_opc(CPURISCVState *env, 
TranslationBlock *tb,
 } else {
 env->pc = data[0];
 }
+#ifndef CONFIG_USER_ONLY
+env->unwind_amo = data[1];
+#endif
 }
 
 static void riscv_cpu_reset(DeviceState *dev)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 126251d5da..b5bbe6fc39 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -1139,26 +1139,11 @@ void riscv_cpu_do_transaction_failed(CPUState *cs, 
hwaddr physaddr,
 RISCVCPU *cpu = RISCV_CPU(cs);
 CPURISCVState *env = &cpu->env;
 
-if (access_type == MMU_DATA_STORE) {
-cs->exception_index = RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
-} else if (access_type == MMU_DATA_LOAD) {
-cs->exception_index = RISCV_EXCP_LOAD_ACCESS_FAULT;
-} else {
-cs->exception_index = RISCV_EXCP_INST_ACCESS_FAULT;
+cpu_restore_state(cs, retaddr, true);
+if (env->unwind_amo) {
+access_type = MMU_DATA_STORE;
 }
 
-env->badaddr = addr;
-env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
-riscv_cpu_two_stage_lookup(mmu_idx);
-cpu_loop_exit_restore(cs, retaddr);
-}
-
-void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
-   MMUAccessType access_type, int mmu_idx,
-   uintptr_t retaddr)
-{
-RISCVCPU *cpu = RISCV_CPU(cs);
-CPURISCVState *env = &cpu->env;
 switch (access_type) {
 case MMU_INST_FETCH:
 cs->exception_index = RISCV_EXCP_INST_ADDR_MIS;
@@ -1172,10 +1157,43 @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr 
addr,
 default:
 g_assert_not_reached();
 }
+
 env->badaddr = addr;
 env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
 riscv_cpu_two_stage_lookup(mmu_idx);
-cpu_loop_exit_restore(cs, retaddr);
+cpu_loop_exit(cs);
+}
+
+void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
+   MMUAccessType access_type, int mmu_idx,
+   uintptr_t retaddr)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = &cpu->env;
+
+cpu_restore_state(cs, retaddr, true);
+if (env->unwind_amo) {
+access_type = MMU_DATA_STORE;
+}
+
+switch (access_type) {
+case MMU_INST_FETCH:
+cs->exception_index = RISCV_EXCP_INST_ADDR_MIS;
+break;
+case MMU_DATA_LOAD:
+cs->exception_index = RISCV_EXCP_LOAD_ADDR_MIS;
+break;
+case MMU_DATA_STORE:
+cs->exception_index = RISCV_EXCP_STORE_AMO_ADDR_MIS;
+break;
+default:
+g_assert_not_reached();
+}
+
+env->badaddr = addr;
+env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
+riscv_cpu_two_stage_lookup(mmu_idx);
+cpu_loop_exit(cs);
 }
 
 bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
@@ -1307,11 +1325,15 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, 
int size,
 } else if (probe) {
 return false;
 } else {
+cpu_restore_state(cs, retaddr, true);
+if (env->unwind_amo) {
+access_type = MMU_DATA_STORE;
+}
 raise_mmu_exception(env, address, access_type, pmp_viol

Re: [PATCH v2] tests/migration: Introduce dirty-ring-size option into guestperf

2022-04-01 Thread Hyman Huang

Hi, Daniel.
Sorry to bother you, but i have a request of you.
I'm posting a simple patch of Qemu guestperf test to support dirty 
ring migration test. I'm very pleased if you could spare some time to 
review it and even give some advices.


Yong

在 2022/3/16 21:39, huang...@chinatelecom.cn 写道:

From: Hyman Huang(黄勇) 

Guestperf tool does not enable diry ring feature when test
migration by default.

To support dirty ring migration performance test, introduce
dirty-ring-size option into guestperf tools, which ranges in
[1024, 65536].

To set dirty ring size with 4096 during migration test:
$ ./tests/migration/guestperf.py --dirty-ring-size 4096 xxx

Signed-off-by: Hyman Huang(黄勇) 
---
  tests/migration/guestperf/engine.py   | 6 +-
  tests/migration/guestperf/hardware.py | 8 ++--
  tests/migration/guestperf/shell.py| 7 ++-
  3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/tests/migration/guestperf/engine.py 
b/tests/migration/guestperf/engine.py
index 87a6ab2..3d3f6bd 100644
--- a/tests/migration/guestperf/engine.py
+++ b/tests/migration/guestperf/engine.py
@@ -304,7 +304,6 @@ def _get_common_args(self, hardware, tunnelled=False):
  cmdline = "'" + cmdline + "'"
  
  argv = [

-"-accel", "kvm",
  "-cpu", "host",
  "-kernel", self._kernel,
  "-initrd", self._initrd,
@@ -315,6 +314,11 @@ def _get_common_args(self, hardware, tunnelled=False):
  "-smp", str(hardware._cpus),
  ]
  
+if hardware._dirty_ring_size:

+argv.extend(["-accel", "kvm,dirty-ring-size=%s" % 
hardware._dirty_ring_size])
+else:
+argv.extend(["-accel", "kvm"])
+
  if self._debug:
  argv.extend(["-device", "sga"])
  
diff --git a/tests/migration/guestperf/hardware.py b/tests/migration/guestperf/hardware.py

index 3145785..f779cc0 100644
--- a/tests/migration/guestperf/hardware.py
+++ b/tests/migration/guestperf/hardware.py
@@ -23,7 +23,8 @@ def __init__(self, cpus=1, mem=1,
   src_cpu_bind=None, src_mem_bind=None,
   dst_cpu_bind=None, dst_mem_bind=None,
   prealloc_pages = False,
- huge_pages=False, locked_pages=False):
+ huge_pages=False, locked_pages=False,
+ dirty_ring_size=0):
  self._cpus = cpus
  self._mem = mem # GiB
  self._src_mem_bind = src_mem_bind # List of NUMA nodes
@@ -33,6 +34,7 @@ def __init__(self, cpus=1, mem=1,
  self._prealloc_pages = prealloc_pages
  self._huge_pages = huge_pages
  self._locked_pages = locked_pages
+self._dirty_ring_size = dirty_ring_size
  
  
  def serialize(self):

@@ -46,6 +48,7 @@ def serialize(self):
  "prealloc_pages": self._prealloc_pages,
  "huge_pages": self._huge_pages,
  "locked_pages": self._locked_pages,
+"dirty_ring_size": self._dirty_ring_size,
  }
  
  @classmethod

@@ -59,4 +62,5 @@ def deserialize(cls, data):
  data["dst_mem_bind"],
  data["prealloc_pages"],
  data["huge_pages"],
-data["locked_pages"])
+data["locked_pages"],
+data["dirty_ring_size"])
diff --git a/tests/migration/guestperf/shell.py 
b/tests/migration/guestperf/shell.py
index 8a809e3..f87bce6 100644
--- a/tests/migration/guestperf/shell.py
+++ b/tests/migration/guestperf/shell.py
@@ -60,6 +60,8 @@ def __init__(self):
  parser.add_argument("--prealloc-pages", dest="prealloc_pages", 
default=False)
  parser.add_argument("--huge-pages", dest="huge_pages", default=False)
  parser.add_argument("--locked-pages", dest="locked_pages", 
default=False)
+parser.add_argument("--dirty-ring-size", dest="dirty_ring_size", 
default=0,
+type=int)
  
  self._parser = parser
  
@@ -89,7 +91,10 @@ def split_map(value):
  
  locked_pages=args.locked_pages,

  huge_pages=args.huge_pages,
-prealloc_pages=args.prealloc_pages)
+prealloc_pages=args.prealloc_pages,
+
+dirty_ring_size=args.dirty_ring_size)
+
  
  
  class Shell(BaseShell):


--
Best regard

Hyman Huang(黄勇)



Re: [RFC PATCH 0/4] hw/i2c: i2c slave mode support

2022-04-01 Thread Corey Minyard
On Fri, Apr 01, 2022 at 08:29:03AM +0200, Klaus Jensen wrote:
> On Mar 31 15:32, Corey Minyard wrote:
> > On Thu, Mar 31, 2022 at 06:57:33PM +0200, Klaus Jensen wrote:
> > > From: Klaus Jensen 
> > > 
> > > Hi all,
> > > 
> > > This RFC series adds I2C "slave mode" support for the Aspeed I2C
> > > controller as well as the necessary infrastructure in the i2c core to
> > > support this.
> > 
> > I've been wondering when this would happen :).  I had put some thought
> > into how this would work, but hadn't come up with anything good.
> > 
> > The big disadvantage of this is you are adding an interface that is
> > incompatible with the current masters and slaves.  So you are using the
> > same I2C bus, but slaves written this way cannot talk to existing
> > masters, and masters written this way cannot talk to existing slave.
> > You could adapt the masters to be able to work either way, and I suppose
> > some slaves that could do it could have both an async send and a normal
> > send. 
> 
> Would it make sense to introduce a QOM Interface to differentiate
> between the slave/master types?

Yes, that would be a good idea, as Damien said.  You will have a type
that is capable of both for both sync and async for the master and the
slave, then types that are capable of one sync and async so the code
can sort out what can talk to what.

> 
> > But you could not adapt a slave device for the Aspeed to do both.
> 
> Exactly, the Aspeed must be able to defer the ack, so it cannot
> implement send(). Even if it buffered up the write, I don't think it
> would be correct to Ack the transfer until the host has Acked it.
> 
> > But that said, I don't know of a better way to handle this.
> > 
> > You don't have the ability to nack a byte in what you have currently.
> > That's probably something that will be needed.
> 
> True. Didn't consider that. Since the ack is basically defined as the
> scheduling of the bh, I guess I have to come up with something where I
> can also pass a "return value".
> 
> > 
> > This is obviously not something useful by itself.  How do you plan to
> > tie this in to something else that would use it?
> > 
> 
> This is specifically for implementing an NVMe-MI device which uses MCTP
> transactions (in which both requests and replies are master->slave
> transfers). I just wanted to get a feel for how you maintaines would
> envision this begin done before posting that. The NVMe-MI device will
> function exactly like the example i2c echo device (i.e. receive an MCTP
> transaction using the normal i2c slave interface, parse the
> transaction/request, master the bus and start a new transfer).

Ok, so you aren't planning to add some sort of interface that would
allow a net connection to hook up as an I2C master.

Someone submitted something a while ago for doing an I2C slave that way,
but there were some issues and nothing came of it.  It's tricky to do
because it has to be non-blocking.

IIRC, there was also some work that allowed two emulations to go on at a
time in a qemu instance, that could allow a BMC and a main processor to
run together.  This might be useful in that scenario.  My question was
really just more curiousity, wondering what else is coming in the
future.

Thanks,

-corey



Re: use of uninitialized variable involving visit_type_uint32() and friends

2022-04-01 Thread Markus Armbruster
Paolo Bonzini  writes:

> On 4/1/22 11:15, Markus Armbruster wrote:
>>   +assert (v->type == expected_type);
>>   +if (expected_type & (VISITOR_INPUT | VISITOR_DEALLOC)) {
>> 
>> Backwards.
>
> Yes, I always get input vs output wrong.

Output becomes input becomes output.  How not to be confused!

>> With an input visitor @v,
>> 
>>  visit_type_uint32(v, "name", &val, errp)
>> 
>> stores to @val without looking at it first.  In other words,
>> uninitialized @val is fine, just like for val = ...
>> 
>> Note: you don't actually need VISITOR_DEALLOC here, because a
>> deallocation visitor isn't going to do anything for non-pointer values.
>
> There's a philosophical question on whether other deallocation visitors 
> can exist than "the" deallocation visitor, but it's not particularly 
> germane to the topic.

Agreed.  Same for "the" clone visitor.

>> Two changes:
>> 
>> * Skip copying to and from full-width buffer @value:
>> 
>>- Skip @value = *obj when we're going to overwrite @value without
>>  reading it first.
>> 
>>  This leaves @value uninitialized instead of initializing it from a
>>  (commonly) uninitialized variable.
>> 
>>  I'm not sure how this helps static analysis, but if it does...
>
> If it can do really serious interprocedural analysis, it _might_ be able 
> to see through the visitor constructor and know that the "value = *obj" 
> is not initialized (e.g. "all callers of object_property_set use an 
> input visitor").  I doubt that honestly, but a man can dream.

I'm wary of arguments based on "a sufficiently smart compiler can"...

> If the conditionals are enough to shut it up, then we won the battle 
> (for now).

If they get us more milage per unit of work out of Coverity, I'm in
favor.  I'll want a comment explaining the conditionals, though.

> If the conditionals are not enough to shut it up, then you have a bit 
> more confidence when marking the false positives.
>
>>- Skip *obj = @value when value must be *obj anyway.
>> 
>>  Should have no observable effect.
>> 
>>  Again, I'm not sure how this helps static analysis.
>
> Mostly consistency, could also be changed to an assert(*obj == value); 
> /* output visitors don't really need obj to be passed by reference */

I guess whatever is easier to explain in a comment.

>> * Pass visitor type in addition to the visitor.  Can you explain why
>>that's useful?
>
> Because it communicates what the caller expects: "I have left this 
> uninitialized because I expect my "v" argument to be the kind of visitor 
> that fills it in".  It's this argument that gives me the confidence 
> needed to shut up Coverity's false positives.
>
> Embedding the visitor type in the signature makes it impossible not to 
> pass it, unlike e.g. an assertion in every getter or setter.

I think we got two kinds of code calling visitor methods:

1. Code for use with one kind of visitor only

   We get to pass a literal argument to the additional parameter you
   propose.

2. Code for use with arbitrary visitors (such as qapi-visit*.c)

   We need to pass v->type, where @v is the existing visitor argument.
   Except we can't: struct Visitor and VisitorType are private, defined
   in .  Easy enough to work around, but has a distinct
   "this design is falling apart" smell, at least to me.

Note that "intent explicit in every method call" is sufficient, but not
necessary for "intent is locally explicit, which lets us dismiss false
positives with confidence".  We could do "every function that calls
methods".  Like checking a precondition.  We already have
visit_is_input().  We could have visit_is_output().

The sane way to make output intent explicit is of course passing the
thing by value rather than by reference.  To get that, we could generate
even more code.  So, if the amount of code we currently generate isn't
disgusting enough, ...




Re: [PATCH v5 0/9] Add support for AST1030 SoC

2022-04-01 Thread Cédric Le Goater

On 4/1/22 11:47, Jamin Lin wrote:

Hi Cedric,
One more question, what is the progress about SFDP patch, 
https://patchwork.kernel.org/project/qemu-devel/list/?series=342081&archive=both
We need these patches for future SPI support.


Francisco had comments I didn't have time to address. Theses were mostly
related to how the table entries are defined. I can respin and see what
we can do.

Anyhow, the series is still in use in the aspeed branch :

  https://github.com/legoater/qemu/commits/aspeed-7.0

We really needed it when SFDP support was introduced in the Linux kernel.
There were plenty of issues with the 4B opcodes usage.

Thanks,

C.



Thanks-Jamin

* Email Confidentiality Notice 
DISCLAIMER:
This message (and any attachments) may contain legally privileged and/or other 
confidential information. If you have received it in error, please notify the 
sender by reply e-mail and immediately delete the e-mail and any attachments 
without copying or disclosing the contents. Thank you.

-Original Message-
From: Jamin Lin 
Sent: Friday, April 1, 2022 5:24 PM
To: Cédric Le Goater ; Alistair Francis ; Peter Maydell ; Andrew 
Jeffery ; Joel Stanley ; Cleber Rosa ; Philippe Mathieu-Daudé 
; Wainer dos Santos Moschetta ; Beraldo Leal ; open list:STM32F205 
; open list:All patches CC here ; Jamin Lin 
Cc: Steven Lee ; Troy Lee 
Subject: RE: [PATCH v5 0/9] Add support for AST1030 SoC

Hi Cedric, Joel and Andrew
First all, thanks for all your kindly support and review. We are so glad that 
QEMU v7.1 will support AST1030 model.

1. The ast1030 and ast2600 HACE controller are identical.
   Steven submitted the patch to support HACE ACC mode. Once his patch accept. 
We will submit patch to support ast1030 model.
2. I submitted the patch to support GOIO index mode because ast1030 driver was 
implement by index mode. I am waiting for review and any suggestion will be 
appreciated.
3. Troy submitted the patch to support I2C new model which included ast1030 
model.
4. As for NIC plan, once AST1030 NIC driver ready, we will upstream, too.
BTW, do you have a plan to upstream it, 
https://github.com/openbmc/qemu/blob/master/hw/misc/aspeed_pwm.c

Thanks again - Jamin

* Email Confidentiality Notice 
DISCLAIMER:
This message (and any attachments) may contain legally privileged and/or other 
confidential information. If you have received it in error, please notify the 
sender by reply e-mail and immediately delete the e-mail and any attachments 
without copying or disclosing the contents. Thank you.

-Original Message-
From: Cédric Le Goater 
Sent: Friday, April 1, 2022 4:55 PM
To: Jamin Lin ; Alistair Francis ; Peter Maydell ; 
Andrew Jeffery ; Joel Stanley ; Cleber Rosa ; Philippe Mathieu-Daudé 
; Wainer dos Santos Moschetta ; Beraldo Leal ; open list:STM32F205 
; open list:All patches CC here 
Cc: Steven Lee ; Troy Lee 
Subject: Re: [PATCH v5 0/9] Add support for AST1030 SoC

Hello Jamin,

Thanks for these new models and machine. They are queued for QEMU 7.1.
There are a couple of patchsets adding support for the AST1030 GPIO controller 
and the I2C new mode that would be good extensions but they need review first.

What are the next steps? any plans for network ? The NIC should be a
FTGMAC100 if I am correct.

Thanks,

C.


   On 4/1/22 10:38, Jamin Lin wrote:

Changes from v5:
- remove TYPE_ASPEED_MINIBMC_MACHINE and ASPEED_MINIBMC_MACHINE
- remove ast1030_machine_instance_init function

Changes from v4:
- drop the ASPEED_SMC_FEATURE_WDT_CONTROL flag in hw/ssi/aspeed_smc.c

Changes from v3:
- remove AspeedMiniBmcMachineState state structure and
AspeedMiniBmcMachineClass class
- remove redundant new line in hw/arm/aspeed_ast10xx.c
- drop the ASPEED_SMC_FEATURE_WDT_CONTROL flag in hw/ssi/aspeed_smc.c

Changes from v2:
- replace aspeed_ast1030.c with aspeed_ast10xx.c for minibmc SOCs
family support
- Add "ast1030-evb" machine in aspeed.c and removes aspeed_minibmc.c

Changes from v1:
The patch series supports ADC, SCU, SMC, TIMER, and WDT for AST1030 SoC.
Add avocado test case for "ast1030-evb" machine.

Test steps:
1. Download image from
 
https://github.com/AspeedTech-BMC/zephyr/releases/download/v00.01.04/a

st1030-evb-demo.zip 2. Extract the zip file to obtain zephyr.elf 3.
Run ./qemu-system-arm -M ast1030-evb -kernel $PATH/zephyr.elf
-nographic 4. Test IO by Zephyr command line, commands are refer to Aspeed 
Zephyr
 SDK User Guide below
 
https://github.com/AspeedTech-BMC/zephyr/releases/download/v00.01.04/Aspeed_Zephy_SDK_User_Guide_v00.01.04.pdf
 - ADC(channel 0):
 uart:~$ adc ADC0 resolution 10
 uart:~$ adc ADC0 calibrate 1
 uart:~$ adc ADC0 read_format 1
 uart:~$ adc ADC0 read 0
 [Result]
 read: 1416mv

 - SCU
 uart:~$ md 7e6e2040
 uart:~$ md 7e6e2080
 uart:~$ md 7e6e20d0
 uart:~$ md 7e6e2200
 uart:~$ md 7e6e2300
 uart:~

Re: [PATCH] target/riscv: Fix incorrect PTE merge in walk_pte

2022-04-01 Thread Richard Henderson

On 4/1/22 06:22, Ralf Ramsauer wrote:

Two non-subsequent PTEs can be mapped to subsequent paddrs. In this
case, walk_pte will erroneously merge them.

Enforce the split up, by tracking the virtual base address.

Let's say we have the mapping:
0x8120 -> 0x89623000 (4K)
0x8120f000 -> 0x89624000 (4K)

Before, walk_pte would have shown:

vaddrpaddrsize attr
   ---
8120 89623000 2000 rwxu-ad

as it only checks for subsequent paddrs. With this patch, it becomes:

vaddrpaddrsize attr
   ---
8120 89623000 1000 rwxu-ad
8120f000 89624000 1000 rwxu-ad

Signed-off-by: Ralf Ramsauer
---
  target/riscv/monitor.c | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 4/7] util: add qemu-co-timeout

2022-04-01 Thread Hanna Reitz

On 01.04.22 11:19, Vladimir Sementsov-Ogievskiy wrote:

Add new API, to make a time limited call of the coroutine.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
  include/qemu/coroutine.h | 13 ++
  util/meson.build |  1 +
  util/qemu-co-timeout.c   | 89 
  3 files changed, 103 insertions(+)
  create mode 100644 util/qemu-co-timeout.c


I don’t really understand what this does.  Intuitively, I would have 
assumed this makes the first yield of the respective coroutine not 
return when the timeout has elapsed, and instead, we switch back to 
qemu_co_timeout(), which returns to its callers.


But it looks like when this yield happens and we switch back to 
qemu_co_timeout(), the coroutine actually isn’t cancelled, and will just 
continue running, actually.  Is that right?  On first look, this looks 
like it’ll be quite difficult to think about what happens when this is 
used, because the coroutine in question is no longer run in sequence 
with its caller, but actually might run in parallel (even though it’s 
still a coroutine, so it’ll remain cooperative multitasking).





Re: [PATCH v2 5/7] block/block-copy: block_copy(): add timeout_ns parameter

2022-04-01 Thread Hanna Reitz

On 01.04.22 11:19, Vladimir Sementsov-Ogievskiy wrote:

Add possibility to limit block_copy() call in time. To be used in the
next commit.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
  block/block-copy.c | 26 +++---
  block/copy-before-write.c  |  2 +-
  include/block/block-copy.h |  2 +-
  3 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/block/block-copy.c b/block/block-copy.c
index ec46775ea5..b47cb188dd 100644
--- a/block/block-copy.c
+++ b/block/block-copy.c


[...]


@@ -894,12 +902,16 @@ int coroutine_fn block_copy(BlockCopyState *s, int64_t 
start, int64_t bytes,
  .max_workers = BLOCK_COPY_MAX_WORKERS,
  };
  
-return block_copy_common(&call_state);

-}
+ret = qemu_co_timeout(block_copy_async_co_entry, call_state, timeout_ns,
+  g_free);


A direct path for timeout_ns == 0 might still be nice to have.


+if (ret < 0) {
+/* Timeout. call_state will be freed by running coroutine. */


Maybe assert(ret == -ETIMEDOUT);?


+return ret;


If I’m right in understanding how qemu_co_timeout() works, 
block_copy_common() will continue to run here.  Shouldn’t we at least 
cancel it by setting call_state->cancelled to true?


(Besides this, I think that letting block_copy_common() running in the 
background should be OK.  I’m not sure what the implications are if we 
do cancel the call here, while on-cbw-error is break-guest-write, 
though.  Should be fine, I guess, because block_copy_common() will still 
correctly keep track of what it has successfully copied and what it hasn’t?)



+}
  
-static void coroutine_fn block_copy_async_co_entry(void *opaque)

-{
-block_copy_common(opaque);
+ret = call_state->ret;
+
+return ret;


But here we still need to free call_state, right?


  }
  
  BlockCopyCallState *block_copy_async(BlockCopyState *s,





  1   2   3   >