Re: [PATCH v3 19/34] spapr: Add return value to spapr_irq_check()

2019-10-01 Thread Cédric Le Goater
On 02/10/2019 04:51, David Gibson wrote:
> Explicitly return success or failure, rather than just relying on the
> Error ** parameter.  This makes handling it less verbose in the caller.
> 
> Signed-off-by: David Gibson 


Reviewed-by: Cédric Le Goater 
> ---
>  hw/ppc/spapr_irq.c | 15 +++
>  1 file changed, 7 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 3ac67ba0c7..0413fbd0a3 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -529,7 +529,7 @@ SpaprIrq spapr_irq_dual = {
>  };
>  
>  
> -static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
> +static int spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>  {
>  MachineState *machine = MACHINE(spapr);
>  
> @@ -545,7 +545,7 @@ static void spapr_irq_check(SpaprMachineState *spapr, 
> Error **errp)
>   */
>  if (spapr->irq == _irq_dual) {
>  spapr->irq = _irq_xics;
> -return;
> +return 0;
>  }
>  
>  /*
> @@ -565,7 +565,7 @@ static void spapr_irq_check(SpaprMachineState *spapr, 
> Error **errp)
>   */
>  if (spapr->irq == _irq_xive) {
>  error_setg(errp, "XIVE-only machines require a POWER9 CPU");
> -return;
> +return -1;
>  }
>  }
>  
> @@ -579,8 +579,10 @@ static void spapr_irq_check(SpaprMachineState *spapr, 
> Error **errp)
>  machine_kernel_irqchip_required(machine) &&
>  xics_kvm_has_broken_disconnect(spapr)) {
>  error_setg(errp, "KVM is too old to support 
> ic-mode=dual,kernel-irqchip=on");
> -return;
> +return -1;
>  }
> +
> +return 0;
>  }
>  
>  /*
> @@ -589,7 +591,6 @@ static void spapr_irq_check(SpaprMachineState *spapr, 
> Error **errp)
>  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  {
>  MachineState *machine = MACHINE(spapr);
> -Error *local_err = NULL;
>  
>  if (machine_kernel_irqchip_split(machine)) {
>  error_setg(errp, "kernel_irqchip split mode not supported on 
> pseries");
> @@ -602,9 +603,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error 
> **errp)
>  return;
>  }
>  
> -spapr_irq_check(spapr, _err);
> -if (local_err) {
> -error_propagate(errp, local_err);
> +if (spapr_irq_check(spapr, errp) < 0) {
>  return;
>  }
>  
> 




Re: [PATCH v3 15/34] spapr: Handle freeing of multiple irqs in frontend only

2019-10-01 Thread Cédric Le Goater
On 02/10/2019 04:51, David Gibson wrote:
> spapr_irq_free() can be used to free multiple irqs at once. That's useful
> for its callers, but there's no need to make the individual backend hooks
> handle this.  We can loop across the irqs in spapr_irq_free() itself and
> have the hooks just do one at time.
> 
> Signed-off-by: David Gibson 


Reviewed-by: Cédric Le Goater 
> ---
>  hw/ppc/spapr_irq.c | 27 ---
>  include/hw/ppc/spapr_irq.h |  2 +-
>  2 files changed, 13 insertions(+), 16 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 9919910a86..d2ac35bbe1 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -133,16 +133,13 @@ static int spapr_irq_claim_xics(SpaprMachineState 
> *spapr, int irq, bool lsi,
>  return 0;
>  }
>  
> -static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq, int num)
> +static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq)
>  {
>  ICSState *ics = spapr->ics;
>  uint32_t srcno = irq - ics->offset;
> -int i;
>  
>  if (ics_valid_irq(ics, irq)) {
> -for (i = srcno; i < srcno + num; ++i) {
> -memset(>irqs[i], 0, sizeof(ICSIRQState));
> -}
> +memset(>irqs[srcno], 0, sizeof(ICSIRQState));
>  }
>  }
>  
> @@ -269,13 +266,9 @@ static int spapr_irq_claim_xive(SpaprMachineState 
> *spapr, int irq, bool lsi,
>  return 0;
>  }
>  
> -static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq, int num)
> +static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
>  {
> -int i;
> -
> -for (i = irq; i < irq + num; ++i) {
> -spapr_xive_irq_free(spapr->xive, i);
> -}
> +spapr_xive_irq_free(spapr->xive, irq);
>  }
>  
>  static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
> @@ -433,10 +426,10 @@ static int spapr_irq_claim_dual(SpaprMachineState 
> *spapr, int irq, bool lsi,
>  return ret;
>  }
>  
> -static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq, int num)
> +static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq)
>  {
> -spapr_irq_xics.free(spapr, irq, num);
> -spapr_irq_xive.free(spapr, irq, num);
> +spapr_irq_xics.free(spapr, irq);
> +spapr_irq_xive.free(spapr, irq);
>  }
>  
>  static void spapr_irq_print_info_dual(SpaprMachineState *spapr, Monitor *mon)
> @@ -635,7 +628,11 @@ int spapr_irq_claim(SpaprMachineState *spapr, int irq, 
> bool lsi, Error **errp)
>  
>  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
>  {
> -spapr->irq->free(spapr, irq, num);
> +int i;
> +
> +for (i = irq; i < (irq + num); i++) {
> +spapr->irq->free(spapr, i);
> +}
>  }
>  
>  qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index 9b60378e28..ed88b4599a 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -43,7 +43,7 @@ typedef struct SpaprIrq {
>  
>  void (*init)(SpaprMachineState *spapr, Error **errp);
>  int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
> -void (*free)(SpaprMachineState *spapr, int irq, int num);
> +void (*free)(SpaprMachineState *spapr, int irq);
>  void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
>  void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
>  void *fdt, uint32_t phandle);
> 




Re: [PATCH v3 01/34] xics: Minor fixes for XICSFabric interface

2019-10-01 Thread David Gibson
On Wed, Oct 02, 2019 at 07:51:45AM +0200, Cédric Le Goater wrote:
> On 02/10/2019 04:51, David Gibson wrote:
> > Interface instances should never be directly dereferenced.  So, the common
> > practice is to make them incomplete types to make sure no-one does that.
> > XICSFrabric, however, had a dummy type which is less safe.
> > 
> > We were also using OBJECT_CHECK() where we should have been using
> > INTERFACE_CHECK().
> > 
> > Signed-off-by: David Gibson 
> > Reviewed-by: Greg Kurz 
> 
> Reviewed-by: Greg Kurz 

Uhhh... you sent me an R-b line for Greg, not yourself...

> 
> > ---
> >  include/hw/ppc/xics.h | 6 +-
> >  1 file changed, 1 insertion(+), 5 deletions(-)
> > 
> > diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> > index 64a2c8862a..faa33ae943 100644
> > --- a/include/hw/ppc/xics.h
> > +++ b/include/hw/ppc/xics.h
> > @@ -147,13 +147,9 @@ struct ICSIRQState {
> >  uint8_t flags;
> >  };
> >  
> > -struct XICSFabric {
> > -Object parent;
> > -};
> > -
> >  #define TYPE_XICS_FABRIC "xics-fabric"
> >  #define XICS_FABRIC(obj) \
> > -OBJECT_CHECK(XICSFabric, (obj), TYPE_XICS_FABRIC)
> > +INTERFACE_CHECK(XICSFabric, (obj), TYPE_XICS_FABRIC)
> >  #define XICS_FABRIC_CLASS(klass) \
> >  OBJECT_CLASS_CHECK(XICSFabricClass, (klass), TYPE_XICS_FABRIC)
> >  #define XICS_FABRIC_GET_CLASS(obj)   \
> > 
> 

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [PATCH v3 01/34] xics: Minor fixes for XICSFabric interface

2019-10-01 Thread Cédric Le Goater
On 02/10/2019 07:51, Cédric Le Goater wrote:
> On 02/10/2019 04:51, David Gibson wrote:
>> Interface instances should never be directly dereferenced.  So, the common
>> practice is to make them incomplete types to make sure no-one does that.
>> XICSFrabric, however, had a dummy type which is less safe.
>>
>> We were also using OBJECT_CHECK() where we should have been using
>> INTERFACE_CHECK().
>>
>> Signed-off-by: David Gibson 
>> Reviewed-by: Greg Kurz 
> 
> Reviewed-by: Greg Kurz 

pfff ...

Reviewed-by: Cédric Le Goater 

> 
>> ---
>>  include/hw/ppc/xics.h | 6 +-
>>  1 file changed, 1 insertion(+), 5 deletions(-)
>>
>> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
>> index 64a2c8862a..faa33ae943 100644
>> --- a/include/hw/ppc/xics.h
>> +++ b/include/hw/ppc/xics.h
>> @@ -147,13 +147,9 @@ struct ICSIRQState {
>>  uint8_t flags;
>>  };
>>  
>> -struct XICSFabric {
>> -Object parent;
>> -};
>> -
>>  #define TYPE_XICS_FABRIC "xics-fabric"
>>  #define XICS_FABRIC(obj) \
>> -OBJECT_CHECK(XICSFabric, (obj), TYPE_XICS_FABRIC)
>> +INTERFACE_CHECK(XICSFabric, (obj), TYPE_XICS_FABRIC)
>>  #define XICS_FABRIC_CLASS(klass) \
>>  OBJECT_CLASS_CHECK(XICSFabricClass, (klass), TYPE_XICS_FABRIC)
>>  #define XICS_FABRIC_GET_CLASS(obj)   \
>>
> 
> 




Re: [PULL 0/8] Ide patches

2019-10-01 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20191001235552.17790-1-js...@redhat.com/



Hi,

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

Type: series
Message-id: 20191001235552.17790-1-js...@redhat.com
Subject: [PULL 0/8] Ide patches

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
1f9b401 hd-geo-test: Add tests for lchs override
7bfdda4 bootdevice: FW_CFG interface for LCHS values
b6feb64 bootdevice: Refactor get_boot_devices_list
ab60aa0 bootdevice: Gather LCHS from all relevant devices
e12a839 scsi: Propagate unrealize() callback to scsi-hd
e6f21f3 bootdevice: Add interface to gather LCHS
40120f4 block: Support providing LCHS from user
adcf56d block: Refactor macros - fix tabbing

=== OUTPUT BEGIN ===
1/8 Checking commit adcf56d080c9 (block: Refactor macros - fix tabbing)
ERROR: Macros with complex values should be enclosed in parenthesis
#57: FILE: include/hw/block/block.h:65:
+#define DEFINE_BLOCK_CHS_PROPERTIES(_state, _conf)  \
+DEFINE_PROP_UINT32("cyls", _state, _conf.cyls, 0),  \
+DEFINE_PROP_UINT32("heads", _state, _conf.heads, 0),\
 DEFINE_PROP_UINT32("secs", _state, _conf.secs, 0)

total: 1 errors, 0 warnings, 37 lines checked

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

2/8 Checking commit 40120f44b44f (block: Support providing LCHS from user)
3/8 Checking commit e6f21f35debf (bootdevice: Add interface to gather LCHS)
4/8 Checking commit e12a839d2b12 (scsi: Propagate unrealize() callback to 
scsi-hd)
5/8 Checking commit ab60aa0f51a5 (bootdevice: Gather LCHS from all relevant 
devices)
6/8 Checking commit b6feb64ebaef (bootdevice: Refactor get_boot_devices_list)
7/8 Checking commit 7bfdda4eaaf4 (bootdevice: FW_CFG interface for LCHS values)
8/8 Checking commit 1f9b401195bc (hd-geo-test: Add tests for lchs override)
WARNING: Block comments use a leading /* on a separate line
#650: FILE: tests/hd-geo-test.c:1003:
+   "skipping hd-geo/override/* tests");

total: 0 errors, 1 warnings, 616 lines checked

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

Test command exited with code: 1


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

Re: [PATCH v3 01/34] xics: Minor fixes for XICSFabric interface

2019-10-01 Thread Cédric Le Goater
On 02/10/2019 04:51, David Gibson wrote:
> Interface instances should never be directly dereferenced.  So, the common
> practice is to make them incomplete types to make sure no-one does that.
> XICSFrabric, however, had a dummy type which is less safe.
> 
> We were also using OBJECT_CHECK() where we should have been using
> INTERFACE_CHECK().
> 
> Signed-off-by: David Gibson 
> Reviewed-by: Greg Kurz 

Reviewed-by: Greg Kurz 

> ---
>  include/hw/ppc/xics.h | 6 +-
>  1 file changed, 1 insertion(+), 5 deletions(-)
> 
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index 64a2c8862a..faa33ae943 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -147,13 +147,9 @@ struct ICSIRQState {
>  uint8_t flags;
>  };
>  
> -struct XICSFabric {
> -Object parent;
> -};
> -
>  #define TYPE_XICS_FABRIC "xics-fabric"
>  #define XICS_FABRIC(obj) \
> -OBJECT_CHECK(XICSFabric, (obj), TYPE_XICS_FABRIC)
> +INTERFACE_CHECK(XICSFabric, (obj), TYPE_XICS_FABRIC)
>  #define XICS_FABRIC_CLASS(klass) \
>  OBJECT_CLASS_CHECK(XICSFabricClass, (klass), TYPE_XICS_FABRIC)
>  #define XICS_FABRIC_GET_CLASS(obj)   \
> 




Re: [PATCH v3 15/34] spapr: Handle freeing of multiple irqs in frontend only

2019-10-01 Thread Greg Kurz
On Wed,  2 Oct 2019 12:51:49 +1000
David Gibson  wrote:

> spapr_irq_free() can be used to free multiple irqs at once. That's useful
> for its callers, but there's no need to make the individual backend hooks
> handle this.  We can loop across the irqs in spapr_irq_free() itself and
> have the hooks just do one at time.
> 
> Signed-off-by: David Gibson 
> ---
>  hw/ppc/spapr_irq.c | 27 ---
>  include/hw/ppc/spapr_irq.h |  2 +-
>  2 files changed, 13 insertions(+), 16 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 9919910a86..d2ac35bbe1 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -133,16 +133,13 @@ static int spapr_irq_claim_xics(SpaprMachineState 
> *spapr, int irq, bool lsi,
>  return 0;
>  }
>  
> -static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq, int num)
> +static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq)
>  {
>  ICSState *ics = spapr->ics;
>  uint32_t srcno = irq - ics->offset;
> -int i;
>  
>  if (ics_valid_irq(ics, irq)) {
> -for (i = srcno; i < srcno + num; ++i) {
> -memset(>irqs[i], 0, sizeof(ICSIRQState));
> -}
> +memset(>irqs[srcno], 0, sizeof(ICSIRQState));
>  }
>  }
>  
> @@ -269,13 +266,9 @@ static int spapr_irq_claim_xive(SpaprMachineState 
> *spapr, int irq, bool lsi,
>  return 0;
>  }
>  
> -static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq, int num)
> +static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
>  {
> -int i;
> -
> -for (i = irq; i < irq + num; ++i) {
> -spapr_xive_irq_free(spapr->xive, i);
> -}
> +spapr_xive_irq_free(spapr->xive, irq);
>  }
>  
>  static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
> @@ -433,10 +426,10 @@ static int spapr_irq_claim_dual(SpaprMachineState 
> *spapr, int irq, bool lsi,
>  return ret;
>  }
>  
> -static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq, int num)
> +static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq)
>  {
> -spapr_irq_xics.free(spapr, irq, num);
> -spapr_irq_xive.free(spapr, irq, num);
> +spapr_irq_xics.free(spapr, irq);
> +spapr_irq_xive.free(spapr, irq);
>  }
>  
>  static void spapr_irq_print_info_dual(SpaprMachineState *spapr, Monitor *mon)
> @@ -635,7 +628,11 @@ int spapr_irq_claim(SpaprMachineState *spapr, int irq, 
> bool lsi, Error **errp)
>  
>  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
>  {
> -spapr->irq->free(spapr, irq, num);
> +int i;
> +
> +for (i = irq; i < (irq + num); i++) {
> +spapr->irq->free(spapr, i);

It is indeed a lot better than passing irq :)

Reviewed-by: Greg Kurz 

> +}
>  }
>  
>  qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index 9b60378e28..ed88b4599a 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -43,7 +43,7 @@ typedef struct SpaprIrq {
>  
>  void (*init)(SpaprMachineState *spapr, Error **errp);
>  int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
> -void (*free)(SpaprMachineState *spapr, int irq, int num);
> +void (*free)(SpaprMachineState *spapr, int irq);
>  void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
>  void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
>  void *fdt, uint32_t phandle);




Re: [PATCH v5 1/5] iotests: remove 'linux' from default supported platforms

2019-10-01 Thread Thomas Huth
On 01/10/2019 20.44, Max Reitz wrote:
[...]
> As I have said, the conceptual problem is that the iotests now run as
> part of make check.  As such, allowing auto tests to run on non-Linux
> platforms may introduce build failures that I cannot do anything about.

Well, simply run "make vm-build-openbsd", "make vm-build-freebsd", ...
if something fails there, it likely should not be in the auto group.

> And those are very much new failures.
> 
>> I think that I have demonstrated sufficiently that it's not correct to
>> prohibit python tests from running on other platforms wholesale, so I'd
>> prefer we don't do that anymore.
> 
> You have not.
> 
> The actual argument to convince me is “This does not affect any tests in
> the auto group, so it will not introduce build failures at this time”.

I've applied the patch here and it works fine with FreeBSD and macOS:

 https://cirrus-ci.com/build/5169384718336000
 https://travis-ci.com/huth/qemu/builds/129968676

It also works fine with "make vm-build-openbsd BUILD_TARGET=check-block"
... so I think you don't have to worry here.

>> Further, iotests on FreeBSD already weren't 100% green, so I'm not
>> causing a regression in that sense, either.
> 
> My problem is twofold:
> 
> (1) You claim “Sure, there are failures, but let’s just deal with them”
> and then you do not deal with them.  Seems wrong to me.
> 
> I’m fine with the argument “Sorry, royal ‘we’.  But it just doesn’t help
> anyone to hide the errors.  If someone’s on BSD and wants to run the
> iotests, let them.”
> 
> That sounds good to me.
> 
> (2) Maybe someone adds a Python test in the future that is in auto and
> that does not specify Linux as the only supported platform.  Then I send
> a pull request and it breaks on macOS.  Now what?  Remove it from auto?
>  Blindly put "macOS" in unsupported platforms?

I think both solutions are good. If a test does not work on all systems,
it either should not be in the "auto" group, or it needs to be modified
to skip testing when running in an unsupported environment.

> In any case, it’ll be a problem for no good reason.

Really? Is "more test coverage" not a good reason?

> More on that in the next chunk.
> 
>> I'm going to meekly push and ask that we stage this as-is, and when
>> something bad happens you can remind me that I wanted this and make me
>> do it.
> 
> Make you do what?  Deal with the fact that a pull request is rejected
> because a test fails on macOS?
> 
> This is precisely the kind of problem I already had with adding the
> iotests to make check, and I’m already very much not happy about it.
> (In that case it was $DISPLAY not being set on Peter’s test system.)
> 
> I’ll let you make the deduction of “The problem isn’t allowing the
> iotests to run on non-Linux platforms, but the fact that they run in
> make check” yourself, so that I no longer feel like I’m the only one who
> considers that having been a mistake.

Max, I can understand that you are a little bit annoyed that this "make
check with iotests" caused some extra hurdles for you. But honestly,
removing that again would be quite egoistic by you. Try to put yourself
into the position of a "normal", non-blocklayer-maintainer QEMU
developer. For me, iotests were a *constant* source of frustration.
Often, when I ran them on top of my latest and greatest patches, to
check whether I caused a regression, the iotests simply failed. Then I
had to start debugging - did my patches cause the break, or is "master"
broken, too? In almost all cases, there was an issue in the master
branch already, either because they were failing on s390x, or because I
was using ext4 instead of xfs, or because I was using an older distro
than you, etc... . So while the iotests likely worked fine for the
limited set of systems that you, Kevin and the other hard-core block
layer developers are using, it's constantly broken for everybody else
who is not using the very same setup as you. The only way of *not*
getting upset about the iotests was to simply completely *ignore* them.
Is it that what you want?

Or maybe let me phrase it differently: Do you consider the iotests as
something that is more or less "private" to the hard-core block layer
developers, and it's ok if others completely ignore them and break them
by accident (and you also don't expect the normal developers to fix the
iotests afterwards)? Then sure, please go ahead and remove the iotests
from "make check" again. Maybe I just understood the idea of having
common tests in the repository wrong (or maybe the iotests should be
moved to a separate repository instead, so that the normal QEMU
developers do not get in touch with them anymore?) ... Otherwise, I
think it was the right step to add them "make check" so that everybody
now *has* to run at least a basic set of the iotests now before they can
their patches merged.

 Thomas


PS: Sorry, if my mail sounded a little bit harsh... but I really had
quite some frustration with the iotests in the past 

Re: [PATCH 00/97] Patch Round-up for stable 4.0.1, freeze on 2019-10-10

2019-10-01 Thread Thomas Huth
On 02/10/2019 01.44, Michael Roth wrote:
> Hi everyone,  
> 
> 
> The following new patches are queued for QEMU stable v4.0.1:
> 
>   https://github.com/mdroth/qemu/commits/stable-4.0-staging
> 
> The release is planned for 2019-10-17:
> 
>   https://wiki.qemu.org/Planning/4.0
> 
> Please respond here or CC qemu-sta...@nongnu.org on any patches you
> think should be included in the release.
>
Would it make sense to include the slirp update:

 e1a4a24d262ba5ac74ea1795adb3ab1cd574c7fb
 "slirp: update with CVE-2019-14378 fix"

?

And maybe these commits:

 22235bb609c18547cf6b215bad1f9d2ec56ad371
 "pc-dimm: fix crash when invalid slot number is used"

 95667c3be0c9f5fc62f58fe845879250f63f7d32
 "nvme: Set number of queues later in nvme_init()"

 c0bccee9b40ec58c9d165b406ae3d4f63652ce53
 "hw/ssi/mss-spi: Avoid crash when reading empty RX FIFO"

 a09ef5040477643a7026703199d8781fe048d3a8
 "hw/display/xlnx_dp: Avoid crash when reading empty RX FIFO"

Thomas



[PATCH v3 30/34] spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate

2019-10-01 Thread David Gibson
It turns out that all the logic in the SpaprIrq::reset hooks (and some in
the SpaprIrq::post_load hooks) isn't really related to resetting the irq
backend (that's handled by the backends' own reset routines).  Rather its
about getting the backend ready to be the active interrupt controller or
stopping being the active interrupt controller - reset (and post_load) is
just the only time that changes at present.

To make this flow clearer, move the logic into the explicit backend
activate and deactivate hooks.

Signed-off-by: David Gibson 
---
 hw/intc/spapr_xive.c   | 35 
 hw/intc/xics_spapr.c   | 16 +
 hw/ppc/spapr_irq.c | 67 ++
 include/hw/ppc/spapr_irq.h |  4 ++-
 4 files changed, 57 insertions(+), 65 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 37ffb74ca5..e8b946982c 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -640,6 +640,39 @@ static void spapr_xive_dt(SpaprInterruptController *intc, 
uint32_t nr_servers,
  plat_res_int_priorities, 
sizeof(plat_res_int_priorities)));
 }
 
+static void spapr_xive_activate(SpaprInterruptController *intc, Error **errp)
+{
+SpaprXive *xive = SPAPR_XIVE(intc);
+CPUState *cs;
+
+CPU_FOREACH(cs) {
+PowerPCCPU *cpu = POWERPC_CPU(cs);
+
+/* (TCG) Set the OS CAM line of the thread interrupt context. */
+spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx);
+}
+
+if (kvm_enabled()) {
+if (spapr_irq_init_kvm(kvmppc_xive_connect, intc, errp) < 0) {
+return;
+}
+}
+
+/* Activate the XIVE MMIOs */
+spapr_xive_mmio_set_enabled(xive, true);
+}
+
+static void spapr_xive_deactivate(SpaprInterruptController *intc)
+{
+SpaprXive *xive = SPAPR_XIVE(intc);
+
+spapr_xive_mmio_set_enabled(xive, false);
+
+if (kvm_irqchip_in_kernel()) {
+kvmppc_xive_disconnect(intc);
+}
+}
+
 static void spapr_xive_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -658,6 +691,8 @@ static void spapr_xive_class_init(ObjectClass *klass, void 
*data)
 xrc->write_nvt = spapr_xive_write_nvt;
 xrc->get_tctx = spapr_xive_get_tctx;
 
+sicc->activate = spapr_xive_activate;
+sicc->deactivate = spapr_xive_deactivate;
 sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
 sicc->claim_irq = spapr_xive_claim_irq;
 sicc->free_irq = spapr_xive_free_irq;
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 4eabafc7e1..8abbc799ba 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -395,6 +395,20 @@ static void xics_spapr_print_info(SpaprInterruptController 
*intc, Monitor *mon)
 ics_pic_print_info(ics, mon);
 }
 
+static void xics_spapr_activate(SpaprInterruptController *intc, Error **errp)
+{
+if (kvm_enabled()) {
+spapr_irq_init_kvm(xics_kvm_connect, intc, errp);
+}
+}
+
+static void xics_spapr_deactivate(SpaprInterruptController *intc)
+{
+if (kvm_irqchip_in_kernel()) {
+xics_kvm_disconnect(intc);
+}
+}
+
 static void ics_spapr_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -403,6 +417,8 @@ static void ics_spapr_class_init(ObjectClass *klass, void 
*data)
 
 device_class_set_parent_realize(dc, ics_spapr_realize,
 >parent_realize);
+sicc->activate = xics_spapr_activate;
+sicc->deactivate = xics_spapr_deactivate;
 sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
 sicc->claim_irq = xics_spapr_claim_irq;
 sicc->free_irq = xics_spapr_free_irq;
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 7cd18e5b15..f70b331f44 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -65,9 +65,9 @@ void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, 
uint32_t num)
 bitmap_clear(spapr->irq_map, irq - SPAPR_IRQ_MSI, num);
 }
 
-static int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
-  SpaprInterruptController *intc,
-  Error **errp)
+int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
+   SpaprInterruptController *intc,
+   Error **errp)
 {
 MachineState *machine = MACHINE(qdev_get_machine());
 Error *local_err = NULL;
@@ -112,11 +112,6 @@ static int spapr_irq_post_load_xics(SpaprMachineState 
*spapr, int version_id)
 return 0;
 }
 
-static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
-{
-spapr_irq_init_kvm(xics_kvm_connect, SPAPR_INTC(spapr->ics), errp);
-}
-
 SpaprIrq spapr_irq_xics = {
 .nr_xirqs= SPAPR_NR_XIRQS,
 .nr_msis = SPAPR_NR_MSIS,
@@ -124,7 +119,6 @@ SpaprIrq spapr_irq_xics = {
 .xive= false,
 
 .post_load   = spapr_irq_post_load_xics,
-.reset   = spapr_irq_reset_xics,
 };
 
 /*
@@ -136,26 +130,6 @@ static int 

[PATCH v3 29/34] spapr: Remove SpaprIrq::init_kvm hook

2019-10-01 Thread David Gibson
This hook is a bit odd.  The only caller is spapr_irq_init_kvm(), but
it explicitly takes an SpaprIrq *, so it's never really called through the
current SpaprIrq.  Essentially this is just a way of passing through a
function pointer so that spapr_irq_init_kvm() can handle some
configuration and error handling logic without duplicating it between the
xics and xive reset paths.

So, make it just take that function pointer.  Because of earlier reworks
to the KVM connect/disconnect code in the xics and xive backends we can
also eliminate some wrapper functions and streamline error handling a bit.

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
Reviewed-by: Cédric Le Goater 
---
 hw/ppc/spapr_irq.c | 74 +-
 include/hw/ppc/spapr_irq.h |  1 -
 2 files changed, 25 insertions(+), 50 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 5c8ffb27da..7cd18e5b15 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -65,33 +65,35 @@ void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, 
uint32_t num)
 bitmap_clear(spapr->irq_map, irq - SPAPR_IRQ_MSI, num);
 }
 
-static void spapr_irq_init_kvm(SpaprMachineState *spapr,
-  SpaprIrq *irq, Error **errp)
+static int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
+  SpaprInterruptController *intc,
+  Error **errp)
 {
-MachineState *machine = MACHINE(spapr);
+MachineState *machine = MACHINE(qdev_get_machine());
 Error *local_err = NULL;
 
 if (kvm_enabled() && machine_kernel_irqchip_allowed(machine)) {
-irq->init_kvm(spapr, _err);
-if (local_err && machine_kernel_irqchip_required(machine)) {
-error_prepend(_err,
-  "kernel_irqchip requested but unavailable: ");
-error_propagate(errp, local_err);
-return;
-}
+if (fn(intc, _err) < 0) {
+if (machine_kernel_irqchip_required(machine)) {
+error_prepend(_err,
+  "kernel_irqchip requested but unavailable: ");
+error_propagate(errp, local_err);
+return -1;
+}
 
-if (!local_err) {
-return;
+/*
+ * We failed to initialize the KVM device, fallback to
+ * emulated mode
+ */
+error_prepend(_err,
+  "kernel_irqchip allowed but unavailable: ");
+error_append_hint(_err,
+  "Falling back to kernel-irqchip=off\n");
+warn_report_err(local_err);
 }
-
-/*
- * We failed to initialize the KVM device, fallback to
- * emulated mode
- */
-error_prepend(_err, "kernel_irqchip allowed but unavailable: ");
-error_append_hint(_err, "Falling back to kernel-irqchip=off\n");
-warn_report_err(local_err);
 }
+
+return 0;
 }
 
 /*
@@ -112,20 +114,7 @@ static int spapr_irq_post_load_xics(SpaprMachineState 
*spapr, int version_id)
 
 static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
 {
-Error *local_err = NULL;
-
-spapr_irq_init_kvm(spapr, _irq_xics, _err);
-if (local_err) {
-error_propagate(errp, local_err);
-return;
-}
-}
-
-static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
-{
-if (kvm_enabled()) {
-xics_kvm_connect(SPAPR_INTC(spapr->ics), errp);
-}
+spapr_irq_init_kvm(xics_kvm_connect, SPAPR_INTC(spapr->ics), errp);
 }
 
 SpaprIrq spapr_irq_xics = {
@@ -136,7 +125,6 @@ SpaprIrq spapr_irq_xics = {
 
 .post_load   = spapr_irq_post_load_xics,
 .reset   = spapr_irq_reset_xics,
-.init_kvm= spapr_irq_init_kvm_xics,
 };
 
 /*
@@ -151,7 +139,6 @@ static int spapr_irq_post_load_xive(SpaprMachineState 
*spapr, int version_id)
 static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
 {
 CPUState *cs;
-Error *local_err = NULL;
 
 CPU_FOREACH(cs) {
 PowerPCCPU *cpu = POWERPC_CPU(cs);
@@ -160,9 +147,8 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, 
Error **errp)
 spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx);
 }
 
-spapr_irq_init_kvm(spapr, _irq_xive, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+if (spapr_irq_init_kvm(kvmppc_xive_connect,
+   SPAPR_INTC(spapr->xive), errp) < 0) {
 return;
 }
 
@@ -170,13 +156,6 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, 
Error **errp)
 spapr_xive_mmio_set_enabled(spapr->xive, true);
 }
 
-static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
-{
-if (kvm_enabled()) {
-kvmppc_xive_connect(SPAPR_INTC(spapr->xive), errp);
-}
-}
-
 SpaprIrq spapr_irq_xive = {
 .nr_xirqs= SPAPR_NR_XIRQS,
 .nr_msis   

[PATCH v3 28/34] spapr, xics, xive: Match signatures for XICS and XIVE KVM connect routines

2019-10-01 Thread David Gibson
Both XICS and XIVE have routines to connect and disconnect KVM with
similar but not identical signatures.  This adjusts them to match
exactly, which will be useful for further cleanups later.

While we're there, we add an explicit return value to the connect path
to streamline error reporting in the callers.  We remove error
reporting the disconnect path.  In the XICS case this wasn't used at
all.  In the XIVE case the only error case was if the KVM device was
set up, but KVM didn't have the capability to do so which is pretty
obviously impossible.

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
Reviewed-by: Cédric Le Goater 
---
 hw/intc/spapr_xive_kvm.c| 22 ++
 hw/intc/xics_kvm.c  |  9 +
 hw/ppc/spapr_irq.c  | 22 +-
 include/hw/ppc/spapr_xive.h |  4 ++--
 include/hw/ppc/xics_spapr.h |  4 ++--
 5 files changed, 24 insertions(+), 37 deletions(-)

diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
index 51b334b676..08012ac7cd 100644
--- a/hw/intc/spapr_xive_kvm.c
+++ b/hw/intc/spapr_xive_kvm.c
@@ -740,8 +740,9 @@ static void *kvmppc_xive_mmap(SpaprXive *xive, int pgoff, 
size_t len,
  * All the XIVE memory regions are now backed by mappings from the KVM
  * XIVE device.
  */
-void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
+int kvmppc_xive_connect(SpaprInterruptController *intc, Error **errp)
 {
+SpaprXive *xive = SPAPR_XIVE(intc);
 XiveSource *xsrc = >source;
 Error *local_err = NULL;
 size_t esb_len = (1ull << xsrc->esb_shift) * xsrc->nr_irqs;
@@ -753,19 +754,19 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
  * rebooting under the XIVE-only interrupt mode.
  */
 if (xive->fd != -1) {
-return;
+return 0;
 }
 
 if (!kvmppc_has_cap_xive()) {
 error_setg(errp, "IRQ_XIVE capability must be present for KVM");
-return;
+return -1;
 }
 
 /* First, create the KVM XIVE device */
 xive->fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_XIVE, false);
 if (xive->fd < 0) {
 error_setg_errno(errp, -xive->fd, "XIVE: error creating KVM device");
-return;
+return -1;
 }
 
 /*
@@ -821,15 +822,17 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
 kvm_kernel_irqchip = true;
 kvm_msi_via_irqfd_allowed = true;
 kvm_gsi_direct_mapping = true;
-return;
+return 0;
 
 fail:
 error_propagate(errp, local_err);
-kvmppc_xive_disconnect(xive, NULL);
+kvmppc_xive_disconnect(intc);
+return -1;
 }
 
-void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp)
+void kvmppc_xive_disconnect(SpaprInterruptController *intc)
 {
+SpaprXive *xive = SPAPR_XIVE(intc);
 XiveSource *xsrc;
 size_t esb_len;
 
@@ -838,11 +841,6 @@ void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp)
 return;
 }
 
-if (!kvmppc_has_cap_xive()) {
-error_setg(errp, "IRQ_XIVE capability must be present for KVM");
-return;
-}
-
 /* Clear the KVM mapping */
 xsrc = >source;
 esb_len = (1ull << xsrc->esb_shift) * xsrc->nr_irqs;
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index ba90d6dc96..954c424b36 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -342,8 +342,9 @@ void ics_kvm_set_irq(ICSState *ics, int srcno, int val)
 }
 }
 
-int xics_kvm_connect(SpaprMachineState *spapr, Error **errp)
+int xics_kvm_connect(SpaprInterruptController *intc, Error **errp)
 {
+ICSState *ics = ICS_SPAPR(intc);
 int rc;
 CPUState *cs;
 Error *local_err = NULL;
@@ -413,7 +414,7 @@ int xics_kvm_connect(SpaprMachineState *spapr, Error **errp)
 }
 
 /* Update the KVM sources */
-ics_set_kvm_state(spapr->ics, _err);
+ics_set_kvm_state(ics, _err);
 if (local_err) {
 goto fail;
 }
@@ -431,11 +432,11 @@ int xics_kvm_connect(SpaprMachineState *spapr, Error 
**errp)
 
 fail:
 error_propagate(errp, local_err);
-xics_kvm_disconnect(spapr, NULL);
+xics_kvm_disconnect(intc);
 return -1;
 }
 
-void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp)
+void xics_kvm_disconnect(SpaprInterruptController *intc)
 {
 /*
  * Only on P9 using the XICS-on XIVE KVM device:
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index a8005072e6..5c8ffb27da 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -124,7 +124,7 @@ static void spapr_irq_reset_xics(SpaprMachineState *spapr, 
Error **errp)
 static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
 {
 if (kvm_enabled()) {
-xics_kvm_connect(spapr, errp);
+xics_kvm_connect(SPAPR_INTC(spapr->ics), errp);
 }
 }
 
@@ -173,7 +173,7 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, 
Error **errp)
 static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
 {
 if (kvm_enabled()) {
-kvmppc_xive_connect(spapr->xive, errp);
+

[PATCH v3 27/34] spapr, xics, xive: Move dt_populate from SpaprIrq to SpaprInterruptController

2019-10-01 Thread David Gibson
This method depends only on the active irq controller.  Now that we've
formalized the notion of active controller we can dispatch directly
through that, rather than dispatching via SpaprIrq with the dual
version having to do a second conditional dispatch.

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
---
 hw/intc/spapr_xive.c| 125 ++--
 hw/intc/xics_spapr.c|   5 +-
 hw/ppc/spapr.c  |   3 +-
 hw/ppc/spapr_irq.c  |  20 +++---
 include/hw/ppc/spapr_irq.h  |   6 +-
 include/hw/ppc/spapr_xive.h |   2 -
 include/hw/ppc/xics_spapr.h |   2 -
 7 files changed, 80 insertions(+), 83 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 700ec5c9c1..37ffb74ca5 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -578,6 +578,68 @@ static void spapr_xive_print_info(SpaprInterruptController 
*intc, Monitor *mon)
 spapr_xive_pic_print_info(xive, mon);
 }
 
+static void spapr_xive_dt(SpaprInterruptController *intc, uint32_t nr_servers,
+  void *fdt, uint32_t phandle)
+{
+SpaprXive *xive = SPAPR_XIVE(intc);
+int node;
+uint64_t timas[2 * 2];
+/* Interrupt number ranges for the IPIs */
+uint32_t lisn_ranges[] = {
+cpu_to_be32(0),
+cpu_to_be32(nr_servers),
+};
+/*
+ * EQ size - the sizes of pages supported by the system 4K, 64K,
+ * 2M, 16M. We only advertise 64K for the moment.
+ */
+uint32_t eq_sizes[] = {
+cpu_to_be32(16), /* 64K */
+};
+/*
+ * The following array is in sync with the reserved priorities
+ * defined by the 'spapr_xive_priority_is_reserved' routine.
+ */
+uint32_t plat_res_int_priorities[] = {
+cpu_to_be32(7),/* start */
+cpu_to_be32(0xf8), /* count */
+};
+
+/* Thread Interrupt Management Area : User (ring 3) and OS (ring 2) */
+timas[0] = cpu_to_be64(xive->tm_base +
+   XIVE_TM_USER_PAGE * (1ull << TM_SHIFT));
+timas[1] = cpu_to_be64(1ull << TM_SHIFT);
+timas[2] = cpu_to_be64(xive->tm_base +
+   XIVE_TM_OS_PAGE * (1ull << TM_SHIFT));
+timas[3] = cpu_to_be64(1ull << TM_SHIFT);
+
+_FDT(node = fdt_add_subnode(fdt, 0, xive->nodename));
+
+_FDT(fdt_setprop_string(fdt, node, "device_type", "power-ivpe"));
+_FDT(fdt_setprop(fdt, node, "reg", timas, sizeof(timas)));
+
+_FDT(fdt_setprop_string(fdt, node, "compatible", "ibm,power-ivpe"));
+_FDT(fdt_setprop(fdt, node, "ibm,xive-eq-sizes", eq_sizes,
+ sizeof(eq_sizes)));
+_FDT(fdt_setprop(fdt, node, "ibm,xive-lisn-ranges", lisn_ranges,
+ sizeof(lisn_ranges)));
+
+/* For Linux to link the LSIs to the interrupt controller. */
+_FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
+_FDT(fdt_setprop_cell(fdt, node, "#interrupt-cells", 2));
+
+/* For SLOF */
+_FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle));
+_FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
+
+/*
+ * The "ibm,plat-res-int-priorities" property defines the priority
+ * ranges reserved by the hypervisor
+ */
+_FDT(fdt_setprop(fdt, 0, "ibm,plat-res-int-priorities",
+ plat_res_int_priorities, 
sizeof(plat_res_int_priorities)));
+}
+
 static void spapr_xive_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -601,6 +663,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void 
*data)
 sicc->free_irq = spapr_xive_free_irq;
 sicc->set_irq = spapr_xive_set_irq;
 sicc->print_info = spapr_xive_print_info;
+sicc->dt = spapr_xive_dt;
 }
 
 static const TypeInfo spapr_xive_info = {
@@ -1601,65 +1664,3 @@ void spapr_xive_hcall_init(SpaprMachineState *spapr)
 spapr_register_hypercall(H_INT_SYNC, h_int_sync);
 spapr_register_hypercall(H_INT_RESET, h_int_reset);
 }
-
-void spapr_dt_xive(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
-   uint32_t phandle)
-{
-SpaprXive *xive = spapr->xive;
-int node;
-uint64_t timas[2 * 2];
-/* Interrupt number ranges for the IPIs */
-uint32_t lisn_ranges[] = {
-cpu_to_be32(0),
-cpu_to_be32(nr_servers),
-};
-/*
- * EQ size - the sizes of pages supported by the system 4K, 64K,
- * 2M, 16M. We only advertise 64K for the moment.
- */
-uint32_t eq_sizes[] = {
-cpu_to_be32(16), /* 64K */
-};
-/*
- * The following array is in sync with the reserved priorities
- * defined by the 'spapr_xive_priority_is_reserved' routine.
- */
-uint32_t plat_res_int_priorities[] = {
-cpu_to_be32(7),/* start */
-cpu_to_be32(0xf8), /* count */
-};
-
-/* Thread Interrupt Management Area : User (ring 3) and OS (ring 2) */
-timas[0] = cpu_to_be64(xive->tm_base +
-   XIVE_TM_USER_PAGE * (1ull << TM_SHIFT));
-

Re: [PATCH v4 00/31] error: auto propagated local_err

2019-10-01 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20191001155319.8066-1-vsement...@virtuozzo.com/



Hi,

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

Type: series
Message-id: 20191001155319.8066-1-vsement...@virtuozzo.com
Subject: [PATCH v4 00/31] error: auto propagated local_err

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
f0134cb ivshmem: Fix error_append_hint/error_prepend usage
927e8d8 PVRDMA: Fix error_append_hint/error_prepend usage
c901c43 nbd: Fix error_append_hint/error_prepend usage
a990496 Sockets: Fix error_append_hint/error_prepend usage
7e9b7be Migration: Fix error_append_hint/error_prepend usage
c37742f QOM: Fix error_append_hint/error_prepend usage
e2d8729 cmdline: Fix error_append_hint/error_prepend usage
111a147 chardev: Fix error_append_hint/error_prepend usage
7f7095d block: Fix error_append_hint/error_prepend usage
42992e2 XIVE: Fix error_append_hint/error_prepend usage
aef0d72 virtio-9p: Fix error_append_hint/error_prepend usage
fadcc18 virtio: Fix error_append_hint/error_prepend usage
0b46fe6 vhost: Fix error_append_hint/error_prepend usage
2b5a95f VFIO: Fix error_append_hint/error_prepend usage
17cff57 USB: Fix error_append_hint/error_prepend usage
b8c7bd2 SCSI: Fix error_append_hint/error_prepend usage
2833abc PCI: Fix error_append_hint/error_prepend usage
61a303e PowerNV (Non-Virtualized): Fix error_append_hint/error_prepend usage
c287bb4 Boston: Fix error_append_hint/error_prepend usage
163ff63 ASPEED BMCs: Fix error_append_hint/error_prepend usage
1eb85cb SmartFusion2: Fix error_append_hint/error_prepend usage
a29bb2d arm: Fix error_append_hint/error_prepend usage
af781f2 PowerPC TCG CPUs: Fix error_append_hint/error_prepend usage
00ceb2b ARM TCG CPUs: Fix error_append_hint/error_prepend usage
a8ac50c s390: Fix error_append_hint/error_prepend usage
82e8c8b python: add commit-per-subsystem.py
a97cab0 scripts: add script to fix error_append_hint/error_prepend usage
987fd13 error: auto propagated local_err
b209564 net/net: fix local variable shadowing in net_client_init
896b2dd hw/core/loader-fit: fix freeing errp in fit_load_fdt
cd953ee errp: rename errp to errp_in where it is IN-argument

=== OUTPUT BEGIN ===
1/31 Checking commit cd953ee1bb8c (errp: rename errp to errp_in where it is 
IN-argument)
2/31 Checking commit 896b2dde85c4 (hw/core/loader-fit: fix freeing errp in 
fit_load_fdt)
3/31 Checking commit b209564a3bf7 (net/net: fix local variable shadowing in 
net_client_init)
4/31 Checking commit 987fd13e64fc (error: auto propagated local_err)
ERROR: Macros with multiple statements should be enclosed in a do - while loop
#71: FILE: include/qapi/error.h:357:
+#define ERRP_AUTO_PROPAGATE() \
+g_auto(ErrorPropagator) __auto_errp_prop = {.errp = errp}; \
+errp = ((errp == NULL || *errp == error_fatal) ? \
+&__auto_errp_prop.local_err : errp)

total: 1 errors, 0 warnings, 43 lines checked

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

5/31 Checking commit a97cab09ecd5 (scripts: add script to fix 
error_append_hint/error_prepend usage)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#16: 
new file mode 100644

total: 0 errors, 1 warnings, 28 lines checked

Patch 5/31 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
6/31 Checking commit 82e8c8bfa5e9 (python: add commit-per-subsystem.py)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#13: 
new file mode 100755

total: 0 errors, 1 warnings, 69 lines checked

Patch 6/31 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
7/31 Checking commit a8ac50cc35ed (s390: Fix error_append_hint/error_prepend 
usage)
8/31 Checking commit 00ceb2bad505 (ARM TCG CPUs: Fix 
error_append_hint/error_prepend usage)
9/31 Checking commit af781f20f6a2 (PowerPC TCG CPUs: Fix 
error_append_hint/error_prepend usage)
10/31 Checking commit a29bb2dcb2b9 (arm: Fix error_append_hint/error_prepend 
usage)
11/31 Checking commit 1eb85cb68ba5 (SmartFusion2: Fix 
error_append_hint/error_prepend usage)
12/31 Checking commit 163ff63668f9 (ASPEED BMCs: Fix 
error_append_hint/error_prepend usage)
13/31 Checking commit c287bb4ab3b2 (Boston: Fix error_append_hint/error_prepend 
usage)
14/31 Checking commit 61a303eb291b (PowerNV (Non-Virtualized): Fix 
error_append_hint/error_prepend usage)
15/31 Checking commit 2833abc764d5 (PCI: Fix error_append_hint/error_prepend 
usage)
16/31 Checking commit 

[PATCH v3 32/34] spapr: Remove SpaprIrq::nr_msis

2019-10-01 Thread David Gibson
The nr_msis value we use here has to line up with whether we're using
legacy or modern irq allocation.  Therefore it's safer to derive it based
on legacy_irq_allocation rather than having SpaprIrq contain a canned
value.

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
---
 hw/ppc/spapr.c  |  5 ++---
 hw/ppc/spapr_irq.c  | 26 +-
 hw/ppc/spapr_pci.c  |  7 ---
 include/hw/pci-host/spapr.h |  4 ++--
 include/hw/ppc/spapr_irq.h  |  4 +---
 5 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index e880db5d38..153cc54354 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1275,7 +1275,7 @@ static void *spapr_build_fdt(SpaprMachineState *spapr)
 }
 
 QLIST_FOREACH(phb, >phbs, list) {
-ret = spapr_dt_phb(phb, PHANDLE_INTC, fdt, spapr->irq->nr_msis, NULL);
+ret = spapr_dt_phb(spapr, phb, PHANDLE_INTC, fdt, NULL);
 if (ret < 0) {
 error_report("couldn't setup PCI devices in fdt");
 exit(1);
@@ -3910,8 +3910,7 @@ int spapr_phb_dt_populate(SpaprDrc *drc, 
SpaprMachineState *spapr,
 return -1;
 }
 
-if (spapr_dt_phb(sphb, intc_phandle, fdt, spapr->irq->nr_msis,
- fdt_start_offset)) {
+if (spapr_dt_phb(spapr, sphb, intc_phandle, fdt, fdt_start_offset)) {
 error_setg(errp, "unable to create FDT node for PHB %d", sphb->index);
 return -1;
 }
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index f3d18b1dad..076da31501 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -29,9 +29,14 @@ static const TypeInfo spapr_intc_info = {
 .class_size = sizeof(SpaprInterruptControllerClass),
 };
 
-void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis)
+static void spapr_irq_msi_init(SpaprMachineState *spapr)
 {
-spapr->irq_map_nr = nr_msis;
+if (SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
+/* Legacy mode doesn't use this allocater */
+return;
+}
+
+spapr->irq_map_nr = spapr_irq_nr_msis(spapr);
 spapr->irq_map = bitmap_new(spapr->irq_map_nr);
 }
 
@@ -102,7 +107,6 @@ int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController 
*, Error **),
 
 SpaprIrq spapr_irq_xics = {
 .nr_xirqs= SPAPR_NR_XIRQS,
-.nr_msis = SPAPR_NR_MSIS,
 .xics= true,
 .xive= false,
 };
@@ -113,7 +117,6 @@ SpaprIrq spapr_irq_xics = {
 
 SpaprIrq spapr_irq_xive = {
 .nr_xirqs= SPAPR_NR_XIRQS,
-.nr_msis = SPAPR_NR_MSIS,
 .xics= false,
 .xive= true,
 };
@@ -132,7 +135,6 @@ SpaprIrq spapr_irq_xive = {
  */
 SpaprIrq spapr_irq_dual = {
 .nr_xirqs= SPAPR_NR_XIRQS,
-.nr_msis = SPAPR_NR_MSIS,
 .xics= true,
 .xive= true,
 };
@@ -247,6 +249,15 @@ void spapr_irq_dt(SpaprMachineState *spapr, uint32_t 
nr_servers,
 sicc->dt(spapr->active_intc, nr_servers, fdt, phandle);
 }
 
+uint32_t spapr_irq_nr_msis(SpaprMachineState *spapr)
+{
+if (SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
+return spapr->irq->nr_xirqs;
+} else {
+return SPAPR_XIRQ_BASE + spapr->irq->nr_xirqs - SPAPR_IRQ_MSI;
+}
+}
+
 void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 {
 MachineState *machine = MACHINE(spapr);
@@ -267,9 +278,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 }
 
 /* Initialize the MSI IRQ allocator. */
-if (!SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
-spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
-}
+spapr_irq_msi_init(spapr);
 
 if (spapr->irq->xics) {
 Error *local_err = NULL;
@@ -551,7 +560,6 @@ int spapr_irq_find(SpaprMachineState *spapr, int num, bool 
align, Error **errp)
 
 SpaprIrq spapr_irq_xics_legacy = {
 .nr_xirqs= SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
-.nr_msis = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
 .xics= true,
 .xive= false,
 };
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 01ff41d4c4..cc0e7829b6 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -2277,8 +2277,8 @@ static void spapr_phb_pci_enumerate(SpaprPhbState *phb)
 
 }
 
-int spapr_dt_phb(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt,
- uint32_t nr_msis, int *node_offset)
+int spapr_dt_phb(SpaprMachineState *spapr, SpaprPhbState *phb,
+ uint32_t intc_phandle, void *fdt, int *node_offset)
 {
 int bus_off, i, j, ret;
 uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) };
@@ -2343,7 +2343,8 @@ int spapr_dt_phb(SpaprPhbState *phb, uint32_t 
intc_phandle, void *fdt,
 _FDT(fdt_setprop(fdt, bus_off, "ranges", , sizeof_ranges));
 _FDT(fdt_setprop(fdt, bus_off, "reg", _reg, sizeof(bus_reg)));
 _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pci-config-space-type", 0x1));
-_FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pe-total-#msi", nr_msis));
+_FDT(fdt_setprop_cell(fdt, 

[PATCH v3 22/34] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController

2019-10-01 Thread David Gibson
This method essentially represents code which belongs to the interrupt
controller, but needs to be called on all possible intcs, rather than
just the currently active one.  The "dual" version therefore calls
into the xics and xive versions confusingly.

Handle this more directly, by making it instead a method on the intc
backend, and always calling it on every backend that exists.

While we're there, streamline the error reporting a bit.

Signed-off-by: David Gibson 
---
 hw/intc/spapr_xive.c   | 25 
 hw/intc/xics_spapr.c   | 18 +
 hw/ppc/spapr_cpu_core.c|  3 +-
 hw/ppc/spapr_irq.c | 81 +++---
 include/hw/ppc/spapr_irq.h | 13 +-
 5 files changed, 79 insertions(+), 61 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index b67e9c3245..9338daba3d 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -495,10 +495,33 @@ static Property spapr_xive_properties[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+static int spapr_xive_cpu_intc_create(SpaprInterruptController *intc,
+  PowerPCCPU *cpu, Error **errp)
+{
+SpaprXive *xive = SPAPR_XIVE(intc);
+Object *obj;
+SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
+
+obj = xive_tctx_create(OBJECT(cpu), XIVE_ROUTER(xive), errp);
+if (!obj) {
+return -1;
+}
+
+spapr_cpu->tctx = XIVE_TCTX(obj);
+
+/*
+ * (TCG) Early setting the OS CAM line for hotplugged CPUs as they
+ * don't beneficiate from the reset of the XIVE IRQ backend
+ */
+spapr_xive_set_tctx_os_cam(spapr_cpu->tctx);
+return 0;
+}
+
 static void spapr_xive_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 XiveRouterClass *xrc = XIVE_ROUTER_CLASS(klass);
+SpaprInterruptControllerClass *sicc = SPAPR_INTC_CLASS(klass);
 
 dc->desc= "sPAPR XIVE Interrupt Controller";
 dc->props   = spapr_xive_properties;
@@ -511,6 +534,8 @@ static void spapr_xive_class_init(ObjectClass *klass, void 
*data)
 xrc->get_nvt = spapr_xive_get_nvt;
 xrc->write_nvt = spapr_xive_write_nvt;
 xrc->get_tctx = spapr_xive_get_tctx;
+
+sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
 }
 
 static const TypeInfo spapr_xive_info = {
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 4874e6be55..946311b858 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -330,13 +330,31 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t 
nr_servers, void *fdt,
 _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
 }
 
+static int xics_spapr_cpu_intc_create(SpaprInterruptController *intc,
+   PowerPCCPU *cpu, Error **errp)
+{
+ICSState *ics = ICS_SPAPR(intc);
+Object *obj;
+SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
+
+obj = icp_create(OBJECT(cpu), TYPE_ICP, ics->xics, errp);
+if (!obj) {
+return -1;
+}
+
+spapr_cpu->icp = ICP(obj);
+return 0;
+}
+
 static void ics_spapr_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 ICSStateClass *isc = ICS_CLASS(klass);
+SpaprInterruptControllerClass *sicc = SPAPR_INTC_CLASS(klass);
 
 device_class_set_parent_realize(dc, ics_spapr_realize,
 >parent_realize);
+sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
 }
 
 static const TypeInfo ics_spapr_info = {
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 1d93de8161..3e4302c7d5 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -237,8 +237,7 @@ static void spapr_realize_vcpu(PowerPCCPU *cpu, 
SpaprMachineState *spapr,
 qemu_register_reset(spapr_cpu_reset, cpu);
 spapr_cpu_reset(cpu);
 
-spapr->irq->cpu_intc_create(spapr, cpu, _err);
-if (local_err) {
+if (spapr_irq_cpu_intc_create(spapr, cpu, _err) < 0) {
 goto error_unregister;
 }
 
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 8791dec1ba..9cb2fc71ca 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -138,23 +138,6 @@ static void spapr_irq_print_info_xics(SpaprMachineState 
*spapr, Monitor *mon)
 ics_pic_print_info(spapr->ics, mon);
 }
 
-static void spapr_irq_cpu_intc_create_xics(SpaprMachineState *spapr,
-   PowerPCCPU *cpu, Error **errp)
-{
-Error *local_err = NULL;
-Object *obj;
-SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
-
-obj = icp_create(OBJECT(cpu), TYPE_ICP, XICS_FABRIC(spapr),
- _err);
-if (local_err) {
-error_propagate(errp, local_err);
-return;
-}
-
-spapr_cpu->icp = ICP(obj);
-}
-
 static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
 {
 if (!kvm_irqchip_in_kernel()) {
@@ -203,7 +186,6 @@ SpaprIrq spapr_irq_xics = {
 .free= spapr_irq_free_xics,
 .print_info  = 

[PATCH v3 26/34] spapr, xics, xive: Move print_info from SpaprIrq to SpaprInterruptController

2019-10-01 Thread David Gibson
This method depends only on the active irq controller.  Now that we've
formalized the notion of active controller we can dispatch directly
through that, rather than dispatching via SpaprIrq with the dual
version having to do a second conditional dispatch.

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
---
 hw/intc/spapr_xive.c   | 15 +
 hw/intc/xics_spapr.c   | 15 +
 hw/ppc/spapr.c |  2 +-
 hw/ppc/spapr_irq.c | 44 +++---
 include/hw/ppc/spapr_irq.h |  4 ++--
 5 files changed, 41 insertions(+), 39 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 52d5e71793..700ec5c9c1 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -564,6 +564,20 @@ static void spapr_xive_set_irq(SpaprInterruptController 
*intc, int irq, int val)
 }
 }
 
+static void spapr_xive_print_info(SpaprInterruptController *intc, Monitor *mon)
+{
+SpaprXive *xive = SPAPR_XIVE(intc);
+CPUState *cs;
+
+CPU_FOREACH(cs) {
+PowerPCCPU *cpu = POWERPC_CPU(cs);
+
+xive_tctx_pic_print_info(spapr_cpu_state(cpu)->tctx, mon);
+}
+
+spapr_xive_pic_print_info(xive, mon);
+}
+
 static void spapr_xive_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -586,6 +600,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void 
*data)
 sicc->claim_irq = spapr_xive_claim_irq;
 sicc->free_irq = spapr_xive_free_irq;
 sicc->set_irq = spapr_xive_set_irq;
+sicc->print_info = spapr_xive_print_info;
 }
 
 static const TypeInfo spapr_xive_info = {
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 02372697f6..415defe394 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -381,6 +381,20 @@ static void xics_spapr_set_irq(SpaprInterruptController 
*intc, int irq, int val)
 ics_set_irq(ics, srcno, val);
 }
 
+static void xics_spapr_print_info(SpaprInterruptController *intc, Monitor *mon)
+{
+ICSState *ics = ICS_SPAPR(intc);
+CPUState *cs;
+
+CPU_FOREACH(cs) {
+PowerPCCPU *cpu = POWERPC_CPU(cs);
+
+icp_pic_print_info(spapr_cpu_state(cpu)->icp, mon);
+}
+
+ics_pic_print_info(ics, mon);
+}
+
 static void ics_spapr_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -393,6 +407,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void 
*data)
 sicc->claim_irq = xics_spapr_claim_irq;
 sicc->free_irq = xics_spapr_free_irq;
 sicc->set_irq = xics_spapr_set_irq;
+sicc->print_info = xics_spapr_print_info;
 }
 
 static const TypeInfo ics_spapr_info = {
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 514a17ae74..6c38de5927 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4271,7 +4271,7 @@ static void spapr_pic_print_info(InterruptStatsProvider 
*obj,
 {
 SpaprMachineState *spapr = SPAPR_MACHINE(obj);
 
-spapr->irq->print_info(spapr, mon);
+spapr_irq_print_info(spapr, mon);
 monitor_printf(mon, "irqchip: %s\n",
kvm_irqchip_in_kernel() ? "in-kernel" : "emulated");
 }
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index bfccb815ed..a29b527232 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -98,19 +98,6 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
  * XICS IRQ backend.
  */
 
-static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon)
-{
-CPUState *cs;
-
-CPU_FOREACH(cs) {
-PowerPCCPU *cpu = POWERPC_CPU(cs);
-
-icp_pic_print_info(spapr_cpu_state(cpu)->icp, mon);
-}
-
-ics_pic_print_info(spapr->ics, mon);
-}
-
 static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
 {
 if (!kvm_irqchip_in_kernel()) {
@@ -147,7 +134,6 @@ SpaprIrq spapr_irq_xics = {
 .xics= true,
 .xive= false,
 
-.print_info  = spapr_irq_print_info_xics,
 .dt_populate = spapr_dt_xics,
 .post_load   = spapr_irq_post_load_xics,
 .reset   = spapr_irq_reset_xics,
@@ -158,20 +144,6 @@ SpaprIrq spapr_irq_xics = {
  * XIVE IRQ backend.
  */
 
-static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
-  Monitor *mon)
-{
-CPUState *cs;
-
-CPU_FOREACH(cs) {
-PowerPCCPU *cpu = POWERPC_CPU(cs);
-
-xive_tctx_pic_print_info(spapr_cpu_state(cpu)->tctx, mon);
-}
-
-spapr_xive_pic_print_info(spapr->xive, mon);
-}
-
 static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id)
 {
 return spapr_xive_post_load(spapr->xive, version_id);
@@ -212,7 +184,6 @@ SpaprIrq spapr_irq_xive = {
 .xics= false,
 .xive= true,
 
-.print_info  = spapr_irq_print_info_xive,
 .dt_populate = spapr_dt_xive,
 .post_load   = spapr_irq_post_load_xive,
 .reset   = spapr_irq_reset_xive,
@@ -238,11 +209,6 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState 
*spapr)
 _irq_xive : 

[PATCH v3 18/34] spapr: Use less cryptic representation of which irq backends are supported

2019-10-01 Thread David Gibson
SpaprIrq::ov5 stores the value for a particular byte in PAPR option vector
5 which indicates whether XICS, XIVE or both interrupt controllers are
available.  As usual for PAPR, the encoding is kind of overly complicated
and confusing (though to be fair there are some backwards compat things it
has to handle).

But to make our internal code clearer, have SpaprIrq encode more directly
which backends are available as two booleans, and derive the OV5 value from
that at the point we need it.

Signed-off-by: David Gibson 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Greg Kurz 
---
 hw/ppc/spapr.c | 15 ---
 hw/ppc/spapr_hcall.c   |  6 +++---
 hw/ppc/spapr_irq.c | 12 
 include/hw/ppc/spapr_irq.h |  3 ++-
 4 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 43920c140d..514a17ae74 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1066,19 +1066,28 @@ static void 
spapr_dt_ov5_platform_support(SpaprMachineState *spapr, void *fdt,
 PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
 
 char val[2 * 4] = {
-23, spapr->irq->ov5, /* Xive mode. */
+23, 0x00, /* XICS / XIVE mode */
 24, 0x00, /* Hash/Radix, filled in below. */
 25, 0x00, /* Hash options: Segment Tables == no, GTSE == no. */
 26, 0x40, /* Radix options: GTSE == yes. */
 };
 
+if (spapr->irq->xics && spapr->irq->xive) {
+val[1] = SPAPR_OV5_XIVE_BOTH;
+} else if (spapr->irq->xive) {
+val[1] = SPAPR_OV5_XIVE_EXPLOIT;
+} else {
+assert(spapr->irq->xics);
+val[1] = SPAPR_OV5_XIVE_LEGACY;
+}
+
 if (!ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0,
   first_ppc_cpu->compat_pvr)) {
 /*
  * If we're in a pre POWER9 compat mode then the guest should
  * do hash and use the legacy interrupt mode
  */
-val[1] = 0x00; /* XICS */
+val[1] = SPAPR_OV5_XIVE_LEGACY; /* XICS */
 val[3] = 0x00; /* Hash */
 } else if (kvm_enabled()) {
 if (kvmppc_has_cap_mmu_radix() && kvmppc_has_cap_mmu_hash_v3()) {
@@ -2767,7 +2776,7 @@ static void spapr_machine_init(MachineState *machine)
 spapr_ovec_set(spapr->ov5, OV5_DRMEM_V2);
 
 /* advertise XIVE on POWER9 machines */
-if (spapr->irq->ov5 & (SPAPR_OV5_XIVE_EXPLOIT | SPAPR_OV5_XIVE_BOTH)) {
+if (spapr->irq->xive) {
 spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT);
 }
 
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 3d3a67149a..140f05c1c6 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1784,13 +1784,13 @@ static target_ulong 
h_client_architecture_support(PowerPCCPU *cpu,
  * terminate the boot.
  */
 if (guest_xive) {
-if (spapr->irq->ov5 == SPAPR_OV5_XIVE_LEGACY) {
+if (!spapr->irq->xive) {
 error_report(
 "Guest requested unavailable interrupt mode (XIVE), try the ic-mode=xive or 
ic-mode=dual machine property");
 exit(EXIT_FAILURE);
 }
 } else {
-if (spapr->irq->ov5 == SPAPR_OV5_XIVE_EXPLOIT) {
+if (!spapr->irq->xics) {
 error_report(
 "Guest requested unavailable interrupt mode (XICS), either don't set the 
ic-mode machine property or try ic-mode=xics or ic-mode=dual");
 exit(EXIT_FAILURE);
@@ -1804,7 +1804,7 @@ static target_ulong 
h_client_architecture_support(PowerPCCPU *cpu,
  */
 if (!spapr->cas_reboot) {
 spapr->cas_reboot = spapr_ovec_test(ov5_updates, OV5_XIVE_EXPLOIT)
-&& spapr->irq->ov5 & SPAPR_OV5_XIVE_BOTH;
+&& spapr->irq->xics && spapr->irq->xive;
 }
 
 spapr_ovec_cleanup(ov5_updates);
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 516bf00a35..3ac67ba0c7 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -210,7 +210,8 @@ static void spapr_irq_init_kvm_xics(SpaprMachineState 
*spapr, Error **errp)
 SpaprIrq spapr_irq_xics = {
 .nr_xirqs= SPAPR_NR_XIRQS,
 .nr_msis = SPAPR_NR_MSIS,
-.ov5 = SPAPR_OV5_XIVE_LEGACY,
+.xics= true,
+.xive= false,
 
 .init= spapr_irq_init_xics,
 .claim   = spapr_irq_claim_xics,
@@ -350,7 +351,8 @@ static void spapr_irq_init_kvm_xive(SpaprMachineState 
*spapr, Error **errp)
 SpaprIrq spapr_irq_xive = {
 .nr_xirqs= SPAPR_NR_XIRQS,
 .nr_msis = SPAPR_NR_MSIS,
-.ov5 = SPAPR_OV5_XIVE_EXPLOIT,
+.xics= false,
+.xive= true,
 
 .init= spapr_irq_init_xive,
 .claim   = spapr_irq_claim_xive,
@@ -511,7 +513,8 @@ static void spapr_irq_set_irq_dual(void *opaque, int irq, 
int val)
 SpaprIrq spapr_irq_dual = {
 .nr_xirqs= SPAPR_NR_XIRQS,
 .nr_msis = SPAPR_NR_MSIS,
-.ov5 = SPAPR_OV5_XIVE_BOTH,
+.xics= true,
+.xive= true,
 
 .init= spapr_irq_init_dual,
 .claim   = 

[PATCH v3 25/34] spapr, xics, xive: Move set_irq from SpaprIrq to SpaprInterruptController

2019-10-01 Thread David Gibson
This method depends only on the active irq controller.  Now that we've
formalized the notion of active controller we can dispatch directly through
that, rather than dispatching via SpaprIrq with the dual version having
to do a second conditional dispatch.

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
---
 hw/intc/spapr_xive.c   | 12 +++
 hw/intc/xics_spapr.c   |  9 +
 hw/ppc/spapr_irq.c | 41 ++
 include/hw/ppc/spapr_irq.h |  4 +++-
 4 files changed, 34 insertions(+), 32 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index ff1a175b44..52d5e71793 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -553,6 +553,17 @@ static int 
spapr_xive_cpu_intc_create(SpaprInterruptController *intc,
 return 0;
 }
 
+static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int 
val)
+{
+SpaprXive *xive = SPAPR_XIVE(intc);
+
+if (kvm_irqchip_in_kernel()) {
+kvmppc_xive_source_set_irq(>source, irq, val);
+} else {
+xive_source_set_irq(>source, irq, val);
+}
+}
+
 static void spapr_xive_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -574,6 +585,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void 
*data)
 sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
 sicc->claim_irq = spapr_xive_claim_irq;
 sicc->free_irq = spapr_xive_free_irq;
+sicc->set_irq = spapr_xive_set_irq;
 }
 
 static const TypeInfo spapr_xive_info = {
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 224fe1efcd..02372697f6 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -373,6 +373,14 @@ static void xics_spapr_free_irq(SpaprInterruptController 
*intc, int irq)
 memset(>irqs[srcno], 0, sizeof(ICSIRQState));
 }
 
+static void xics_spapr_set_irq(SpaprInterruptController *intc, int irq, int 
val)
+{
+ICSState *ics = ICS_SPAPR(intc);
+uint32_t srcno = irq - ics->offset;
+
+ics_set_irq(ics, srcno, val);
+}
+
 static void ics_spapr_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -384,6 +392,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void 
*data)
 sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
 sicc->claim_irq = xics_spapr_claim_irq;
 sicc->free_irq = xics_spapr_free_irq;
+sicc->set_irq = xics_spapr_set_irq;
 }
 
 static const TypeInfo ics_spapr_info = {
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 249a2688ac..bfccb815ed 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -123,14 +123,6 @@ static int spapr_irq_post_load_xics(SpaprMachineState 
*spapr, int version_id)
 return 0;
 }
 
-static void spapr_irq_set_irq_xics(void *opaque, int irq, int val)
-{
-SpaprMachineState *spapr = opaque;
-uint32_t srcno = irq - spapr->ics->offset;
-
-ics_set_irq(spapr->ics, srcno, val);
-}
-
 static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
 {
 Error *local_err = NULL;
@@ -159,7 +151,6 @@ SpaprIrq spapr_irq_xics = {
 .dt_populate = spapr_dt_xics,
 .post_load   = spapr_irq_post_load_xics,
 .reset   = spapr_irq_reset_xics,
-.set_irq = spapr_irq_set_irq_xics,
 .init_kvm= spapr_irq_init_kvm_xics,
 };
 
@@ -208,17 +199,6 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, 
Error **errp)
 spapr_xive_mmio_set_enabled(spapr->xive, true);
 }
 
-static void spapr_irq_set_irq_xive(void *opaque, int irq, int val)
-{
-SpaprMachineState *spapr = opaque;
-
-if (kvm_irqchip_in_kernel()) {
-kvmppc_xive_source_set_irq(>xive->source, irq, val);
-} else {
-xive_source_set_irq(>xive->source, irq, val);
-}
-}
-
 static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
 {
 if (kvm_enabled()) {
@@ -236,7 +216,6 @@ SpaprIrq spapr_irq_xive = {
 .dt_populate = spapr_dt_xive,
 .post_load   = spapr_irq_post_load_xive,
 .reset   = spapr_irq_reset_xive,
-.set_irq = spapr_irq_set_irq_xive,
 .init_kvm= spapr_irq_init_kvm_xive,
 };
 
@@ -316,13 +295,6 @@ static void spapr_irq_reset_dual(SpaprMachineState *spapr, 
Error **errp)
 spapr_irq_current(spapr)->reset(spapr, errp);
 }
 
-static void spapr_irq_set_irq_dual(void *opaque, int irq, int val)
-{
-SpaprMachineState *spapr = opaque;
-
-spapr_irq_current(spapr)->set_irq(spapr, irq, val);
-}
-
 /*
  * Define values in sync with the XIVE and XICS backend
  */
@@ -336,7 +308,6 @@ SpaprIrq spapr_irq_dual = {
 .dt_populate = spapr_irq_dt_populate_dual,
 .post_load   = spapr_irq_post_load_dual,
 .reset   = spapr_irq_reset_dual,
-.set_irq = spapr_irq_set_irq_dual,
 .init_kvm= NULL, /* should not be used */
 };
 
@@ -424,6 +395,15 @@ int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
 return 0;
 }
 
+static void spapr_set_irq(void *opaque, int irq, int level)
+{
+

[PATCH v3 13/34] spapr: Eliminate SpaprIrq:get_nodename method

2019-10-01 Thread David Gibson
This method is used to determine the name of the irq backend's node in the
device tree, so that we can find its phandle (after SLOF may have modified
it from the phandle we initially gave it).

But, in the two cases the only difference between the node name is the
presence of a unit address.  Searching for a node name without considering
unit address is standard practice for the device tree, and
fdt_subnode_offset() will do exactly that, making this method unecessary.

While we're there, remove the XICS_NODENAME define.  The name
"interrupt-controller" is required by PAPR (and IEEE1275), and a bunch of
places assume it already.

Signed-off-by: David Gibson 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Greg Kurz 
---
 hw/intc/xics_spapr.c|  2 +-
 hw/ppc/spapr_irq.c  | 25 +++--
 include/hw/ppc/spapr_irq.h  |  1 -
 include/hw/ppc/xics_spapr.h |  2 --
 4 files changed, 4 insertions(+), 26 deletions(-)

diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index e6dd004587..6e5eb24b3c 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -316,7 +316,7 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t 
nr_servers, void *fdt,
 };
 int node;
 
-_FDT(node = fdt_add_subnode(fdt, 0, XICS_NODENAME));
+_FDT(node = fdt_add_subnode(fdt, 0, "interrupt-controller"));
 
 _FDT(fdt_setprop_string(fdt, node, "device_type",
 "PowerPC-External-Interrupt-Presentation"));
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 8f179076c6..ec2229d2d1 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -211,11 +211,6 @@ static void spapr_irq_reset_xics(SpaprMachineState *spapr, 
Error **errp)
 }
 }
 
-static const char *spapr_irq_get_nodename_xics(SpaprMachineState *spapr)
-{
-return XICS_NODENAME;
-}
-
 static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
 {
 if (kvm_enabled()) {
@@ -237,7 +232,6 @@ SpaprIrq spapr_irq_xics = {
 .post_load   = spapr_irq_post_load_xics,
 .reset   = spapr_irq_reset_xics,
 .set_irq = spapr_irq_set_irq_xics,
-.get_nodename = spapr_irq_get_nodename_xics,
 .init_kvm= spapr_irq_init_kvm_xics,
 };
 
@@ -362,11 +356,6 @@ static void spapr_irq_set_irq_xive(void *opaque, int irq, 
int val)
 }
 }
 
-static const char *spapr_irq_get_nodename_xive(SpaprMachineState *spapr)
-{
-return spapr->xive->nodename;
-}
-
 static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
 {
 if (kvm_enabled()) {
@@ -388,7 +377,6 @@ SpaprIrq spapr_irq_xive = {
 .post_load   = spapr_irq_post_load_xive,
 .reset   = spapr_irq_reset_xive,
 .set_irq = spapr_irq_set_irq_xive,
-.get_nodename = spapr_irq_get_nodename_xive,
 .init_kvm= spapr_irq_init_kvm_xive,
 };
 
@@ -533,11 +521,6 @@ static void spapr_irq_set_irq_dual(void *opaque, int irq, 
int val)
 spapr_irq_current(spapr)->set_irq(spapr, irq, val);
 }
 
-static const char *spapr_irq_get_nodename_dual(SpaprMachineState *spapr)
-{
-return spapr_irq_current(spapr)->get_nodename(spapr);
-}
-
 /*
  * Define values in sync with the XIVE and XICS backend
  */
@@ -555,7 +538,6 @@ SpaprIrq spapr_irq_dual = {
 .post_load   = spapr_irq_post_load_dual,
 .reset   = spapr_irq_reset_dual,
 .set_irq = spapr_irq_set_irq_dual,
-.get_nodename = spapr_irq_get_nodename_dual,
 .init_kvm= NULL, /* should not be used */
 };
 
@@ -699,13 +681,13 @@ void spapr_irq_reset(SpaprMachineState *spapr, Error 
**errp)
 
 int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp)
 {
-const char *nodename = spapr->irq->get_nodename(spapr);
+const char *nodename = "interrupt-controller";
 int offset, phandle;
 
 offset = fdt_subnode_offset(fdt, 0, nodename);
 if (offset < 0) {
-error_setg(errp, "Can't find node \"%s\": %s", nodename,
-   fdt_strerror(offset));
+error_setg(errp, "Can't find node \"%s\": %s",
+   nodename, fdt_strerror(offset));
 return -1;
 }
 
@@ -789,6 +771,5 @@ SpaprIrq spapr_irq_xics_legacy = {
 .post_load   = spapr_irq_post_load_xics,
 .reset   = spapr_irq_reset_xics,
 .set_irq = spapr_irq_set_irq_xics,
-.get_nodename = spapr_irq_get_nodename_xics,
 .init_kvm= spapr_irq_init_kvm_xics,
 };
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index a4e790ef60..9b60378e28 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -52,7 +52,6 @@ typedef struct SpaprIrq {
 int (*post_load)(SpaprMachineState *spapr, int version_id);
 void (*reset)(SpaprMachineState *spapr, Error **errp);
 void (*set_irq)(void *opaque, int srcno, int val);
-const char *(*get_nodename)(SpaprMachineState *spapr);
 void (*init_kvm)(SpaprMachineState *spapr, Error **errp);
 } SpaprIrq;
 
diff --git a/include/hw/ppc/xics_spapr.h 

[PATCH v3 33/34] spapr: Move SpaprIrq::nr_xirqs to SpaprMachineClass

2019-10-01 Thread David Gibson
For the benefit of peripheral device allocation, the number of available
irqs really wants to be the same on a given machine type version,
regardless of what irq backends we are using.  That's the case now, but
only because we make sure the different SpaprIrq instances have the same
value except for the special legacy one.

Since this really only depends on machine type version, move the value to
SpaprMachineClass instead of SpaprIrq.  This also puts the code to set it
to the lower value on old machine types right next to setting
legacy_irq_allocation, which needs to go hand in hand.

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
---
 hw/ppc/spapr.c |  2 ++
 hw/ppc/spapr_irq.c | 33 -
 include/hw/ppc/spapr.h |  1 +
 include/hw/ppc/spapr_irq.h |  1 -
 4 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 153cc54354..e1ff03152e 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4443,6 +4443,7 @@ static void spapr_machine_class_init(ObjectClass *oc, 
void *data)
 smc->irq = _irq_dual;
 smc->dr_phb_enabled = true;
 smc->linux_pci_probe = true;
+smc->nr_xirqs = SPAPR_NR_XIRQS;
 }
 
 static const TypeInfo spapr_machine_info = {
@@ -4578,6 +4579,7 @@ static void spapr_machine_3_0_class_options(MachineClass 
*mc)
 compat_props_add(mc->compat_props, hw_compat_3_0, hw_compat_3_0_len);
 
 smc->legacy_irq_allocation = true;
+smc->nr_xirqs = 0x400;
 smc->irq = _irq_xics_legacy;
 }
 
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 076da31501..2768f9a765 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -106,7 +106,6 @@ int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController 
*, Error **),
  */
 
 SpaprIrq spapr_irq_xics = {
-.nr_xirqs= SPAPR_NR_XIRQS,
 .xics= true,
 .xive= false,
 };
@@ -116,7 +115,6 @@ SpaprIrq spapr_irq_xics = {
  */
 
 SpaprIrq spapr_irq_xive = {
-.nr_xirqs= SPAPR_NR_XIRQS,
 .xics= false,
 .xive= true,
 };
@@ -134,7 +132,6 @@ SpaprIrq spapr_irq_xive = {
  * Define values in sync with the XIVE and XICS backend
  */
 SpaprIrq spapr_irq_dual = {
-.nr_xirqs= SPAPR_NR_XIRQS,
 .xics= true,
 .xive= true,
 };
@@ -251,16 +248,19 @@ void spapr_irq_dt(SpaprMachineState *spapr, uint32_t 
nr_servers,
 
 uint32_t spapr_irq_nr_msis(SpaprMachineState *spapr)
 {
-if (SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
-return spapr->irq->nr_xirqs;
+SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+
+if (smc->legacy_irq_allocation) {
+return smc->nr_xirqs;
 } else {
-return SPAPR_XIRQ_BASE + spapr->irq->nr_xirqs - SPAPR_IRQ_MSI;
+return SPAPR_XIRQ_BASE + smc->nr_xirqs - SPAPR_IRQ_MSI;
 }
 }
 
 void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 {
 MachineState *machine = MACHINE(spapr);
+SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
 
 if (machine_kernel_irqchip_split(machine)) {
 error_setg(errp, "kernel_irqchip split mode not supported on pseries");
@@ -298,8 +298,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 return;
 }
 
-object_property_set_int(obj, spapr->irq->nr_xirqs, "nr-irqs",
-_err);
+object_property_set_int(obj, smc->nr_xirqs, "nr-irqs", _err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
@@ -320,8 +319,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 int i;
 
 dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
-qdev_prop_set_uint32(dev, "nr-irqs",
- spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
+qdev_prop_set_uint32(dev, "nr-irqs", smc->nr_xirqs + SPAPR_XIRQ_BASE);
 /*
  * 8 XIVE END structures per CPU. One for each available
  * priority
@@ -346,17 +344,18 @@ void spapr_irq_init(SpaprMachineState *spapr, Error 
**errp)
 }
 
 spapr->qirqs = qemu_allocate_irqs(spapr_set_irq, spapr,
-  spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
+  smc->nr_xirqs + SPAPR_XIRQ_BASE);
 }
 
 int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
 {
 SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
 int i;
+SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
 int rc;
 
 assert(irq >= SPAPR_XIRQ_BASE);
-assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
+assert(irq < (smc->nr_xirqs + SPAPR_XIRQ_BASE));
 
 for (i = 0; i < ARRAY_SIZE(intcs); i++) {
 SpaprInterruptController *intc = intcs[i];
@@ -376,9 +375,10 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int 
num)
 {
 SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
 int i, j;
+SpaprMachineClass *smc = 

[PATCH v3 19/34] spapr: Add return value to spapr_irq_check()

2019-10-01 Thread David Gibson
Explicitly return success or failure, rather than just relying on the
Error ** parameter.  This makes handling it less verbose in the caller.

Signed-off-by: David Gibson 
---
 hw/ppc/spapr_irq.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 3ac67ba0c7..0413fbd0a3 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -529,7 +529,7 @@ SpaprIrq spapr_irq_dual = {
 };
 
 
-static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
+static int spapr_irq_check(SpaprMachineState *spapr, Error **errp)
 {
 MachineState *machine = MACHINE(spapr);
 
@@ -545,7 +545,7 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error 
**errp)
  */
 if (spapr->irq == _irq_dual) {
 spapr->irq = _irq_xics;
-return;
+return 0;
 }
 
 /*
@@ -565,7 +565,7 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error 
**errp)
  */
 if (spapr->irq == _irq_xive) {
 error_setg(errp, "XIVE-only machines require a POWER9 CPU");
-return;
+return -1;
 }
 }
 
@@ -579,8 +579,10 @@ static void spapr_irq_check(SpaprMachineState *spapr, 
Error **errp)
 machine_kernel_irqchip_required(machine) &&
 xics_kvm_has_broken_disconnect(spapr)) {
 error_setg(errp, "KVM is too old to support 
ic-mode=dual,kernel-irqchip=on");
-return;
+return -1;
 }
+
+return 0;
 }
 
 /*
@@ -589,7 +591,6 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error 
**errp)
 void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 {
 MachineState *machine = MACHINE(spapr);
-Error *local_err = NULL;
 
 if (machine_kernel_irqchip_split(machine)) {
 error_setg(errp, "kernel_irqchip split mode not supported on pseries");
@@ -602,9 +603,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 return;
 }
 
-spapr_irq_check(spapr, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+if (spapr_irq_check(spapr, errp) < 0) {
 return;
 }
 
-- 
2.21.0




[PATCH v3 23/34] spapr, xics, xive: Move irq claim and free from SpaprIrq to SpaprInterruptController

2019-10-01 Thread David Gibson
These methods, like cpu_intc_create, really belong to the interrupt
controller, but need to be called on all possible intcs.

Like cpu_intc_create, therefore, make them methods on the intc and
always call it for all existing intcs.

Signed-off-by: David Gibson 
---
 hw/intc/spapr_xive.c|  71 ---
 hw/intc/xics_spapr.c|  29 ++
 hw/ppc/spapr_irq.c  | 110 +++-
 include/hw/ppc/spapr_irq.h  |   5 +-
 include/hw/ppc/spapr_xive.h |   2 -
 5 files changed, 102 insertions(+), 115 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 9338daba3d..ff1a175b44 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -487,6 +487,42 @@ static const VMStateDescription vmstate_spapr_xive = {
 },
 };
 
+static int spapr_xive_claim_irq(SpaprInterruptController *intc, int lisn,
+bool lsi, Error **errp)
+{
+SpaprXive *xive = SPAPR_XIVE(intc);
+XiveSource *xsrc = >source;
+
+assert(lisn < xive->nr_irqs);
+
+if (xive_eas_is_valid(>eat[lisn])) {
+error_setg(errp, "IRQ %d is not free", lisn);
+return -EBUSY;
+}
+
+/*
+ * Set default values when allocating an IRQ number
+ */
+xive->eat[lisn].w |= cpu_to_be64(EAS_VALID | EAS_MASKED);
+if (lsi) {
+xive_source_irq_set_lsi(xsrc, lisn);
+}
+
+if (kvm_irqchip_in_kernel()) {
+return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
+}
+
+return 0;
+}
+
+static void spapr_xive_free_irq(SpaprInterruptController *intc, int lisn)
+{
+SpaprXive *xive = SPAPR_XIVE(intc);
+assert(lisn < xive->nr_irqs);
+
+xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
+}
+
 static Property spapr_xive_properties[] = {
 DEFINE_PROP_UINT32("nr-irqs", SpaprXive, nr_irqs, 0),
 DEFINE_PROP_UINT32("nr-ends", SpaprXive, nr_ends, 0),
@@ -536,6 +572,8 @@ static void spapr_xive_class_init(ObjectClass *klass, void 
*data)
 xrc->get_tctx = spapr_xive_get_tctx;
 
 sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
+sicc->claim_irq = spapr_xive_claim_irq;
+sicc->free_irq = spapr_xive_free_irq;
 }
 
 static const TypeInfo spapr_xive_info = {
@@ -557,39 +595,6 @@ static void spapr_xive_register_types(void)
 
 type_init(spapr_xive_register_types)
 
-int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp)
-{
-XiveSource *xsrc = >source;
-
-assert(lisn < xive->nr_irqs);
-
-if (xive_eas_is_valid(>eat[lisn])) {
-error_setg(errp, "IRQ %d is not free", lisn);
-return -EBUSY;
-}
-
-/*
- * Set default values when allocating an IRQ number
- */
-xive->eat[lisn].w |= cpu_to_be64(EAS_VALID | EAS_MASKED);
-if (lsi) {
-xive_source_irq_set_lsi(xsrc, lisn);
-}
-
-if (kvm_irqchip_in_kernel()) {
-return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
-}
-
-return 0;
-}
-
-void spapr_xive_irq_free(SpaprXive *xive, int lisn)
-{
-assert(lisn < xive->nr_irqs);
-
-xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
-}
-
 /*
  * XIVE hcalls
  *
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 946311b858..224fe1efcd 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -346,6 +346,33 @@ static int 
xics_spapr_cpu_intc_create(SpaprInterruptController *intc,
 return 0;
 }
 
+static int xics_spapr_claim_irq(SpaprInterruptController *intc, int irq,
+bool lsi, Error **errp)
+{
+ICSState *ics = ICS_SPAPR(intc);
+
+assert(ics);
+assert(ics_valid_irq(ics, irq));
+
+if (!ics_irq_free(ics, irq - ics->offset)) {
+error_setg(errp, "IRQ %d is not free", irq);
+return -EBUSY;
+}
+
+ics_set_irq_type(ics, irq - ics->offset, lsi);
+return 0;
+}
+
+static void xics_spapr_free_irq(SpaprInterruptController *intc, int irq)
+{
+ICSState *ics = ICS_SPAPR(intc);
+uint32_t srcno = irq - ics->offset;
+
+assert(ics_valid_irq(ics, irq));
+
+memset(>irqs[srcno], 0, sizeof(ICSIRQState));
+}
+
 static void ics_spapr_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -355,6 +382,8 @@ static void ics_spapr_class_init(ObjectClass *klass, void 
*data)
 device_class_set_parent_realize(dc, ics_spapr_realize,
 >parent_realize);
 sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
+sicc->claim_irq = xics_spapr_claim_irq;
+sicc->free_irq = xics_spapr_free_irq;
 }
 
 static const TypeInfo ics_spapr_info = {
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 9cb2fc71ca..83882cfad3 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -98,33 +98,6 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
  * XICS IRQ backend.
  */
 
-static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
-Error **errp)
-{
-ICSState *ics = spapr->ics;
-
-

[PATCH v3 09/34] spapr: Clarify and fix handling of nr_irqs

2019-10-01 Thread David Gibson
Both the XICS and XIVE interrupt backends have a "nr-irqs" property, but
it means slightly different things.  For XICS (or, strictly, the ICS) it
indicates the number of "real" external IRQs.  Those start at XICS_IRQ_BASE
(0x1000) and don't include the special IPI vector.  For XIVE, however, it
includes the whole IRQ space, including XIVE's many IPI vectors.

The spapr code currently doesn't handle this sensibly, with the
nr_irqs value in SpaprIrq having different meanings depending on the
backend.  We fix this by renaming nr_irqs to nr_xirqs and making it
always indicate just the number of external irqs, adjusting the value
we pass to XIVE accordingly.  We also move to using common constants
in most of the irq configurations, to make it clearer that the IRQ
space looks the same to the guest (and emulated devices), even if the
backend is different.

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
---
 hw/ppc/spapr_irq.c | 53 ++
 include/hw/ppc/spapr_irq.h | 19 +-
 2 files changed, 31 insertions(+), 41 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 8c26fa2d1e..3207b6bd01 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -92,7 +92,7 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
  * XICS IRQ backend.
  */
 
-static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
+static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_xirqs,
 Error **errp)
 {
 Object *obj;
@@ -102,7 +102,7 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, 
int nr_irqs,
 object_property_add_child(OBJECT(spapr), "ics", obj, _abort);
 object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
_fatal);
-object_property_set_int(obj, nr_irqs, "nr-irqs",  _fatal);
+object_property_set_int(obj, nr_xirqs, "nr-irqs",  _fatal);
 object_property_set_bool(obj, true, "realized", _err);
 if (local_err) {
 error_propagate(errp, local_err);
@@ -234,13 +234,9 @@ static void spapr_irq_init_kvm_xics(SpaprMachineState 
*spapr, Error **errp)
 }
 }
 
-#define SPAPR_IRQ_XICS_NR_IRQS 0x1000
-#define SPAPR_IRQ_XICS_NR_MSIS \
-(XICS_IRQ_BASE + SPAPR_IRQ_XICS_NR_IRQS - SPAPR_IRQ_MSI)
-
 SpaprIrq spapr_irq_xics = {
-.nr_irqs = SPAPR_IRQ_XICS_NR_IRQS,
-.nr_msis = SPAPR_IRQ_XICS_NR_MSIS,
+.nr_xirqs= SPAPR_NR_XIRQS,
+.nr_msis = SPAPR_NR_MSIS,
 .ov5 = SPAPR_OV5_XIVE_LEGACY,
 
 .init= spapr_irq_init_xics,
@@ -260,7 +256,7 @@ SpaprIrq spapr_irq_xics = {
 /*
  * XIVE IRQ backend.
  */
-static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_irqs,
+static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_xirqs,
 Error **errp)
 {
 uint32_t nr_servers = spapr_max_server_number(spapr);
@@ -268,7 +264,7 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, 
int nr_irqs,
 int i;
 
 dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
-qdev_prop_set_uint32(dev, "nr-irqs", nr_irqs);
+qdev_prop_set_uint32(dev, "nr-irqs", nr_xirqs + SPAPR_XIRQ_BASE);
 /*
  * 8 XIVE END structures per CPU. One for each available priority
  */
@@ -308,7 +304,7 @@ static qemu_irq spapr_qirq_xive(SpaprMachineState *spapr, 
int irq)
 {
 SpaprXive *xive = spapr->xive;
 
-if (irq >= xive->nr_irqs) {
+if ((irq < SPAPR_XIRQ_BASE) || (irq >= xive->nr_irqs)) {
 return NULL;
 }
 
@@ -404,17 +400,9 @@ static void spapr_irq_init_kvm_xive(SpaprMachineState 
*spapr, Error **errp)
 }
 }
 
-/*
- * XIVE uses the full IRQ number space. Set it to 8K to be compatible
- * with XICS.
- */
-
-#define SPAPR_IRQ_XIVE_NR_IRQS 0x2000
-#define SPAPR_IRQ_XIVE_NR_MSIS (SPAPR_IRQ_XIVE_NR_IRQS - SPAPR_IRQ_MSI)
-
 SpaprIrq spapr_irq_xive = {
-.nr_irqs = SPAPR_IRQ_XIVE_NR_IRQS,
-.nr_msis = SPAPR_IRQ_XIVE_NR_MSIS,
+.nr_xirqs= SPAPR_NR_XIRQS,
+.nr_msis = SPAPR_NR_MSIS,
 .ov5 = SPAPR_OV5_XIVE_EXPLOIT,
 
 .init= spapr_irq_init_xive,
@@ -450,18 +438,18 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState 
*spapr)
 _irq_xive : _irq_xics;
 }
 
-static void spapr_irq_init_dual(SpaprMachineState *spapr, int nr_irqs,
+static void spapr_irq_init_dual(SpaprMachineState *spapr, int nr_xirqs,
 Error **errp)
 {
 Error *local_err = NULL;
 
-spapr_irq_xics.init(spapr, spapr_irq_xics.nr_irqs, _err);
+spapr_irq_xics.init(spapr, spapr_irq_xics.nr_xirqs, _err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
 }
 
-spapr_irq_xive.init(spapr, spapr_irq_xive.nr_irqs, _err);
+spapr_irq_xive.init(spapr, spapr_irq_xive.nr_xirqs, _err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
@@ -586,12 +574,9 @@ static const char 

[PATCH v3 17/34] xive: Improve irq claim/free path

2019-10-01 Thread David Gibson
spapr_xive_irq_claim() returns a bool to indicate if it succeeded.
But most of the callers and one callee use int return values and/or an
Error * with more information instead.  In any case, ints are a more
common idiom for success/failure states than bools (one never knows
what sense they'll be in).

So instead change to an int return value to indicate presence of error
+ an Error * to describe the details through that call chain.

It also didn't actually check if the irq was already claimed, which is
one of the primary purposes of the claim path, so do that.

spapr_xive_irq_free() also returned a bool... which no callers checked
and was always true, so just drop it.

Signed-off-by: David Gibson 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Greg Kurz 
---
 hw/intc/spapr_xive.c| 20 +---
 hw/intc/spapr_xive_kvm.c|  8 
 hw/ppc/spapr_irq.c  | 11 +--
 include/hw/ppc/spapr_xive.h |  4 ++--
 include/hw/ppc/xive.h   |  2 +-
 5 files changed, 21 insertions(+), 24 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 47b5ec0b56..04879abf2e 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -528,12 +528,17 @@ static void spapr_xive_register_types(void)
 
 type_init(spapr_xive_register_types)
 
-bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi)
+int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp)
 {
 XiveSource *xsrc = >source;
 
 assert(lisn < xive->nr_irqs);
 
+if (xive_eas_is_valid(>eat[lisn])) {
+error_setg(errp, "IRQ %d is not free", lisn);
+return -EBUSY;
+}
+
 /*
  * Set default values when allocating an IRQ number
  */
@@ -543,24 +548,17 @@ bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, 
bool lsi)
 }
 
 if (kvm_irqchip_in_kernel()) {
-Error *local_err = NULL;
-
-kvmppc_xive_source_reset_one(xsrc, lisn, _err);
-if (local_err) {
-error_report_err(local_err);
-return false;
-}
+return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
 }
 
-return true;
+return 0;
 }
 
-bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn)
+void spapr_xive_irq_free(SpaprXive *xive, int lisn)
 {
 assert(lisn < xive->nr_irqs);
 
 xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
-return true;
 }
 
 /*
diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
index 2006f96aec..51b334b676 100644
--- a/hw/intc/spapr_xive_kvm.c
+++ b/hw/intc/spapr_xive_kvm.c
@@ -232,14 +232,14 @@ void kvmppc_xive_sync_source(SpaprXive *xive, uint32_t 
lisn, Error **errp)
  * only need to inform the KVM XIVE device about their type: LSI or
  * MSI.
  */
-void kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
+int kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
 {
 SpaprXive *xive = SPAPR_XIVE(xsrc->xive);
 uint64_t state = 0;
 
 /* The KVM XIVE device is not in use */
 if (xive->fd == -1) {
-return;
+return -ENODEV;
 }
 
 if (xive_source_irq_is_lsi(xsrc, srcno)) {
@@ -249,8 +249,8 @@ void kvmppc_xive_source_reset_one(XiveSource *xsrc, int 
srcno, Error **errp)
 }
 }
 
-kvm_device_access(xive->fd, KVM_DEV_XIVE_GRP_SOURCE, srcno, ,
-  true, errp);
+return kvm_device_access(xive->fd, KVM_DEV_XIVE_GRP_SOURCE, srcno, ,
+ true, errp);
 }
 
 static void kvmppc_xive_source_reset(XiveSource *xsrc, Error **errp)
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 025c802e7b..516bf00a35 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -246,7 +246,10 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, 
Error **errp)
 
 /* Enable the CPU IPIs */
 for (i = 0; i < nr_servers; ++i) {
-spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false);
+if (spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
+ false, errp) < 0) {
+return;
+}
 }
 
 spapr_xive_hcall_init(spapr);
@@ -255,11 +258,7 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, 
Error **errp)
 static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
 Error **errp)
 {
-if (!spapr_xive_irq_claim(spapr->xive, irq, lsi)) {
-error_setg(errp, "IRQ %d is invalid", irq);
-return -1;
-}
-return 0;
+return spapr_xive_irq_claim(spapr->xive, irq, lsi, errp);
 }
 
 static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
index bfd40f01d8..0df20a6590 100644
--- a/include/hw/ppc/spapr_xive.h
+++ b/include/hw/ppc/spapr_xive.h
@@ -54,8 +54,8 @@ typedef struct SpaprXive {
  */
 #define SPAPR_XIVE_BLOCK_ID 0x0
 
-bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi);
-bool 

[PATCH v3 24/34] spapr: Formalize notion of active interrupt controller

2019-10-01 Thread David Gibson
spapr now has the mechanism of constructing both XICS and XIVE instances of
the SpaprInterruptController interface.  However, only one of the interrupt
controllers will actually be active at any given time, depending on feature
negotiation with the guest.  This is handled in the current code via
spapr_irq_current() which checks the OV5 vector from feature negotiation to
determine the current backend.

Determining the active controller at the point we need it like this
can be pretty confusing, because it makes it very non obvious at what
points the active controller can change.  This can make it difficult
to reason about the code and where a change of active controller could
appear in sequence with other events.

Make this mechanism more explicit by adding an 'active_intc' pointer
and an explicit spapr_irq_update_active_intc() function to update it
from the CAS state.  We also add hooks on the intc backend which will
get called when it is activated or deactivated.

For now we just introduce the switch and hooks, later patches will
actually start using them.

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
---
 hw/ppc/spapr_irq.c | 51 ++
 include/hw/ppc/spapr.h |  5 ++--
 include/hw/ppc/spapr_irq.h |  5 
 3 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 83882cfad3..249a2688ac 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -586,6 +586,7 @@ qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
 
 int spapr_irq_post_load(SpaprMachineState *spapr, int version_id)
 {
+spapr_irq_update_active_intc(spapr);
 return spapr->irq->post_load(spapr, version_id);
 }
 
@@ -593,6 +594,8 @@ void spapr_irq_reset(SpaprMachineState *spapr, Error **errp)
 {
 assert(!spapr->irq_map || bitmap_empty(spapr->irq_map, spapr->irq_map_nr));
 
+spapr_irq_update_active_intc(spapr);
+
 if (spapr->irq->reset) {
 spapr->irq->reset(spapr, errp);
 }
@@ -619,6 +622,54 @@ int spapr_irq_get_phandle(SpaprMachineState *spapr, void 
*fdt, Error **errp)
 return phandle;
 }
 
+static void set_active_intc(SpaprMachineState *spapr,
+SpaprInterruptController *new_intc)
+{
+SpaprInterruptControllerClass *sicc;
+
+assert(new_intc);
+
+if (new_intc == spapr->active_intc) {
+/* Nothing to do */
+return;
+}
+
+if (spapr->active_intc) {
+sicc = SPAPR_INTC_GET_CLASS(spapr->active_intc);
+if (sicc->deactivate) {
+sicc->deactivate(spapr->active_intc);
+}
+}
+
+sicc = SPAPR_INTC_GET_CLASS(new_intc);
+if (sicc->activate) {
+sicc->activate(new_intc, _fatal);
+}
+
+spapr->active_intc = new_intc;
+}
+
+void spapr_irq_update_active_intc(SpaprMachineState *spapr)
+{
+SpaprInterruptController *new_intc;
+
+if (!spapr->ics) {
+/*
+ * XXX before we run CAS, ov5_cas is initialized empty, which
+ * indicates XICS, even if we have ic-mode=xive.  TODO: clean
+ * up the CAS path so that we have a clearer way of handling
+ * this.
+ */
+new_intc = SPAPR_INTC(spapr->xive);
+} else if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
+new_intc = SPAPR_INTC(spapr->xive);
+} else {
+new_intc = SPAPR_INTC(spapr->ics);
+}
+
+set_active_intc(spapr, new_intc);
+}
+
 /*
  * XICS legacy routines - to deprecate one day
  */
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index cbd1a4c9f3..763da757f0 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -143,7 +143,6 @@ struct SpaprMachineState {
 struct SpaprVioBus *vio_bus;
 QLIST_HEAD(, SpaprPhbState) phbs;
 struct SpaprNvram *nvram;
-ICSState *ics;
 SpaprRtcState rtc;
 
 SpaprResizeHpt resize_hpt;
@@ -195,9 +194,11 @@ struct SpaprMachineState {
 
 int32_t irq_map_nr;
 unsigned long *irq_map;
-SpaprXive  *xive;
 SpaprIrq *irq;
 qemu_irq *qirqs;
+SpaprInterruptController *active_intc;
+ICSState *ics;
+SpaprXive *xive;
 
 bool cmd_line_caps[SPAPR_CAP_NUM];
 SpaprCapabilities def, eff, mig;
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index adfef0fcbe..18660a29db 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -44,6 +44,9 @@ typedef struct SpaprInterruptController 
SpaprInterruptController;
 typedef struct SpaprInterruptControllerClass {
 InterfaceClass parent;
 
+void (*activate)(SpaprInterruptController *intc, Error **errp);
+void (*deactivate)(SpaprInterruptController *intc);
+
 /*
  * These methods will typically be called on all intcs, active and
  * inactive
@@ -55,6 +58,8 @@ typedef struct SpaprInterruptControllerClass {
 void (*free_irq)(SpaprInterruptController *intc, int irq);
 } SpaprInterruptControllerClass;
 
+void spapr_irq_update_active_intc(SpaprMachineState *spapr);
+

[PATCH v3 10/34] spapr: Eliminate nr_irqs parameter to SpaprIrq::init

2019-10-01 Thread David Gibson
The only reason this parameter was needed was to work around the
inconsistent meaning of nr_irqs between xics and xive.  Now that we've
fixed that, we can consistently use the number directly in the SpaprIrq
configuration.

Signed-off-by: David Gibson 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Greg Kurz 
---
 hw/ppc/spapr_irq.c | 21 ++---
 include/hw/ppc/spapr_irq.h |  2 +-
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 3207b6bd01..cded3a0154 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -92,8 +92,7 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
  * XICS IRQ backend.
  */
 
-static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_xirqs,
-Error **errp)
+static void spapr_irq_init_xics(SpaprMachineState *spapr, Error **errp)
 {
 Object *obj;
 Error *local_err = NULL;
@@ -102,7 +101,8 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, 
int nr_xirqs,
 object_property_add_child(OBJECT(spapr), "ics", obj, _abort);
 object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
_fatal);
-object_property_set_int(obj, nr_xirqs, "nr-irqs",  _fatal);
+object_property_set_int(obj, spapr->irq->nr_xirqs,
+"nr-irqs",  _fatal);
 object_property_set_bool(obj, true, "realized", _err);
 if (local_err) {
 error_propagate(errp, local_err);
@@ -256,15 +256,15 @@ SpaprIrq spapr_irq_xics = {
 /*
  * XIVE IRQ backend.
  */
-static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_xirqs,
-Error **errp)
+static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
 {
 uint32_t nr_servers = spapr_max_server_number(spapr);
 DeviceState *dev;
 int i;
 
 dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
-qdev_prop_set_uint32(dev, "nr-irqs", nr_xirqs + SPAPR_XIRQ_BASE);
+qdev_prop_set_uint32(dev, "nr-irqs",
+ spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
 /*
  * 8 XIVE END structures per CPU. One for each available priority
  */
@@ -438,18 +438,17 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState 
*spapr)
 _irq_xive : _irq_xics;
 }
 
-static void spapr_irq_init_dual(SpaprMachineState *spapr, int nr_xirqs,
-Error **errp)
+static void spapr_irq_init_dual(SpaprMachineState *spapr, Error **errp)
 {
 Error *local_err = NULL;
 
-spapr_irq_xics.init(spapr, spapr_irq_xics.nr_xirqs, _err);
+spapr_irq_xics.init(spapr, _err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
 }
 
-spapr_irq_xive.init(spapr, spapr_irq_xive.nr_xirqs, _err);
+spapr_irq_xive.init(spapr, _err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
@@ -678,7 +677,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
 }
 
-spapr->irq->init(spapr, spapr->irq->nr_xirqs, errp);
+spapr->irq->init(spapr, errp);
 
 spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
   spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index a8f9a2ab11..7e26288fcd 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -41,7 +41,7 @@ typedef struct SpaprIrq {
 uint32_tnr_msis;
 uint8_t ov5;
 
-void (*init)(SpaprMachineState *spapr, int nr_irqs, Error **errp);
+void (*init)(SpaprMachineState *spapr, Error **errp);
 int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
 void (*free)(SpaprMachineState *spapr, int irq, int num);
 qemu_irq (*qirq)(SpaprMachineState *spapr, int irq);
-- 
2.21.0




[PATCH v3 14/34] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics()

2019-10-01 Thread David Gibson
These traces contain some useless information (the always-0 source#) and
have no equivalents for XIVE mode.  For now just remove them, and we can
put back something more sensible if and when we need it.

Signed-off-by: David Gibson 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Greg Kurz 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/ppc/spapr_irq.c  | 4 
 hw/ppc/trace-events | 4 
 2 files changed, 8 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index ec2229d2d1..9919910a86 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -140,11 +140,7 @@ static void spapr_irq_free_xics(SpaprMachineState *spapr, 
int irq, int num)
 int i;
 
 if (ics_valid_irq(ics, irq)) {
-trace_spapr_irq_free(0, irq, num);
 for (i = srcno; i < srcno + num; ++i) {
-if (ics_irq_free(ics, i)) {
-trace_spapr_irq_free_warn(0, i);
-}
 memset(>irqs[i], 0, sizeof(ICSIRQState));
 }
 }
diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events
index 96dad767a1..9ea620f23c 100644
--- a/hw/ppc/trace-events
+++ b/hw/ppc/trace-events
@@ -13,10 +13,6 @@ spapr_pci_msi_retry(unsigned config_addr, unsigned req_num, 
unsigned max_irqs) "
 spapr_cas_failed(unsigned long n) "DT diff buffer is too small: %ld bytes"
 spapr_cas_continue(unsigned long n) "Copy changes to the guest: %ld bytes"
 
-# spapr_irq.c
-spapr_irq_free(int src, int irq, int num) "Source#%d, first irq %d, %d irqs"
-spapr_irq_free_warn(int src, int irq) "Source#%d, irq %d is already free"
-
 # spapr_hcall.c
 spapr_cas_pvr(uint32_t cur_pvr, bool explicit_match, uint32_t new_pvr) 
"current=0x%x, explicit_match=%u, new=0x%x"
 spapr_h_resize_hpt_prepare(uint64_t flags, uint64_t shift) "flags=0x%"PRIx64", 
shift=%"PRIu64
-- 
2.21.0




[PATCH v3 21/34] spapr, xics, xive: Introduce SpaprInterruptController QOM interface

2019-10-01 Thread David Gibson
The SpaprIrq structure is used to represent ths spapr machine's irq
backend.  Except that it kind of conflates two concepts: one is the
backend proper - a specific interrupt controller that we might or
might not be using, the other is the irq configuration which covers
the layout of irq space and which interrupt controllers are allowed.

This leads to some pretty confusing code paths for the "dual"
configuration where its hooks redirect to other SpaprIrq structures
depending on the currently active irq controller.

To clean this up, we start by introducing a new
SpaprInterruptController QOM interface to represent strictly an
interrupt controller backend, not counting anything configuration
related.  We implement this interface in the XICs and XIVE interrupt
controllers, and in future we'll move relevant methods from SpaprIrq
into it.

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
Reviewed-by: Cédric Le Goater 
---
 hw/intc/spapr_xive.c   |  4 
 hw/intc/xics_spapr.c   |  4 
 hw/ppc/spapr_irq.c | 13 +
 include/hw/ppc/spapr_irq.h | 14 ++
 4 files changed, 35 insertions(+)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 04879abf2e..b67e9c3245 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -519,6 +519,10 @@ static const TypeInfo spapr_xive_info = {
 .instance_init = spapr_xive_instance_init,
 .instance_size = sizeof(SpaprXive),
 .class_init = spapr_xive_class_init,
+.interfaces = (InterfaceInfo[]) {
+{ TYPE_SPAPR_INTC },
+{ }
+},
 };
 
 static void spapr_xive_register_types(void)
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 6e5eb24b3c..4874e6be55 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -343,6 +343,10 @@ static const TypeInfo ics_spapr_info = {
 .name = TYPE_ICS_SPAPR,
 .parent = TYPE_ICS,
 .class_init = ics_spapr_class_init,
+.interfaces = (InterfaceInfo[]) {
+{ TYPE_SPAPR_INTC },
+{ }
+},
 };
 
 static void xics_spapr_register_types(void)
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 457eabe24c..8791dec1ba 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -23,6 +23,12 @@
 
 #include "trace.h"
 
+static const TypeInfo spapr_intc_info = {
+.name = TYPE_SPAPR_INTC,
+.parent = TYPE_INTERFACE,
+.class_size = sizeof(SpaprInterruptControllerClass),
+};
+
 void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis)
 {
 spapr->irq_map_nr = nr_msis;
@@ -762,3 +768,10 @@ SpaprIrq spapr_irq_xics_legacy = {
 .set_irq = spapr_irq_set_irq_xics,
 .init_kvm= spapr_irq_init_kvm_xics,
 };
+
+static void spapr_irq_register_types(void)
+{
+type_register_static(_intc_info);
+}
+
+type_init(spapr_irq_register_types)
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 69a37f608e..b9398e0be3 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -31,6 +31,20 @@
 
 typedef struct SpaprMachineState SpaprMachineState;
 
+typedef struct SpaprInterruptController SpaprInterruptController;
+
+#define TYPE_SPAPR_INTC "spapr-interrupt-controller"
+#define SPAPR_INTC(obj) \
+INTERFACE_CHECK(SpaprInterruptController, (obj), TYPE_SPAPR_INTC)
+#define SPAPR_INTC_CLASS(klass) \
+OBJECT_CLASS_CHECK(SpaprInterruptControllerClass, (klass), TYPE_SPAPR_INTC)
+#define SPAPR_INTC_GET_CLASS(obj)   \
+OBJECT_GET_CLASS(SpaprInterruptControllerClass, (obj), TYPE_SPAPR_INTC)
+
+typedef struct SpaprInterruptControllerClass {
+InterfaceClass parent;
+} SpaprInterruptControllerClass;
+
 void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
 int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
 Error **errp);
-- 
2.21.0




[PATCH v3 34/34] spapr: Remove last pieces of SpaprIrq

2019-10-01 Thread David Gibson
The only thing remaining in this structure are the flags to allow either
XICS or XIVE to be present.  These actually make more sense as spapr
capabilities - that way they can take advantage of the existing
infrastructure to sanity check capability states across migration and so
forth.

Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c | 38 +
 hw/ppc/spapr_caps.c| 64 +
 hw/ppc/spapr_hcall.c   |  7 ++--
 hw/ppc/spapr_irq.c | 84 ++
 include/hw/ppc/spapr.h |  8 ++--
 include/hw/ppc/spapr_irq.h | 10 -
 6 files changed, 99 insertions(+), 112 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index e1ff03152e..b9ac01d90c 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1072,12 +1072,13 @@ static void 
spapr_dt_ov5_platform_support(SpaprMachineState *spapr, void *fdt,
 26, 0x40, /* Radix options: GTSE == yes. */
 };
 
-if (spapr->irq->xics && spapr->irq->xive) {
+if (spapr_get_cap(spapr, SPAPR_CAP_XICS)
+&& spapr_get_cap(spapr, SPAPR_CAP_XIVE)) {
 val[1] = SPAPR_OV5_XIVE_BOTH;
-} else if (spapr->irq->xive) {
+} else if (spapr_get_cap(spapr, SPAPR_CAP_XIVE)) {
 val[1] = SPAPR_OV5_XIVE_EXPLOIT;
 } else {
-assert(spapr->irq->xics);
+assert(spapr_get_cap(spapr, SPAPR_CAP_XICS));
 val[1] = SPAPR_OV5_XIVE_LEGACY;
 }
 
@@ -2775,7 +2776,7 @@ static void spapr_machine_init(MachineState *machine)
 spapr_ovec_set(spapr->ov5, OV5_DRMEM_V2);
 
 /* advertise XIVE on POWER9 machines */
-if (spapr->irq->xive) {
+if (spapr_get_cap(spapr, SPAPR_CAP_XIVE)) {
 spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT);
 }
 
@@ -3242,14 +3243,18 @@ static void spapr_set_vsmt(Object *obj, Visitor *v, 
const char *name,
 static char *spapr_get_ic_mode(Object *obj, Error **errp)
 {
 SpaprMachineState *spapr = SPAPR_MACHINE(obj);
+SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
 
-if (spapr->irq == _irq_xics_legacy) {
+if (smc->legacy_irq_allocation) {
 return g_strdup("legacy");
-} else if (spapr->irq == _irq_xics) {
+} else if (spapr_get_cap(spapr, SPAPR_CAP_XICS)
+   && !spapr_get_cap(spapr, SPAPR_CAP_XIVE)) {
 return g_strdup("xics");
-} else if (spapr->irq == _irq_xive) {
+} else if (!spapr_get_cap(spapr, SPAPR_CAP_XICS)
+   && spapr_get_cap(spapr, SPAPR_CAP_XIVE)) {
 return g_strdup("xive");
-} else if (spapr->irq == _irq_dual) {
+} else if (spapr_get_cap(spapr, SPAPR_CAP_XICS)
+   && spapr_get_cap(spapr, SPAPR_CAP_XIVE)) {
 return g_strdup("dual");
 }
 g_assert_not_reached();
@@ -3266,11 +3271,14 @@ static void spapr_set_ic_mode(Object *obj, const char 
*value, Error **errp)
 
 /* The legacy IRQ backend can not be set */
 if (strcmp(value, "xics") == 0) {
-spapr->irq = _irq_xics;
+object_property_set_bool(obj, true, "cap-xics", errp);
+object_property_set_bool(obj, false, "cap-xive", errp);
 } else if (strcmp(value, "xive") == 0) {
-spapr->irq = _irq_xive;
+object_property_set_bool(obj, false, "cap-xics", errp);
+object_property_set_bool(obj, true, "cap-xive", errp);
 } else if (strcmp(value, "dual") == 0) {
-spapr->irq = _irq_dual;
+object_property_set_bool(obj, true, "cap-xics", errp);
+object_property_set_bool(obj, true, "cap-xive", errp);
 } else {
 error_setg(errp, "Bad value for \"ic-mode\" property");
 }
@@ -3309,7 +3317,6 @@ static void spapr_set_host_serial(Object *obj, const char 
*value, Error **errp)
 static void spapr_instance_init(Object *obj)
 {
 SpaprMachineState *spapr = SPAPR_MACHINE(obj);
-SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
 
 spapr->htab_fd = -1;
 spapr->use_hotplug_event_source = true;
@@ -3345,7 +3352,6 @@ static void spapr_instance_init(Object *obj)
  spapr_get_msix_emulation, NULL, NULL);
 
 /* The machine class defines the default interrupt controller mode */
-spapr->irq = smc->irq;
 object_property_add_str(obj, "ic-mode", spapr_get_ic_mode,
 spapr_set_ic_mode, NULL);
 object_property_set_description(obj, "ic-mode",
@@ -4439,8 +4445,9 @@ static void spapr_machine_class_init(ObjectClass *oc, 
void *data)
 smc->default_caps.caps[SPAPR_CAP_NESTED_KVM_HV] = SPAPR_CAP_OFF;
 smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_ON;
 smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF;
+smc->default_caps.caps[SPAPR_CAP_XICS] = SPAPR_CAP_ON;
+smc->default_caps.caps[SPAPR_CAP_XIVE] = SPAPR_CAP_ON;
 spapr_caps_add_properties(smc, _abort);
-smc->irq = _irq_dual;
 smc->dr_phb_enabled = true;
 smc->linux_pci_probe = true;
 smc->nr_xirqs = SPAPR_NR_XIRQS;
@@ -4539,7 +4546,7 @@ static void 

[PATCH v3 31/34] spapr, xics, xive: Move SpaprIrq::post_load hook to backends

2019-10-01 Thread David Gibson
The remaining logic in the post_load hook really belongs to the interrupt
controller backends, and just needs to be called on the active controller
(after the active controller is set to the right thing based on the
incoming migration in the generic spapr_irq_post_load() logic).

Signed-off-by: David Gibson 
---
 hw/intc/spapr_xive.c|  5 +++--
 hw/intc/xics_spapr.c| 13 +++
 hw/ppc/spapr_irq.c  | 45 -
 include/hw/ppc/spapr_irq.h  |  3 +--
 include/hw/ppc/spapr_xive.h |  1 -
 5 files changed, 21 insertions(+), 46 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index e8b946982c..ab68e6eaf6 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -462,10 +462,10 @@ static int vmstate_spapr_xive_pre_save(void *opaque)
  * Called by the sPAPR IRQ backend 'post_load' method at the machine
  * level.
  */
-int spapr_xive_post_load(SpaprXive *xive, int version_id)
+static int spapr_xive_post_load(SpaprInterruptController *intc, int version_id)
 {
 if (kvm_irqchip_in_kernel()) {
-return kvmppc_xive_post_load(xive, version_id);
+return kvmppc_xive_post_load(SPAPR_XIVE(intc), version_id);
 }
 
 return 0;
@@ -699,6 +699,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void 
*data)
 sicc->set_irq = spapr_xive_set_irq;
 sicc->print_info = spapr_xive_print_info;
 sicc->dt = spapr_xive_dt;
+sicc->post_load = spapr_xive_post_load;
 }
 
 static const TypeInfo spapr_xive_info = {
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 8abbc799ba..9590eedc3d 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -395,6 +395,18 @@ static void xics_spapr_print_info(SpaprInterruptController 
*intc, Monitor *mon)
 ics_pic_print_info(ics, mon);
 }
 
+static int xics_spapr_post_load(SpaprInterruptController *intc, int version_id)
+{
+if (!kvm_irqchip_in_kernel()) {
+CPUState *cs;
+CPU_FOREACH(cs) {
+PowerPCCPU *cpu = POWERPC_CPU(cs);
+icp_resend(spapr_cpu_state(cpu)->icp);
+}
+}
+return 0;
+}
+
 static void xics_spapr_activate(SpaprInterruptController *intc, Error **errp)
 {
 if (kvm_enabled()) {
@@ -425,6 +437,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void 
*data)
 sicc->set_irq = xics_spapr_set_irq;
 sicc->print_info = xics_spapr_print_info;
 sicc->dt = xics_spapr_dt;
+sicc->post_load = xics_spapr_post_load;
 }
 
 static const TypeInfo ics_spapr_info = {
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index f70b331f44..f3d18b1dad 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -100,43 +100,22 @@ int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController 
*, Error **),
  * XICS IRQ backend.
  */
 
-static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
-{
-if (!kvm_irqchip_in_kernel()) {
-CPUState *cs;
-CPU_FOREACH(cs) {
-PowerPCCPU *cpu = POWERPC_CPU(cs);
-icp_resend(spapr_cpu_state(cpu)->icp);
-}
-}
-return 0;
-}
-
 SpaprIrq spapr_irq_xics = {
 .nr_xirqs= SPAPR_NR_XIRQS,
 .nr_msis = SPAPR_NR_MSIS,
 .xics= true,
 .xive= false,
-
-.post_load   = spapr_irq_post_load_xics,
 };
 
 /*
  * XIVE IRQ backend.
  */
 
-static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id)
-{
-return spapr_xive_post_load(spapr->xive, version_id);
-}
-
 SpaprIrq spapr_irq_xive = {
 .nr_xirqs= SPAPR_NR_XIRQS,
 .nr_msis = SPAPR_NR_MSIS,
 .xics= false,
 .xive= true,
-
-.post_load   = spapr_irq_post_load_xive,
 };
 
 /*
@@ -148,21 +127,6 @@ SpaprIrq spapr_irq_xive = {
  * activated after an extra machine reset.
  */
 
-/*
- * Returns the sPAPR IRQ backend negotiated by CAS. XICS is the
- * default.
- */
-static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
-{
-return spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT) ?
-_irq_xive : _irq_xics;
-}
-
-static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id)
-{
-return spapr_irq_current(spapr)->post_load(spapr, version_id);
-}
-
 /*
  * Define values in sync with the XIVE and XICS backend
  */
@@ -171,8 +135,6 @@ SpaprIrq spapr_irq_dual = {
 .nr_msis = SPAPR_NR_MSIS,
 .xics= true,
 .xive= true,
-
-.post_load   = spapr_irq_post_load_dual,
 };
 
 
@@ -447,8 +409,11 @@ qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
 
 int spapr_irq_post_load(SpaprMachineState *spapr, int version_id)
 {
+SpaprInterruptControllerClass *sicc;
+
 spapr_irq_update_active_intc(spapr);
-return spapr->irq->post_load(spapr, version_id);
+sicc = SPAPR_INTC_GET_CLASS(spapr->active_intc);
+return sicc->post_load(spapr->active_intc, version_id);
 }
 
 void spapr_irq_reset(SpaprMachineState *spapr, Error **errp)
@@ -589,8 +554,6 @@ SpaprIrq spapr_irq_xics_legacy = {

[PATCH v3 15/34] spapr: Handle freeing of multiple irqs in frontend only

2019-10-01 Thread David Gibson
spapr_irq_free() can be used to free multiple irqs at once. That's useful
for its callers, but there's no need to make the individual backend hooks
handle this.  We can loop across the irqs in spapr_irq_free() itself and
have the hooks just do one at time.

Signed-off-by: David Gibson 
---
 hw/ppc/spapr_irq.c | 27 ---
 include/hw/ppc/spapr_irq.h |  2 +-
 2 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 9919910a86..d2ac35bbe1 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -133,16 +133,13 @@ static int spapr_irq_claim_xics(SpaprMachineState *spapr, 
int irq, bool lsi,
 return 0;
 }
 
-static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq, int num)
+static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq)
 {
 ICSState *ics = spapr->ics;
 uint32_t srcno = irq - ics->offset;
-int i;
 
 if (ics_valid_irq(ics, irq)) {
-for (i = srcno; i < srcno + num; ++i) {
-memset(>irqs[i], 0, sizeof(ICSIRQState));
-}
+memset(>irqs[srcno], 0, sizeof(ICSIRQState));
 }
 }
 
@@ -269,13 +266,9 @@ static int spapr_irq_claim_xive(SpaprMachineState *spapr, 
int irq, bool lsi,
 return 0;
 }
 
-static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq, int num)
+static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
 {
-int i;
-
-for (i = irq; i < irq + num; ++i) {
-spapr_xive_irq_free(spapr->xive, i);
-}
+spapr_xive_irq_free(spapr->xive, irq);
 }
 
 static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
@@ -433,10 +426,10 @@ static int spapr_irq_claim_dual(SpaprMachineState *spapr, 
int irq, bool lsi,
 return ret;
 }
 
-static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq, int num)
+static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq)
 {
-spapr_irq_xics.free(spapr, irq, num);
-spapr_irq_xive.free(spapr, irq, num);
+spapr_irq_xics.free(spapr, irq);
+spapr_irq_xive.free(spapr, irq);
 }
 
 static void spapr_irq_print_info_dual(SpaprMachineState *spapr, Monitor *mon)
@@ -635,7 +628,11 @@ int spapr_irq_claim(SpaprMachineState *spapr, int irq, 
bool lsi, Error **errp)
 
 void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
 {
-spapr->irq->free(spapr, irq, num);
+int i;
+
+for (i = irq; i < (irq + num); i++) {
+spapr->irq->free(spapr, i);
+}
 }
 
 qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 9b60378e28..ed88b4599a 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -43,7 +43,7 @@ typedef struct SpaprIrq {
 
 void (*init)(SpaprMachineState *spapr, Error **errp);
 int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
-void (*free)(SpaprMachineState *spapr, int irq, int num);
+void (*free)(SpaprMachineState *spapr, int irq);
 void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
 void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
 void *fdt, uint32_t phandle);
-- 
2.21.0




[PATCH v3 16/34] spapr, xics, xive: Better use of assert()s on irq claim/free paths

2019-10-01 Thread David Gibson
The irq claim and free paths for both XICS and XIVE check for some
validity conditions.  Some of these represent genuine runtime failures,
however others - particularly checking that the basic irq number is in a
sane range - could only fail in the case of bugs in the callin code.
Therefore use assert()s instead of runtime failures for those.

In addition the non backend-specific part of the claim/free paths should
only be used for PAPR external irqs, that is in the range SPAPR_XIRQ_BASE
to the maximum irq number.  Put assert()s for that into the top level
dispatchers as well.

Signed-off-by: David Gibson 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Greg Kurz 
---
 hw/intc/spapr_xive.c |  8 ++--
 hw/ppc/spapr_irq.c   | 18 ++
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index c1c97192a7..47b5ec0b56 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -532,9 +532,7 @@ bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, 
bool lsi)
 {
 XiveSource *xsrc = >source;
 
-if (lisn >= xive->nr_irqs) {
-return false;
-}
+assert(lisn < xive->nr_irqs);
 
 /*
  * Set default values when allocating an IRQ number
@@ -559,9 +557,7 @@ bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, 
bool lsi)
 
 bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn)
 {
-if (lisn >= xive->nr_irqs) {
-return false;
-}
+assert(lisn < xive->nr_irqs);
 
 xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
 return true;
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index d2ac35bbe1..025c802e7b 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -118,11 +118,7 @@ static int spapr_irq_claim_xics(SpaprMachineState *spapr, 
int irq, bool lsi,
 ICSState *ics = spapr->ics;
 
 assert(ics);
-
-if (!ics_valid_irq(ics, irq)) {
-error_setg(errp, "IRQ %d is invalid", irq);
-return -1;
-}
+assert(ics_valid_irq(ics, irq));
 
 if (!ics_irq_free(ics, irq - ics->offset)) {
 error_setg(errp, "IRQ %d is not free", irq);
@@ -138,9 +134,9 @@ static void spapr_irq_free_xics(SpaprMachineState *spapr, 
int irq)
 ICSState *ics = spapr->ics;
 uint32_t srcno = irq - ics->offset;
 
-if (ics_valid_irq(ics, irq)) {
-memset(>irqs[srcno], 0, sizeof(ICSIRQState));
-}
+assert(ics_valid_irq(ics, irq));
+
+memset(>irqs[srcno], 0, sizeof(ICSIRQState));
 }
 
 static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon)
@@ -623,6 +619,9 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 
 int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
 {
+assert(irq >= SPAPR_XIRQ_BASE);
+assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
+
 return spapr->irq->claim(spapr, irq, lsi, errp);
 }
 
@@ -630,6 +629,9 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int 
num)
 {
 int i;
 
+assert(irq >= SPAPR_XIRQ_BASE);
+assert((irq + num) <= (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
+
 for (i = irq; i < (irq + num); i++) {
 spapr->irq->free(spapr, i);
 }
-- 
2.21.0




[PATCH v3 08/34] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper

2019-10-01 Thread David Gibson
Every caller of spapr_vio_qirq() immediately calls qemu_irq_pulse() with
the result, so we might as well just fold that into the helper.

Signed-off-by: David Gibson 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Greg Kurz 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/char/spapr_vty.c| 3 +--
 hw/net/spapr_llan.c| 3 +--
 hw/ppc/spapr_vio.c | 3 +--
 include/hw/ppc/spapr_vio.h | 5 +++--
 4 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
index 087c93e4fa..8f4d9fe472 100644
--- a/hw/char/spapr_vty.c
+++ b/hw/char/spapr_vty.c
@@ -5,7 +5,6 @@
 #include "cpu.h"
 #include "migration/vmstate.h"
 #include "chardev/char-fe.h"
-#include "hw/irq.h"
 #include "hw/ppc/spapr.h"
 #include "hw/ppc/spapr_vio.h"
 #include "hw/qdev-properties.h"
@@ -37,7 +36,7 @@ static void vty_receive(void *opaque, const uint8_t *buf, int 
size)
 
 if ((dev->in == dev->out) && size) {
 /* toggle line to simulate edge interrupt */
-qemu_irq_pulse(spapr_vio_qirq(>sdev));
+spapr_vio_irq_pulse(>sdev);
 }
 for (i = 0; i < size; i++) {
 if (dev->in - dev->out >= VTERM_BUFSIZE) {
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
index 701e6e1514..3d96884d66 100644
--- a/hw/net/spapr_llan.c
+++ b/hw/net/spapr_llan.c
@@ -27,7 +27,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "hw/irq.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
 #include "net/net.h"
@@ -267,7 +266,7 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const 
uint8_t *buf,
 }
 
 if (sdev->signal_state & 1) {
-qemu_irq_pulse(spapr_vio_qirq(sdev));
+spapr_vio_irq_pulse(sdev);
 }
 
 return size;
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index 0803649658..554de9930d 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -23,7 +23,6 @@
 #include "qemu/error-report.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
-#include "hw/irq.h"
 #include "qemu/log.h"
 #include "hw/loader.h"
 #include "elf.h"
@@ -294,7 +293,7 @@ int spapr_vio_send_crq(SpaprVioDevice *dev, uint8_t *crq)
 dev->crq.qnext = (dev->crq.qnext + 16) % dev->crq.qsize;
 
 if (dev->signal_state & 1) {
-qemu_irq_pulse(spapr_vio_qirq(dev));
+spapr_vio_irq_pulse(dev);
 }
 
 return 0;
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index 875be28cdd..72762ed16b 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -24,6 +24,7 @@
 
 #include "hw/ppc/spapr.h"
 #include "sysemu/dma.h"
+#include "hw/irq.h"
 
 #define TYPE_VIO_SPAPR_DEVICE "vio-spapr-device"
 #define VIO_SPAPR_DEVICE(obj) \
@@ -84,11 +85,11 @@ extern SpaprVioDevice *spapr_vio_find_by_reg(SpaprVioBus 
*bus, uint32_t reg);
 void spapr_dt_vdevice(SpaprVioBus *bus, void *fdt);
 extern gchar *spapr_vio_stdout_path(SpaprVioBus *bus);
 
-static inline qemu_irq spapr_vio_qirq(SpaprVioDevice *dev)
+static inline void spapr_vio_irq_pulse(SpaprVioDevice *dev)
 {
 SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
 
-return spapr_qirq(spapr, dev->irq);
+qemu_irq_pulse(spapr_qirq(spapr, dev->irq));
 }
 
 static inline bool spapr_vio_dma_valid(SpaprVioDevice *dev, uint64_t taddr,
-- 
2.21.0




[PATCH v3 20/34] spapr: Eliminate SpaprIrq::init hook

2019-10-01 Thread David Gibson
This method is used to set up the interrupt backends for the current
configuration.  However, this means some confusing redirection between
the "dual" mode init and the init hooks for xics only and xive only modes.

Since we now have simple flags indicating whether XICS and/or XIVE are
supported, it's easier to just open code each initialization directly in
spapr_irq_init().  This will also make some future cleanups simpler.

Signed-off-by: David Gibson 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Greg Kurz 
---
 hw/ppc/spapr_irq.c | 130 +
 include/hw/ppc/spapr_irq.h |   1 -
 2 files changed, 61 insertions(+), 70 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 0413fbd0a3..457eabe24c 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -92,26 +92,6 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
  * XICS IRQ backend.
  */
 
-static void spapr_irq_init_xics(SpaprMachineState *spapr, Error **errp)
-{
-Object *obj;
-Error *local_err = NULL;
-
-obj = object_new(TYPE_ICS_SPAPR);
-object_property_add_child(OBJECT(spapr), "ics", obj, _abort);
-object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
-   _fatal);
-object_property_set_int(obj, spapr->irq->nr_xirqs,
-"nr-irqs",  _fatal);
-object_property_set_bool(obj, true, "realized", _err);
-if (local_err) {
-error_propagate(errp, local_err);
-return;
-}
-
-spapr->ics = ICS_SPAPR(obj);
-}
-
 static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
 Error **errp)
 {
@@ -213,7 +193,6 @@ SpaprIrq spapr_irq_xics = {
 .xics= true,
 .xive= false,
 
-.init= spapr_irq_init_xics,
 .claim   = spapr_irq_claim_xics,
 .free= spapr_irq_free_xics,
 .print_info  = spapr_irq_print_info_xics,
@@ -228,33 +207,6 @@ SpaprIrq spapr_irq_xics = {
 /*
  * XIVE IRQ backend.
  */
-static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
-{
-uint32_t nr_servers = spapr_max_server_number(spapr);
-DeviceState *dev;
-int i;
-
-dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
-qdev_prop_set_uint32(dev, "nr-irqs",
- spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
-/*
- * 8 XIVE END structures per CPU. One for each available priority
- */
-qdev_prop_set_uint32(dev, "nr-ends", nr_servers << 3);
-qdev_init_nofail(dev);
-
-spapr->xive = SPAPR_XIVE(dev);
-
-/* Enable the CPU IPIs */
-for (i = 0; i < nr_servers; ++i) {
-if (spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
- false, errp) < 0) {
-return;
-}
-}
-
-spapr_xive_hcall_init(spapr);
-}
 
 static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
 Error **errp)
@@ -354,7 +306,6 @@ SpaprIrq spapr_irq_xive = {
 .xics= false,
 .xive= true,
 
-.init= spapr_irq_init_xive,
 .claim   = spapr_irq_claim_xive,
 .free= spapr_irq_free_xive,
 .print_info  = spapr_irq_print_info_xive,
@@ -385,23 +336,6 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState 
*spapr)
 _irq_xive : _irq_xics;
 }
 
-static void spapr_irq_init_dual(SpaprMachineState *spapr, Error **errp)
-{
-Error *local_err = NULL;
-
-spapr_irq_xics.init(spapr, _err);
-if (local_err) {
-error_propagate(errp, local_err);
-return;
-}
-
-spapr_irq_xive.init(spapr, _err);
-if (local_err) {
-error_propagate(errp, local_err);
-return;
-}
-}
-
 static int spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
 Error **errp)
 {
@@ -516,7 +450,6 @@ SpaprIrq spapr_irq_dual = {
 .xics= true,
 .xive= true,
 
-.init= spapr_irq_init_dual,
 .claim   = spapr_irq_claim_dual,
 .free= spapr_irq_free_dual,
 .print_info  = spapr_irq_print_info_dual,
@@ -612,7 +545,67 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
 }
 
-spapr->irq->init(spapr, errp);
+if (spapr->irq->xics) {
+Error *local_err = NULL;
+Object *obj;
+
+obj = object_new(TYPE_ICS_SPAPR);
+object_property_add_child(OBJECT(spapr), "ics", obj, _err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+
+object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
+   _err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+
+object_property_set_int(obj, spapr->irq->nr_xirqs, "nr-irqs",
+_err);
+if 

[PATCH v3 01/34] xics: Minor fixes for XICSFabric interface

2019-10-01 Thread David Gibson
Interface instances should never be directly dereferenced.  So, the common
practice is to make them incomplete types to make sure no-one does that.
XICSFrabric, however, had a dummy type which is less safe.

We were also using OBJECT_CHECK() where we should have been using
INTERFACE_CHECK().

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
---
 include/hw/ppc/xics.h | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 64a2c8862a..faa33ae943 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -147,13 +147,9 @@ struct ICSIRQState {
 uint8_t flags;
 };
 
-struct XICSFabric {
-Object parent;
-};
-
 #define TYPE_XICS_FABRIC "xics-fabric"
 #define XICS_FABRIC(obj) \
-OBJECT_CHECK(XICSFabric, (obj), TYPE_XICS_FABRIC)
+INTERFACE_CHECK(XICSFabric, (obj), TYPE_XICS_FABRIC)
 #define XICS_FABRIC_CLASS(klass) \
 OBJECT_CLASS_CHECK(XICSFabricClass, (klass), TYPE_XICS_FABRIC)
 #define XICS_FABRIC_GET_CLASS(obj)   \
-- 
2.21.0




[PATCH v3 11/34] spapr: Fix indexing of XICS irqs

2019-10-01 Thread David Gibson
spapr global irq numbers are different from the source numbers on the ICS
when using XICS - they're offset by XICS_IRQ_BASE (0x1000).  But
spapr_irq_set_irq_xics() was passing through the global irq number to
the ICS code unmodified.

We only got away with this because of a counteracting bug - we were
incorrectly adjusting the qemu_irq we returned for a requested global irq
number.

That approach mostly worked but is very confusing, incorrectly relies on
the way the qemu_irq array is allocated, and undermines the intention of
having the global array of qemu_irqs for spapr have a consistent meaning
regardless of irq backend.

So, fix both set_irq and qemu_irq indexing.  We rename some parameters at
the same time to make it clear that they are referring to spapr global
irq numbers.

Signed-off-by: David Gibson 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Greg Kurz 
---
 hw/ppc/spapr_irq.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index cded3a0154..8f79aa829f 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -153,10 +153,9 @@ static void spapr_irq_free_xics(SpaprMachineState *spapr, 
int irq, int num)
 static qemu_irq spapr_qirq_xics(SpaprMachineState *spapr, int irq)
 {
 ICSState *ics = spapr->ics;
-uint32_t srcno = irq - ics->offset;
 
 if (ics_valid_irq(ics, irq)) {
-return spapr->qirqs[srcno];
+return spapr->qirqs[irq];
 }
 
 return NULL;
@@ -204,9 +203,10 @@ static int spapr_irq_post_load_xics(SpaprMachineState 
*spapr, int version_id)
 return 0;
 }
 
-static void spapr_irq_set_irq_xics(void *opaque, int srcno, int val)
+static void spapr_irq_set_irq_xics(void *opaque, int irq, int val)
 {
 SpaprMachineState *spapr = opaque;
+uint32_t srcno = irq - spapr->ics->offset;
 
 ics_set_irq(spapr->ics, srcno, val);
 }
@@ -377,14 +377,14 @@ static void spapr_irq_reset_xive(SpaprMachineState 
*spapr, Error **errp)
 spapr_xive_mmio_set_enabled(spapr->xive, true);
 }
 
-static void spapr_irq_set_irq_xive(void *opaque, int srcno, int val)
+static void spapr_irq_set_irq_xive(void *opaque, int irq, int val)
 {
 SpaprMachineState *spapr = opaque;
 
 if (kvm_irqchip_in_kernel()) {
-kvmppc_xive_source_set_irq(>xive->source, srcno, val);
+kvmppc_xive_source_set_irq(>xive->source, irq, val);
 } else {
-xive_source_set_irq(>xive->source, srcno, val);
+xive_source_set_irq(>xive->source, irq, val);
 }
 }
 
@@ -558,11 +558,11 @@ static void spapr_irq_reset_dual(SpaprMachineState 
*spapr, Error **errp)
 spapr_irq_current(spapr)->reset(spapr, errp);
 }
 
-static void spapr_irq_set_irq_dual(void *opaque, int srcno, int val)
+static void spapr_irq_set_irq_dual(void *opaque, int irq, int val)
 {
 SpaprMachineState *spapr = opaque;
 
-spapr_irq_current(spapr)->set_irq(spapr, srcno, val);
+spapr_irq_current(spapr)->set_irq(spapr, irq, val);
 }
 
 static const char *spapr_irq_get_nodename_dual(SpaprMachineState *spapr)
-- 
2.21.0




[PATCH v3 12/34] spapr: Simplify spapr_qirq() handling

2019-10-01 Thread David Gibson
Currently spapr_qirq(), whic is used to find the qemu_irq for an spapr
global irq number, redirects through the SpaprIrq::qirq method.  But
the array of qemu_irqs is allocated in the PAPR layer, not the
backends, and so the method implementations all return the same thing,
just differing in the preliminary checks they make.

So, we can remove the method, and just implement spapr_qirq() directly,
including all the relevant checks in one place.  We change all those
checks into assert()s as well, since a failure here indicates an error in
the calling code.

Signed-off-by: David Gibson 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Greg Kurz 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/ppc/spapr_irq.c | 54 ++
 include/hw/ppc/spapr_irq.h |  1 -
 2 files changed, 19 insertions(+), 36 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 8f79aa829f..8f179076c6 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -150,17 +150,6 @@ static void spapr_irq_free_xics(SpaprMachineState *spapr, 
int irq, int num)
 }
 }
 
-static qemu_irq spapr_qirq_xics(SpaprMachineState *spapr, int irq)
-{
-ICSState *ics = spapr->ics;
-
-if (ics_valid_irq(ics, irq)) {
-return spapr->qirqs[irq];
-}
-
-return NULL;
-}
-
 static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon)
 {
 CPUState *cs;
@@ -242,7 +231,6 @@ SpaprIrq spapr_irq_xics = {
 .init= spapr_irq_init_xics,
 .claim   = spapr_irq_claim_xics,
 .free= spapr_irq_free_xics,
-.qirq= spapr_qirq_xics,
 .print_info  = spapr_irq_print_info_xics,
 .dt_populate = spapr_dt_xics,
 .cpu_intc_create = spapr_irq_cpu_intc_create_xics,
@@ -300,20 +288,6 @@ static void spapr_irq_free_xive(SpaprMachineState *spapr, 
int irq, int num)
 }
 }
 
-static qemu_irq spapr_qirq_xive(SpaprMachineState *spapr, int irq)
-{
-SpaprXive *xive = spapr->xive;
-
-if ((irq < SPAPR_XIRQ_BASE) || (irq >= xive->nr_irqs)) {
-return NULL;
-}
-
-/* The sPAPR machine/device should have claimed the IRQ before */
-assert(xive_eas_is_valid(>eat[irq]));
-
-return spapr->qirqs[irq];
-}
-
 static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
   Monitor *mon)
 {
@@ -408,7 +382,6 @@ SpaprIrq spapr_irq_xive = {
 .init= spapr_irq_init_xive,
 .claim   = spapr_irq_claim_xive,
 .free= spapr_irq_free_xive,
-.qirq= spapr_qirq_xive,
 .print_info  = spapr_irq_print_info_xive,
 .dt_populate = spapr_dt_xive,
 .cpu_intc_create = spapr_irq_cpu_intc_create_xive,
@@ -482,11 +455,6 @@ static void spapr_irq_free_dual(SpaprMachineState *spapr, 
int irq, int num)
 spapr_irq_xive.free(spapr, irq, num);
 }
 
-static qemu_irq spapr_qirq_dual(SpaprMachineState *spapr, int irq)
-{
-return spapr_irq_current(spapr)->qirq(spapr, irq);
-}
-
 static void spapr_irq_print_info_dual(SpaprMachineState *spapr, Monitor *mon)
 {
 spapr_irq_current(spapr)->print_info(spapr, mon);
@@ -581,7 +549,6 @@ SpaprIrq spapr_irq_dual = {
 .init= spapr_irq_init_dual,
 .claim   = spapr_irq_claim_dual,
 .free= spapr_irq_free_dual,
-.qirq= spapr_qirq_dual,
 .print_info  = spapr_irq_print_info_dual,
 .dt_populate = spapr_irq_dt_populate_dual,
 .cpu_intc_create = spapr_irq_cpu_intc_create_dual,
@@ -695,7 +662,25 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int 
num)
 
 qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
 {
-return spapr->irq->qirq(spapr, irq);
+/*
+ * This interface is basically for VIO and PHB devices to find the
+ * right qemu_irq to manipulate, so we only allow access to the
+ * external irqs for now.  Currently anything which needs to
+ * access the IPIs most naturally gets there via the guest side
+ * interfaces, we can change this if we need to in future.
+ */
+assert(irq >= SPAPR_XIRQ_BASE);
+assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
+
+if (spapr->ics) {
+assert(ics_valid_irq(spapr->ics, irq));
+}
+if (spapr->xive) {
+assert(irq < spapr->xive->nr_irqs);
+assert(xive_eas_is_valid(>xive->eat[irq]));
+}
+
+return spapr->qirqs[irq];
 }
 
 int spapr_irq_post_load(SpaprMachineState *spapr, int version_id)
@@ -798,7 +783,6 @@ SpaprIrq spapr_irq_xics_legacy = {
 .init= spapr_irq_init_xics,
 .claim   = spapr_irq_claim_xics,
 .free= spapr_irq_free_xics,
-.qirq= spapr_qirq_xics,
 .print_info  = spapr_irq_print_info_xics,
 .dt_populate = spapr_dt_xics,
 .cpu_intc_create = spapr_irq_cpu_intc_create_xics,
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 7e26288fcd..a4e790ef60 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -44,7 +44,6 @@ typedef struct SpaprIrq {
 void 

[PATCH v3 06/34] xics: Create sPAPR specific ICS subtype

2019-10-01 Thread David Gibson
We create a subtype of TYPE_ICS specifically for sPAPR.  For now all this
does is move the setup of the PAPR specific hcalls and RTAS calls to
the realize() function for this, rather than requiring the PAPR code to
explicitly call xics_spapr_init().  In future it will have some more
function.

Signed-off-by: David Gibson 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Greg Kurz 
---
 hw/intc/xics_spapr.c| 34 +-
 hw/ppc/spapr_irq.c  |  6 ++
 include/hw/ppc/xics_spapr.h |  4 +++-
 3 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 3e9444813a..e6dd004587 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -283,8 +283,18 @@ static void rtas_int_on(PowerPCCPU *cpu, SpaprMachineState 
*spapr,
 rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
 
-void xics_spapr_init(SpaprMachineState *spapr)
+static void ics_spapr_realize(DeviceState *dev, Error **errp)
 {
+ICSState *ics = ICS_SPAPR(dev);
+ICSStateClass *icsc = ICS_GET_CLASS(ics);
+Error *local_err = NULL;
+
+icsc->parent_realize(dev, _err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+
 spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_set_xive);
 spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_get_xive);
 spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_int_off);
@@ -319,3 +329,25 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t 
nr_servers, void *fdt,
 _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle));
 _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
 }
+
+static void ics_spapr_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+ICSStateClass *isc = ICS_CLASS(klass);
+
+device_class_set_parent_realize(dc, ics_spapr_realize,
+>parent_realize);
+}
+
+static const TypeInfo ics_spapr_info = {
+.name = TYPE_ICS_SPAPR,
+.parent = TYPE_ICS,
+.class_init = ics_spapr_class_init,
+};
+
+static void xics_spapr_register_types(void)
+{
+type_register_static(_spapr_info);
+}
+
+type_init(xics_spapr_register_types)
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 6c45d2a3c0..8c26fa2d1e 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -98,7 +98,7 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int 
nr_irqs,
 Object *obj;
 Error *local_err = NULL;
 
-obj = object_new(TYPE_ICS);
+obj = object_new(TYPE_ICS_SPAPR);
 object_property_add_child(OBJECT(spapr), "ics", obj, _abort);
 object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
_fatal);
@@ -109,9 +109,7 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, 
int nr_irqs,
 return;
 }
 
-spapr->ics = ICS(obj);
-
-xics_spapr_init(spapr);
+spapr->ics = ICS_SPAPR(obj);
 }
 
 static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
index 5dabc9a138..691a6d00f7 100644
--- a/include/hw/ppc/xics_spapr.h
+++ b/include/hw/ppc/xics_spapr.h
@@ -31,11 +31,13 @@
 
 #define XICS_NODENAME "interrupt-controller"
 
+#define TYPE_ICS_SPAPR "ics-spapr"
+#define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
+
 void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
uint32_t phandle);
 int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
 void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
 bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr);
-void xics_spapr_init(SpaprMachineState *spapr);
 
 #endif /* XICS_SPAPR_H */
-- 
2.21.0




[PATCH v3 03/34] xics: Rename misleading ics_simple_*() functions

2019-10-01 Thread David Gibson
There are a number of ics_simple_*() functions that aren't actually
specific to TYPE_XICS_SIMPLE at all, and are equally valid on
TYPE_XICS_BASE.  Rename them to ics_*() accordingly.

Signed-off-by: David Gibson 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Greg Kurz 
---
 hw/intc/trace-events  |  6 +++---
 hw/intc/xics.c| 29 ++---
 hw/intc/xics_spapr.c  | 12 ++--
 hw/ppc/pnv_psi.c  |  4 ++--
 hw/ppc/spapr_irq.c|  2 +-
 include/hw/ppc/xics.h |  6 +++---
 6 files changed, 29 insertions(+), 30 deletions(-)

diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index fdc716c2cc..527c3f76ca 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -66,10 +66,10 @@ xics_icp_accept(uint32_t old_xirr, uint32_t new_xirr) 
"icp_accept: XIRR 0x%"PRIx
 xics_icp_eoi(int server, uint32_t xirr, uint32_t new_xirr) "icp_eoi: server %d 
given XIRR 0x%"PRIx32" new XIRR 0x%"PRIx32
 xics_icp_irq(int server, int nr, uint8_t priority) "cpu %d trying to deliver 
irq 0x%"PRIx32" priority 0x%x"
 xics_icp_raise(uint32_t xirr, uint8_t pending_priority) "raising IRQ new 
XIRR=0x%x new pending priority=0x%x"
-xics_ics_simple_set_irq_msi(int srcno, int nr) "set_irq_msi: srcno %d [irq 
0x%x]"
+xics_ics_set_irq_msi(int srcno, int nr) "set_irq_msi: srcno %d [irq 0x%x]"
 xics_masked_pending(void) "set_irq_msi: masked pending"
-xics_ics_simple_set_irq_lsi(int srcno, int nr) "set_irq_lsi: srcno %d [irq 
0x%x]"
-xics_ics_simple_write_xive(int nr, int srcno, int server, uint8_t priority) 
"ics_write_xive: irq 0x%x [src %d] server 0x%x prio 0x%x"
+xics_ics_set_irq_lsi(int srcno, int nr) "set_irq_lsi: srcno %d [irq 0x%x]"
+xics_ics_write_xive(int nr, int srcno, int server, uint8_t priority) 
"ics_write_xive: irq 0x%x [src %d] server 0x%x prio 0x%x"
 xics_ics_reject(int nr, int srcno) "reject irq 0x%x [src %d]"
 xics_ics_eoi(int nr) "ics_eoi: irq 0x%x"
 
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 93139b0189..310dc72b46 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -428,11 +428,11 @@ static void ics_resend_lsi(ICSState *ics, int srcno)
 }
 }
 
-static void ics_simple_set_irq_msi(ICSState *ics, int srcno, int val)
+static void ics_set_irq_msi(ICSState *ics, int srcno, int val)
 {
 ICSIRQState *irq = ics->irqs + srcno;
 
-trace_xics_ics_simple_set_irq_msi(srcno, srcno + ics->offset);
+trace_xics_ics_set_irq_msi(srcno, srcno + ics->offset);
 
 if (val) {
 if (irq->priority == 0xff) {
@@ -444,11 +444,11 @@ static void ics_simple_set_irq_msi(ICSState *ics, int 
srcno, int val)
 }
 }
 
-static void ics_simple_set_irq_lsi(ICSState *ics, int srcno, int val)
+static void ics_set_irq_lsi(ICSState *ics, int srcno, int val)
 {
 ICSIRQState *irq = ics->irqs + srcno;
 
-trace_xics_ics_simple_set_irq_lsi(srcno, srcno + ics->offset);
+trace_xics_ics_set_irq_lsi(srcno, srcno + ics->offset);
 if (val) {
 irq->status |= XICS_STATUS_ASSERTED;
 } else {
@@ -457,7 +457,7 @@ static void ics_simple_set_irq_lsi(ICSState *ics, int 
srcno, int val)
 ics_resend_lsi(ics, srcno);
 }
 
-void ics_simple_set_irq(void *opaque, int srcno, int val)
+void ics_set_irq(void *opaque, int srcno, int val)
 {
 ICSState *ics = (ICSState *)opaque;
 
@@ -467,13 +467,13 @@ void ics_simple_set_irq(void *opaque, int srcno, int val)
 }
 
 if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
-ics_simple_set_irq_lsi(ics, srcno, val);
+ics_set_irq_lsi(ics, srcno, val);
 } else {
-ics_simple_set_irq_msi(ics, srcno, val);
+ics_set_irq_msi(ics, srcno, val);
 }
 }
 
-static void ics_simple_write_xive_msi(ICSState *ics, int srcno)
+static void ics_write_xive_msi(ICSState *ics, int srcno)
 {
 ICSIRQState *irq = ics->irqs + srcno;
 
@@ -486,13 +486,13 @@ static void ics_simple_write_xive_msi(ICSState *ics, int 
srcno)
 icp_irq(ics, irq->server, srcno + ics->offset, irq->priority);
 }
 
-static void ics_simple_write_xive_lsi(ICSState *ics, int srcno)
+static void ics_write_xive_lsi(ICSState *ics, int srcno)
 {
 ics_resend_lsi(ics, srcno);
 }
 
-void ics_simple_write_xive(ICSState *ics, int srcno, int server,
-   uint8_t priority, uint8_t saved_priority)
+void ics_write_xive(ICSState *ics, int srcno, int server,
+uint8_t priority, uint8_t saved_priority)
 {
 ICSIRQState *irq = ics->irqs + srcno;
 
@@ -500,13 +500,12 @@ void ics_simple_write_xive(ICSState *ics, int srcno, int 
server,
 irq->priority = priority;
 irq->saved_priority = saved_priority;
 
-trace_xics_ics_simple_write_xive(ics->offset + srcno, srcno, server,
- priority);
+trace_xics_ics_write_xive(ics->offset + srcno, srcno, server, priority);
 
 if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
-ics_simple_write_xive_lsi(ics, srcno);
+ics_write_xive_lsi(ics, srcno);
 } else {
-ics_simple_write_xive_msi(ics, srcno);
+   

[PATCH v3 05/34] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes

2019-10-01 Thread David Gibson
TYPE_ICS_SIMPLE is the only subtype of TYPE_ICS_BASE that's ever
instantiated.  The existence of different classes is mostly a hang
over from when we (misguidedly) had separate subtypes for the KVM and
non-KVM version of the device.

There could be some call for an abstract base type for ICS variants
that use a different representation of their state (PowerNV PHB3 might
want this).  The current split isn't really in the right place for
that though.  If we need this in future, we can re-implement it more
in line with what we actually need.

So, collapse the two classes together into just TYPE_ICS.

Signed-off-by: David Gibson 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Greg Kurz 
---
 hw/intc/xics.c| 86 ++-
 hw/ppc/pnv_psi.c  |  2 +-
 hw/ppc/spapr_irq.c|  4 +-
 include/hw/ppc/xics.h | 16 +++-
 4 files changed, 36 insertions(+), 72 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 82e6f09259..dfe7dbd254 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -555,7 +555,7 @@ static void ics_reset_irq(ICSIRQState *irq)
 
 static void ics_reset(DeviceState *dev)
 {
-ICSState *ics = ICS_BASE(dev);
+ICSState *ics = ICS(dev);
 int i;
 uint8_t flags[ics->nr_irqs];
 
@@ -573,7 +573,7 @@ static void ics_reset(DeviceState *dev)
 if (kvm_irqchip_in_kernel()) {
 Error *local_err = NULL;
 
-ics_set_kvm_state(ICS_BASE(dev), _err);
+ics_set_kvm_state(ICS(dev), _err);
 if (local_err) {
 error_report_err(local_err);
 }
@@ -585,47 +585,15 @@ static void ics_reset_handler(void *dev)
 ics_reset(dev);
 }
 
-static void ics_simple_realize(DeviceState *dev, Error **errp)
+static void ics_realize(DeviceState *dev, Error **errp)
 {
-ICSState *ics = ICS_SIMPLE(dev);
-ICSStateClass *icsc = ICS_BASE_GET_CLASS(ics);
+ICSState *ics = ICS(dev);
 Error *local_err = NULL;
-
-icsc->parent_realize(dev, _err);
-if (local_err) {
-error_propagate(errp, local_err);
-return;
-}
-
-qemu_register_reset(ics_reset_handler, ics);
-}
-
-static void ics_simple_class_init(ObjectClass *klass, void *data)
-{
-DeviceClass *dc = DEVICE_CLASS(klass);
-ICSStateClass *isc = ICS_BASE_CLASS(klass);
-
-device_class_set_parent_realize(dc, ics_simple_realize,
->parent_realize);
-}
-
-static const TypeInfo ics_simple_info = {
-.name = TYPE_ICS_SIMPLE,
-.parent = TYPE_ICS_BASE,
-.instance_size = sizeof(ICSState),
-.class_init = ics_simple_class_init,
-.class_size = sizeof(ICSStateClass),
-};
-
-static void ics_base_realize(DeviceState *dev, Error **errp)
-{
-ICSState *ics = ICS_BASE(dev);
 Object *obj;
-Error *err = NULL;
 
-obj = object_property_get_link(OBJECT(dev), ICS_PROP_XICS, );
+obj = object_property_get_link(OBJECT(dev), ICS_PROP_XICS, _err);
 if (!obj) {
-error_propagate_prepend(errp, err,
+error_propagate_prepend(errp, local_err,
 "required link '" ICS_PROP_XICS
 "' not found: ");
 return;
@@ -637,16 +605,18 @@ static void ics_base_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState));
+
+qemu_register_reset(ics_reset_handler, ics);
 }
 
-static void ics_base_instance_init(Object *obj)
+static void ics_instance_init(Object *obj)
 {
-ICSState *ics = ICS_BASE(obj);
+ICSState *ics = ICS(obj);
 
 ics->offset = XICS_IRQ_BASE;
 }
 
-static int ics_base_pre_save(void *opaque)
+static int ics_pre_save(void *opaque)
 {
 ICSState *ics = opaque;
 
@@ -657,7 +627,7 @@ static int ics_base_pre_save(void *opaque)
 return 0;
 }
 
-static int ics_base_post_load(void *opaque, int version_id)
+static int ics_post_load(void *opaque, int version_id)
 {
 ICSState *ics = opaque;
 
@@ -675,7 +645,7 @@ static int ics_base_post_load(void *opaque, int version_id)
 return 0;
 }
 
-static const VMStateDescription vmstate_ics_base_irq = {
+static const VMStateDescription vmstate_ics_irq = {
 .name = "ics/irq",
 .version_id = 2,
 .minimum_version_id = 1,
@@ -689,45 +659,44 @@ static const VMStateDescription vmstate_ics_base_irq = {
 },
 };
 
-static const VMStateDescription vmstate_ics_base = {
+static const VMStateDescription vmstate_ics = {
 .name = "ics",
 .version_id = 1,
 .minimum_version_id = 1,
-.pre_save = ics_base_pre_save,
-.post_load = ics_base_post_load,
+.pre_save = ics_pre_save,
+.post_load = ics_post_load,
 .fields = (VMStateField[]) {
 /* Sanity check */
 VMSTATE_UINT32_EQUAL(nr_irqs, ICSState, NULL),
 
 VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs, ICSState, nr_irqs,
- vmstate_ics_base_irq,
+ vmstate_ics_irq,
   

[PATCH v3 02/34] xics: Eliminate 'reject', 'resend' and 'eoi' class hooks

2019-10-01 Thread David Gibson
Currently ics_reject(), ics_resend() and ics_eoi() indirect through
class methods.  But there's only one implementation of each method,
the one in TYPE_ICS_SIMPLE.  TYPE_ICS_BASE has no implementation, but
it's never instantiated, and has no other subtypes.

So clean up by eliminating the method and just having ics_reject(),
ics_resend() and ics_eoi() contain the logic directly.

Signed-off-by: David Gibson 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Greg Kurz 
---
 hw/intc/trace-events  |  4 ++--
 hw/intc/xics.c| 54 +++
 include/hw/ppc/xics.h |  4 
 3 files changed, 15 insertions(+), 47 deletions(-)

diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 719f46b516..fdc716c2cc 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -70,8 +70,8 @@ xics_ics_simple_set_irq_msi(int srcno, int nr) "set_irq_msi: 
srcno %d [irq 0x%x]
 xics_masked_pending(void) "set_irq_msi: masked pending"
 xics_ics_simple_set_irq_lsi(int srcno, int nr) "set_irq_lsi: srcno %d [irq 
0x%x]"
 xics_ics_simple_write_xive(int nr, int srcno, int server, uint8_t priority) 
"ics_write_xive: irq 0x%x [src %d] server 0x%x prio 0x%x"
-xics_ics_simple_reject(int nr, int srcno) "reject irq 0x%x [src %d]"
-xics_ics_simple_eoi(int nr) "ics_eoi: irq 0x%x"
+xics_ics_reject(int nr, int srcno) "reject irq 0x%x [src %d]"
+xics_ics_eoi(int nr) "ics_eoi: irq 0x%x"
 
 # s390_flic_kvm.c
 flic_create_device(int err) "flic: create device failed %d"
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index b2fca2975c..93139b0189 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -98,32 +98,8 @@ void ics_pic_print_info(ICSState *ics, Monitor *mon)
 #define XISR(icp)   (((icp)->xirr) & XISR_MASK)
 #define CPPR(icp)   (((icp)->xirr) >> 24)
 
-static void ics_reject(ICSState *ics, uint32_t nr)
-{
-ICSStateClass *k = ICS_BASE_GET_CLASS(ics);
-
-if (k->reject) {
-k->reject(ics, nr);
-}
-}
-
-void ics_resend(ICSState *ics)
-{
-ICSStateClass *k = ICS_BASE_GET_CLASS(ics);
-
-if (k->resend) {
-k->resend(ics);
-}
-}
-
-static void ics_eoi(ICSState *ics, int nr)
-{
-ICSStateClass *k = ICS_BASE_GET_CLASS(ics);
-
-if (k->eoi) {
-k->eoi(ics, nr);
-}
-}
+static void ics_reject(ICSState *ics, uint32_t nr);
+static void ics_eoi(ICSState *ics, uint32_t nr);
 
 static void icp_check_ipi(ICPState *icp)
 {
@@ -427,7 +403,7 @@ Object *icp_create(Object *cpu, const char *type, 
XICSFabric *xi, Error **errp)
 /*
  * ICS: Source layer
  */
-static void ics_simple_resend_msi(ICSState *ics, int srcno)
+static void ics_resend_msi(ICSState *ics, int srcno)
 {
 ICSIRQState *irq = ics->irqs + srcno;
 
@@ -440,7 +416,7 @@ static void ics_simple_resend_msi(ICSState *ics, int srcno)
 }
 }
 
-static void ics_simple_resend_lsi(ICSState *ics, int srcno)
+static void ics_resend_lsi(ICSState *ics, int srcno)
 {
 ICSIRQState *irq = ics->irqs + srcno;
 
@@ -478,7 +454,7 @@ static void ics_simple_set_irq_lsi(ICSState *ics, int 
srcno, int val)
 } else {
 irq->status &= ~XICS_STATUS_ASSERTED;
 }
-ics_simple_resend_lsi(ics, srcno);
+ics_resend_lsi(ics, srcno);
 }
 
 void ics_simple_set_irq(void *opaque, int srcno, int val)
@@ -512,7 +488,7 @@ static void ics_simple_write_xive_msi(ICSState *ics, int 
srcno)
 
 static void ics_simple_write_xive_lsi(ICSState *ics, int srcno)
 {
-ics_simple_resend_lsi(ics, srcno);
+ics_resend_lsi(ics, srcno);
 }
 
 void ics_simple_write_xive(ICSState *ics, int srcno, int server,
@@ -534,11 +510,11 @@ void ics_simple_write_xive(ICSState *ics, int srcno, int 
server,
 }
 }
 
-static void ics_simple_reject(ICSState *ics, uint32_t nr)
+static void ics_reject(ICSState *ics, uint32_t nr)
 {
 ICSIRQState *irq = ics->irqs + nr - ics->offset;
 
-trace_xics_ics_simple_reject(nr, nr - ics->offset);
+trace_xics_ics_reject(nr, nr - ics->offset);
 if (irq->flags & XICS_FLAGS_IRQ_MSI) {
 irq->status |= XICS_STATUS_REJECTED;
 } else if (irq->flags & XICS_FLAGS_IRQ_LSI) {
@@ -546,26 +522,26 @@ static void ics_simple_reject(ICSState *ics, uint32_t nr)
 }
 }
 
-static void ics_simple_resend(ICSState *ics)
+void ics_resend(ICSState *ics)
 {
 int i;
 
 for (i = 0; i < ics->nr_irqs; i++) {
 /* FIXME: filter by server#? */
 if (ics->irqs[i].flags & XICS_FLAGS_IRQ_LSI) {
-ics_simple_resend_lsi(ics, i);
+ics_resend_lsi(ics, i);
 } else {
-ics_simple_resend_msi(ics, i);
+ics_resend_msi(ics, i);
 }
 }
 }
 
-static void ics_simple_eoi(ICSState *ics, uint32_t nr)
+static void ics_eoi(ICSState *ics, uint32_t nr)
 {
 int srcno = nr - ics->offset;
 ICSIRQState *irq = ics->irqs + srcno;
 
-trace_xics_ics_simple_eoi(nr);
+trace_xics_ics_eoi(nr);
 
 if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
 irq->status &= ~XICS_STATUS_SENT;
@@ -617,10 +593,6 @@ static void 

[PATCH v3 00/34] spapr: IRQ subsystem cleanup

2019-10-01 Thread David Gibson
This is a substantial rework to clean up the handling of IRQs in
spapr.  It includes some cleanups to both the XICS and XIVE interrupt
controller backends, as well as more to the common spapr irq handling
infrastructure.

Changes since v2:
 * Fixed a bug where the "move handling multiple irq frees" to
   frontend patch was actually freeing one irq over and over, rather
   than freeing multiple irqs
 * Fixed some places I missed still using only-Error * style, and flow
   on adjustments
 * New idiom to iterate across all constructed backends for the things
   that need that (cpu_intc_create, claim & freem), rather than
   open-coding a call on the xics, then xive versions.

Changes since v1:
 * Lots of extra patches
 * Many minor adjustments based on feedback
 * Moved towards return value + Error * style, instead of just Error *
   style

David Gibson (34):
  xics: Minor fixes for XICSFabric interface
  xics: Eliminate 'reject', 'resend' and 'eoi' class hooks
  xics: Rename misleading ics_simple_*() functions
  xics: Eliminate reset hook
  xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes
  xics: Create sPAPR specific ICS subtype
  spapr: Fold spapr_phb_lsi_qirq() into its single caller
  spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse()
helper
  spapr: Clarify and fix handling of nr_irqs
  spapr: Eliminate nr_irqs parameter to SpaprIrq::init
  spapr: Fix indexing of XICS irqs
  spapr: Simplify spapr_qirq() handling
  spapr: Eliminate SpaprIrq:get_nodename method
  spapr: Remove unhelpful tracepoints from spapr_irq_free_xics()
  spapr: Handle freeing of multiple irqs in frontend only
  spapr, xics, xive: Better use of assert()s on irq claim/free paths
  xive: Improve irq claim/free path
  spapr: Use less cryptic representation of which irq backends are
supported
  spapr: Add return value to spapr_irq_check()
  spapr: Eliminate SpaprIrq::init hook
  spapr, xics, xive: Introduce SpaprInterruptController QOM interface
  spapr, xics, xive: Move cpu_intc_create from SpaprIrq to
SpaprInterruptController
  spapr, xics, xive: Move irq claim and free from SpaprIrq to
SpaprInterruptController
  spapr: Formalize notion of active interrupt controller
  spapr, xics, xive: Move set_irq from SpaprIrq to
SpaprInterruptController
  spapr, xics, xive: Move print_info from SpaprIrq to
SpaprInterruptController
  spapr, xics, xive: Move dt_populate from SpaprIrq to
SpaprInterruptController
  spapr, xics, xive: Match signatures for XICS and XIVE KVM connect
routines
  spapr: Remove SpaprIrq::init_kvm hook
  spapr, xics, xive: Move SpaprIrq::reset hook logic into
activate/deactivate
  spapr, xics, xive: Move SpaprIrq::post_load hook to backends
  spapr: Remove SpaprIrq::nr_msis
  spapr: Move SpaprIrq::nr_xirqs to SpaprMachineClass
  spapr: Remove last pieces of SpaprIrq

 hw/char/spapr_vty.c |   3 +-
 hw/intc/spapr_xive.c| 298 -
 hw/intc/spapr_xive_kvm.c|  30 +-
 hw/intc/trace-events|  10 +-
 hw/intc/xics.c  | 210 +++--
 hw/intc/xics_kvm.c  |   9 +-
 hw/intc/xics_spapr.c| 157 ++-
 hw/net/spapr_llan.c |   3 +-
 hw/ppc/pnv_psi.c|   6 +-
 hw/ppc/spapr.c  |  57 ++-
 hw/ppc/spapr_caps.c |  64 +++
 hw/ppc/spapr_cpu_core.c |   3 +-
 hw/ppc/spapr_hcall.c|   7 +-
 hw/ppc/spapr_irq.c  | 847 +++-
 hw/ppc/spapr_pci.c  |  10 +-
 hw/ppc/spapr_vio.c  |   3 +-
 hw/ppc/trace-events |   4 -
 include/hw/pci-host/spapr.h |  11 +-
 include/hw/ppc/spapr.h  |  14 +-
 include/hw/ppc/spapr_irq.h  |  89 ++--
 include/hw/ppc/spapr_vio.h  |   5 +-
 include/hw/ppc/spapr_xive.h |   9 +-
 include/hw/ppc/xics.h   |  33 +-
 include/hw/ppc/xics_spapr.h |  10 +-
 include/hw/ppc/xive.h   |   2 +-
 25 files changed, 897 insertions(+), 997 deletions(-)

-- 
2.21.0




[PATCH v3 07/34] spapr: Fold spapr_phb_lsi_qirq() into its single caller

2019-10-01 Thread David Gibson
No point having a two-line helper that's used exactly once, and not likely
to be used anywhere else in future.

Signed-off-by: David Gibson 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Greg Kurz 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/ppc/spapr_pci.c  | 3 ++-
 include/hw/pci-host/spapr.h | 7 ---
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index c1c9634755..01ff41d4c4 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -721,9 +721,10 @@ static void pci_spapr_set_irq(void *opaque, int irq_num, 
int level)
  * corresponding qemu_irq.
  */
 SpaprPhbState *phb = opaque;
+SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
 
 trace_spapr_pci_lsi_set(phb->dtbusname, irq_num, 
phb->lsi_table[irq_num].irq);
-qemu_set_irq(spapr_phb_lsi_qirq(phb, irq_num), level);
+qemu_set_irq(spapr_qirq(spapr, phb->lsi_table[irq_num].irq), level);
 }
 
 static PCIINTxRoute spapr_route_intx_pin_to_irq(void *opaque, int pin)
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index abd87605b2..23506f05d9 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -128,13 +128,6 @@ struct SpaprPhbState {
 #define SPAPR_PCI_NV2ATSD_WIN_SIZE   (NVGPU_MAX_NUM * NVGPU_MAX_LINKS * \
   64 * KiB)
 
-static inline qemu_irq spapr_phb_lsi_qirq(struct SpaprPhbState *phb, int pin)
-{
-SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
-
-return spapr_qirq(spapr, phb->lsi_table[pin].irq);
-}
-
 int spapr_dt_phb(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt,
  uint32_t nr_msis, int *node_offset);
 
-- 
2.21.0




[PATCH v3 04/34] xics: Eliminate reset hook

2019-10-01 Thread David Gibson
Currently TYPE_XICS_BASE and TYPE_XICS_SIMPLE have their own reset methods,
using the standard technique for having the subtype call the supertype's
methods before doing its own thing.

But TYPE_XICS_SIMPLE is the only subtype of TYPE_XICS_BASE ever
instantiated, so there's no point having the split here.  Merge them
together into just an ics_reset() function.

Signed-off-by: David Gibson 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Greg Kurz 
---
 hw/intc/xics.c| 57 ++-
 include/hw/ppc/xics.h |  1 -
 2 files changed, 24 insertions(+), 34 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 310dc72b46..82e6f09259 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -547,11 +547,28 @@ static void ics_eoi(ICSState *ics, uint32_t nr)
 }
 }
 
-static void ics_simple_reset(DeviceState *dev)
+static void ics_reset_irq(ICSIRQState *irq)
 {
-ICSStateClass *icsc = ICS_BASE_GET_CLASS(dev);
+irq->priority = 0xff;
+irq->saved_priority = 0xff;
+}
 
-icsc->parent_reset(dev);
+static void ics_reset(DeviceState *dev)
+{
+ICSState *ics = ICS_BASE(dev);
+int i;
+uint8_t flags[ics->nr_irqs];
+
+for (i = 0; i < ics->nr_irqs; i++) {
+flags[i] = ics->irqs[i].flags;
+}
+
+memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs);
+
+for (i = 0; i < ics->nr_irqs; i++) {
+ics_reset_irq(ics->irqs + i);
+ics->irqs[i].flags = flags[i];
+}
 
 if (kvm_irqchip_in_kernel()) {
 Error *local_err = NULL;
@@ -563,9 +580,9 @@ static void ics_simple_reset(DeviceState *dev)
 }
 }
 
-static void ics_simple_reset_handler(void *dev)
+static void ics_reset_handler(void *dev)
 {
-ics_simple_reset(dev);
+ics_reset(dev);
 }
 
 static void ics_simple_realize(DeviceState *dev, Error **errp)
@@ -580,7 +597,7 @@ static void ics_simple_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-qemu_register_reset(ics_simple_reset_handler, ics);
+qemu_register_reset(ics_reset_handler, ics);
 }
 
 static void ics_simple_class_init(ObjectClass *klass, void *data)
@@ -590,8 +607,6 @@ static void ics_simple_class_init(ObjectClass *klass, void 
*data)
 
 device_class_set_parent_realize(dc, ics_simple_realize,
 >parent_realize);
-device_class_set_parent_reset(dc, ics_simple_reset,
-  >parent_reset);
 }
 
 static const TypeInfo ics_simple_info = {
@@ -602,30 +617,6 @@ static const TypeInfo ics_simple_info = {
 .class_size = sizeof(ICSStateClass),
 };
 
-static void ics_reset_irq(ICSIRQState *irq)
-{
-irq->priority = 0xff;
-irq->saved_priority = 0xff;
-}
-
-static void ics_base_reset(DeviceState *dev)
-{
-ICSState *ics = ICS_BASE(dev);
-int i;
-uint8_t flags[ics->nr_irqs];
-
-for (i = 0; i < ics->nr_irqs; i++) {
-flags[i] = ics->irqs[i].flags;
-}
-
-memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs);
-
-for (i = 0; i < ics->nr_irqs; i++) {
-ics_reset_irq(ics->irqs + i);
-ics->irqs[i].flags = flags[i];
-}
-}
-
 static void ics_base_realize(DeviceState *dev, Error **errp)
 {
 ICSState *ics = ICS_BASE(dev);
@@ -726,7 +717,7 @@ static void ics_base_class_init(ObjectClass *klass, void 
*data)
 
 dc->realize = ics_base_realize;
 dc->props = ics_base_properties;
-dc->reset = ics_base_reset;
+dc->reset = ics_reset;
 dc->vmsd = _ics_base;
 }
 
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 8874bad328..7efd49c02c 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -105,7 +105,6 @@ struct ICSStateClass {
 DeviceClass parent_class;
 
 DeviceRealize parent_realize;
-DeviceReset parent_reset;
 };
 
 struct ICSState {
-- 
2.21.0




Re: [PATCH 0/6] qcow2: advanced compression options

2019-10-01 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/1569958040-697220-1-git-send-email-andrey.shinkev...@virtuozzo.com/



Hi,

This series failed the docker-mingw@fedora build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

=== TEST SCRIPT BEGIN ===
#! /bin/bash
export ARCH=x86_64
make docker-image-fedora V=1 NETWORK=1
time make docker-test-mingw@fedora J=14 NETWORK=1
=== TEST SCRIPT END ===

  CC  block/qed-table.o
  CC  block/qed-cluster.o
  CC  block/qed-check.o
/tmp/qemu-test/src/block/qcow2.c:4077:64: error: unknown type name 'AioTask'; 
did you mean 'AioWait'?
 static coroutine_fn int qcow2_co_pwritev_compressed_task_entry(AioTask *task)
^~~
AioWait
/tmp/qemu-test/src/block/qcow2.c: In function 
'qcow2_co_pwritev_compressed_part':
/tmp/qemu-test/src/block/qcow2.c:4098:5: error: unknown type name 'AioTaskPool'
 AioTaskPool *aio = NULL;
 ^~~
/tmp/qemu-test/src/block/qcow2.c:4123:21: error: implicit declaration of 
function 'aio_task_pool_status' [-Werror=implicit-function-declaration]
 while (bytes && aio_task_pool_status(aio) == 0) {
 ^~~~
/tmp/qemu-test/src/block/qcow2.c:4123:21: error: nested extern declaration of 
'aio_task_pool_status' [-Werror=nested-externs]
/tmp/qemu-test/src/block/qcow2.c:4130:19: error: implicit declaration of 
function 'aio_task_pool_new'; did you mean 'aio_timer_new'? 
[-Werror=implicit-function-declaration]
 aio = aio_task_pool_new(QCOW2_MAX_WORKERS);
   ^
   aio_timer_new
/tmp/qemu-test/src/block/qcow2.c:4130:19: error: nested extern declaration of 
'aio_task_pool_new' [-Werror=nested-externs]
/tmp/qemu-test/src/block/qcow2.c:4130:37: error: 'QCOW2_MAX_WORKERS' undeclared 
(first use in this function); did you mean 'QCOW2_MAX_THREADS'?
 aio = aio_task_pool_new(QCOW2_MAX_WORKERS);
 ^
 QCOW2_MAX_THREADS
/tmp/qemu-test/src/block/qcow2.c:4130:37: note: each undeclared identifier is 
reported only once for each function it appears in
/tmp/qemu-test/src/block/qcow2.c:4133:15: error: implicit declaration of 
function 'qcow2_add_task'; did you mean 'qcow2_do_open'? 
[-Werror=implicit-function-declaration]
 ret = qcow2_add_task(bs, aio, qcow2_co_pwritev_compressed_task_entry,
   ^~
   qcow2_do_open
/tmp/qemu-test/src/block/qcow2.c:4133:15: error: nested extern declaration of 
'qcow2_add_task' [-Werror=nested-externs]
/tmp/qemu-test/src/block/qcow2.c:4133:39: error: 
'qcow2_co_pwritev_compressed_task_entry' undeclared (first use in this 
function); did you mean 'qcow2_co_pwritev_compressed_task'?
 ret = qcow2_add_task(bs, aio, qcow2_co_pwritev_compressed_task_entry,
   ^~
   qcow2_co_pwritev_compressed_task
/tmp/qemu-test/src/block/qcow2.c:4145:9: error: implicit declaration of 
function 'aio_task_pool_wait_all' [-Werror=implicit-function-declaration]
 aio_task_pool_wait_all(aio);
 ^~
/tmp/qemu-test/src/block/qcow2.c:4145:9: error: nested extern declaration of 
'aio_task_pool_wait_all' [-Werror=nested-externs]
At top level:
/tmp/qemu-test/src/block/qcow2.c:4012:1: error: 
'qcow2_co_pwritev_compressed_task' defined but not used 
[-Werror=unused-function]
 qcow2_co_pwritev_compressed_task(BlockDriverState *bs,
 ^~~~
cc1: all warnings being treated as errors
make: *** [/tmp/qemu-test/src/rules.mak:69: block/qcow2.o] Error 1
make: *** Waiting for unfinished jobs
Traceback (most recent call last):
  File "./tests/docker/docker.py", line 662, in 
---
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', 
'--label', 'com.qemu.instance.uuid=5e43e6e4ab784c32a96f618a29b7ceef', '-u', 
'1003', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', 
'-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 
'SHOW_ENV=', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', 
'/home/patchew2/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', 
'/var/tmp/patchew-tester-tmp-yubxkwpj/src/docker-src.2019-10-01-22.23.28.10478:/var/tmp/qemu:z,ro',
 'qemu:fedora', '/var/tmp/qemu/run', 'test-mingw']' returned non-zero exit 
status 2.
filter=--filter=label=com.qemu.instance.uuid=5e43e6e4ab784c32a96f618a29b7ceef
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-yubxkwpj/src'
make: *** [docker-run-test-mingw@fedora] Error 2

real2m9.622s
user0m7.777s


The full log is available at

Re: [PATCH 0/6] qcow2: advanced compression options

2019-10-01 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/1569958040-697220-1-git-send-email-andrey.shinkev...@virtuozzo.com/



Hi,

This series failed the docker-quick@centos7 build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

=== TEST SCRIPT BEGIN ===
#!/bin/bash
make docker-image-centos7 V=1 NETWORK=1
time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1
=== TEST SCRIPT END ===

  CC  block/qed-l2-cache.o
  CC  block/qed-table.o
  CC  block/qed-cluster.o
/tmp/qemu-test/src/block/qcow2.c:4077:64: error: unknown type name 'AioTask'
 static coroutine_fn int qcow2_co_pwritev_compressed_task_entry(AioTask *task)
^
/tmp/qemu-test/src/block/qcow2.c: In function 
'qcow2_co_pwritev_compressed_part':
/tmp/qemu-test/src/block/qcow2.c:4098:5: error: unknown type name 'AioTaskPool'
 AioTaskPool *aio = NULL;
 ^
/tmp/qemu-test/src/block/qcow2.c:4123:5: error: implicit declaration of 
function 'aio_task_pool_status' [-Werror=implicit-function-declaration]
 while (bytes && aio_task_pool_status(aio) == 0) {
 ^
/tmp/qemu-test/src/block/qcow2.c:4123:5: error: nested extern declaration of 
'aio_task_pool_status' [-Werror=nested-externs]
/tmp/qemu-test/src/block/qcow2.c:4130:13: error: implicit declaration of 
function 'aio_task_pool_new' [-Werror=implicit-function-declaration]
 aio = aio_task_pool_new(QCOW2_MAX_WORKERS);
 ^
/tmp/qemu-test/src/block/qcow2.c:4130:13: error: nested extern declaration of 
'aio_task_pool_new' [-Werror=nested-externs]
/tmp/qemu-test/src/block/qcow2.c:4130:37: error: 'QCOW2_MAX_WORKERS' undeclared 
(first use in this function)
 aio = aio_task_pool_new(QCOW2_MAX_WORKERS);
 ^
/tmp/qemu-test/src/block/qcow2.c:4130:37: note: each undeclared identifier is 
reported only once for each function it appears in
/tmp/qemu-test/src/block/qcow2.c:4133:9: error: implicit declaration of 
function 'qcow2_add_task' [-Werror=implicit-function-declaration]
 ret = qcow2_add_task(bs, aio, qcow2_co_pwritev_compressed_task_entry,
 ^
/tmp/qemu-test/src/block/qcow2.c:4133:9: error: nested extern declaration of 
'qcow2_add_task' [-Werror=nested-externs]
/tmp/qemu-test/src/block/qcow2.c:4133:39: error: 
'qcow2_co_pwritev_compressed_task_entry' undeclared (first use in this function)
 ret = qcow2_add_task(bs, aio, qcow2_co_pwritev_compressed_task_entry,
   ^
/tmp/qemu-test/src/block/qcow2.c:4145:9: error: implicit declaration of 
function 'aio_task_pool_wait_all' [-Werror=implicit-function-declaration]
 aio_task_pool_wait_all(aio);
 ^
/tmp/qemu-test/src/block/qcow2.c:4145:9: error: nested extern declaration of 
'aio_task_pool_wait_all' [-Werror=nested-externs]
/tmp/qemu-test/src/block/qcow2.c: At top level:
/tmp/qemu-test/src/block/qcow2.c:4012:1: error: 
'qcow2_co_pwritev_compressed_task' defined but not used 
[-Werror=unused-function]
 qcow2_co_pwritev_compressed_task(BlockDriverState *bs,
 ^
cc1: all warnings being treated as errors
make: *** [block/qcow2.o] Error 1
make: *** Waiting for unfinished jobs
Traceback (most recent call last):
  File "./tests/docker/docker.py", line 662, in 
---
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', 
'--label', 'com.qemu.instance.uuid=c0ff6dd6fb3f46d1b9c07a106c9dd26a', '-u', 
'1001', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', 
'-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 
'SHOW_ENV=1', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', 
'/home/patchew/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', 
'/var/tmp/patchew-tester-tmp-8m_nebab/src/docker-src.2019-10-01-22.22.08.6455:/var/tmp/qemu:z,ro',
 'qemu:centos7', '/var/tmp/qemu/run', 'test-quick']' returned non-zero exit 
status 2.
filter=--filter=label=com.qemu.instance.uuid=c0ff6dd6fb3f46d1b9c07a106c9dd26a
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-8m_nebab/src'
make: *** [docker-run-test-quick@centos7] Error 2

real1m40.390s
user0m8.966s


The full log is available at
http://patchew.org/logs/1569958040-697220-1-git-send-email-andrey.shinkev...@virtuozzo.com/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

[PULL 8/8] hd-geo-test: Add tests for lchs override

2019-10-01 Thread John Snow
From: Sam Eiderman 

Add QTest tests to check the logical geometry override option.

The tests in hd-geo-test are out of date - they only test IDE and do not
test interesting MBRs.

I added a few helper functions which will make adding more tests easier.

QTest's fw_cfg helper functions support only legacy fw_cfg, so I had to
read the new fw_cfg layout on my own.

Creating qcow2 disks with specific size and MBR layout is currently
unused - we only use a default empty MBR.

Reviewed-by: Karl Heubaum 
Reviewed-by: Arbel Moshe 
Signed-off-by: Sam Eiderman 
Message-id: 20190925110639.100699-9-sam...@google.com
Signed-off-by: John Snow 
---
 tests/hd-geo-test.c| 589 +
 tests/Makefile.include |   2 +-
 2 files changed, 590 insertions(+), 1 deletion(-)

diff --git a/tests/hd-geo-test.c b/tests/hd-geo-test.c
index 62eb624726..458de99c31 100644
--- a/tests/hd-geo-test.c
+++ b/tests/hd-geo-test.c
@@ -17,7 +17,12 @@
 
 #include "qemu/osdep.h"
 #include "qemu-common.h"
+#include "qemu/bswap.h"
+#include "qapi/qmp/qlist.h"
 #include "libqtest.h"
+#include "libqos/fw_cfg.h"
+#include "libqos/libqos.h"
+#include "standard-headers/linux/qemu_fw_cfg.h"
 
 #define ARGV_SIZE 256
 
@@ -388,6 +393,575 @@ static void test_ide_drive_cd_0(void)
 qtest_quit(qts);
 }
 
+typedef struct {
+bool active;
+uint32_t head;
+uint32_t sector;
+uint32_t cyl;
+uint32_t end_head;
+uint32_t end_sector;
+uint32_t end_cyl;
+uint32_t start_sect;
+uint32_t nr_sects;
+} MBRpartitions[4];
+
+static MBRpartitions empty_mbr = { {false, 0, 0, 0, 0, 0, 0, 0, 0},
+   {false, 0, 0, 0, 0, 0, 0, 0, 0},
+   {false, 0, 0, 0, 0, 0, 0, 0, 0},
+   {false, 0, 0, 0, 0, 0, 0, 0, 0} };
+
+static char *create_qcow2_with_mbr(MBRpartitions mbr, uint64_t sectors)
+{
+const char *template = "/tmp/qtest.XX";
+char *raw_path = strdup(template);
+char *qcow2_path = strdup(template);
+char cmd[100 + 2 * PATH_MAX];
+uint8_t buf[512];
+int i, ret, fd, offset;
+uint64_t qcow2_size = sectors * 512;
+uint8_t status, parttype, head, sector, cyl;
+char *qemu_img_path;
+char *qemu_img_abs_path;
+
+offset = 0xbe;
+
+for (i = 0; i < 4; i++) {
+status = mbr[i].active ? 0x80 : 0x00;
+g_assert(mbr[i].head < 256);
+g_assert(mbr[i].sector < 64);
+g_assert(mbr[i].cyl < 1024);
+head = mbr[i].head;
+sector = mbr[i].sector + ((mbr[i].cyl & 0x300) >> 2);
+cyl = mbr[i].cyl & 0xff;
+
+buf[offset + 0x0] = status;
+buf[offset + 0x1] = head;
+buf[offset + 0x2] = sector;
+buf[offset + 0x3] = cyl;
+
+parttype = 0;
+g_assert(mbr[i].end_head < 256);
+g_assert(mbr[i].end_sector < 64);
+g_assert(mbr[i].end_cyl < 1024);
+head = mbr[i].end_head;
+sector = mbr[i].end_sector + ((mbr[i].end_cyl & 0x300) >> 2);
+cyl = mbr[i].end_cyl & 0xff;
+
+buf[offset + 0x4] = parttype;
+buf[offset + 0x5] = head;
+buf[offset + 0x6] = sector;
+buf[offset + 0x7] = cyl;
+
+(*(uint32_t *)[offset + 0x8]) = cpu_to_le32(mbr[i].start_sect);
+(*(uint32_t *)[offset + 0xc]) = cpu_to_le32(mbr[i].nr_sects);
+
+offset += 0x10;
+}
+
+fd = mkstemp(raw_path);
+g_assert(fd);
+close(fd);
+
+fd = open(raw_path, O_WRONLY);
+g_assert(fd >= 0);
+ret = write(fd, buf, sizeof(buf));
+g_assert(ret == sizeof(buf));
+close(fd);
+
+fd = mkstemp(qcow2_path);
+g_assert(fd);
+close(fd);
+
+qemu_img_path = getenv("QTEST_QEMU_IMG");
+g_assert(qemu_img_path);
+qemu_img_abs_path = realpath(qemu_img_path, NULL);
+g_assert(qemu_img_abs_path);
+
+ret = snprintf(cmd, sizeof(cmd),
+   "%s convert -f raw -O qcow2 %s %s > /dev/null",
+   qemu_img_abs_path,
+   raw_path, qcow2_path);
+g_assert((0 < ret) && (ret <= sizeof(cmd)));
+ret = system(cmd);
+g_assert(ret == 0);
+
+ret = snprintf(cmd, sizeof(cmd),
+   "%s resize %s %" PRIu64 " > /dev/null",
+   qemu_img_abs_path,
+   qcow2_path, qcow2_size);
+g_assert((0 < ret) && (ret <= sizeof(cmd)));
+ret = system(cmd);
+g_assert(ret == 0);
+
+free(qemu_img_abs_path);
+
+unlink(raw_path);
+free(raw_path);
+
+return qcow2_path;
+}
+
+struct QemuCfgFile {
+uint32_t  size;/* file size */
+uint16_t  select;  /* write this to 0x510 to read it */
+uint16_t  reserved;
+char name[56];
+};
+
+static uint16_t find_fw_cfg_file(QFWCFG *fw_cfg,
+ const char *filename)
+{
+struct QemuCfgFile qfile;
+uint32_t count, e;
+uint16_t select;
+
+count = qfw_cfg_get_u32(fw_cfg, FW_CFG_FILE_DIR);
+count = be32_to_cpu(count);
+for (select 

[PULL 6/8] bootdevice: Refactor get_boot_devices_list

2019-10-01 Thread John Snow
From: Sam Eiderman 

Move device name construction to a separate function.

We will reuse this function in the following commit to pass logical CHS
parameters through fw_cfg much like we currently pass bootindex.

Reviewed-by: Karl Heubaum 
Reviewed-by: Arbel Moshe 
Signed-off-by: Sam Eiderman 
Message-id: 20190925110639.100699-7-sam...@google.com
Signed-off-by: John Snow 
---
 bootdevice.c | 61 +---
 1 file changed, 34 insertions(+), 27 deletions(-)

diff --git a/bootdevice.c b/bootdevice.c
index bc5e1c2de4..2b12fb85a4 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -202,6 +202,39 @@ DeviceState *get_boot_device(uint32_t position)
 return res;
 }
 
+static char *get_boot_device_path(DeviceState *dev, bool ignore_suffixes,
+  char *suffix)
+{
+char *devpath = NULL, *s = NULL, *d, *bootpath;
+
+if (dev) {
+devpath = qdev_get_fw_dev_path(dev);
+assert(devpath);
+}
+
+if (!ignore_suffixes) {
+if (dev) {
+d = qdev_get_own_fw_dev_path_from_handler(dev->parent_bus, dev);
+if (d) {
+assert(!suffix);
+s = d;
+} else {
+s = g_strdup(suffix);
+}
+} else {
+s = g_strdup(suffix);
+}
+}
+
+bootpath = g_strdup_printf("%s%s",
+   devpath ? devpath : "",
+   s ? s : "");
+g_free(devpath);
+g_free(s);
+
+return bootpath;
+}
+
 /*
  * This function returns null terminated string that consist of new line
  * separated device paths.
@@ -218,36 +251,10 @@ char *get_boot_devices_list(size_t *size)
 bool ignore_suffixes = mc->ignore_boot_device_suffixes;
 
 QTAILQ_FOREACH(i, _boot_order, link) {
-char *devpath = NULL,  *suffix = NULL;
 char *bootpath;
-char *d;
 size_t len;
 
-if (i->dev) {
-devpath = qdev_get_fw_dev_path(i->dev);
-assert(devpath);
-}
-
-if (!ignore_suffixes) {
-if (i->dev) {
-d = qdev_get_own_fw_dev_path_from_handler(i->dev->parent_bus,
-  i->dev);
-if (d) {
-assert(!i->suffix);
-suffix = d;
-} else {
-suffix = g_strdup(i->suffix);
-}
-} else {
-suffix = g_strdup(i->suffix);
-}
-}
-
-bootpath = g_strdup_printf("%s%s",
-   devpath ? devpath : "",
-   suffix ? suffix : "");
-g_free(devpath);
-g_free(suffix);
+bootpath = get_boot_device_path(i->dev, ignore_suffixes, i->suffix);
 
 if (total) {
 list[total-1] = '\n';
-- 
2.21.0




[PULL 2/8] block: Support providing LCHS from user

2019-10-01 Thread John Snow
From: Sam Eiderman 

Add logical geometry variables to BlockConf.

A user can now supply "lcyls", "lheads" & "lsecs" for any HD device
that supports CHS ("cyls", "heads", "secs").

These devices include:
* ide-hd
* scsi-hd
* virtio-blk-pci

In future commits we will use the provided LCHS and pass it to the BIOS
through fw_cfg to be supplied using INT13 routines.

Reviewed-by: Karl Heubaum 
Reviewed-by: Arbel Moshe 
Signed-off-by: Sam Eiderman 
Message-id: 20190925110639.100699-3-sam...@google.com
Signed-off-by: John Snow 
---
 include/hw/block/block.h | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index fd55a30bca..d7246f3862 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -26,6 +26,7 @@ typedef struct BlockConf {
 uint32_t discard_granularity;
 /* geometry, not all devices use this */
 uint32_t cyls, heads, secs;
+uint32_t lcyls, lheads, lsecs;
 OnOffAuto wce;
 bool share_rw;
 BlockdevOnError rerror;
@@ -65,7 +66,10 @@ static inline unsigned int get_physical_block_exp(BlockConf 
*conf)
 #define DEFINE_BLOCK_CHS_PROPERTIES(_state, _conf)  \
 DEFINE_PROP_UINT32("cyls", _state, _conf.cyls, 0),  \
 DEFINE_PROP_UINT32("heads", _state, _conf.heads, 0),\
-DEFINE_PROP_UINT32("secs", _state, _conf.secs, 0)
+DEFINE_PROP_UINT32("secs", _state, _conf.secs, 0),  \
+DEFINE_PROP_UINT32("lcyls", _state, _conf.lcyls, 0),\
+DEFINE_PROP_UINT32("lheads", _state, _conf.lheads, 0),  \
+DEFINE_PROP_UINT32("lsecs", _state, _conf.lsecs, 0)
 
 #define DEFINE_BLOCK_ERROR_PROPERTIES(_state, _conf)\
 DEFINE_PROP_BLOCKDEV_ON_ERROR("rerror", _state, _conf.rerror,   \
-- 
2.21.0




Re: [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController

2019-10-01 Thread David Gibson
On Tue, Oct 01, 2019 at 01:43:12PM +0200, Cédric Le Goater wrote:
> On 01/10/2019 10:11, David Gibson wrote:
> > On Tue, Oct 01, 2019 at 09:41:27AM +0200, Cédric Le Goater wrote:
> >> On 01/10/2019 08:47, David Gibson wrote:
> >>> On Tue, Oct 01, 2019 at 07:43:51AM +0200, Cédric Le Goater wrote:
>  On 01/10/2019 04:31, David Gibson wrote:
> > On Mon, Sep 30, 2019 at 12:13:14PM +0200, Cédric Le Goater wrote:
> >> On 30/09/2019 08:14, David Gibson wrote:
> >>> On Mon, Sep 30, 2019 at 07:28:45AM +0200, Cédric Le Goater wrote:
>  On 30/09/2019 03:49, David Gibson wrote:
> > On Fri, Sep 27, 2019 at 12:16:49PM +0200, Greg Kurz wrote:
> >> On Fri, 27 Sep 2019 15:50:16 +1000
> >> David Gibson  wrote:
> >>
> >>> This method essentially represents code which belongs to the 
> >>> interrupt
> >>> controller, but needs to be called on all possible intcs, rather 
> >>> than
> >>> just the currently active one.  The "dual" version therefore calls
> >>> into the xics and xive versions confusingly.
> >>>
> >>> Handle this more directly, by making it instead a method on the 
> >>> intc
> >>> backend, and always calling it on every backend that exists.
> >>>
> >>> While we're there, streamline the error reporting a bit.
> >>>
> >>> Signed-off-by: David Gibson 
> > [snip]
> >>> @@ -525,6 +469,30 @@ static void 
> >>> spapr_irq_check(SpaprMachineState *spapr, Error **errp)
> >>>  /*
> >>>   * sPAPR IRQ frontend routines for devices
> >>>   */
> >>> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> >>> +  PowerPCCPU *cpu, Error **errp)
> >>> +{
> >>> +if (spapr->xive) {
> >>> +SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
> >>> +SpaprInterruptControllerClass *sicc = 
> >>> SPAPR_INTC_GET_CLASS(intc);
> >>> +
> >>> +if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
> >>> +return -1;
> >>> +}
> >>> +}
> >>> +
> >>> +if (spapr->ics) {
> >>> +SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
> >>> +SpaprInterruptControllerClass *sicc = 
> >>> SPAPR_INTC_GET_CLASS(intc);
> >>> +
> >>> +if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
> >>> +return -1;
> >>> +}
> >>> +}
> >>> +
> >>
> >> Instead of these hooks, what about open-coding 
> >> spapr_xive_cpu_intc_create()
> >> and xics_spapr_cpu_intc_create() directly here, like you already 
> >> did for the
> >> ICS and the XIVE objects in spapr_irq_init() ?
> >
> > I'd prefer not to.  The idea is I want to treat this as basically:
> >
> > foreach_possible_intc(intc)
> > intc::cpu_intc_create(...)
> >
> > If I find time I might indeed replace the explicit ics and xive
> > pointers with just an array of SpaprInterruptController *.
> 
>  Or you could use object_child_foreach() and check for the type. If 
>  we had
>  a helper object_child_foreach_type(), we could use it elsewhere.
> >>>
> >>> I thought about that, but I don't think it quite works.  The
> >>> complication is that the xics device is made explicitly a child of the
> >>> machine, but the xive device has mmio, so it's a SusBusDevice sitting
> >>> on the root bus instead.
> >>
> >> PnvXscom works fine with Devices and SysBusDevices.
> >
> > Uh... what's an example of it working with a SysBusDevice?  All the
> > implementors of PNV_XSCOM_INTERFACE I could find were instantiated
> > with object_initialize_child() making them explicitly children of the
> > chip.  The SPAPR_XIVE is instantiated with qdev_create(NULL,
> > TYPE_SPAPR_XIVE), making it a child of the root bus, not the machine,
> > I believe.
> 
>  I see. We should reparent the interrupt controller then.
> >>>
> >>> Well, maybe.  It's not obvious to me that that's the right approach
> >>> just because of this.
> >>>
> >>>
>  Could we rework 
>  the code to instantiate and realize the XICS and XIVE model objects ? 
>  We have the handlers spapr_instance_init() and spapr_machine_init(). 
> >>>
> >>> I'm not really sure what you're suggesting here.
> >>
> >> Define the device model objects under the machine and not pointers :
> >>
> >>struct SpaprMachineState {
> >>...
> >>ICSState ics;
> >>SpaprXive  xive;
> >>...
> >>};
> >>
> >> in spapr_instance_init() :
> >>
> >>object_initialize_child(obj, "ics",  >ics, sizeof(spapr->ics),
> 

[PATCH 06/97] block: Fix AioContext switch for bs->drv == NULL

2019-10-01 Thread Michael Roth
From: Kevin Wolf 

Even for block nodes with bs->drv == NULL, we can't just ignore a
bdrv_set_aio_context() call. Leaving the node in its old context can
mean that it's still in an iothread context in bdrv_close_all() during
shutdown, resulting in an attempted unlock of the AioContext lock which
we don't hold.

This is an example stack trace of a related crash:

 #0  0x759da57f in raise () at /lib64/libc.so.6
 #1  0x759c4895 in abort () at /lib64/libc.so.6
 #2  0x55b97b1e in error_exit (err=, 
msg=msg@entry=0x55d386d0 <__func__.19059> "qemu_mutex_unlock_impl") at 
util/qemu-thread-posix.c:36
 #3  0x55b97f7f in qemu_mutex_unlock_impl 
(mutex=mutex@entry=0x568002f0, file=file@entry=0x55d378df 
"util/async.c", line=line@entry=507) at util/qemu-thread-posix.c:97
 #4  0x55b92f55 in aio_context_release (ctx=ctx@entry=0x56800290) 
at util/async.c:507
 #5  0x55b05cf8 in bdrv_prwv_co (child=child@entry=0x7fffc80012f0, 
offset=offset@entry=131072, qiov=qiov@entry=0x7fffd4f0, 
is_write=is_write@entry=true, flags=flags@entry=0)
 at block/io.c:833
 #6  0x55b060a9 in bdrv_pwritev (qiov=0x7fffd4f0, offset=131072, 
child=0x7fffc80012f0) at block/io.c:990
 #7  0x55b060a9 in bdrv_pwrite (child=0x7fffc80012f0, offset=131072, 
buf=, bytes=) at block/io.c:990
 #8  0x55ae172b in qcow2_cache_entry_flush (bs=bs@entry=0x56810680, 
c=c@entry=0x568cc740, i=i@entry=0) at block/qcow2-cache.c:51
 #9  0x55ae18dd in qcow2_cache_write (bs=bs@entry=0x56810680, 
c=0x568cc740) at block/qcow2-cache.c:248
 #10 0x55ae15de in qcow2_cache_flush (bs=0x56810680, c=) at block/qcow2-cache.c:259
 #11 0x55ae16b1 in qcow2_cache_flush_dependency (c=0x568a1700, 
c=0x568a1700, bs=0x56810680) at block/qcow2-cache.c:194
 #12 0x55ae16b1 in qcow2_cache_entry_flush (bs=bs@entry=0x56810680, 
c=c@entry=0x568a1700, i=i@entry=0) at block/qcow2-cache.c:194
 #13 0x55ae18dd in qcow2_cache_write (bs=bs@entry=0x56810680, 
c=0x568a1700) at block/qcow2-cache.c:248
 #14 0x55ae15de in qcow2_cache_flush (bs=bs@entry=0x56810680, 
c=) at block/qcow2-cache.c:259
 #15 0x55ad242c in qcow2_inactivate (bs=bs@entry=0x56810680) at 
block/qcow2.c:2124
 #16 0x55ad2590 in qcow2_close (bs=0x56810680) at block/qcow2.c:2153
 #17 0x55ab0c62 in bdrv_close (bs=0x56810680) at block.c:3358
 #18 0x55ab0c62 in bdrv_delete (bs=0x56810680) at block.c:3542
 #19 0x55ab0c62 in bdrv_unref (bs=0x56810680) at block.c:4598
 #20 0x55af4d72 in blk_remove_bs (blk=blk@entry=0x568103d0) at 
block/block-backend.c:785
 #21 0x55af4dbb in blk_remove_all_bs () at block/block-backend.c:483
 #22 0x55aae02f in bdrv_close_all () at block.c:3412
 #23 0x557f9796 in main (argc=, argv=, 
envp=) at vl.c:4776

The reproducer I used is a qcow2 image on gluster volume, where the
virtual disk size (4 GB) is larger than the gluster volume size (64M),
so we can easily trigger an ENOSPC. This backend is assigned to a
virtio-blk device using an iothread, and then from the guest a
'dd if=/dev/zero of=/dev/vda bs=1G count=1' causes the VM to stop
because of an I/O error. qemu_gluster_co_flush_to_disk() sets
bs->drv = NULL on error, so when virtio-blk stops the dataplane, the
block nodes stay in the iothread AioContext. A 'quit' monitor command
issued from this paused state crashes the process.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1631227
Cc: qemu-sta...@nongnu.org
Signed-off-by: Kevin Wolf 
Reviewed-by: Eric Blake 
Reviewed-by: Max Reitz 
Reviewed-by: Stefano Garzarella 
(cherry picked from commit 1bffe1ae7a7b707c3a14ea2ccd00d3609d3ce4d8)
Signed-off-by: Michael Roth 
---
 block.c | 12 ++--
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/block.c b/block.c
index 16615bc876..9ae5c0ed2f 100644
--- a/block.c
+++ b/block.c
@@ -5672,10 +5672,6 @@ void bdrv_detach_aio_context(BlockDriverState *bs)
 BdrvAioNotifier *baf, *baf_tmp;
 BdrvChild *child;
 
-if (!bs->drv) {
-return;
-}
-
 assert(!bs->walking_aio_notifiers);
 bs->walking_aio_notifiers = true;
 QLIST_FOREACH_SAFE(baf, >aio_notifiers, list, baf_tmp) {
@@ -5690,7 +5686,7 @@ void bdrv_detach_aio_context(BlockDriverState *bs)
  */
 bs->walking_aio_notifiers = false;
 
-if (bs->drv->bdrv_detach_aio_context) {
+if (bs->drv && bs->drv->bdrv_detach_aio_context) {
 bs->drv->bdrv_detach_aio_context(bs);
 }
 QLIST_FOREACH(child, >children, next) {
@@ -5709,10 +5705,6 @@ void bdrv_attach_aio_context(BlockDriverState *bs,
 BdrvAioNotifier *ban, *ban_tmp;
 BdrvChild *child;
 
-if (!bs->drv) {
-return;
-}
-
 if (bs->quiesce_counter) {
 aio_disable_external(new_context);
 }
@@ -5722,7 +5714,7 @@ void bdrv_attach_aio_context(BlockDriverState *bs,
 

[ANNOUNCE] QEMU 3.1.1.1 Stable released

2019-10-01 Thread Michael Roth
Hi everyone,

I am pleased to announce that the QEMU v3.1.1.1 stable release is now
available:

You can grab the tarball from our download page here:

  https://www.qemu.org/download/#source

v3.1.1.1 is now tagged in the official qemu.git repository,
and the stable-3.1 branch has been updated accordingly:

  https://git.qemu.org/?p=qemu.git;a=shortlog;h=refs/heads/stable-3.1

This is a small update which contains only a security fix for CVE-2019-14378
(slirp) and a fix for a pvrdma build regression introduced in 3.1.1.

Please see the changelog for additional details and update accordingly.

Thank you to everyone involved!

CHANGELOG:

920019e0e0: Update version for 3.1.1.1 release (Michael Roth)
9efdbc0224: slrip: ip_reass: Fix use after free (Michael Roth)
28c1dde9aa: slirp: Fix heap overflow in ip_reass on big packet input (Michael 
Roth)
ab630a065a: pvrdma: Fix compilation error (Cole Robinson)



[PATCH 63/97] backup: Copy only dirty areas

2019-10-01 Thread Michael Roth
From: Max Reitz 

The backup job must only copy areas that the copy_bitmap reports as
dirty.  This is always the case when using traditional non-offloading
backup, because it copies each cluster separately.  When offloading the
copy operation, we sometimes copy more than one cluster at a time, but
we only check whether the first one is dirty.

Therefore, whenever copy offloading is possible, the backup job
currently produces wrong output when the guest writes to an area of
which an inner part has already been backed up, because that inner part
will be re-copied.

Fixes: 9ded4a0114968e98b41494fc035ba14f84cdf700
Signed-off-by: Max Reitz 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Message-id: 20190801173900.23851-2-mre...@redhat.com
Cc: qemu-sta...@nongnu.org
Signed-off-by: Max Reitz 
(cherry picked from commit 4a5b91ca024fc6fd87021c54655af76a35f2ef1e)
Signed-off-by: Michael Roth 
---
 block/backup.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index d1b94a6dbe..f67c208cf0 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -204,22 +204,31 @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
 cow_request_begin(_request, job, start, end);
 
 while (start < end) {
+int64_t dirty_end;
+
 if (!hbitmap_get(job->copy_bitmap, start)) {
 trace_backup_do_cow_skip(job, start);
 start += job->cluster_size;
 continue; /* already copied */
 }
 
+dirty_end = hbitmap_next_zero(job->copy_bitmap, start, (end - start));
+if (dirty_end < 0) {
+dirty_end = end;
+}
+
 trace_backup_do_cow_process(job, start);
 
 if (job->use_copy_range) {
-ret = backup_cow_with_offload(job, start, end, is_write_notifier);
+ret = backup_cow_with_offload(job, start, dirty_end,
+  is_write_notifier);
 if (ret < 0) {
 job->use_copy_range = false;
 }
 }
 if (!job->use_copy_range) {
-ret = backup_cow_with_bounce_buffer(job, start, end, 
is_write_notifier,
+ret = backup_cow_with_bounce_buffer(job, start, dirty_end,
+is_write_notifier,
 error_is_read, _buffer);
 }
 if (ret < 0) {
-- 
2.17.1




Re: Is kexec supported in QEMU for ARM64 (qemu-system-aarch64) with arm-trusted-firmware, optee, and u-boot.

2019-10-01 Thread Lakshmi Ramasubramanian

On 10/1/19 9:30 AM, Ard Biesheuvel wrote:



kexec is a linux concept, so whether it is supported should not depend
on the secure world firmware or the underlying host.


I agree Ard.
When I don't use ATF I am able to do kexec in QEMU and successfully boot 
into the new kernel.

Is the following expected?

When I execute kexec ("kexec -l ", followed by "kexec -e") I hit 
the following assert in ATF (in the file

arm-trusted-firmware/plat/qemu/qemu_pm.c)

/***
  * Platform handler called when a power domain is about to be turned
  * off. The target_state encodes the power state that each level should
  * transition to.
**/
void qemu_pwr_domain_off(const psci_power_state_t *target_state)
{
 assert(0);
}

Thanks,
 -lakshmi





[PULL 5/8] bootdevice: Gather LCHS from all relevant devices

2019-10-01 Thread John Snow
From: Sam Eiderman 

Relevant devices are:
* ide-hd (and ide-cd, ide-drive)
* scsi-hd (and scsi-cd, scsi-disk, scsi-block)
* virtio-blk-pci

We do not call del_boot_device_lchs() for ide-* since we don't need to -
IDE block devices do not support unplugging.

Signed-off-by: Sam Eiderman 
Reviewed-by: Karl Heubaum 
Reviewed-by: Arbel Moshe 
Signed-off-by: Sam Eiderman 
Message-id: 20190925110639.100699-6-sam...@google.com
Signed-off-by: John Snow 
---
 hw/block/virtio-blk.c |  6 ++
 hw/ide/qdev.c |  5 +
 hw/scsi/scsi-disk.c   | 12 
 3 files changed, 23 insertions(+)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 18851601cb..6d8ff34a16 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -1186,6 +1186,11 @@ static void virtio_blk_device_realize(DeviceState *dev, 
Error **errp)
 blk_set_guest_block_size(s->blk, s->conf.conf.logical_block_size);
 
 blk_iostatus_enable(s->blk);
+
+add_boot_device_lchs(dev, "/disk@0,0",
+ conf->conf.lcyls,
+ conf->conf.lheads,
+ conf->conf.lsecs);
 }
 
 static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
@@ -1193,6 +1198,7 @@ static void virtio_blk_device_unrealize(DeviceState *dev, 
Error **errp)
 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
 VirtIOBlock *s = VIRTIO_BLK(dev);
 
+del_boot_device_lchs(dev, "/disk@0,0");
 virtio_blk_data_plane_destroy(s->dataplane);
 s->dataplane = NULL;
 qemu_del_vm_change_state_handler(s->change);
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 6dd219944f..2ffd387a73 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -220,6 +220,11 @@ static void ide_dev_initfn(IDEDevice *dev, IDEDriveKind 
kind, Error **errp)
 
 add_boot_device_path(dev->conf.bootindex, >qdev,
  dev->unit ? "/disk@1" : "/disk@0");
+
+add_boot_device_lchs(>qdev, dev->unit ? "/disk@1" : "/disk@0",
+ dev->conf.lcyls,
+ dev->conf.lheads,
+ dev->conf.lsecs);
 }
 
 static void ide_dev_get_bootindex(Object *obj, Visitor *v, const char *name,
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 915641a0f1..d19896fe4d 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -35,6 +35,7 @@
 #include "hw/block/block.h"
 #include "hw/qdev-properties.h"
 #include "sysemu/dma.h"
+#include "sysemu/sysemu.h"
 #include "qemu/cutils.h"
 #include "trace.h"
 
@@ -2402,6 +2403,16 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
 blk_set_guest_block_size(s->qdev.conf.blk, s->qdev.blocksize);
 
 blk_iostatus_enable(s->qdev.conf.blk);
+
+add_boot_device_lchs(>qdev, NULL,
+ dev->conf.lcyls,
+ dev->conf.lheads,
+ dev->conf.lsecs);
+}
+
+static void scsi_unrealize(SCSIDevice *dev, Error **errp)
+{
+del_boot_device_lchs(>qdev, NULL);
 }
 
 static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
@@ -3006,6 +3017,7 @@ static void scsi_hd_class_initfn(ObjectClass *klass, void 
*data)
 SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
 
 sc->realize  = scsi_hd_realize;
+sc->unrealize= scsi_unrealize;
 sc->alloc_req= scsi_new_request;
 sc->unit_attention_reported = scsi_disk_unit_attention_reported;
 dc->desc = "virtual SCSI disk";
-- 
2.21.0




[PATCH 74/97] xen-bus: Fix backend state transition on device reset

2019-10-01 Thread Michael Roth
From: Anthony PERARD 

When a frontend wants to reset its state and the backend one, it
starts with setting "Closing", then waits for the backend (QEMU) to do
the same.

But when QEMU is setting "Closing" to its state, it triggers an event
(xenstore watch) that re-execute xen_device_backend_changed() and set
the backend state to "Closed". QEMU should wait for the frontend to
set "Closed" before doing the same.

Before setting "Closed" to the backend_state, we are also going to
check if there is a frontend. If that the case, when the backend state
is set to "Closing" the frontend should react and sets its state to
"Closing" then "Closed". The backend should wait for that to happen.

Fixes: b6af8926fb858c4f1426e5acb2cfc1f0580ec98a
Signed-off-by: Anthony PERARD 
Reviewed-by: Paul Durrant 
Message-Id: <20190823101534.465-2-anthony.per...@citrix.com>
(cherry picked from commit cb3231460747552d70af9d546dc53d8195bcb796)
Signed-off-by: Michael Roth 
---
 hw/xen/xen-bus.c | 23 ---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index 49a725e8c7..0a1033d9a9 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -515,6 +515,23 @@ static void xen_device_backend_set_online(XenDevice 
*xendev, bool online)
 xen_device_backend_printf(xendev, "online", "%u", online);
 }
 
+/*
+ * Tell from the state whether the frontend is likely alive,
+ * i.e. it will react to a change of state of the backend.
+ */
+static bool xen_device_state_is_active(enum xenbus_state state)
+{
+switch (state) {
+case XenbusStateInitWait:
+case XenbusStateInitialised:
+case XenbusStateConnected:
+case XenbusStateClosing:
+return true;
+default:
+return false;
+}
+}
+
 static void xen_device_backend_changed(void *opaque)
 {
 XenDevice *xendev = opaque;
@@ -538,11 +555,11 @@ static void xen_device_backend_changed(void *opaque)
 
 /*
  * If the toolstack (or unplug request callback) has set the backend
- * state to Closing, but there is no active frontend (i.e. the
- * state is not Connected) then set the backend state to Closed.
+ * state to Closing, but there is no active frontend then set the
+ * backend state to Closed.
  */
 if (xendev->backend_state == XenbusStateClosing &&
-xendev->frontend_state != XenbusStateConnected) {
+!xen_device_state_is_active(state)) {
 xen_device_backend_set_state(xendev, XenbusStateClosed);
 }
 
-- 
2.17.1




[PULL 7/8] bootdevice: FW_CFG interface for LCHS values

2019-10-01 Thread John Snow
From: Sam Eiderman 

Using fw_cfg, supply logical CHS values directly from QEMU to the BIOS.

Non-standard logical geometries break under QEMU.

A virtual disk which contains an operating system which depends on
logical geometries (consistent values being reported from BIOS INT13
AH=08) will most likely break under QEMU/SeaBIOS if it has non-standard
logical geometries - for example 56 SPT (sectors per track).
No matter what QEMU will report - SeaBIOS, for large enough disks - will
use LBA translation, which will report 63 SPT instead.

In addition we cannot force SeaBIOS to rely on physical geometries at
all. A virtio-blk-pci virtual disk with 255 phyiscal heads cannot
report more than 16 physical heads when moved to an IDE controller,
since the ATA spec allows a maximum of 16 heads - this is an artifact of
virtualization.

By supplying the logical geometries directly we are able to support such
"exotic" disks.

We serialize this information in a similar way to the "bootorder"
interface.
The new fw_cfg entry is "bios-geometry".

Reviewed-by: Karl Heubaum 
Reviewed-by: Arbel Moshe 
Signed-off-by: Sam Eiderman 
Message-id: 20190925110639.100699-8-sam...@google.com
Signed-off-by: John Snow 
---
 include/sysemu/sysemu.h |  1 +
 bootdevice.c| 32 
 hw/nvram/fw_cfg.c   | 14 +++---
 3 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 5bc5c79cbc..80c57fdc4e 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -106,6 +106,7 @@ void validate_bootdevices(const char *devices, Error 
**errp);
 void add_boot_device_lchs(DeviceState *dev, const char *suffix,
   uint32_t lcyls, uint32_t lheads, uint32_t lsecs);
 void del_boot_device_lchs(DeviceState *dev, const char *suffix);
+char *get_boot_devices_lchs_list(size_t *size);
 
 /* handler to set the boot_device order for a specific type of MachineClass */
 typedef void QEMUBootSetHandler(void *opaque, const char *boot_order,
diff --git a/bootdevice.c b/bootdevice.c
index 2b12fb85a4..b034ad7bdc 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -405,3 +405,35 @@ void del_boot_device_lchs(DeviceState *dev, const char 
*suffix)
 }
 }
 }
+
+/* Serialized as: (device name\0 + lchs struct) x devices */
+char *get_boot_devices_lchs_list(size_t *size)
+{
+FWLCHSEntry *i;
+size_t total = 0;
+char *list = NULL;
+
+QTAILQ_FOREACH(i, _lchs, link) {
+char *bootpath;
+char *chs_string;
+size_t len;
+
+bootpath = get_boot_device_path(i->dev, false, i->suffix);
+chs_string = g_strdup_printf("%s %" PRIu32 " %" PRIu32 " %" PRIu32,
+ bootpath, i->lcyls, i->lheads, i->lsecs);
+
+if (total) {
+list[total - 1] = '\n';
+}
+len = strlen(chs_string) + 1;
+list = g_realloc(list, total + len);
+memcpy([total], chs_string, len);
+total += len;
+g_free(chs_string);
+g_free(bootpath);
+}
+
+*size = total;
+
+return list;
+}
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 7dc3ac378e..18aff658c0 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -920,13 +920,21 @@ void *fw_cfg_modify_file(FWCfgState *s, const char 
*filename,
 
 static void fw_cfg_machine_reset(void *opaque)
 {
+MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
+FWCfgState *s = opaque;
 void *ptr;
 size_t len;
-FWCfgState *s = opaque;
-char *bootindex = get_boot_devices_list();
+char *buf;
 
-ptr = fw_cfg_modify_file(s, "bootorder", (uint8_t *)bootindex, len);
+buf = get_boot_devices_list();
+ptr = fw_cfg_modify_file(s, "bootorder", (uint8_t *)buf, len);
 g_free(ptr);
+
+if (!mc->legacy_fw_cfg_order) {
+buf = get_boot_devices_lchs_list();
+ptr = fw_cfg_modify_file(s, "bios-geometry", (uint8_t *)buf, len);
+g_free(ptr);
+}
 }
 
 static void fw_cfg_machine_ready(struct Notifier *n, void *data)
-- 
2.21.0




[PULL 4/8] scsi: Propagate unrealize() callback to scsi-hd

2019-10-01 Thread John Snow
From: Sam Eiderman 

We will need to add LCHS removal logic to scsi-hd's unrealize() in the
next commit.

Signed-off-by: Sam Eiderman 
Reviewed-by: Karl Heubaum 
Reviewed-by: Arbel Moshe 
Signed-off-by: Sam Eiderman 
Message-id: 20190925110639.100699-5-sam...@google.com
Signed-off-by: John Snow 
---
 include/hw/scsi/scsi.h |  1 +
 hw/scsi/scsi-bus.c | 16 
 2 files changed, 17 insertions(+)

diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index d77a92361b..332ef602f4 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -59,6 +59,7 @@ struct SCSIRequest {
 typedef struct SCSIDeviceClass {
 DeviceClass parent_class;
 void (*realize)(SCSIDevice *dev, Error **errp);
+void (*unrealize)(SCSIDevice *dev, Error **errp);
 int (*parse_cdb)(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
  void *hba_private);
 SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index bccb7cc4c6..359d50d6d0 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -59,6 +59,14 @@ static void scsi_device_realize(SCSIDevice *s, Error **errp)
 }
 }
 
+static void scsi_device_unrealize(SCSIDevice *s, Error **errp)
+{
+SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s);
+if (sc->unrealize) {
+sc->unrealize(s, errp);
+}
+}
+
 int scsi_bus_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
void *hba_private)
 {
@@ -217,12 +225,20 @@ static void scsi_qdev_realize(DeviceState *qdev, Error 
**errp)
 static void scsi_qdev_unrealize(DeviceState *qdev, Error **errp)
 {
 SCSIDevice *dev = SCSI_DEVICE(qdev);
+Error *local_err = NULL;
 
 if (dev->vmsentry) {
 qemu_del_vm_change_state_handler(dev->vmsentry);
 }
 
 scsi_device_purge_requests(dev, SENSE_CODE(NO_SENSE));
+
+scsi_device_unrealize(dev, _err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+
 blockdev_mark_auto_del(dev->conf.blk);
 }
 
-- 
2.21.0




[PULL 1/8] block: Refactor macros - fix tabbing

2019-10-01 Thread John Snow
From: Sam Eiderman 

Fixing tabbing in block related macros.

Reviewed-by: Karl Heubaum 
Reviewed-by: Arbel Moshe 
Signed-off-by: Sam Eiderman 
Message-id: 20190925110639.100699-2-sam...@google.com
Signed-off-by: John Snow 
---
 include/hw/block/block.h | 16 
 hw/ide/qdev.c|  2 +-
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index 607539057a..fd55a30bca 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -50,21 +50,21 @@ static inline unsigned int get_physical_block_exp(BlockConf 
*conf)
   _conf.logical_block_size),\
 DEFINE_PROP_BLOCKSIZE("physical_block_size", _state,\
   _conf.physical_block_size),   \
-DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 0),  \
+DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 0),\
 DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 0),\
-DEFINE_PROP_UINT32("discard_granularity", _state, \
-   _conf.discard_granularity, -1), \
-DEFINE_PROP_ON_OFF_AUTO("write-cache", _state, _conf.wce, \
-ON_OFF_AUTO_AUTO), \
+DEFINE_PROP_UINT32("discard_granularity", _state,   \
+   _conf.discard_granularity, -1),  \
+DEFINE_PROP_ON_OFF_AUTO("write-cache", _state, _conf.wce,   \
+ON_OFF_AUTO_AUTO),  \
 DEFINE_PROP_BOOL("share-rw", _state, _conf.share_rw, false)
 
 #define DEFINE_BLOCK_PROPERTIES(_state, _conf)  \
 DEFINE_PROP_DRIVE("drive", _state, _conf.blk),  \
 DEFINE_BLOCK_PROPERTIES_BASE(_state, _conf)
 
-#define DEFINE_BLOCK_CHS_PROPERTIES(_state, _conf)  \
-DEFINE_PROP_UINT32("cyls", _state, _conf.cyls, 0),  \
-DEFINE_PROP_UINT32("heads", _state, _conf.heads, 0), \
+#define DEFINE_BLOCK_CHS_PROPERTIES(_state, _conf)  \
+DEFINE_PROP_UINT32("cyls", _state, _conf.cyls, 0),  \
+DEFINE_PROP_UINT32("heads", _state, _conf.heads, 0),\
 DEFINE_PROP_UINT32("secs", _state, _conf.secs, 0)
 
 #define DEFINE_BLOCK_ERROR_PROPERTIES(_state, _conf)\
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 6fba6b62b8..6dd219944f 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -290,7 +290,7 @@ static void ide_drive_realize(IDEDevice *dev, Error **errp)
 DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf),\
 DEFINE_BLOCK_ERROR_PROPERTIES(IDEDrive, dev.conf),  \
 DEFINE_PROP_STRING("ver",  IDEDrive, dev.version),  \
-DEFINE_PROP_UINT64("wwn",  IDEDrive, dev.wwn, 0),\
+DEFINE_PROP_UINT64("wwn",  IDEDrive, dev.wwn, 0),   \
 DEFINE_PROP_STRING("serial",  IDEDrive, dev.serial),\
 DEFINE_PROP_STRING("model", IDEDrive, dev.model)
 
-- 
2.21.0




Re: [PATCH] spapr/xive: skip partially initialized vCPUs in presenter

2019-10-01 Thread David Gibson
On Tue, Oct 01, 2019 at 06:56:28PM +0200, Greg Kurz wrote:
> On Tue, 1 Oct 2019 13:56:10 +0200
> Cédric Le Goater  wrote:
> 
> > On 01/10/2019 13:06, Greg Kurz wrote:
> > > On Tue,  1 Oct 2019 10:57:22 +0200
> > > Cédric Le Goater  wrote:
> > > 
> > >> When vCPUs are hotplugged, they are added to the QEMU CPU list before
> > >> being fully realized. This can crash the XIVE presenter because the
> > >> 'tctx' pointer is not necessarily initialized when looking for a
> > >> matching target.
> > >>
> > > 
> > > Ouch... :-\
> > > 
> > >> These vCPUs are not valid targets for the presenter. Skip them.
> > >>
> > > 
> > > This likely fixes this specific issue, but more generally, this
> > > seems to indicate that using CPU_FOREACH() is rather fragile.
> > > 
> > > What about tracking XIVE TM contexts with a QLIST in xive.c ?
> > 
> > This is a good idea.  
> > 
> > On HW, the thread interrupt contexts belong to the XIVE presenter 
> > subengine. This is the logic doing the CAM line matching to find
> > a target for an event notification. So we should model the context 
> > list below the XiveRouter in QEMU which models both router and 
> > presenter subengines. We have done without a presenter model for 
> > the moment and I don't think we will need to introduce one.  
> > 
> > This would be a nice improvements of my patchset adding support
> > for xive escalations and better support of multi chip systems. 
> > I have introduced a PNV_CHIP_CPU_FOREACH in this patchset which 
> > would become useless with a list of tctx under the XIVE interrupt
> > controller, XiveRouter, SpaprXive, PnvXive.
> > 
> 
> I agree. It makes more sense to have the list below the XiveRouter,
> rather than relying on CPU_FOREACH(), which looks a bit weird from
> a device emulation code perspective.

That does sound like a better idea long term.  However, for now, I
think the NULL check is a reasonable way of fixing the real error
we're hitting, so I've applied the patch here.

Future cleanups to a different approach remain welcome, of course.

> > Next step would be to get rid of the tctx->cs pointer. In my latest
> > patches, it is only used to calculate the HW CAM line. 
> > 
> > There might be some consequences on the object hierarchy and it will
> > break migration.
> > 
> 
> This could break if the contexts were devices sitting in a bus, which
> isn't the case here. I'll try to come up with a proposal for spapr,
> and we can work out the changes on your recent XIVE series for pnv.
> 
> > Thanks,
> > 
> > C.
> > 
> > > 
> > > 
> > > diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
> > > index 6d38755f8459..89b9ef7f20b1 100644
> > > --- a/include/hw/ppc/xive.h
> > > +++ b/include/hw/ppc/xive.h
> > > @@ -319,6 +319,8 @@ typedef struct XiveTCTX {
> > >  qemu_irqos_output;
> > >  
> > >  uint8_t regs[XIVE_TM_RING_COUNT * XIVE_TM_RING_SIZE];
> > > +
> > > +QTAILQ_ENTRY(XiveTCTX) next;
> > >  } XiveTCTX;
> > >  
> > >  /*
> > > diff --git a/hw/intc/xive.c b/hw/intc/xive.c
> > > index b7417210d817..f7721c711041 100644
> > > --- a/hw/intc/xive.c
> > > +++ b/hw/intc/xive.c
> > > @@ -568,6 +568,8 @@ static void xive_tctx_reset(void *dev)
> > >  ipb_to_pipr(tctx->regs[TM_QW3_HV_PHYS + TM_IPB]);
> > >  }
> > >  
> > > +static QTAILQ_HEAD(, XiveTCTX) xive_tctx_list = 
> > > QTAILQ_HEAD_INITIALIZER(xive_tctx_list);
> > > +
> > >  static void xive_tctx_realize(DeviceState *dev, Error **errp)
> > >  {
> > >  XiveTCTX *tctx = XIVE_TCTX(dev);
> > > @@ -609,10 +611,14 @@ static void xive_tctx_realize(DeviceState *dev, 
> > > Error **errp)
> > >  }
> > >  
> > >  qemu_register_reset(xive_tctx_reset, dev);
> > > +QTAILQ_INSERT_HEAD(_tctx_list, tctx, next);
> > >  }
> > >  
> > >  static void xive_tctx_unrealize(DeviceState *dev, Error **errp)
> > >  {
> > > +XiveTCTX *tctx = XIVE_TCTX(dev);
> > > +
> > > +QTAILQ_REMOVE(_tctx_list, tctx, next);
> > >  qemu_unregister_reset(xive_tctx_reset, dev);
> > >  }
> > >  
> > > @@ -1385,15 +1391,14 @@ static bool xive_presenter_match(XiveRouter 
> > > *xrtr, uint8_t format,
> > >   bool cam_ignore, uint8_t priority,
> > >   uint32_t logic_serv, XiveTCTXMatch 
> > > *match)
> > >  {
> > > -CPUState *cs;
> > > +XiveTCTX *tctx;
> > >  
> > >  /*
> > >   * TODO (PowerNV): handle chip_id overwrite of block field for
> > >   * hardwired CAM compares
> > >   */
> > >  
> > > -CPU_FOREACH(cs) {
> > > -XiveTCTX *tctx = xive_router_get_tctx(xrtr, cs);
> > > +QTAILQ_FOREACH(tctx, _tctx_list, next) {
> > >  int ring;
> > >  
> > >  /*
> > > 
> > > 
> > >> Signed-off-by: Cédric Le Goater 
> > >> ---
> > >>  hw/intc/xive.c | 8 
> > >>  1 file changed, 8 insertions(+)
> > >>
> > >> 

[PATCH 79/97] iotests: Restrict file Python tests to file

2019-10-01 Thread Michael Roth
From: Max Reitz 

Most of our Python unittest-style tests only support the file protocol.
You can run them with any other protocol, but the test will simply
ignore your choice and use file anyway.

We should let them signal that they require the file protocol so they
are skipped when you want to test some other protocol.

Signed-off-by: Max Reitz 
Signed-off-by: Kevin Wolf 
(cherry picked from commit 103cbc771e5660d1f5bb458be80aa9e363547ae0)
 Conflicts:
tests/qemu-iotests/257
*drop changes for test 257, not present in 4.0
Signed-off-by: Michael Roth 
---
 tests/qemu-iotests/030 | 3 ++-
 tests/qemu-iotests/040 | 3 ++-
 tests/qemu-iotests/041 | 3 ++-
 tests/qemu-iotests/044 | 3 ++-
 tests/qemu-iotests/045 | 3 ++-
 tests/qemu-iotests/055 | 3 ++-
 tests/qemu-iotests/056 | 3 ++-
 tests/qemu-iotests/057 | 3 ++-
 tests/qemu-iotests/065 | 3 ++-
 tests/qemu-iotests/096 | 3 ++-
 tests/qemu-iotests/118 | 3 ++-
 tests/qemu-iotests/124 | 3 ++-
 tests/qemu-iotests/129 | 3 ++-
 tests/qemu-iotests/132 | 3 ++-
 tests/qemu-iotests/139 | 3 ++-
 tests/qemu-iotests/148 | 3 ++-
 tests/qemu-iotests/151 | 3 ++-
 tests/qemu-iotests/152 | 3 ++-
 tests/qemu-iotests/155 | 3 ++-
 tests/qemu-iotests/163 | 3 ++-
 tests/qemu-iotests/165 | 3 ++-
 tests/qemu-iotests/169 | 3 ++-
 tests/qemu-iotests/196 | 3 ++-
 tests/qemu-iotests/199 | 3 ++-
 tests/qemu-iotests/245 | 3 ++-
 25 files changed, 50 insertions(+), 25 deletions(-)

diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030
index c6311d1825..cb550812a7 100755
--- a/tests/qemu-iotests/030
+++ b/tests/qemu-iotests/030
@@ -865,4 +865,5 @@ class TestSetSpeed(iotests.QMPTestCase):
 self.cancel_and_wait(resume=True)
 
 if __name__ == '__main__':
-iotests.main(supported_fmts=['qcow2', 'qed'])
+iotests.main(supported_fmts=['qcow2', 'qed'],
+ supported_protocols=['file'])
diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040
index b81133a474..e2ca706117 100755
--- a/tests/qemu-iotests/040
+++ b/tests/qemu-iotests/040
@@ -395,4 +395,5 @@ class TestReopenOverlay(ImageCommitTestCase):
 self.run_commit_test(self.img1, self.img0)
 
 if __name__ == '__main__':
-iotests.main(supported_fmts=['qcow2', 'qed'])
+iotests.main(supported_fmts=['qcow2', 'qed'],
+ supported_protocols=['file'])
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
index 26bf1701eb..ae6ed952c6 100755
--- a/tests/qemu-iotests/041
+++ b/tests/qemu-iotests/041
@@ -1068,4 +1068,5 @@ class TestOrphanedSource(iotests.QMPTestCase):
 self.assert_qmp(result, 'error/class', 'GenericError')
 
 if __name__ == '__main__':
-iotests.main(supported_fmts=['qcow2', 'qed'])
+iotests.main(supported_fmts=['qcow2', 'qed'],
+ supported_protocols=['file'])
diff --git a/tests/qemu-iotests/044 b/tests/qemu-iotests/044
index 9ec3dba734..05ea1f49c5 100755
--- a/tests/qemu-iotests/044
+++ b/tests/qemu-iotests/044
@@ -118,4 +118,5 @@ class TestRefcountTableGrowth(iotests.QMPTestCase):
 pass
 
 if __name__ == '__main__':
-iotests.main(supported_fmts=['qcow2'])
+iotests.main(supported_fmts=['qcow2'],
+ supported_protocols=['file'])
diff --git a/tests/qemu-iotests/045 b/tests/qemu-iotests/045
index d5484a0ee1..01cc038884 100755
--- a/tests/qemu-iotests/045
+++ b/tests/qemu-iotests/045
@@ -175,4 +175,5 @@ class TestSCMFd(iotests.QMPTestCase):
 "File descriptor named '%s' not found" % fdname)
 
 if __name__ == '__main__':
-iotests.main(supported_fmts=['raw'])
+iotests.main(supported_fmts=['raw'],
+ supported_protocols=['file'])
diff --git a/tests/qemu-iotests/055 b/tests/qemu-iotests/055
index 3437c11507..c732a112d6 100755
--- a/tests/qemu-iotests/055
+++ b/tests/qemu-iotests/055
@@ -563,4 +563,5 @@ class TestDriveCompression(iotests.QMPTestCase):
 target='drive1')
 
 if __name__ == '__main__':
-iotests.main(supported_fmts=['raw', 'qcow2'])
+iotests.main(supported_fmts=['raw', 'qcow2'],
+ supported_protocols=['file'])
diff --git a/tests/qemu-iotests/056 b/tests/qemu-iotests/056
index e5ac25127b..ce7adf9174 100755
--- a/tests/qemu-iotests/056
+++ b/tests/qemu-iotests/056
@@ -335,4 +335,5 @@ class BackupTest(iotests.QMPTestCase):
 self.dismissal_failure(True)
 
 if __name__ == '__main__':
-iotests.main(supported_fmts=['qcow2', 'qed'])
+iotests.main(supported_fmts=['qcow2', 'qed'],
+ supported_protocols=['file'])
diff --git a/tests/qemu-iotests/057 b/tests/qemu-iotests/057
index 9f0a5a3057..9fbba759b6 100755
--- a/tests/qemu-iotests/057
+++ b/tests/qemu-iotests/057
@@ -256,4 +256,5 @@ class TestSnapshotDelete(ImageSnapshotTestCase):
 self.assert_qmp(result, 'error/class', 'GenericError')
 
 if __name__ == '__main__':
-iotests.main(supported_fmts=['qcow2'])
+iotests.main(supported_fmts=['qcow2'],
+ supported_protocols=['file'])
diff --git 

[PATCH 86/97] curl: Keep pointer to the CURLState in CURLSocket

2019-10-01 Thread Michael Roth
From: Max Reitz 

A follow-up patch will make curl_multi_do() and curl_multi_read() take a
CURLSocket instead of the CURLState.  They still need the latter,
though, so add a pointer to it to the former.

Cc: qemu-sta...@nongnu.org
Signed-off-by: Max Reitz 
Reviewed-by: John Snow 
Message-id: 20190910124136.10565-2-mre...@redhat.com
Reviewed-by: Maxim Levitsky 
Signed-off-by: Max Reitz 
(cherry picked from commit 0487861685294660b23bc146e1ebd5304aa8bbe0)
Signed-off-by: Michael Roth 
---
 block/curl.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/block/curl.c b/block/curl.c
index 606709fea4..4eaae9e211 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -79,6 +79,7 @@ static CURLMcode __curl_multi_socket_action(CURLM 
*multi_handle,
 #define CURL_BLOCK_OPT_TIMEOUT_DEFAULT 5
 
 struct BDRVCURLState;
+struct CURLState;
 
 static bool libcurl_initialized;
 
@@ -96,6 +97,7 @@ typedef struct CURLAIOCB {
 
 typedef struct CURLSocket {
 int fd;
+struct CURLState *state;
 QLIST_ENTRY(CURLSocket) next;
 } CURLSocket;
 
@@ -179,6 +181,7 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int 
action,
 if (!socket) {
 socket = g_new0(CURLSocket, 1);
 socket->fd = fd;
+socket->state = state;
 QLIST_INSERT_HEAD(>sockets, socket, next);
 }
 socket = NULL;
-- 
2.17.1




[PATCH 23/97] iotests: add iotest 256 for testing blockdev-backup across iothread contexts

2019-10-01 Thread Michael Roth
From: John Snow 

Signed-off-by: John Snow 
Message-id: 20190523170643.20794-6-js...@redhat.com
Reviewed-by: Max Reitz 
[mreitz: Moved from 250 to 256]
Signed-off-by: Max Reitz 
(cherry picked from commit ba7704f2228f16ed61b9903801e28e17666c7e38)
Signed-off-by: Michael Roth 
---
 tests/qemu-iotests/256 | 122 +
 tests/qemu-iotests/256.out | 119 
 tests/qemu-iotests/group   |   1 +
 3 files changed, 242 insertions(+)
 create mode 100755 tests/qemu-iotests/256
 create mode 100644 tests/qemu-iotests/256.out

diff --git a/tests/qemu-iotests/256 b/tests/qemu-iotests/256
new file mode 100755
index 00..c594a43205
--- /dev/null
+++ b/tests/qemu-iotests/256
@@ -0,0 +1,122 @@
+#!/usr/bin/env python
+#
+# Test incremental/backup across iothread contexts
+#
+# Copyright (c) 2019 John Snow for Red Hat, Inc.
+#
+# 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 .
+#
+# owner=js...@redhat.com
+
+import os
+import iotests
+from iotests import log
+
+iotests.verify_image_format(supported_fmts=['qcow2'])
+size = 64 * 1024 * 1024
+
+with iotests.FilePath('img0') as img0_path, \
+ iotests.FilePath('img1') as img1_path, \
+ iotests.FilePath('img0-full') as img0_full_path, \
+ iotests.FilePath('img1-full') as img1_full_path, \
+ iotests.FilePath('img0-incr') as img0_incr_path, \
+ iotests.FilePath('img1-incr') as img1_incr_path, \
+ iotests.VM() as vm:
+
+def create_target(filepath, name, size):
+basename = os.path.basename(filepath)
+nodename = "file_{}".format(basename)
+log(vm.command('blockdev-create', job_id='job1',
+   options={
+   'driver': 'file',
+   'filename': filepath,
+   'size': 0,
+   }))
+vm.run_job('job1')
+log(vm.command('blockdev-add', driver='file',
+   node_name=nodename, filename=filepath))
+log(vm.command('blockdev-create', job_id='job2',
+   options={
+   'driver': iotests.imgfmt,
+   'file': nodename,
+   'size': size,
+   }))
+vm.run_job('job2')
+log(vm.command('blockdev-add', driver=iotests.imgfmt,
+   node_name=name,
+   file=nodename))
+
+log('--- Preparing images & VM ---\n')
+vm.add_object('iothread,id=iothread0')
+vm.add_object('iothread,id=iothread1')
+vm.add_device('virtio-scsi-pci,id=scsi0,iothread=iothread0')
+vm.add_device('virtio-scsi-pci,id=scsi1,iothread=iothread1')
+iotests.qemu_img_create('-f', iotests.imgfmt, img0_path, str(size))
+iotests.qemu_img_create('-f', iotests.imgfmt, img1_path, str(size))
+vm.add_drive(img0_path, interface='none')
+vm.add_device('scsi-hd,id=device0,drive=drive0,bus=scsi0.0')
+vm.add_drive(img1_path, interface='none')
+vm.add_device('scsi-hd,id=device1,drive=drive1,bus=scsi1.0')
+
+log('--- Starting VM ---\n')
+vm.launch()
+
+log('--- Create Targets & Full Backups ---\n')
+create_target(img0_full_path, 'img0-full', size)
+create_target(img1_full_path, 'img1-full', size)
+ret = vm.qmp_log('transaction', indent=2, actions=[
+{ 'type': 'block-dirty-bitmap-add',
+  'data': { 'node': 'drive0', 'name': 'bitmap0' }},
+{ 'type': 'block-dirty-bitmap-add',
+  'data': { 'node': 'drive1', 'name': 'bitmap1' }},
+{ 'type': 'blockdev-backup',
+  'data': { 'device': 'drive0',
+'target': 'img0-full',
+'sync': 'full',
+'job-id': 'j0' }},
+{ 'type': 'blockdev-backup',
+  'data': { 'device': 'drive1',
+'target': 'img1-full',
+'sync': 'full',
+'job-id': 'j1' }}
+])
+if "error" in ret:
+raise Exception(ret['error']['desc'])
+vm.run_job('j0', auto_dismiss=True)
+vm.run_job('j1', auto_dismiss=True)
+
+log('\n--- Create Targets & Incremental Backups ---\n')
+create_target(img0_incr_path, 'img0-incr', size)
+create_target(img1_incr_path, 'img1-incr', size)
+ret = vm.qmp_log('transaction', indent=2, actions=[
+{ 'type': 'blockdev-backup',
+  'data': { 

[PULL 0/8] Ide patches

2019-10-01 Thread John Snow
The following changes since commit 7f21573c822805a8e6be379d9bcf3ad9effef3dc:

  Merge remote-tracking branch 
'remotes/huth-gitlab/tags/pull-request-2019-10-01' into staging (2019-10-01 
13:13:38 +0100)

are available in the Git repository at:

  https://github.com/jnsnow/qemu.git tags/ide-pull-request

for you to fetch changes up to d5eedf4633376d22a34a17a061d3ed47ddb6fee0:

  hd-geo-test: Add tests for lchs override (2019-10-01 17:50:16 -0400)


"IDE" Pull request. (CHS changes for SeaBios)



Sam Eiderman (8):
  block: Refactor macros - fix tabbing
  block: Support providing LCHS from user
  bootdevice: Add interface to gather LCHS
  scsi: Propagate unrealize() callback to scsi-hd
  bootdevice: Gather LCHS from all relevant devices
  bootdevice: Refactor get_boot_devices_list
  bootdevice: FW_CFG interface for LCHS values
  hd-geo-test: Add tests for lchs override

 include/hw/block/block.h |  22 +-
 include/hw/scsi/scsi.h   |   1 +
 include/sysemu/sysemu.h  |   4 +
 bootdevice.c | 148 --
 hw/block/virtio-blk.c|   6 +
 hw/ide/qdev.c|   7 +-
 hw/nvram/fw_cfg.c|  14 +-
 hw/scsi/scsi-bus.c   |  16 ++
 hw/scsi/scsi-disk.c  |  12 +
 tests/hd-geo-test.c  | 589 +++
 tests/Makefile.include   |   2 +-
 11 files changed, 780 insertions(+), 41 deletions(-)

-- 
2.21.0




[PULL 3/8] bootdevice: Add interface to gather LCHS

2019-10-01 Thread John Snow
From: Sam Eiderman 

Add an interface to provide direct logical CHS values for boot devices.
We will use this interface in the next commits.

Reviewed-by: Karl Heubaum 
Reviewed-by: Arbel Moshe 
Signed-off-by: Sam Eiderman 
Message-id: 20190925110639.100699-4-sam...@google.com
Signed-off-by: John Snow 
---
 include/sysemu/sysemu.h |  3 +++
 bootdevice.c| 55 +
 2 files changed, 58 insertions(+)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 44f18eb739..5bc5c79cbc 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -103,6 +103,9 @@ void device_add_bootindex_property(Object *obj, int32_t 
*bootindex,
DeviceState *dev, Error **errp);
 void restore_boot_order(void *opaque);
 void validate_bootdevices(const char *devices, Error **errp);
+void add_boot_device_lchs(DeviceState *dev, const char *suffix,
+  uint32_t lcyls, uint32_t lheads, uint32_t lsecs);
+void del_boot_device_lchs(DeviceState *dev, const char *suffix);
 
 /* handler to set the boot_device order for a specific type of MachineClass */
 typedef void QEMUBootSetHandler(void *opaque, const char *boot_order,
diff --git a/bootdevice.c b/bootdevice.c
index 1d225202f9..bc5e1c2de4 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -343,3 +343,58 @@ void device_add_bootindex_property(Object *obj, int32_t 
*bootindex,
 /* initialize devices' bootindex property to -1 */
 object_property_set_int(obj, -1, name, NULL);
 }
+
+typedef struct FWLCHSEntry FWLCHSEntry;
+
+struct FWLCHSEntry {
+QTAILQ_ENTRY(FWLCHSEntry) link;
+DeviceState *dev;
+char *suffix;
+uint32_t lcyls;
+uint32_t lheads;
+uint32_t lsecs;
+};
+
+static QTAILQ_HEAD(, FWLCHSEntry) fw_lchs =
+QTAILQ_HEAD_INITIALIZER(fw_lchs);
+
+void add_boot_device_lchs(DeviceState *dev, const char *suffix,
+  uint32_t lcyls, uint32_t lheads, uint32_t lsecs)
+{
+FWLCHSEntry *node;
+
+if (!lcyls && !lheads && !lsecs) {
+return;
+}
+
+assert(dev != NULL || suffix != NULL);
+
+node = g_malloc0(sizeof(FWLCHSEntry));
+node->suffix = g_strdup(suffix);
+node->dev = dev;
+node->lcyls = lcyls;
+node->lheads = lheads;
+node->lsecs = lsecs;
+
+QTAILQ_INSERT_TAIL(_lchs, node, link);
+}
+
+void del_boot_device_lchs(DeviceState *dev, const char *suffix)
+{
+FWLCHSEntry *i;
+
+if (dev == NULL) {
+return;
+}
+
+QTAILQ_FOREACH(i, _lchs, link) {
+if ((!suffix || !g_strcmp0(i->suffix, suffix)) &&
+ i->dev == dev) {
+QTAILQ_REMOVE(_lchs, i, link);
+g_free(i->suffix);
+g_free(i);
+
+break;
+}
+}
+}
-- 
2.21.0




[PATCH 19/97] iotests.py: do not use infinite waits

2019-10-01 Thread Michael Roth
From: John Snow 

Cap waits to 60 seconds so that iotests can fail gracefully if something
goes wrong.

Signed-off-by: John Snow 
Message-id: 20190523170643.20794-3-js...@redhat.com
Reviewed-by: Max Reitz 
Signed-off-by: Max Reitz 
(cherry picked from commit 8b6f5f8b9f3bec5cbeebefab34bae0102a2581b3)
Signed-off-by: Michael Roth 
---
 tests/qemu-iotests/iotests.py | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 8b209ea0ee..8061f01ade 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -521,7 +521,7 @@ class VM(qtest.QEMUQtestMachine):
 output_list += [key + '=' + obj[key]]
 return ','.join(output_list)
 
-def get_qmp_events_filtered(self, wait=True):
+def get_qmp_events_filtered(self, wait=60.0):
 result = []
 for ev in self.get_qmp_events(wait=wait):
 result.append(filter_qmp_event(ev))
@@ -539,10 +539,10 @@ class VM(qtest.QEMUQtestMachine):
 
 # Returns None on success, and an error string on failure
 def run_job(self, job, auto_finalize=True, auto_dismiss=False,
-pre_finalize=None):
+pre_finalize=None, wait=60.0):
 error = None
 while True:
-for ev in self.get_qmp_events_filtered(wait=True):
+for ev in self.get_qmp_events_filtered(wait=wait):
 if ev['event'] == 'JOB_STATUS_CHANGE':
 status = ev['data']['status']
 if status == 'aborting':
@@ -633,7 +633,7 @@ class QMPTestCase(unittest.TestCase):
 
self.assertEqual(self.vm.flatten_qmp_object(json.loads(json_filename[5:])),
  self.vm.flatten_qmp_object(reference))
 
-def cancel_and_wait(self, drive='drive0', force=False, resume=False):
+def cancel_and_wait(self, drive='drive0', force=False, resume=False, 
wait=60.0):
 '''Cancel a block job and wait for it to finish, returning the event'''
 result = self.vm.qmp('block-job-cancel', device=drive, force=force)
 self.assert_qmp(result, 'return', {})
@@ -644,7 +644,7 @@ class QMPTestCase(unittest.TestCase):
 cancelled = False
 result = None
 while not cancelled:
-for event in self.vm.get_qmp_events(wait=True):
+for event in self.vm.get_qmp_events(wait=wait):
 if event['event'] == 'BLOCK_JOB_COMPLETED' or \
event['event'] == 'BLOCK_JOB_CANCELLED':
 self.assert_qmp(event, 'data/device', drive)
@@ -657,10 +657,10 @@ class QMPTestCase(unittest.TestCase):
 self.assert_no_active_block_jobs()
 return result
 
-def wait_until_completed(self, drive='drive0', check_offset=True):
+def wait_until_completed(self, drive='drive0', check_offset=True, 
wait=60.0):
 '''Wait for a block job to finish, returning the event'''
 while True:
-for event in self.vm.get_qmp_events(wait=True):
+for event in self.vm.get_qmp_events(wait=wait):
 if event['event'] == 'BLOCK_JOB_COMPLETED':
 self.assert_qmp(event, 'data/device', drive)
 self.assert_qmp_absent(event, 'data/error')
-- 
2.17.1




[PATCH 57/97] tpm_emulator: Translate TPM error codes to strings

2019-10-01 Thread Michael Roth
From: Stefan Berger 

Implement a function to translate TPM error codes to strings so that
at least the most common error codes can be translated to human
readable strings.

Signed-off-by: Stefan Berger 
Reviewed-by: Marc-André Lureau 
(cherry picked from commit 7e095e84ba0b7c0a1ac45bc6824dace2fd352e56)
Signed-off-by: Michael Roth 
---
 hw/tpm/tpm_emulator.c | 60 +++
 hw/tpm/tpm_int.h  | 13 ++
 2 files changed, 63 insertions(+), 10 deletions(-)

diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
index 70f4b10284..58894dc320 100644
--- a/hw/tpm/tpm_emulator.c
+++ b/hw/tpm/tpm_emulator.c
@@ -81,6 +81,40 @@ typedef struct TPMEmulator {
 TPMBlobBuffers state_blobs;
 } TPMEmulator;
 
+struct tpm_error {
+uint32_t tpm_result;
+const char *string;
+};
+
+static const struct tpm_error tpm_errors[] = {
+/* TPM 1.2 error codes */
+{ TPM_BAD_PARAMETER   , "a parameter is bad" },
+{ TPM_FAIL, "operation failed" },
+{ TPM_KEYNOTFOUND , "key could not be found" },
+{ TPM_BAD_PARAM_SIZE  , "bad parameter size"},
+{ TPM_ENCRYPT_ERROR   , "encryption error" },
+{ TPM_DECRYPT_ERROR   , "decryption error" },
+{ TPM_BAD_KEY_PROPERTY, "bad key property" },
+{ TPM_BAD_MODE, "bad (encryption) mode" },
+{ TPM_BAD_VERSION , "bad version identifier" },
+{ TPM_BAD_LOCALITY, "bad locality" },
+/* TPM 2 error codes */
+{ TPM_RC_FAILURE , "operation failed" },
+{ TPM_RC_LOCALITY, "bad locality" },
+{ TPM_RC_INSUFFICIENT, "insufficient amount of data" },
+};
+
+static const char *tpm_emulator_strerror(uint32_t tpm_result)
+{
+size_t i;
+
+for (i = 0; i < ARRAY_SIZE(tpm_errors); i++) {
+if (tpm_errors[i].tpm_result == tpm_result) {
+return tpm_errors[i].string;
+}
+}
+return "";
+}
 
 static int tpm_emulator_ctrlcmd(TPMEmulator *tpm, unsigned long cmd, void *msg,
 size_t msg_len_in, size_t msg_len_out)
@@ -263,7 +297,8 @@ static int tpm_emulator_stop_tpm(TPMBackend *tb)
 
 res = be32_to_cpu(res);
 if (res) {
-error_report("tpm-emulator: TPM result for CMD_STOP: 0x%x", res);
+error_report("tpm-emulator: TPM result for CMD_STOP: 0x%x %s", res,
+ tpm_emulator_strerror(res));
 return -1;
 }
 
@@ -292,8 +327,9 @@ static int tpm_emulator_set_buffer_size(TPMBackend *tb,
 
 psbs.u.resp.tpm_result = be32_to_cpu(psbs.u.resp.tpm_result);
 if (psbs.u.resp.tpm_result != 0) {
-error_report("tpm-emulator: TPM result for set buffer size : 0x%x",
- psbs.u.resp.tpm_result);
+error_report("tpm-emulator: TPM result for set buffer size : 0x%x %s",
+ psbs.u.resp.tpm_result,
+ tpm_emulator_strerror(psbs.u.resp.tpm_result));
 return -1;
 }
 
@@ -338,7 +374,8 @@ static int tpm_emulator_startup_tpm_resume(TPMBackend *tb, 
size_t buffersize,
 
 res = be32_to_cpu(init.u.resp.tpm_result);
 if (res) {
-error_report("tpm-emulator: TPM result for CMD_INIT: 0x%x", res);
+error_report("tpm-emulator: TPM result for CMD_INIT: 0x%x %s", res,
+ tpm_emulator_strerror(res));
 goto err_exit;
 }
 return 0;
@@ -398,8 +435,9 @@ static int 
tpm_emulator_reset_tpm_established_flag(TPMBackend *tb,
 
 res = be32_to_cpu(reset_est.u.resp.tpm_result);
 if (res) {
-error_report("tpm-emulator: TPM result for rest establixhed flag: 
0x%x",
- res);
+error_report(
+"tpm-emulator: TPM result for rest established flag: 0x%x %s",
+res, tpm_emulator_strerror(res));
 return -1;
 }
 
@@ -637,7 +675,8 @@ static int tpm_emulator_get_state_blob(TPMEmulator *tpm_emu,
 res = be32_to_cpu(pgs.u.resp.tpm_result);
 if (res != 0 && (res & 0x800) == 0) {
 error_report("tpm-emulator: Getting the stateblob (type %d) failed "
- "with a TPM error 0x%x", type, res);
+ "with a TPM error 0x%x %s", type, res,
+ tpm_emulator_strerror(res));
 return -1;
 }
 
@@ -757,7 +796,8 @@ static int tpm_emulator_set_state_blob(TPMEmulator *tpm_emu,
 tpm_result = be32_to_cpu(pss.u.resp.tpm_result);
 if (tpm_result != 0) {
 error_report("tpm-emulator: Setting the stateblob (type %d) failed "
- "with a TPM error 0x%x", type, tpm_result);
+ "with a TPM error 0x%x %s", type, tpm_result,
+ tpm_emulator_strerror(tpm_result));
 return -1;
 }
 
@@ -887,8 +927,8 @@ static void tpm_emulator_shutdown(TPMEmulator *tpm_emu)
 error_report("tpm-emulator: Could not cleanly shutdown the TPM: %s",
  strerror(errno));
 } else if (res != 0) {
-error_report("tpm-emulator: TPM result for sutdown: 0x%x",
-  

[PATCH 93/97] slirp: Fix heap overflow in ip_reass on big packet input

2019-10-01 Thread Michael Roth
When the first fragment does not fit in the preallocated buffer, q will
already be pointing to the ext buffer, so we mustn't try to update it.

Signed-off-by: Samuel Thibault 
(from libslirp.git commit 126c04acbabd7ad32c2b018fe10dfac2a3bc1210)
(from libslirp.git commit e0be80430c390bce181ea04dfcdd6ea3dfa97de1)
*squash in e0be80 (clarifying comments)
Signed-off-by: Michael Roth 
---
 slirp/src/ip_input.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/slirp/src/ip_input.c b/slirp/src/ip_input.c
index a714fecd58..68a99de5b5 100644
--- a/slirp/src/ip_input.c
+++ b/slirp/src/ip_input.c
@@ -331,6 +331,8 @@ insert:
 q = fp->frag_link.next;
m = dtom(slirp, q);
 
+   int was_ext = m->m_flags & M_EXT;
+
q = (struct ipasfrag *) q->ipf_next;
while (q != (struct ipasfrag*)>frag_link) {
  struct mbuf *t = dtom(slirp, q);
@@ -347,13 +349,12 @@ insert:
q = fp->frag_link.next;
 
/*
-* If the fragments concatenated to an mbuf that's
-* bigger than the total size of the fragment, then and
-* m_ext buffer was alloced. But fp->ipq_next points to
-* the old buffer (in the mbuf), so we must point ip
-* into the new buffer.
+* If the fragments concatenated to an mbuf that's bigger than the total
+* size of the fragment and the mbuf was not already using an m_ext 
buffer,
+* then an m_ext buffer was alloced. But fp->ipq_next points to the old
+* buffer (in the mbuf), so we must point ip into the new buffer.
 */
-   if (m->m_flags & M_EXT) {
+   if (!was_ext && m->m_flags & M_EXT) {
  int delta = (char *)q - m->m_dat;
  q = (struct ipasfrag *)(m->m_ext + delta);
}
-- 
2.17.1




[PATCH 87/97] curl: Keep *socket until the end of curl_sock_cb()

2019-10-01 Thread Michael Roth
From: Max Reitz 

This does not really change anything, but it makes the code a bit easier
to follow once we use @socket as the opaque pointer for
aio_set_fd_handler().

Cc: qemu-sta...@nongnu.org
Signed-off-by: Max Reitz 
Message-id: 20190910124136.10565-3-mre...@redhat.com
Reviewed-by: Maxim Levitsky 
Reviewed-by: John Snow 
Signed-off-by: Max Reitz 
(cherry picked from commit 007f339b1099af46a008dac438ca0943e31dba72)
Signed-off-by: Michael Roth 
---
 block/curl.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/block/curl.c b/block/curl.c
index 4eaae9e211..a0381ae0b4 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -171,10 +171,6 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int 
action,
 
 QLIST_FOREACH(socket, >sockets, next) {
 if (socket->fd == fd) {
-if (action == CURL_POLL_REMOVE) {
-QLIST_REMOVE(socket, next);
-g_free(socket);
-}
 break;
 }
 }
@@ -184,7 +180,6 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int 
action,
 socket->state = state;
 QLIST_INSERT_HEAD(>sockets, socket, next);
 }
-socket = NULL;
 
 trace_curl_sock_cb(action, (int)fd);
 switch (action) {
@@ -206,6 +201,11 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int 
action,
 break;
 }
 
+if (action == CURL_POLL_REMOVE) {
+QLIST_REMOVE(socket, next);
+g_free(socket);
+}
+
 return 0;
 }
 
-- 
2.17.1




[PATCH 09/97] docs/interop/bitmaps: rewrite and modernize doc

2019-10-01 Thread Michael Roth
From: John Snow 

This just about rewrites the entirety of the bitmaps.rst document to
make it consistent with the 4.0 release. I have added new features seen
in the 4.0 release, as well as tried to clarify some points that keep
coming up when discussing this feature both in-house and upstream.

It does not yet cover pull backups or migration details, but I intend to
keep extending this document to cover those cases.

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Message-id: 20190426221528.30293-3-js...@redhat.com
[Adjusted commit message. --js]
Signed-off-by: John Snow 
(cherry picked from commit 90edef80a0852cf8a3d2668898ee40e8970e4314)
Signed-off-by: Michael Roth 
---
 docs/interop/bitmaps.rst | 1573 ++
 1 file changed, 1251 insertions(+), 322 deletions(-)

diff --git a/docs/interop/bitmaps.rst b/docs/interop/bitmaps.rst
index 7bcfe7f461..510e8809a9 100644
--- a/docs/interop/bitmaps.rst
+++ b/docs/interop/bitmaps.rst
@@ -1,5 +1,5 @@
 ..
-   Copyright 2015 John Snow  and Red Hat, Inc.
+   Copyright 2019 John Snow  and Red Hat, Inc.
All rights reserved.
 
This file is licensed via The FreeBSD Documentation License, the full
@@ -9,547 +9,1476 @@
 Dirty Bitmaps and Incremental Backup
 
 
--  Dirty Bitmaps are objects that track which data needs to be backed up
-   for the next incremental backup.
+Dirty Bitmaps are in-memory objects that track writes to block devices. They
+can be used in conjunction with various block job operations to perform
+incremental or differential backup regimens.
 
--  Dirty bitmaps can be created at any time and attached to any node
-   (not just complete drives).
+This document explains the conceptual mechanisms, as well as up-to-date,
+complete and comprehensive documentation on the API to manipulate them.
+(Hopefully, the "why", "what", and "how".)
+
+The intended audience for this document is developers who are adding QEMU
+backup features to management applications, or power users who run and
+administer QEMU directly via QMP.
 
 .. contents::
 
+Overview
+
+
+Bitmaps are bit vectors where each '1' bit in the vector indicates a modified
+("dirty") segment of the corresponding block device. The size of the segment
+that is tracked is the granularity of the bitmap. If the granularity of a
+bitmap is 64K, each '1' bit means that a 64K region as a whole may have
+changed in some way, possibly by as little as one byte.
+
+Smaller granularities mean more accurate tracking of modified disk data, but
+requires more computational overhead and larger bitmap sizes. Larger
+granularities mean smaller bitmap sizes, but less targeted backups.
+
+The size of a bitmap (in bytes) can be computed as such:
+``size`` = ceil(ceil(``image_size`` / ``granularity``) / 8)
+
+e.g. the size of a 64KiB granularity bitmap on a 2TiB image is:
+``size`` = ((2147483648K / 64K) / 8)
+ = 4194304B = 4MiB.
+
+QEMU uses these bitmaps when making incremental backups to know which sections
+of the file to copy out. They are not enabled by default and must be
+explicitly added in order to begin tracking writes.
+
+Bitmaps can be created at any time and can be attached to any arbitrary block
+node in the storage graph, but are most useful conceptually when attached to
+the root node attached to the guest's storage device model.
+
+That is to say: It's likely most useful to track the guest's writes to disk,
+but you could theoretically track things like qcow2 metadata changes by
+attaching the bitmap elsewhere in the storage graph. This is beyond the scope
+of this document.
+
+QEMU supports persisting these bitmaps to disk via the qcow2 image format.
+Bitmaps which are stored or loaded in this way are called "persistent",
+whereas bitmaps that are not are called "transient".
+
+QEMU also supports the migration of both transient bitmaps (tracking any
+arbitrary image format) or persistent bitmaps (qcow2) via live migration.
+
+Supported Image Formats
+---
+
+QEMU supports all documented features below on the qcow2 image format.
+
+However, qcow2 is only strictly necessary for the persistence feature, which
+writes bitmap data to disk upon close. If persistence is not required for a
+specific use case, all bitmap features excepting persistence are available for
+any arbitrary image format.
+
+For example, Dirty Bitmaps can be combined with the 'raw' image format, but
+any changes to the bitmap will be discarded upon exit.
+
+.. warning:: Transient bitmaps will not be saved on QEMU exit! Persistent
+ bitmaps are available only on qcow2 images.
+
 Dirty Bitmap Names
 --
 
--  A dirty bitmap's name is unique to the node, but bitmaps attached to
-   different nodes can share the same name.
+Bitmap objects need a method to reference them in the API. All API-created and
+managed bitmaps have a human-readable name chosen by the user at creation
+time.

[PATCH 75/97] pr-manager: Fix invalid g_free() crash bug

2019-10-01 Thread Michael Roth
From: Markus Armbruster 

pr_manager_worker() passes its @opaque argument to g_free().  Wrong;
it points to pr_manager_worker()'s automatic @data.  Broken when
commit 2f3a7ab39be converted @data from heap- to stack-allocated.  Fix
by deleting the g_free().

Fixes: 2f3a7ab39bec4ba8022dc4d42ea641165b004e3e
Cc: qemu-sta...@nongnu.org
Signed-off-by: Markus Armbruster 
Reviewed-by: Philippe Mathieu-Daudé 
Acked-by: Paolo Bonzini 
Signed-off-by: Kevin Wolf 
(cherry picked from commit 6b9d62c2a9e83bbad73fb61406f0ff69b46ff6f3)
Signed-off-by: Michael Roth 
---
 scsi/pr-manager.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/scsi/pr-manager.c b/scsi/pr-manager.c
index d9f4e8c3ad..227bdfaad2 100644
--- a/scsi/pr-manager.c
+++ b/scsi/pr-manager.c
@@ -38,7 +38,6 @@ static int pr_manager_worker(void *opaque)
 int fd = data->fd;
 int r;
 
-g_free(data);
 trace_pr_manager_run(fd, hdr->cmdp[0], hdr->cmdp[1]);
 
 /* The reference was taken in pr_manager_execute.  */
-- 
2.17.1




[PATCH 10/97] spapr/xive: fix EQ page addresses above 64GB

2019-10-01 Thread Michael Roth
From: Cédric Le Goater 

The high order bits of the address of the OS event queue is stored in
bits [4-31] of word2 of the XIVE END internal structures and the low
order bits in word3. This structure is using Big Endian ordering and
computing the value requires some simple arithmetic which happens to
be wrong. The mask removing bits [0-3] of word2 is applied to the
wrong value and the resulting address is bogus when above 64GB.

Guests with more than 64GB of RAM will allocate pages for the OS event
queues which will reside above the 64GB limit. In this case, the XIVE
device model will wake up the CPUs in case of a notification, such as
IPIs, but the update of the event queue will be written at the wrong
place in memory. The result is uncertain as the guest memory is
trashed and IPI are not delivered.

Introduce a helper xive_end_qaddr() to compute this value correctly in
all places where it is used.

Signed-off-by: Cédric Le Goater 
Message-Id: <20190508171946.657-3-...@kaod.org>
Reviewed-by: Greg Kurz 
Signed-off-by: David Gibson 
(cherry picked from commit 13df93244efbd4bb8b4cf4e26104a26033178674)
Signed-off-by: Michael Roth 
---
 hw/intc/spapr_xive.c   | 3 +--
 hw/intc/xive.c | 9 +++--
 include/hw/ppc/xive_regs.h | 6 ++
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 097f88d460..db75f5d608 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -1144,8 +1144,7 @@ static target_ulong h_int_get_queue_config(PowerPCCPU 
*cpu,
 }
 
 if (xive_end_is_enqueue(end)) {
-args[1] = (uint64_t) be32_to_cpu(end->w2 & 0x0fff) << 32
-| be32_to_cpu(end->w3);
+args[1] = xive_end_qaddr(end);
 args[2] = xive_get_field32(END_W0_QSIZE, end->w0) + 12;
 } else {
 args[1] = 0;
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index a0b87001da..dcf2fcd108 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1042,8 +1042,7 @@ static const TypeInfo xive_source_info = {
 
 void xive_end_queue_pic_print_info(XiveEND *end, uint32_t width, Monitor *mon)
 {
-uint64_t qaddr_base = (uint64_t) be32_to_cpu(end->w2 & 0x0fff) << 32
-| be32_to_cpu(end->w3);
+uint64_t qaddr_base = xive_end_qaddr(end);
 uint32_t qsize = xive_get_field32(END_W0_QSIZE, end->w0);
 uint32_t qindex = xive_get_field32(END_W1_PAGE_OFF, end->w1);
 uint32_t qentries = 1 << (qsize + 10);
@@ -1072,8 +1071,7 @@ void xive_end_queue_pic_print_info(XiveEND *end, uint32_t 
width, Monitor *mon)
 
 void xive_end_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon)
 {
-uint64_t qaddr_base = (uint64_t) be32_to_cpu(end->w2 & 0x0fff) << 32
-| be32_to_cpu(end->w3);
+uint64_t qaddr_base = xive_end_qaddr(end);
 uint32_t qindex = xive_get_field32(END_W1_PAGE_OFF, end->w1);
 uint32_t qgen = xive_get_field32(END_W1_GENERATION, end->w1);
 uint32_t qsize = xive_get_field32(END_W0_QSIZE, end->w0);
@@ -1101,8 +1099,7 @@ void xive_end_pic_print_info(XiveEND *end, uint32_t 
end_idx, Monitor *mon)
 
 static void xive_end_enqueue(XiveEND *end, uint32_t data)
 {
-uint64_t qaddr_base = (uint64_t) be32_to_cpu(end->w2 & 0x0fff) << 32
-| be32_to_cpu(end->w3);
+uint64_t qaddr_base = xive_end_qaddr(end);
 uint32_t qsize = xive_get_field32(END_W0_QSIZE, end->w0);
 uint32_t qindex = xive_get_field32(END_W1_PAGE_OFF, end->w1);
 uint32_t qgen = xive_get_field32(END_W1_GENERATION, end->w1);
diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index bf36678a24..1a8c5b5e64 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -208,6 +208,12 @@ typedef struct XiveEND {
 #define xive_end_is_backlog(end)  (be32_to_cpu((end)->w0) & END_W0_BACKLOG)
 #define xive_end_is_escalate(end) (be32_to_cpu((end)->w0) & 
END_W0_ESCALATE_CTL)
 
+static inline uint64_t xive_end_qaddr(XiveEND *end)
+{
+return ((uint64_t) be32_to_cpu(end->w2) & 0x0fff) << 32 |
+be32_to_cpu(end->w3);
+}
+
 /* Notification Virtual Target (NVT) */
 typedef struct XiveNVT {
 uint32_tw0;
-- 
2.17.1




[PATCH 85/97] blockjob: update nodes head while removing all bdrv

2019-10-01 Thread Michael Roth
From: Sergio Lopez 

block_job_remove_all_bdrv() iterates through job->nodes, calling
bdrv_root_unref_child() for each entry. The call to the latter may
reach child_job_[can_]set_aio_ctx(), which will also attempt to
traverse job->nodes, potentially finding entries that where freed
on previous iterations.

To avoid this situation, update job->nodes head on each iteration to
ensure that already freed entries are no longer linked to the list.

RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1746631
Signed-off-by: Sergio Lopez 
Cc: qemu-sta...@nongnu.org
Signed-off-by: Max Reitz 
Message-id: 20190911100316.32282-1-mre...@redhat.com
Reviewed-by: Sergio Lopez 
Signed-off-by: Max Reitz 
(cherry picked from commit d876bf676f5e7c6aa9ac64555e48cba8734ecb2f)
Signed-off-by: Michael Roth 
---
 blockjob.c | 17 +
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/blockjob.c b/blockjob.c
index 730101d282..d770144fd6 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -193,14 +193,23 @@ static const BdrvChildRole child_job = {
 
 void block_job_remove_all_bdrv(BlockJob *job)
 {
-GSList *l;
-for (l = job->nodes; l; l = l->next) {
+/*
+ * bdrv_root_unref_child() may reach child_job_[can_]set_aio_ctx(),
+ * which will also traverse job->nodes, so consume the list one by
+ * one to make sure that such a concurrent access does not attempt
+ * to process an already freed BdrvChild.
+ */
+while (job->nodes) {
+GSList *l = job->nodes;
 BdrvChild *c = l->data;
+
+job->nodes = l->next;
+
 bdrv_op_unblock_all(c->bs, job->blocker);
 bdrv_root_unref_child(c);
+
+g_slist_free_1(l);
 }
-g_slist_free(job->nodes);
-job->nodes = NULL;
 }
 
 int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
-- 
2.17.1




[PATCH 96/97] hw/core/loader: Fix possible crash in rom_copy()

2019-10-01 Thread Michael Roth
From: Thomas Huth 

Both, "rom->addr" and "addr" are derived from the binary image
that can be loaded with the "-kernel" paramer. The code in
rom_copy() then calculates:

d = dest + (rom->addr - addr);

and uses "d" as destination in a memcpy() some lines later. Now with
bad kernel images, it is possible that rom->addr is smaller than addr,
thus "rom->addr - addr" gets negative and the memcpy() then tries to
copy contents from the image to a bad memory location. This could
maybe be used to inject code from a kernel image into the QEMU binary,
so we better fix it with an additional sanity check here.

Cc: qemu-sta...@nongnu.org
Reported-by: Guangming Liu
Buglink: https://bugs.launchpad.net/qemu/+bug/1844635
Message-Id: <20190925130331.27825-1-th...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Thomas Huth 
(cherry picked from commit e423455c4f23a1a828901c78fe6d03b7dde79319)
Signed-off-by: Michael Roth 
---
 hw/core/loader.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/core/loader.c b/hw/core/loader.c
index fe5cb24122..4ef2095247 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -1240,7 +1240,7 @@ int rom_copy(uint8_t *dest, hwaddr addr, size_t size)
 if (rom->addr + rom->romsize < addr) {
 continue;
 }
-if (rom->addr > end) {
+if (rom->addr > end || rom->addr < addr) {
 break;
 }
 
-- 
2.17.1




[PATCH 94/97] slirp: ip_reass: Fix use after free

2019-10-01 Thread Michael Roth
Using ip_deq after m_free might read pointers from an allocation reuse.

This would be difficult to exploit, but that is still related with
CVE-2019-14378 which generates fragmented IP packets that would trigger this
issue and at least produce a DoS.

Signed-off-by: Samuel Thibault 
(from libslirp.git commit c59279437eda91841b9d26079c70b8a540d41204)
Signed-off-by: Michael Roth 
---
 slirp/src/ip_input.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/slirp/src/ip_input.c b/slirp/src/ip_input.c
index 68a99de5b5..89ae04e0c1 100644
--- a/slirp/src/ip_input.c
+++ b/slirp/src/ip_input.c
@@ -297,6 +297,7 @@ ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp)
 */
while (q != (struct ipasfrag*)>frag_link &&
 ip->ip_off + ip->ip_len > q->ipf_off) {
+struct ipasfrag *prev;
i = (ip->ip_off + ip->ip_len) - q->ipf_off;
if (i < q->ipf_len) {
q->ipf_len -= i;
@@ -304,9 +305,10 @@ ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp)
m_adj(dtom(slirp, q), i);
break;
}
+prev = q;
q = q->ipf_next;
-   m_free(dtom(slirp, q->ipf_prev));
-   ip_deq(q->ipf_prev);
+   ip_deq(prev);
+   m_free(dtom(slirp, prev));
}
 
 insert:
-- 
2.17.1




[PATCH 82/97] libvhost-user: fix SLAVE_SEND_FD handling

2019-10-01 Thread Michael Roth
From: Johannes Berg 

It doesn't look like this could possibly work properly since
VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD is defined to 10, but the
dev->protocol_features has a bitmap. I suppose the peer this
was tested with also supported VHOST_USER_PROTOCOL_F_LOG_SHMFD,
in which case the test would always be false, but nevertheless
the code seems wrong.

Use has_feature() to fix this.

Fixes: d84599f56c82 ("libvhost-user: support host notifier")
Signed-off-by: Johannes Berg 
Message-Id: <20190903200422.11693-1-johan...@sipsolutions.net>
Reviewed-by: Tiwei Bie 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
(cherry picked from commit 8726b70b449896f1211f869ec4f608904f027207)
Signed-off-by: Michael Roth 
---
 contrib/libvhost-user/libvhost-user.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/contrib/libvhost-user/libvhost-user.c 
b/contrib/libvhost-user/libvhost-user.c
index e08d6c7b97..516d0de7bb 100644
--- a/contrib/libvhost-user/libvhost-user.c
+++ b/contrib/libvhost-user/libvhost-user.c
@@ -1085,7 +1085,8 @@ bool vu_set_queue_host_notifier(VuDev *dev, VuVirtq *vq, 
int fd,
 
 vmsg.fd_num = fd_num;
 
-if ((dev->protocol_features & VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD) == 0) {
+if (!has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD)) {
 return false;
 }
 
-- 
2.17.1




[PATCH 95/97] s390: PCI: fix IOMMU region init

2019-10-01 Thread Michael Roth
From: Matthew Rosato 

The fix in dbe9cf606c shrinks the IOMMU memory region to a size
that seems reasonable on the surface, however is actually too
small as it is based against a 0-mapped address space.  This
causes breakage with small guests as they can overrun the IOMMU window.

Let's go back to the prior method of initializing iommu for now.

Fixes: dbe9cf606c ("s390x/pci: Set the iommu region size mpcifc request")
Cc: qemu-sta...@nongnu.org
Reviewed-by: Pierre Morel 
Reported-by: Boris Fiuczynski 
Tested-by: Boris Fiuczynski 
Reported-by: Stefan Zimmerman 
Signed-off-by: Matthew Rosato 
Message-Id: <1569507036-15314-1-git-send-email-mjros...@linux.ibm.com>
Signed-off-by: Christian Borntraeger 
(cherry picked from commit 7df1dac5f1c85312474df9cb3a8fcae72303da62)
Signed-off-by: Michael Roth 
---
 hw/s390x/s390-pci-bus.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 2d0a28d544..a6be6305b8 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -694,10 +694,15 @@ static const MemoryRegionOps s390_msi_ctrl_ops = {
 
 void s390_pci_iommu_enable(S390PCIIOMMU *iommu)
 {
+/*
+ * The iommu region is initialized against a 0-mapped address space,
+ * so the smallest IOMMU region we can define runs from 0 to the end
+ * of the PCI address space.
+ */
 char *name = g_strdup_printf("iommu-s390-%04x", iommu->pbdev->uid);
 memory_region_init_iommu(>iommu_mr, sizeof(iommu->iommu_mr),
  TYPE_S390_IOMMU_MEMORY_REGION, OBJECT(>mr),
- name, iommu->pal - iommu->pba + 1);
+ name, iommu->pal + 1);
 iommu->enabled = true;
 memory_region_add_subregion(>mr, 0, 
MEMORY_REGION(>iommu_mr));
 g_free(name);
-- 
2.17.1




[PATCH 17/97] block: Drain source node in bdrv_replace_node()

2019-10-01 Thread Michael Roth
From: Kevin Wolf 

Instead of just asserting that no requests are in flight in
bdrv_replace_node(), which is a requirement that most callers ignore, we
can just drain the source node right there. This fixes at least starting
a commit job while I/O is active on the backing chain, but probably
other callers, too.

Having requests in flight on the target node isn't a problem because the
target just gets new parents, but the call path of running requests
isn't modified. So we can just drop this assertion without a replacement.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1711643
Signed-off-by: Kevin Wolf 
Reviewed-by: Max Reitz 
(cherry picked from commit f871abd60f4b67547e62c57c9bec19420052be39)
*prereq for d81e1efb tests
Signed-off-by: Michael Roth 
---
 block.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/block.c b/block.c
index 9ae5c0ed2f..c0e1c86911 100644
--- a/block.c
+++ b/block.c
@@ -3987,13 +3987,13 @@ void bdrv_replace_node(BlockDriverState *from, 
BlockDriverState *to,
 uint64_t perm = 0, shared = BLK_PERM_ALL;
 int ret;
 
-assert(!atomic_read(>in_flight));
-assert(!atomic_read(>in_flight));
-
 /* Make sure that @from doesn't go away until we have successfully attached
  * all of its parents to @to. */
 bdrv_ref(from);
 
+assert(qemu_get_current_aio_context() == qemu_get_aio_context());
+bdrv_drained_begin(from);
+
 /* Put all parents into @list and calculate their cumulative permissions */
 QLIST_FOREACH_SAFE(c, >parents, next_parent, next) {
 assert(c->bs == from);
@@ -4034,6 +4034,7 @@ void bdrv_replace_node(BlockDriverState *from, 
BlockDriverState *to,
 
 out:
 g_slist_free(list);
+bdrv_drained_end(from);
 bdrv_unref(from);
 }
 
-- 
2.17.1




[PATCH 61/97] block/backup: unify different modes code path

2019-10-01 Thread Michael Roth
From: Vladimir Sementsov-Ogievskiy 

Do full, top and incremental mode copying all in one place. This
unifies the code path and helps further improvements.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Max Reitz 
Message-id: 20190429090842.57910-5-vsement...@virtuozzo.com
Signed-off-by: Max Reitz 
(cherry picked from commit c334e897d08eea1f5a3a95f6a2208afe6757c103)
*prereq for 110571be4e
Signed-off-by: Michael Roth 
---
 block/backup.c | 43 ++-
 1 file changed, 10 insertions(+), 33 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index 298e85f1a9..b54386b699 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -393,15 +393,23 @@ static bool bdrv_is_unallocated_range(BlockDriverState 
*bs,
 return offset >= end;
 }
 
-static int coroutine_fn backup_run_incremental(BackupBlockJob *job)
+static int coroutine_fn backup_loop(BackupBlockJob *job)
 {
 int ret;
 bool error_is_read;
 int64_t offset;
 HBitmapIter hbi;
+BlockDriverState *bs = blk_bs(job->common.blk);
 
 hbitmap_iter_init(, job->copy_bitmap, 0);
 while ((offset = hbitmap_iter_next()) != -1) {
+if (job->sync_mode == MIRROR_SYNC_MODE_TOP &&
+bdrv_is_unallocated_range(bs, offset, job->cluster_size))
+{
+hbitmap_reset(job->copy_bitmap, offset, job->cluster_size);
+continue;
+}
+
 do {
 if (yield_and_check(job)) {
 return 0;
@@ -446,7 +454,6 @@ static int coroutine_fn backup_run(Job *job, Error **errp)
 {
 BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
 BlockDriverState *bs = blk_bs(s->common.blk);
-int64_t offset;
 int ret = 0;
 
 QLIST_INIT(>inflight_reqs);
@@ -471,38 +478,8 @@ static int coroutine_fn backup_run(Job *job, Error **errp)
  * notify callback service CoW requests. */
 job_yield(job);
 }
-} else if (s->sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
-ret = backup_run_incremental(s);
 } else {
-/* Both FULL and TOP SYNC_MODE's require copying.. */
-for (offset = 0; offset < s->len;
- offset += s->cluster_size) {
-bool error_is_read;
-
-if (yield_and_check(s)) {
-break;
-}
-
-if (s->sync_mode == MIRROR_SYNC_MODE_TOP &&
-bdrv_is_unallocated_range(bs, offset, s->cluster_size))
-{
-continue;
-}
-
-ret = backup_do_cow(s, offset, s->cluster_size,
-_is_read, false);
-if (ret < 0) {
-/* Depending on error action, fail now or retry cluster */
-BlockErrorAction action =
-backup_error_action(s, error_is_read, -ret);
-if (action == BLOCK_ERROR_ACTION_REPORT) {
-break;
-} else {
-offset -= s->cluster_size;
-continue;
-}
-}
-}
+ret = backup_loop(s);
 }
 
 notifier_with_return_remove(>before_write);
-- 
2.17.1




[PATCH 73/97] target/arm: Don't abort on M-profile exception return in linux-user mode

2019-10-01 Thread Michael Roth
From: Peter Maydell 

An attempt to do an exception-return (branch to one of the magic
addresses) in linux-user mode for M-profile should behave like
a normal branch, because linux-user mode is always going to be
in 'handler' mode. This used to work, but we broke it when we added
support for the M-profile security extension in commit d02a8698d7ae2bfed.

In that commit we allowed even handler-mode calls to magic return
values to be checked for and dealt with by causing an
EXCP_EXCEPTION_EXIT exception to be taken, because this is
needed for the FNC_RETURN return-from-non-secure-function-call
handling. For system mode we added a check in do_v7m_exception_exit()
to make any spurious calls from Handler mode behave correctly, but
forgot that linux-user mode would also be affected.

How an attempted return-from-non-secure-function-call in linux-user
mode should be handled is not clear -- on real hardware it would
result in return to secure code (not to the Linux kernel) which
could then handle the error in any way it chose. For QEMU we take
the simple approach of treating this erroneous return the same way
it would be handled on a CPU without the security extensions --
treat it as a normal branch.

The upshot of all this is that for linux-user mode we should never
do any of the bx_excret magic, so the code change is simple.

This ought to be a weird corner case that only affects broken guest
code (because Linux user processes should never be attempting to do
exception returns or NS function returns), except that the code that
assigns addresses in RAM for the process and stack in our linux-user
code does not attempt to avoid this magic address range, so
legitimate code attempting to return to a trampoline routine on the
stack can fall into this case. This change fixes those programs,
but we should also look at restricting the range of memory we
use for M-profile linux-user guests to the area that would be
real RAM in hardware.

Cc: qemu-sta...@nongnu.org
Reported-by: Christophe Lyon 
Reviewed-by: Richard Henderson 
Signed-off-by: Peter Maydell 
Message-id: 20190822131534.16602-1-peter.mayd...@linaro.org
Fixes: https://bugs.launchpad.net/qemu/+bug/1840922
Signed-off-by: Peter Maydell 
(cherry picked from commit 5e5584c89f36b302c666bc6db535fd3f7ff35ad2)
Signed-off-by: Michael Roth 
---
 target/arm/translate.c | 21 -
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index d408e4d7ef..d9d4e765ca 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -964,10 +964,27 @@ static inline void gen_bx(DisasContext *s, TCGv_i32 var)
 store_cpu_field(var, thumb);
 }
 
-/* Set PC and Thumb state from var. var is marked as dead.
+/*
+ * Set PC and Thumb state from var. var is marked as dead.
  * For M-profile CPUs, include logic to detect exception-return
  * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
  * and BX reg, and no others, and happens only for code in Handler mode.
+ * The Security Extension also requires us to check for the FNC_RETURN
+ * which signals a function return from non-secure state; this can happen
+ * in both Handler and Thread mode.
+ * To avoid having to do multiple comparisons in inline generated code,
+ * we make the check we do here loose, so it will match for EXC_RETURN
+ * in Thread mode. For system emulation do_v7m_exception_exit() checks
+ * for these spurious cases and returns without doing anything (giving
+ * the same behaviour as for a branch to a non-magic address).
+ *
+ * In linux-user mode it is unclear what the right behaviour for an
+ * attempted FNC_RETURN should be, because in real hardware this will go
+ * directly to Secure code (ie not the Linux kernel) which will then treat
+ * the error in any way it chooses. For QEMU we opt to make the FNC_RETURN
+ * attempt behave the way it would on a CPU without the security extension,
+ * which is to say "like a normal branch". That means we can simply treat
+ * all branches as normal with no magic address behaviour.
  */
 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
 {
@@ -975,10 +992,12 @@ static inline void gen_bx_excret(DisasContext *s, 
TCGv_i32 var)
  * s->base.is_jmp that we need to do the rest of the work later.
  */
 gen_bx(s, var);
+#ifndef CONFIG_USER_ONLY
 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
 s->base.is_jmp = DISAS_BX_EXCRET;
 }
+#endif
 }
 
 static inline void gen_bx_excret_final_code(DisasContext *s)
-- 
2.17.1




[PATCH 92/97] curl: Check curl_multi_add_handle()'s return code

2019-10-01 Thread Michael Roth
From: Max Reitz 

If we had done that all along, debugging would have been much simpler.
(Also, I/O errors are better than hangs.)

Signed-off-by: Max Reitz 
Message-id: 20190910124136.10565-8-mre...@redhat.com
Reviewed-by: Maxim Levitsky 
Reviewed-by: John Snow 
Signed-off-by: Max Reitz 
(cherry picked from commit c34dc07f9f01cf686e512f939aece744723072cd)
Signed-off-by: Michael Roth 
---
 block/curl.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/block/curl.c b/block/curl.c
index af40203711..7a29b40954 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -881,7 +881,13 @@ static void curl_setup_preadv(BlockDriverState *bs, 
CURLAIOCB *acb)
 trace_curl_setup_preadv(acb->bytes, start, state->range);
 curl_easy_setopt(state->curl, CURLOPT_RANGE, state->range);
 
-curl_multi_add_handle(s->multi, state->curl);
+if (curl_multi_add_handle(s->multi, state->curl) != CURLM_OK) {
+state->acb[0] = NULL;
+acb->ret = -EIO;
+
+curl_clean_state(state);
+goto out;
+}
 
 /* Tell curl it needs to kick things off */
 curl_multi_socket_action(s->multi, CURL_SOCKET_TIMEOUT, 0, );
-- 
2.17.1




[PATCH 07/97] cutils: Fix size_to_str() on 32-bit platforms

2019-10-01 Thread Michael Roth
From: Eric Blake 

When extracting a human-readable size formatter, we changed 'uint64_t
div' pre-patch to 'unsigned long div' post-patch. Which breaks on
32-bit platforms, resulting in 'inf' instead of intended values larger
than 999GB.

Fixes: 22951aaa
CC: qemu-sta...@nongnu.org
Reported-by: Max Reitz 
Signed-off-by: Eric Blake 
Reviewed-by: Max Reitz 
Signed-off-by: Kevin Wolf 
(cherry picked from commit 754da86714d550c3f995f11a2587395081362e0a)
Signed-off-by: Michael Roth 
---
 util/cutils.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/util/cutils.c b/util/cutils.c
index e098debdc0..d682c90901 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -825,7 +825,7 @@ const char *qemu_ether_ntoa(const MACAddr *mac)
 char *size_to_str(uint64_t val)
 {
 static const char *suffixes[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei" };
-unsigned long div;
+uint64_t div;
 int i;
 
 /*
-- 
2.17.1




[PATCH 90/97] curl: Report only ready sockets

2019-10-01 Thread Michael Roth
From: Max Reitz 

Instead of reporting all sockets to cURL, only report the one that has
caused curl_multi_do_locked() to be called.  This lets us get rid of the
QLIST_FOREACH_SAFE() list, which was actually wrong: SAFE foreaches are
only safe when the current element is removed in each iteration.  If it
possible for the list to be concurrently modified, we cannot guarantee
that only the current element will be removed.  Therefore, we must not
use QLIST_FOREACH_SAFE() here.

Fixes: ff5ca1664af85b24a4180d595ea6873fd3deac57
Cc: qemu-sta...@nongnu.org
Signed-off-by: Max Reitz 
Message-id: 20190910124136.10565-6-mre...@redhat.com
Reviewed-by: Maxim Levitsky 
Reviewed-by: John Snow 
Signed-off-by: Max Reitz 
(cherry picked from commit 9abaf9fc474c3dd53e8e119326abc774c977c331)
Signed-off-by: Michael Roth 
---
 block/curl.c | 17 ++---
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/block/curl.c b/block/curl.c
index 5b163d71dc..de0cebd361 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -391,24 +391,19 @@ static void curl_multi_check_completion(BDRVCURLState *s)
 }
 
 /* Called with s->mutex held.  */
-static void curl_multi_do_locked(CURLSocket *ready_socket)
+static void curl_multi_do_locked(CURLSocket *socket)
 {
-CURLSocket *socket, *next_socket;
-CURLState *s = ready_socket->state;
+BDRVCURLState *s = socket->state->s;
 int running;
 int r;
 
-if (!s->s->multi) {
+if (!s->multi) {
 return;
 }
 
-/* Need to use _SAFE because curl_multi_socket_action() may trigger
- * curl_sock_cb() which might modify this list */
-QLIST_FOREACH_SAFE(socket, >sockets, next, next_socket) {
-do {
-r = curl_multi_socket_action(s->s->multi, socket->fd, 0, );
-} while (r == CURLM_CALL_MULTI_PERFORM);
-}
+do {
+r = curl_multi_socket_action(s->multi, socket->fd, 0, );
+} while (r == CURLM_CALL_MULTI_PERFORM);
 }
 
 static void curl_multi_do(void *arg)
-- 
2.17.1




[PATCH 97/97] scsi: lsi: exit infinite loop while executing script (CVE-2019-12068)

2019-10-01 Thread Michael Roth
From: Paolo Bonzini 

When executing script in lsi_execute_script(), the LSI scsi adapter
emulator advances 's->dsp' index to read next opcode. This can lead
to an infinite loop if the next opcode is empty. Move the existing
loop exit after 10k iterations so that it covers no-op opcodes as
well.

Reported-by: Bugs SysSec 
Signed-off-by: Paolo Bonzini 
Signed-off-by: Prasad J Pandit 
Signed-off-by: Paolo Bonzini 
(cherry picked from commit de594e47659029316bbf9391efb79da0a1a08e08)
Signed-off-by: Michael Roth 
---
 hw/scsi/lsi53c895a.c | 41 +++--
 1 file changed, 27 insertions(+), 14 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index da7239d94f..d3380b6f95 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -184,6 +184,9 @@ static const char *names[] = {
 /* Flag set if this is a tagged command.  */
 #define LSI_TAG_VALID (1 << 16)
 
+/* Maximum instructions to process. */
+#define LSI_MAX_INSN1
+
 typedef struct lsi_request {
 SCSIRequest *req;
 uint32_t tag;
@@ -1131,7 +1134,21 @@ static void lsi_execute_script(LSIState *s)
 
 s->istat1 |= LSI_ISTAT1_SRUN;
 again:
-insn_processed++;
+if (++insn_processed > LSI_MAX_INSN) {
+/* Some windows drivers make the device spin waiting for a memory
+   location to change.  If we have been executed a lot of code then
+   assume this is the case and force an unexpected device disconnect.
+   This is apparently sufficient to beat the drivers into submission.
+ */
+if (!(s->sien0 & LSI_SIST0_UDC)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "lsi_scsi: inf. loop with UDC masked");
+}
+lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
+lsi_disconnect(s);
+trace_lsi_execute_script_stop();
+return;
+}
 insn = read_dword(s, s->dsp);
 if (!insn) {
 /* If we receive an empty opcode increment the DSP by 4 bytes
@@ -1568,19 +1585,7 @@ again:
 }
 }
 }
-if (insn_processed > 1 && s->waiting == LSI_NOWAIT) {
-/* Some windows drivers make the device spin waiting for a memory
-   location to change.  If we have been executed a lot of code then
-   assume this is the case and force an unexpected device disconnect.
-   This is apparently sufficient to beat the drivers into submission.
- */
-if (!(s->sien0 & LSI_SIST0_UDC)) {
-qemu_log_mask(LOG_GUEST_ERROR,
-  "lsi_scsi: inf. loop with UDC masked");
-}
-lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
-lsi_disconnect(s);
-} else if (s->istat1 & LSI_ISTAT1_SRUN && s->waiting == LSI_NOWAIT) {
+if (s->istat1 & LSI_ISTAT1_SRUN && s->waiting == LSI_NOWAIT) {
 if (s->dcntl & LSI_DCNTL_SSM) {
 lsi_script_dma_interrupt(s, LSI_DSTAT_SSI);
 } else {
@@ -1968,6 +1973,10 @@ static void lsi_reg_writeb(LSIState *s, int offset, 
uint8_t val)
 case 0x2f: /* DSP[24:31] */
 s->dsp &= 0x00ff;
 s->dsp |= val << 24;
+/*
+ * FIXME: if s->waiting != LSI_NOWAIT, this will only execute one
+ * instruction.  Is this correct?
+ */
 if ((s->dmode & LSI_DMODE_MAN) == 0
 && (s->istat1 & LSI_ISTAT1_SRUN) == 0)
 lsi_execute_script(s);
@@ -1986,6 +1995,10 @@ static void lsi_reg_writeb(LSIState *s, int offset, 
uint8_t val)
 break;
 case 0x3b: /* DCNTL */
 s->dcntl = val & ~(LSI_DCNTL_PFF | LSI_DCNTL_STD);
+/*
+ * FIXME: if s->waiting != LSI_NOWAIT, this will only execute one
+ * instruction.  Is this correct?
+ */
 if ((val & LSI_DCNTL_STD) && (s->istat1 & LSI_ISTAT1_SRUN) == 0)
 lsi_execute_script(s);
 break;
-- 
2.17.1




[PATCH 59/97] block/backup: move to copy_bitmap with granularity

2019-10-01 Thread Michael Roth
From: Vladimir Sementsov-Ogievskiy 

We are going to share this bitmap between backup and backup-top filter
driver, so let's share something more meaningful. It also simplifies
some calculations.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Max Reitz 
Message-id: 20190429090842.57910-3-vsement...@virtuozzo.com
Signed-off-by: Max Reitz 
(cherry picked from commit a8389e315ef71913ae99cf8f3b1f89e84631f599)
*prereq for 4a5b91ca
Signed-off-by: Michael Roth 
---
 block/backup.c | 48 +++-
 1 file changed, 23 insertions(+), 25 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index d9f5db18ac..510fc54f98 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -113,7 +113,8 @@ static int coroutine_fn 
backup_cow_with_bounce_buffer(BackupBlockJob *job,
 int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
 int write_flags = job->serialize_target_writes ? BDRV_REQ_SERIALISING : 0;
 
-hbitmap_reset(job->copy_bitmap, start / job->cluster_size, 1);
+assert(QEMU_IS_ALIGNED(start, job->cluster_size));
+hbitmap_reset(job->copy_bitmap, start, job->cluster_size);
 nbytes = MIN(job->cluster_size, job->len - start);
 if (!*bounce_buffer) {
 *bounce_buffer = blk_blockalign(blk, job->cluster_size);
@@ -147,7 +148,7 @@ static int coroutine_fn 
backup_cow_with_bounce_buffer(BackupBlockJob *job,
 
 return nbytes;
 fail:
-hbitmap_set(job->copy_bitmap, start / job->cluster_size, 1);
+hbitmap_set(job->copy_bitmap, start, job->cluster_size);
 return ret;
 
 }
@@ -167,16 +168,15 @@ static int coroutine_fn 
backup_cow_with_offload(BackupBlockJob *job,
 int write_flags = job->serialize_target_writes ? BDRV_REQ_SERIALISING : 0;
 
 assert(QEMU_IS_ALIGNED(job->copy_range_size, job->cluster_size));
+assert(QEMU_IS_ALIGNED(start, job->cluster_size));
 nbytes = MIN(job->copy_range_size, end - start);
 nr_clusters = DIV_ROUND_UP(nbytes, job->cluster_size);
-hbitmap_reset(job->copy_bitmap, start / job->cluster_size,
-  nr_clusters);
+hbitmap_reset(job->copy_bitmap, start, job->cluster_size * nr_clusters);
 ret = blk_co_copy_range(blk, start, job->target, start, nbytes,
 read_flags, write_flags);
 if (ret < 0) {
 trace_backup_do_cow_copy_range_fail(job, start, ret);
-hbitmap_set(job->copy_bitmap, start / job->cluster_size,
-nr_clusters);
+hbitmap_set(job->copy_bitmap, start, job->cluster_size * nr_clusters);
 return ret;
 }
 
@@ -204,7 +204,7 @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
 cow_request_begin(_request, job, start, end);
 
 while (start < end) {
-if (!hbitmap_get(job->copy_bitmap, start / job->cluster_size)) {
+if (!hbitmap_get(job->copy_bitmap, start)) {
 trace_backup_do_cow_skip(job, start);
 start += job->cluster_size;
 continue; /* already copied */
@@ -300,6 +300,11 @@ static void backup_clean(Job *job)
 assert(s->target);
 blk_unref(s->target);
 s->target = NULL;
+
+if (s->copy_bitmap) {
+hbitmap_free(s->copy_bitmap);
+s->copy_bitmap = NULL;
+}
 }
 
 static void backup_attached_aio_context(BlockJob *job, AioContext *aio_context)
@@ -312,7 +317,6 @@ static void backup_attached_aio_context(BlockJob *job, 
AioContext *aio_context)
 void backup_do_checkpoint(BlockJob *job, Error **errp)
 {
 BackupBlockJob *backup_job = container_of(job, BackupBlockJob, common);
-int64_t len;
 
 assert(block_job_driver(job) == _job_driver);
 
@@ -322,8 +326,7 @@ void backup_do_checkpoint(BlockJob *job, Error **errp)
 return;
 }
 
-len = DIV_ROUND_UP(backup_job->len, backup_job->cluster_size);
-hbitmap_set(backup_job->copy_bitmap, 0, len);
+hbitmap_set(backup_job->copy_bitmap, 0, backup_job->len);
 }
 
 static void backup_drain(BlockJob *job)
@@ -378,16 +381,16 @@ static int coroutine_fn 
backup_run_incremental(BackupBlockJob *job)
 {
 int ret;
 bool error_is_read;
-int64_t cluster;
+int64_t offset;
 HBitmapIter hbi;
 
 hbitmap_iter_init(, job->copy_bitmap, 0);
-while ((cluster = hbitmap_iter_next()) != -1) {
+while ((offset = hbitmap_iter_next()) != -1) {
 do {
 if (yield_and_check(job)) {
 return 0;
 }
-ret = backup_do_cow(job, cluster * job->cluster_size,
+ret = backup_do_cow(job, offset,
 job->cluster_size, _is_read, false);
 if (ret < 0 && backup_error_action(job, error_is_read, -ret) ==
BLOCK_ERROR_ACTION_REPORT)
@@ -409,12 +412,9 @@ static void 
backup_incremental_init_copy_bitmap(BackupBlockJob *job)
 while (bdrv_dirty_bitmap_next_dirty_area(job->sync_bitmap,
  , ))
 {
-uint64_t cluster = offset / 

[PATCH 81/97] iotests: Test blockdev-create for vpc

2019-10-01 Thread Michael Roth
From: Max Reitz 

Signed-off-by: Max Reitz 
Signed-off-by: Kevin Wolf 
(cherry picked from commit cb73747e1a47b93d3dfdc3f769c576b053916938)
 Conflicts:
tests/qemu-iotests/group
*drop context dep. on tests not in 4.0
Signed-off-by: Michael Roth 
---
 tests/qemu-iotests/266 | 153 +
 tests/qemu-iotests/266.out | 137 +
 tests/qemu-iotests/group   |   1 +
 3 files changed, 291 insertions(+)
 create mode 100755 tests/qemu-iotests/266
 create mode 100644 tests/qemu-iotests/266.out

diff --git a/tests/qemu-iotests/266 b/tests/qemu-iotests/266
new file mode 100755
index 00..5b35cd67e4
--- /dev/null
+++ b/tests/qemu-iotests/266
@@ -0,0 +1,153 @@
+#!/usr/bin/env python
+#
+# Test VPC and file image creation
+#
+# Copyright (C) 2019 Red Hat, Inc.
+#
+# 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 iotests
+from iotests import imgfmt
+
+
+def blockdev_create(vm, options):
+result = vm.qmp_log('blockdev-create', job_id='job0', options=options,
+filters=[iotests.filter_qmp_testfiles])
+
+if 'return' in result:
+assert result['return'] == {}
+vm.run_job('job0')
+
+
+# Successful image creation (defaults)
+def implicit_defaults(vm, file_path):
+iotests.log("=== Successful image creation (defaults) ===")
+iotests.log("")
+
+# 8 heads, 964 cyls/head, 17 secs/cyl
+# (Close to 64 MB)
+size = 8 * 964 * 17 * 512
+
+blockdev_create(vm, { 'driver': imgfmt,
+  'file': 'protocol-node',
+  'size': size })
+
+
+# Successful image creation (explicit defaults)
+def explicit_defaults(vm, file_path):
+iotests.log("=== Successful image creation (explicit defaults) ===")
+iotests.log("")
+
+# 16 heads, 964 cyls/head, 17 secs/cyl
+# (Close to 128 MB)
+size = 16 * 964 * 17 * 512
+
+blockdev_create(vm, { 'driver': imgfmt,
+  'file': 'protocol-node',
+  'size': size,
+  'subformat': 'dynamic',
+  'force-size': False })
+
+
+# Successful image creation (non-default options)
+def non_defaults(vm, file_path):
+iotests.log("=== Successful image creation (non-default options) ===")
+iotests.log("")
+
+# Not representable in CHS (fine with force-size=True)
+size = 1048576
+
+blockdev_create(vm, { 'driver': imgfmt,
+  'file': 'protocol-node',
+  'size': size,
+  'subformat': 'fixed',
+  'force-size': True })
+
+
+# Size not representable in CHS with force-size=False
+def non_chs_size_without_force(vm, file_path):
+iotests.log("=== Size not representable in CHS ===")
+iotests.log("")
+
+# Not representable in CHS (will not work with force-size=False)
+size = 1048576
+
+blockdev_create(vm, { 'driver': imgfmt,
+  'file': 'protocol-node',
+  'size': size,
+  'force-size': False })
+
+
+# Zero size
+def zero_size(vm, file_path):
+iotests.log("=== Zero size===")
+iotests.log("")
+
+blockdev_create(vm, { 'driver': imgfmt,
+  'file': 'protocol-node',
+  'size': 0 })
+
+
+# Maximum CHS size
+def maximum_chs_size(vm, file_path):
+iotests.log("=== Maximum CHS size===")
+iotests.log("")
+
+blockdev_create(vm, { 'driver': imgfmt,
+  'file': 'protocol-node',
+  'size': 16 * 65535 * 255 * 512 })
+
+
+# Actual maximum size
+def maximum_size(vm, file_path):
+iotests.log("=== Actual maximum size===")
+iotests.log("")
+
+blockdev_create(vm, { 'driver': imgfmt,
+  'file': 'protocol-node',
+  'size': 0xff00 * 512,
+  'force-size': True })
+
+
+def main():
+for test_func in [implicit_defaults, explicit_defaults, non_defaults,
+  non_chs_size_without_force, zero_size, maximum_chs_size,
+  maximum_size]:
+
+with iotests.FilePath('t.vpc') as file_path, \
+ iotests.VM() as vm:
+
+vm.launch()
+
+iotests.log('--- Creating empty file ---')
+

[PATCH 71/97] qcow2: Fix the calculation of the maximum L2 cache size

2019-10-01 Thread Michael Roth
From: Alberto Garcia 

The size of the qcow2 L2 cache defaults to 32 MB, which can be easily
larger than the maximum amount of L2 metadata that the image can have.
For example: with 64 KB clusters the user would need a qcow2 image
with a virtual size of 256 GB in order to have 32 MB of L2 metadata.

Because of that, since commit b749562d9822d14ef69c9eaa5f85903010b86c30
we forbid the L2 cache to become larger than the maximum amount of L2
metadata for the image, calculated using this formula:

uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8);

The problem with this formula is that the result should be rounded up
to the cluster size because an L2 table on disk always takes one full
cluster.

For example, a 1280 MB qcow2 image with 64 KB clusters needs exactly
160 KB of L2 metadata, but we need 192 KB on disk (3 clusters) even if
the last 32 KB of those are not going to be used.

However QEMU rounds the numbers down and only creates 2 cache tables
(128 KB), which is not enough for the image.

A quick test doing 4KB random writes on a 1280 MB image gives me
around 500 IOPS, while with the correct cache size I get 16K IOPS.

Cc: qemu-sta...@nongnu.org
Signed-off-by: Alberto Garcia 
Signed-off-by: Kevin Wolf 
(cherry picked from commit b70d08205b2e4044c529eefc21df2c8ab61b473b)
Signed-off-by: Michael Roth 
---
 block/qcow2.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 840f289a48..c80f48a02b 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -831,7 +831,11 @@ static void read_cache_sizes(BlockDriverState *bs, 
QemuOpts *opts,
 bool l2_cache_entry_size_set;
 int min_refcount_cache = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size;
 uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
-uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8);
+uint64_t max_l2_entries = DIV_ROUND_UP(virtual_disk_size, s->cluster_size);
+/* An L2 table is always one cluster in size so the max cache size
+ * should be a multiple of the cluster size. */
+uint64_t max_l2_cache = ROUND_UP(max_l2_entries * sizeof(uint64_t),
+ s->cluster_size);
 
 combined_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_CACHE_SIZE);
 l2_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_SIZE);
-- 
2.17.1




[PATCH 84/97] block/nfs: tear down aio before nfs_close

2019-10-01 Thread Michael Roth
From: Peter Lieven 

nfs_close is a sync call from libnfs and has its own event
handler polling on the nfs FD. Avoid that both QEMU and libnfs
are intefering here.

CC: qemu-sta...@nongnu.org
Signed-off-by: Peter Lieven 
Signed-off-by: Kevin Wolf 
(cherry picked from commit 601dc6559725f7a614b6f893611e17ff0908e914)
Signed-off-by: Michael Roth 
---
 block/nfs.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/block/nfs.c b/block/nfs.c
index 531903610b..f04f675c63 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -389,12 +389,14 @@ static void nfs_attach_aio_context(BlockDriverState *bs,
 static void nfs_client_close(NFSClient *client)
 {
 if (client->context) {
+qemu_mutex_lock(>mutex);
+aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
+   false, NULL, NULL, NULL, NULL);
+qemu_mutex_unlock(>mutex);
 if (client->fh) {
 nfs_close(client->context, client->fh);
 client->fh = NULL;
 }
-aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
-   false, NULL, NULL, NULL, NULL);
 nfs_destroy_context(client->context);
 client->context = NULL;
 }
-- 
2.17.1




[PATCH 60/97] block/backup: refactor and tolerate unallocated cluster skipping

2019-10-01 Thread Michael Roth
From: Vladimir Sementsov-Ogievskiy 

Split allocation checking to separate function and reduce nesting.
Consider bdrv_is_allocated() fail as allocated area, as copying more
than needed is not wrong (and we do it anyway) and seems better than
fail the whole job. And, most probably we will fail on the next read,
if there are real problem with source.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Max Reitz 
Message-id: 20190429090842.57910-4-vsement...@virtuozzo.com
Signed-off-by: Max Reitz 
(cherry picked from commit 9eb5a248f3e50c1f034bc6ff4b2f25c8c56515a5)
*prereq for 110571be4e
Signed-off-by: Michael Roth 
---
 block/backup.c | 60 +++---
 1 file changed, 23 insertions(+), 37 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index 510fc54f98..298e85f1a9 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -377,6 +377,22 @@ static bool coroutine_fn yield_and_check(BackupBlockJob 
*job)
 return false;
 }
 
+static bool bdrv_is_unallocated_range(BlockDriverState *bs,
+  int64_t offset, int64_t bytes)
+{
+int64_t end = offset + bytes;
+
+while (offset < end && !bdrv_is_allocated(bs, offset, bytes, )) {
+if (bytes == 0) {
+return true;
+}
+offset += bytes;
+bytes = end - offset;
+}
+
+return offset >= end;
+}
+
 static int coroutine_fn backup_run_incremental(BackupBlockJob *job)
 {
 int ret;
@@ -462,49 +478,19 @@ static int coroutine_fn backup_run(Job *job, Error **errp)
 for (offset = 0; offset < s->len;
  offset += s->cluster_size) {
 bool error_is_read;
-int alloced = 0;
 
 if (yield_and_check(s)) {
 break;
 }
 
-if (s->sync_mode == MIRROR_SYNC_MODE_TOP) {
-int i;
-int64_t n;
-
-/* Check to see if these blocks are already in the
- * backing file. */
-
-for (i = 0; i < s->cluster_size;) {
-/* bdrv_is_allocated() only returns true/false based
- * on the first set of sectors it comes across that
- * are are all in the same state.
- * For that reason we must verify each sector in the
- * backup cluster length.  We end up copying more than
- * needed but at some point that is always the case. */
-alloced =
-bdrv_is_allocated(bs, offset + i,
-  s->cluster_size - i, );
-i += n;
-
-if (alloced || n == 0) {
-break;
-}
-}
-
-/* If the above loop never found any sectors that are in
- * the topmost image, skip this backup. */
-if (alloced == 0) {
-continue;
-}
-}
-/* FULL sync mode we copy the whole drive. */
-if (alloced < 0) {
-ret = alloced;
-} else {
-ret = backup_do_cow(s, offset, s->cluster_size,
-_is_read, false);
+if (s->sync_mode == MIRROR_SYNC_MODE_TOP &&
+bdrv_is_unallocated_range(bs, offset, s->cluster_size))
+{
+continue;
 }
+
+ret = backup_do_cow(s, offset, s->cluster_size,
+_is_read, false);
 if (ret < 0) {
 /* Depending on error action, fail now or retry cluster */
 BlockErrorAction action =
-- 
2.17.1




[PATCH 89/97] curl: Pass CURLSocket to curl_multi_do()

2019-10-01 Thread Michael Roth
From: Max Reitz 

curl_multi_do_locked() currently marks all sockets as ready.  That is
not only inefficient, but in fact unsafe (the loop is).  A follow-up
patch will change that, but to do so, curl_multi_do_locked() needs to
know exactly which socket is ready; and that is accomplished by this
patch here.

Cc: qemu-sta...@nongnu.org
Signed-off-by: Max Reitz 
Message-id: 20190910124136.10565-5-mre...@redhat.com
Reviewed-by: Maxim Levitsky 
Reviewed-by: John Snow 
Signed-off-by: Max Reitz 
(cherry picked from commit 9dbad87d25587ff640ef878f7b6159fc368ff541)
Signed-off-by: Michael Roth 
---
 block/curl.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/block/curl.c b/block/curl.c
index bf64c2a0db..5b163d71dc 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -184,15 +184,15 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int 
action,
 switch (action) {
 case CURL_POLL_IN:
 aio_set_fd_handler(s->aio_context, fd, false,
-   curl_multi_do, NULL, NULL, state);
+   curl_multi_do, NULL, NULL, socket);
 break;
 case CURL_POLL_OUT:
 aio_set_fd_handler(s->aio_context, fd, false,
-   NULL, curl_multi_do, NULL, state);
+   NULL, curl_multi_do, NULL, socket);
 break;
 case CURL_POLL_INOUT:
 aio_set_fd_handler(s->aio_context, fd, false,
-   curl_multi_do, curl_multi_do, NULL, state);
+   curl_multi_do, curl_multi_do, NULL, socket);
 break;
 case CURL_POLL_REMOVE:
 aio_set_fd_handler(s->aio_context, fd, false,
@@ -391,9 +391,10 @@ static void curl_multi_check_completion(BDRVCURLState *s)
 }
 
 /* Called with s->mutex held.  */
-static void curl_multi_do_locked(CURLState *s)
+static void curl_multi_do_locked(CURLSocket *ready_socket)
 {
 CURLSocket *socket, *next_socket;
+CURLState *s = ready_socket->state;
 int running;
 int r;
 
@@ -412,12 +413,13 @@ static void curl_multi_do_locked(CURLState *s)
 
 static void curl_multi_do(void *arg)
 {
-CURLState *s = (CURLState *)arg;
+CURLSocket *socket = arg;
+BDRVCURLState *s = socket->state->s;
 
-qemu_mutex_lock(>s->mutex);
-curl_multi_do_locked(s);
-curl_multi_check_completion(s->s);
-qemu_mutex_unlock(>s->mutex);
+qemu_mutex_lock(>mutex);
+curl_multi_do_locked(socket);
+curl_multi_check_completion(s);
+qemu_mutex_unlock(>mutex);
 }
 
 static void curl_multi_timeout_do(void *arg)
-- 
2.17.1




[PATCH 08/97] Makefile: add nit-picky mode to sphinx-build

2019-10-01 Thread Michael Roth
From: John Snow 

If we add references that don't resolve (or accidentally remove them),
it will be helpful to have warning messages alerting us to that.

Further, turn those warnings into errors so we can be alerted to these
problems sooner rather than later.

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Message-id: 20190426221528.30293-2-js...@redhat.com
[adjusted commit message. --js]
Signed-off-by: John Snow 
(cherry picked from commit 9e5b6cb87db66dfb606604fe6cf40e5ddf1ef0e7)
Signed-off-by: Michael Roth 
---
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 04a0d45050..d4c5750256 100644
--- a/Makefile
+++ b/Makefile
@@ -899,7 +899,7 @@ docs/version.texi: $(SRC_PATH)/VERSION
 sphinxdocs: $(MANUAL_BUILDDIR)/devel/index.html 
$(MANUAL_BUILDDIR)/interop/index.html
 
 # Canned command to build a single manual
-build-manual = $(call quiet-command,sphinx-build $(if $(V),,-q) -b html -D 
version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1 
$(SRC_PATH)/docs/$1 $(MANUAL_BUILDDIR)/$1 ,"SPHINX","$(MANUAL_BUILDDIR)/$1")
+build-manual = $(call quiet-command,sphinx-build $(if $(V),,-q) -W -n -b html 
-D version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1 
$(SRC_PATH)/docs/$1 $(MANUAL_BUILDDIR)/$1 ,"SPHINX","$(MANUAL_BUILDDIR)/$1")
 # We assume all RST files in the manual's directory are used in it
 manual-deps = $(wildcard $(SRC_PATH)/docs/$1/*.rst) 
$(SRC_PATH)/docs/$1/conf.py $(SRC_PATH)/docs/conf.py
 
-- 
2.17.1




[PATCH 91/97] curl: Handle success in multi_check_completion

2019-10-01 Thread Michael Roth
From: Max Reitz 

Background: As of cURL 7.59.0, it verifies that several functions are
not called from within a callback.  Among these functions is
curl_multi_add_handle().

curl_read_cb() is a callback from cURL and not a coroutine.  Waking up
acb->co will lead to entering it then and there, which means the current
request will settle and the caller (if it runs in the same coroutine)
may then issue the next request.  In such a case, we will enter
curl_setup_preadv() effectively from within curl_read_cb().

Calling curl_multi_add_handle() will then fail and the new request will
not be processed.

Fix this by not letting curl_read_cb() wake up acb->co.  Instead, leave
the whole business of settling the AIOCB objects to
curl_multi_check_completion() (which is called from our timer callback
and our FD handler, so not from any cURL callbacks).

Reported-by: Natalie Gavrielov 
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1740193
Cc: qemu-sta...@nongnu.org
Signed-off-by: Max Reitz 
Message-id: 20190910124136.10565-7-mre...@redhat.com
Reviewed-by: John Snow 
Reviewed-by: Maxim Levitsky 
Signed-off-by: Max Reitz 
(cherry picked from commit bfb23b480a49114315877aacf700b49453e0f9d9)
Signed-off-by: Michael Roth 
---
 block/curl.c | 69 ++--
 1 file changed, 29 insertions(+), 40 deletions(-)

diff --git a/block/curl.c b/block/curl.c
index de0cebd361..af40203711 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -228,7 +228,6 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t 
nmemb, void *opaque)
 {
 CURLState *s = ((CURLState*)opaque);
 size_t realsize = size * nmemb;
-int i;
 
 trace_curl_read_cb(realsize);
 
@@ -244,32 +243,6 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t 
nmemb, void *opaque)
 memcpy(s->orig_buf + s->buf_off, ptr, realsize);
 s->buf_off += realsize;
 
-for(i=0; iacb[i];
-
-if (!acb)
-continue;
-
-if ((s->buf_off >= acb->end)) {
-size_t request_length = acb->bytes;
-
-qemu_iovec_from_buf(acb->qiov, 0, s->orig_buf + acb->start,
-acb->end - acb->start);
-
-if (acb->end - acb->start < request_length) {
-size_t offset = acb->end - acb->start;
-qemu_iovec_memset(acb->qiov, offset, 0,
-  request_length - offset);
-}
-
-acb->ret = 0;
-s->acb[i] = NULL;
-qemu_mutex_unlock(>s->mutex);
-aio_co_wake(acb->co);
-qemu_mutex_lock(>s->mutex);
-}
-}
-
 read_end:
 /* curl will error out if we do not return this value */
 return size * nmemb;
@@ -350,13 +323,14 @@ static void curl_multi_check_completion(BDRVCURLState *s)
 break;
 
 if (msg->msg == CURLMSG_DONE) {
+int i;
 CURLState *state = NULL;
+bool error = msg->data.result != CURLE_OK;
+
 curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE,
   (char **));
 
-/* ACBs for successful messages get completed in curl_read_cb */
-if (msg->data.result != CURLE_OK) {
-int i;
+if (error) {
 static int errcount = 100;
 
 /* Don't lose the original error message from curl, since
@@ -368,20 +342,35 @@ static void curl_multi_check_completion(BDRVCURLState *s)
 error_report("curl: further errors suppressed");
 }
 }
+}
 
-for (i = 0; i < CURL_NUM_ACB; i++) {
-CURLAIOCB *acb = state->acb[i];
+for (i = 0; i < CURL_NUM_ACB; i++) {
+CURLAIOCB *acb = state->acb[i];
 
-if (acb == NULL) {
-continue;
-}
+if (acb == NULL) {
+continue;
+}
+
+if (!error) {
+/* Assert that we have read all data */
+assert(state->buf_off >= acb->end);
+
+qemu_iovec_from_buf(acb->qiov, 0,
+state->orig_buf + acb->start,
+acb->end - acb->start);
 
-acb->ret = -EIO;
-state->acb[i] = NULL;
-qemu_mutex_unlock(>mutex);
-aio_co_wake(acb->co);
-qemu_mutex_lock(>mutex);
+if (acb->end - acb->start < acb->bytes) {
+size_t offset = acb->end - acb->start;
+qemu_iovec_memset(acb->qiov, offset, 0,
+  acb->bytes - offset);
+}
 }
+
+acb->ret = error ? -EIO : 0;
+state->acb[i] = NULL;
+qemu_mutex_unlock(>mutex);

[PATCH 67/97] mirror: Only mirror granularity-aligned chunks

2019-10-01 Thread Michael Roth
From: Max Reitz 

In write-blocking mode, all writes to the top node directly go to the
target.  We must only mirror chunks of data that are aligned to the
job's granularity, because that is how the dirty bitmap works.
Therefore, the request alignment for writes must be the job's
granularity (in write-blocking mode).

Unfortunately, this forces all reads and writes to have the same
granularity (we only need this alignment for writes to the target, not
the source), but that is something to be fixed another time.

Cc: qemu-sta...@nongnu.org
Signed-off-by: Max Reitz 
Message-id: 20190805153308.2657-1-mre...@redhat.com
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Fixes: d06107ade0ce74dc39739bac80de84b51ec18546
Signed-off-by: Max Reitz 
(cherry picked from commit 9adc1cb49af8d4e54f57980b1eed5c0a4b2dafa6)
Signed-off-by: Michael Roth 
---
 block/mirror.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/block/mirror.c b/block/mirror.c
index ff15cfb197..062dc42867 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1477,6 +1477,15 @@ static void bdrv_mirror_top_child_perm(BlockDriverState 
*bs, BdrvChild *c,
 *nshared = BLK_PERM_ALL;
 }
 
+static void bdrv_mirror_top_refresh_limits(BlockDriverState *bs, Error **errp)
+{
+MirrorBDSOpaque *s = bs->opaque;
+
+if (s && s->job && s->job->copy_mode == MIRROR_COPY_MODE_WRITE_BLOCKING) {
+bs->bl.request_alignment = s->job->granularity;
+}
+}
+
 /* Dummy node that provides consistent read to its users without requiring it
  * from its backing file and that allows writes on the backing file chain. */
 static BlockDriver bdrv_mirror_top = {
@@ -1489,6 +1498,7 @@ static BlockDriver bdrv_mirror_top = {
 .bdrv_co_block_status   = bdrv_co_block_status_from_backing,
 .bdrv_refresh_filename  = bdrv_mirror_top_refresh_filename,
 .bdrv_child_perm= bdrv_mirror_top_child_perm,
+.bdrv_refresh_limits= bdrv_mirror_top_refresh_limits,
 };
 
 static void mirror_start_job(const char *job_id, BlockDriverState *bs,
@@ -1627,6 +1637,25 @@ static void mirror_start_job(const char *job_id, 
BlockDriverState *bs,
 s->should_complete = true;
 }
 
+/*
+ * Must be called before we start tracking writes, but after
+ *
+ * ((MirrorBlockJob *)
+ * ((MirrorBDSOpaque *)
+ * mirror_top_bs->opaque
+ * )->job
+ * )->copy_mode
+ *
+ * has the correct value.
+ * (We start tracking writes as of the following
+ * bdrv_create_dirty_bitmap() call.)
+ */
+bdrv_refresh_limits(mirror_top_bs, _err);
+if (local_err) {
+error_propagate(errp, local_err);
+goto fail;
+}
+
 s->dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
 if (!s->dirty_bitmap) {
 goto fail;
-- 
2.17.1




[PATCH 88/97] curl: Check completion in curl_multi_do()

2019-10-01 Thread Michael Roth
From: Max Reitz 

While it is more likely that transfers complete after some file
descriptor has data ready to read, we probably should not rely on it.
Better be safe than sorry and call curl_multi_check_completion() in
curl_multi_do(), too, just like it is done in curl_multi_read().

With this change, curl_multi_do() and curl_multi_read() are actually the
same, so drop curl_multi_read() and use curl_multi_do() as the sole FD
handler.

Signed-off-by: Max Reitz 
Message-id: 20190910124136.10565-4-mre...@redhat.com
Reviewed-by: Maxim Levitsky 
Reviewed-by: John Snow 
Signed-off-by: Max Reitz 
(cherry picked from commit 948403bcb1c7e71dcbe8ab8479cf3934a0efcbb5)
Signed-off-by: Michael Roth 
---
 block/curl.c | 14 ++
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/block/curl.c b/block/curl.c
index a0381ae0b4..bf64c2a0db 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -138,7 +138,6 @@ typedef struct BDRVCURLState {
 
 static void curl_clean_state(CURLState *s);
 static void curl_multi_do(void *arg);
-static void curl_multi_read(void *arg);
 
 #ifdef NEED_CURL_TIMER_CALLBACK
 /* Called from curl_multi_do_locked, with s->mutex held.  */
@@ -185,7 +184,7 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int 
action,
 switch (action) {
 case CURL_POLL_IN:
 aio_set_fd_handler(s->aio_context, fd, false,
-   curl_multi_read, NULL, NULL, state);
+   curl_multi_do, NULL, NULL, state);
 break;
 case CURL_POLL_OUT:
 aio_set_fd_handler(s->aio_context, fd, false,
@@ -193,7 +192,7 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int 
action,
 break;
 case CURL_POLL_INOUT:
 aio_set_fd_handler(s->aio_context, fd, false,
-   curl_multi_read, curl_multi_do, NULL, state);
+   curl_multi_do, curl_multi_do, NULL, state);
 break;
 case CURL_POLL_REMOVE:
 aio_set_fd_handler(s->aio_context, fd, false,
@@ -415,15 +414,6 @@ static void curl_multi_do(void *arg)
 {
 CURLState *s = (CURLState *)arg;
 
-qemu_mutex_lock(>s->mutex);
-curl_multi_do_locked(s);
-qemu_mutex_unlock(>s->mutex);
-}
-
-static void curl_multi_read(void *arg)
-{
-CURLState *s = (CURLState *)arg;
-
 qemu_mutex_lock(>s->mutex);
 curl_multi_do_locked(s);
 curl_multi_check_completion(s->s);
-- 
2.17.1




[PATCH 68/97] iotests: Test unaligned blocking mirror write

2019-10-01 Thread Michael Roth
From: Max Reitz 

Signed-off-by: Max Reitz 
Message-id: 20190805113526.20319-1-mre...@redhat.com
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: Max Reitz 
(cherry picked from commit 19ba4651fe2d17cc49adae29acbb4a8cc29db8d1)
Signed-off-by: Michael Roth 
---
 tests/qemu-iotests/151 | 25 +
 tests/qemu-iotests/151.out |  4 ++--
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/tests/qemu-iotests/151 b/tests/qemu-iotests/151
index 1bb74d67c4..ad7359fc8d 100755
--- a/tests/qemu-iotests/151
+++ b/tests/qemu-iotests/151
@@ -114,6 +114,31 @@ class TestActiveMirror(iotests.QMPTestCase):
 def testActiveIOFlushed(self):
 self.doActiveIO(True)
 
+def testUnalignedActiveIO(self):
+# Fill the source image
+result = self.vm.hmp_qemu_io('source', 'write -P 1 0 2M')
+
+# Start the block job (very slowly)
+result = self.vm.qmp('blockdev-mirror',
+ job_id='mirror',
+ filter_node_name='mirror-node',
+ device='source-node',
+ target='target-node',
+ sync='full',
+ copy_mode='write-blocking',
+ buf_size=(1048576 // 4),
+ speed=1)
+self.assert_qmp(result, 'return', {})
+
+# Start an unaligned request to a dirty area
+result = self.vm.hmp_qemu_io('source', 'write -P 2 %i 1' % (1048576 + 
42))
+
+# Let the job finish
+result = self.vm.qmp('block-job-set-speed', device='mirror', speed=0)
+self.assert_qmp(result, 'return', {})
+self.complete_and_wait(drive='mirror')
+
+self.potential_writes_in_flight = False
 
 
 if __name__ == '__main__':
diff --git a/tests/qemu-iotests/151.out b/tests/qemu-iotests/151.out
index fbc63e62f8..8d7e996700 100644
--- a/tests/qemu-iotests/151.out
+++ b/tests/qemu-iotests/151.out
@@ -1,5 +1,5 @@
-..
+...
 --
-Ran 2 tests
+Ran 3 tests
 
 OK
-- 
2.17.1




[PATCH 69/97] block/backup: disable copy_range for compressed backup

2019-10-01 Thread Michael Roth
From: Vladimir Sementsov-Ogievskiy 

Enabled by default copy_range ignores compress option. It's definitely
unexpected for user.

It's broken since introduction of copy_range usage in backup in
9ded4a011496.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Message-id: 20190730163251.755248-3-vsement...@virtuozzo.com
Reviewed-by: John Snow 
Reviewed-by: Max Reitz 
Cc: qemu-sta...@nongnu.org
Signed-off-by: Max Reitz 
(cherry picked from commit 110571be4e70ac015628e76d2731f96dd8d1998c)
Signed-off-by: Michael Roth 
---
 block/backup.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/block/backup.c b/block/backup.c
index f67c208cf0..381659d5ef 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -666,7 +666,7 @@ BlockJob *backup_job_create(const char *job_id, 
BlockDriverState *bs,
 job->cluster_size = cluster_size;
 job->copy_bitmap = copy_bitmap;
 copy_bitmap = NULL;
-job->use_copy_range = true;
+job->use_copy_range = !compress; /* compression isn't supported for it */
 job->copy_range_size = MIN_NON_ZERO(blk_get_max_transfer(job->common.blk),
 blk_get_max_transfer(job->target));
 job->copy_range_size = MAX(job->cluster_size,
-- 
2.17.1




[PATCH 76/97] iotests: add testing shim for script-style python tests

2019-10-01 Thread Michael Roth
From: John Snow 

Because the new-style python tests don't use the iotests.main() test
launcher, we don't turn on the debugger logging for these scripts
when invoked via ./check -d.

Refactor the launcher shim into new and old style shims so that they
share environmental configuration.

Two cleanup notes: debug was not actually used as a global, and there
was no reason to create a class in an inner scope just to achieve
default variables; we can simply create an instance of the runner with
the values we want instead.

Signed-off-by: John Snow 
Reviewed-by: Max Reitz 
Message-id: 20190709232550.10724-14-js...@redhat.com
Signed-off-by: John Snow 
(cherry picked from commit 456a2d5ac7641c7e75c76328a561b528a8607a8e)
*prereq for 1a37e31244/88d2aa533a
Signed-off-by: Michael Roth 
---
 tests/qemu-iotests/iotests.py | 40 +++
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index a7006662ff..5efc21d801 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -61,7 +61,6 @@ cachemode = os.environ.get('CACHEMODE')
 qemu_default_machine = os.environ.get('QEMU_DEFAULT_MACHINE')
 
 socket_scm_helper = os.environ.get('SOCKET_SCM_HELPER', 'socket_scm_helper')
-debug = False
 
 luks_default_secret_object = 'secret,id=keysec0,data=' + \
  os.environ.get('IMGKEYSECRET', '')
@@ -817,11 +816,22 @@ def skip_if_unsupported(required_formats=[], 
read_only=False):
 return func_wrapper
 return skip_test_decorator
 
-def main(supported_fmts=[], supported_oses=['linux'], supported_cache_modes=[],
- unsupported_fmts=[]):
-'''Run tests'''
+def execute_unittest(output, verbosity, debug):
+runner = unittest.TextTestRunner(stream=output, descriptions=True,
+ verbosity=verbosity)
+try:
+# unittest.main() will use sys.exit(); so expect a SystemExit
+# exception
+unittest.main(testRunner=runner)
+finally:
+if not debug:
+sys.stderr.write(re.sub(r'Ran (\d+) tests? in [\d.]+s',
+r'Ran \1 tests', output.getvalue()))
 
-global debug
+def execute_test(test_function=None,
+ supported_fmts=[], supported_oses=['linux'],
+ supported_cache_modes=[], unsupported_fmts=[]):
+"""Run either unittest or script-style tests."""
 
 # We are using TEST_DIR and QEMU_DEFAULT_MACHINE as proxies to
 # indicate that we're not being run via "check". There may be
@@ -853,13 +863,15 @@ def main(supported_fmts=[], supported_oses=['linux'], 
supported_cache_modes=[],
 
 logging.basicConfig(level=(logging.DEBUG if debug else logging.WARN))
 
-class MyTestRunner(unittest.TextTestRunner):
-def __init__(self, stream=output, descriptions=True, 
verbosity=verbosity):
-unittest.TextTestRunner.__init__(self, stream, descriptions, 
verbosity)
+if not test_function:
+execute_unittest(output, verbosity, debug)
+else:
+test_function()
+
+def script_main(test_function, *args, **kwargs):
+"""Run script-style tests outside of the unittest framework"""
+execute_test(test_function, *args, **kwargs)
 
-# unittest.main() will use sys.exit() so expect a SystemExit exception
-try:
-unittest.main(testRunner=MyTestRunner)
-finally:
-if not debug:
-sys.stderr.write(re.sub(r'Ran (\d+) tests? in [\d.]+s', r'Ran \1 
tests', output.getvalue()))
+def main(*args, **kwargs):
+"""Run tests using the unittest framework"""
+execute_test(None, *args, **kwargs)
-- 
2.17.1




[PATCH 80/97] iotests: Restrict nbd Python tests to nbd

2019-10-01 Thread Michael Roth
From: Max Reitz 

We have two Python unittest-style tests that test NBD.  As such, they
should specify supported_protocols=['nbd'] so they are skipped when the
user wants to test some other protocol.

Furthermore, we should restrict their choice of formats to 'raw'.  The
idea of a protocol/format combination is to use some format over some
protocol; but we always use the raw format over NBD.  It does not really
matter what the NBD server uses on its end, and it is not a useful test
of the respective format driver anyway.

Signed-off-by: Max Reitz 
Signed-off-by: Kevin Wolf 
(cherry picked from commit 7c932a1d69a6d6ac5c0b615c11d191da3bbe9aa8)
Signed-off-by: Michael Roth 
---
 tests/qemu-iotests/147 | 5 ++---
 tests/qemu-iotests/205 | 3 ++-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/tests/qemu-iotests/147 b/tests/qemu-iotests/147
index 82513279b0..ce1f5b459d 100755
--- a/tests/qemu-iotests/147
+++ b/tests/qemu-iotests/147
@@ -287,6 +287,5 @@ class BuiltinNBD(NBDBlockdevAddBase):
 
 
 if __name__ == '__main__':
-# Need to support image creation
-iotests.main(supported_fmts=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2',
- 'vmdk', 'raw', 'vhdx', 'qed'])
+iotests.main(supported_fmts=['raw'],
+ supported_protocols=['nbd'])
diff --git a/tests/qemu-iotests/205 b/tests/qemu-iotests/205
index 31b2f5707a..1cf2215730 100755
--- a/tests/qemu-iotests/205
+++ b/tests/qemu-iotests/205
@@ -153,4 +153,5 @@ class TestNbdServerRemove(iotests.QMPTestCase):
 
 
 if __name__ == '__main__':
-iotests.main(supported_fmts=['generic'])
+iotests.main(supported_fmts=['raw'],
+ supported_protocols=['nbd'])
-- 
2.17.1




[PATCH 70/97] Revert "ide/ahci: Check for -ECANCELED in aio callbacks"

2019-10-01 Thread Michael Roth
From: John Snow 

This reverts commit 0d910cfeaf2076b116b4517166d5deb0fea76394.

It's not correct to just ignore an error code in a callback; we need to
handle that error and possible report failure to the guest so that they
don't wait indefinitely for an operation that will now never finish.

This ought to help cases reported by Nutanix where iSCSI returns a
legitimate -ECANCELED for certain operations which should be propagated
normally.

Reported-by: Shaju Abraham 
Signed-off-by: John Snow 
Message-id: 20190729223605.7163-1-js...@redhat.com
Signed-off-by: John Snow 
(cherry picked from commit 8ec41c4265714255d5a138f8b538faf3583dcff6)
Signed-off-by: Michael Roth 
---
 hw/ide/ahci.c |  3 ---
 hw/ide/core.c | 14 --
 2 files changed, 17 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index d700ca973b..bda9583c8b 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1022,9 +1022,6 @@ static void ncq_cb(void *opaque, int ret)
 IDEState *ide_state = _tfs->drive->port.ifs[0];
 
 ncq_tfs->aiocb = NULL;
-if (ret == -ECANCELED) {
-return;
-}
 
 if (ret < 0) {
 bool is_read = ncq_tfs->cmd == READ_FPDMA_QUEUED;
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 6afadf894f..8e1624f7ce 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -722,9 +722,6 @@ static void ide_sector_read_cb(void *opaque, int ret)
 s->pio_aiocb = NULL;
 s->status &= ~BUSY_STAT;
 
-if (ret == -ECANCELED) {
-return;
-}
 if (ret != 0) {
 if (ide_handle_rw_error(s, -ret, IDE_RETRY_PIO |
 IDE_RETRY_READ)) {
@@ -840,10 +837,6 @@ static void ide_dma_cb(void *opaque, int ret)
 uint64_t offset;
 bool stay_active = false;
 
-if (ret == -ECANCELED) {
-return;
-}
-
 if (ret == -EINVAL) {
 ide_dma_error(s);
 return;
@@ -975,10 +968,6 @@ static void ide_sector_write_cb(void *opaque, int ret)
 IDEState *s = opaque;
 int n;
 
-if (ret == -ECANCELED) {
-return;
-}
-
 s->pio_aiocb = NULL;
 s->status &= ~BUSY_STAT;
 
@@ -1058,9 +1047,6 @@ static void ide_flush_cb(void *opaque, int ret)
 
 s->pio_aiocb = NULL;
 
-if (ret == -ECANCELED) {
-return;
-}
 if (ret < 0) {
 /* XXX: What sector number to set here? */
 if (ide_handle_rw_error(s, -ret, IDE_RETRY_FLUSH)) {
-- 
2.17.1




  1   2   3   4   5   6   >