qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 2/3] xics/spapr: Register RTAS/hypercalls once a


From: David Gibson
Subject: Re: [Qemu-devel] [PATCH 2/3] xics/spapr: Register RTAS/hypercalls once at machine init
Date: Fri, 14 Jun 2019 11:38:27 +1000
User-agent: Mutt/1.11.4 (2019-03-13)

On Thu, Jun 13, 2019 at 06:44:59PM +0200, Greg Kurz wrote:
> QEMU may crash when running a spapr machine in 'dual' interrupt controller
> mode on some older (but not that old, eg. ubuntu 18.04.2) KVMs with partial
> XIVE support:
> 
> qemu-system-ppc64: hw/ppc/spapr_rtas.c:411: spapr_rtas_register:
>  Assertion `!name || !rtas_table[token].name' failed.
> 
> XICS is controlled by the guest thanks to a set of RTAS calls. Depending
> on whether KVM XICS is used or not, the RTAS calls are handled by KVM or
> QEMU. In both cases, QEMU needs to expose the RTAS calls to the guest
> through the "rtas" node of the device tree.
> 
> The spapr_rtas_register() helper takes care of all of that: it adds the
> RTAS call token to the "rtas" node and registers a QEMU callback to be
> invoked when the guest issues the RTAS call. In the KVM XICS case, QEMU
> registers a dummy callback that just prints an error since it isn't
> supposed to be invoked, ever.
> 
> Historically, the XICS controller was setup during machine init and
> released during final teardown. This changed when the 'dual' interrupt
> controller mode was added to the spapr machine: in this case we need
> to tear the XICS down and set it up again during machine reset. The
> crash happens because we indeed have an incompatibility with older
> KVMs that forces QEMU to fallback on emulated XICS, which tries to
> re-registers the same RTAS calls.
> 
> This could be fixed by adding proper rollback that would unregister
> RTAS calls on error. But since the emulated RTAS calls in QEMU can
> now detect when they are mistakenly called while KVM XICS is in
> use, it seems simpler to register them once and for all at machine
> init. This fixes the crash and allows to remove some now useless
> lines of code.
> 
> Signed-off-by: Greg Kurz <address@hidden>

Applied, thanks.

> ---
>  hw/intc/xics_kvm.c          |   19 -------------------
>  hw/intc/xics_spapr.c        |    8 --------
>  hw/ppc/spapr_irq.c          |    3 ++-
>  include/hw/ppc/spapr.h      |    4 ----
>  include/hw/ppc/xics.h       |    1 -
>  include/hw/ppc/xics_spapr.h |    1 +
>  6 files changed, 3 insertions(+), 33 deletions(-)
> 
> diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
> index 5ba5b775615e..5c4208f43008 100644
> --- a/hw/intc/xics_kvm.c
> +++ b/hw/intc/xics_kvm.c
> @@ -331,15 +331,6 @@ void ics_kvm_set_irq(ICSState *ics, int srcno, int val)
>      }
>  }
>  
> -static void rtas_dummy(PowerPCCPU *cpu, SpaprMachineState *spapr,
> -                       uint32_t token,
> -                       uint32_t nargs, target_ulong args,
> -                       uint32_t nret, target_ulong rets)
> -{
> -    error_report("pseries: %s must never be called for in-kernel XICS",
> -                 __func__);
> -}
> -
>  int xics_kvm_init(SpaprMachineState *spapr, Error **errp)
>  {
>      int rc;
> @@ -360,11 +351,6 @@ int xics_kvm_init(SpaprMachineState *spapr, Error **errp)
>          goto fail;
>      }
>  
> -    spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_dummy);
> -    spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_dummy);
> -    spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_dummy);
> -    spapr_rtas_register(RTAS_IBM_INT_ON, "ibm,int-on", rtas_dummy);
> -
>      rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_SET_XIVE, "ibm,set-xive");
>      if (rc < 0) {
>          error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,set-xive");
> @@ -454,11 +440,6 @@ void xics_kvm_disconnect(SpaprMachineState *spapr, Error 
> **errp)
>      close(kernel_xics_fd);
>      kernel_xics_fd = -1;
>  
> -    spapr_rtas_unregister(RTAS_IBM_SET_XIVE);
> -    spapr_rtas_unregister(RTAS_IBM_GET_XIVE);
> -    spapr_rtas_unregister(RTAS_IBM_INT_OFF);
> -    spapr_rtas_unregister(RTAS_IBM_INT_ON);
> -
>      kvmppc_define_rtas_kernel_token(0, "ibm,set-xive");
>      kvmppc_define_rtas_kernel_token(0, "ibm,get-xive");
>      kvmppc_define_rtas_kernel_token(0, "ibm,int-on");
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index d470ab5f7a2a..8d605b68a7a0 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -285,14 +285,6 @@ static void rtas_int_on(PowerPCCPU *cpu, 
> SpaprMachineState *spapr,
>  
>  void xics_spapr_init(SpaprMachineState *spapr)
>  {
> -    /* Emulated mode can only be initialized once. */
> -    if (spapr->ics->init) {
> -        return;
> -    }
> -
> -    spapr->ics->init = true;
> -
> -    /* Registration of global state belongs into realize */
>      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);
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 3156daf09381..dfb99f35ea00 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -114,6 +114,8 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, 
> int nr_irqs,
>      }
>  
>      spapr->ics = ICS_BASE(obj);
> +
> +    xics_spapr_init(spapr);
>  }
>  
>  #define ICS_IRQ_FREE(ics, srcno)   \
> @@ -236,7 +238,6 @@ static const char 
> *spapr_irq_get_nodename_xics(SpaprMachineState *spapr)
>  
>  static void spapr_irq_init_emu_xics(SpaprMachineState *spapr, Error **errp)
>  {
> -    xics_spapr_init(spapr);
>  }
>  
>  static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index 4f5becf1f3cc..60553d32c4fa 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -676,10 +676,6 @@ typedef void (*spapr_rtas_fn)(PowerPCCPU *cpu, 
> SpaprMachineState *sm,
>                                uint32_t nargs, target_ulong args,
>                                uint32_t nret, target_ulong rets);
>  void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn);
> -static inline void spapr_rtas_unregister(int token)
> -{
> -    spapr_rtas_register(token, NULL, NULL);
> -}
>  target_ulong spapr_rtas_call(PowerPCCPU *cpu, SpaprMachineState *sm,
>                               uint32_t token, uint32_t nargs, target_ulong 
> args,
>                               uint32_t nret, target_ulong rets);
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index d6f8e4c4c282..eb65ad7e43b7 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -119,7 +119,6 @@ struct ICSState {
>      uint32_t offset;
>      ICSIRQState *irqs;
>      XICSFabric *xics;
> -    bool init; /* sPAPR ICS device initialized */
>  };
>  
>  #define ICS_PROP_XICS "xics"
> diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
> index 2476b540edfa..6c1d9ee55945 100644
> --- a/include/hw/ppc/xics_spapr.h
> +++ b/include/hw/ppc/xics_spapr.h
> @@ -36,5 +36,6 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t 
> nr_servers, void *fdt,
>  int xics_kvm_init(SpaprMachineState *spapr, Error **errp);
>  void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
>  void xics_spapr_init(SpaprMachineState *spapr);
> +void xics_spapr_connect(SpaprMachineState *spapr);
>  
>  #endif /* XICS_SPAPR_H */
> 

-- 
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

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]