On Fri, Aug 28, 2015 at 05:15:19PM +1000, Gavin Shan wrote:
> This supports RTAS calls "ibm,{open,close}-errinjct" to manupliate
> the token, which is passed to RTAS call "ibm,errinjct" to indicate
> the valid context for error injection. Each VM is permitted to have
> only one token at once and we simply have sequential number for that.
> The token is resetted in ppc_spapr_reset() when rebooting guest. It's
> notable that the least bit of the token is reserved to indicate if the
> token has been opened, meaning the valid token should be always odd.
>
> Signed-off-by: Gavin Shan <[email protected]>Reviewed-by: David Gibson <[email protected]> > --- > hw/ppc/spapr.c | 9 +++++++- > hw/ppc/spapr_rtas.c | 60 > ++++++++++++++++++++++++++++++++++++++++++++++++++ > include/hw/ppc/spapr.h | 9 +++++++- > 3 files changed, 76 insertions(+), 2 deletions(-) > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c > index 06d000d..6ac0012 100644 > --- a/hw/ppc/spapr.c > +++ b/hw/ppc/spapr.c > @@ -1064,6 +1064,9 @@ static void ppc_spapr_reset(void) > > qemu_devices_reset(); > > + /* Reset error injection token */ > + spapr->errinjct_token = 0; > + > /* > * We place the device tree and RTAS just below either the top of the > RMA, > * or just below 2GB, whichever is lowere, so that it can be > @@ -1191,7 +1194,7 @@ static bool version_before_3(void *opaque, int > version_id) > > static const VMStateDescription vmstate_spapr = { > .name = "spapr", > - .version_id = 3, > + .version_id = 4, > .minimum_version_id = 1, > .post_load = spapr_post_load, > .fields = (VMStateField[]) { > @@ -1202,6 +1205,10 @@ static const VMStateDescription vmstate_spapr = { > VMSTATE_UINT64_TEST(rtc_offset, sPAPRMachineState, version_before_3), > > VMSTATE_PPC_TIMEBASE_V(tb, sPAPRMachineState, 2), > + > + /* Error injection token */ > + VMSTATE_UINT32_V(errinjct_token, sPAPRMachineState, 4), > + > VMSTATE_END_OF_LIST() > }, > }; > diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c > index e99e25f..64924c6 100644 > --- a/hw/ppc/spapr_rtas.c > +++ b/hw/ppc/spapr_rtas.c > @@ -604,6 +604,62 @@ out: > rtas_st(rets, 0, rc); > } > > +static void rtas_ibm_open_errinjct(PowerPCCPU *cpu, > + sPAPRMachineState *spapr, > + uint32_t token, uint32_t nargs, > + target_ulong args, uint32_t nret, > + target_ulong rets) > +{ > + int32_t ret; > + > + /* Sanity check on number of arguments */ > + if (nargs != 0 || nret != 2) { > + ret = RTAS_OUT_PARAM_ERROR; > + goto out; > + } > + > + /* Check if we already had token */ > + if (spapr->errinjct_token & 1) { > + ret = RTAS_OUT_TOKEN_OPENED; > + goto out; > + } > + > + /* Grab the token */ > + rtas_st(rets, 0, ++spapr->errinjct_token); > + ret = RTAS_OUT_SUCCESS; > +out: > + rtas_st(rets, 1, ret); > +} > + > +static void rtas_ibm_close_errinjct(PowerPCCPU *cpu, > + sPAPRMachineState *spapr, > + uint32_t token, uint32_t nargs, > + target_ulong args, uint32_t nret, > + target_ulong rets) > +{ > + uint32_t open_token; > + int32_t ret; > + > + /* Sanity check on number of arguments */ > + if (nargs != 1 || nret != 1) { > + ret = RTAS_OUT_PARAM_ERROR; > + goto out; > + } > + > + /* Match with the passed token */ > + open_token = rtas_ld(args, 0); > + if (!(spapr->errinjct_token & 1) || > + spapr->errinjct_token != open_token) { > + ret = RTAS_OUT_CLOSE_ERROR; > + goto out; > + } > + > + spapr->errinjct_token++; > + ret = RTAS_OUT_SUCCESS; > +out: > + rtas_st(rets, 0, ret); > +} > + > static struct rtas_call { > const char *name; > spapr_rtas_fn fn; > @@ -754,6 +810,10 @@ static void core_rtas_register_types(void) > rtas_get_sensor_state); > spapr_rtas_register(RTAS_IBM_CONFIGURE_CONNECTOR, > "ibm,configure-connector", > rtas_ibm_configure_connector); > + spapr_rtas_register(RTAS_IBM_OPEN_ERRINJCT, "ibm,open-errinjct", > + rtas_ibm_open_errinjct); > + spapr_rtas_register(RTAS_IBM_CLOSE_ERRINJCT, "ibm,close-errinjct", > + rtas_ibm_close_errinjct); > } > > type_init(core_rtas_register_types) > diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h > index c75cc5e..7931e18 100644 > --- a/include/hw/ppc/spapr.h > +++ b/include/hw/ppc/spapr.h > @@ -73,6 +73,9 @@ struct sPAPRMachineState { > int htab_fd; > bool htab_fd_stale; > > + /* Error injection token */ > + uint32_t errinjct_token; > + > /* RTAS state */ > QTAILQ_HEAD(, sPAPRConfigureConnectorState) ccs_list; > > @@ -412,6 +415,8 @@ int spapr_allocate_irq_block(int num, bool lsi, bool msi); > #define RTAS_OUT_BUSY -2 > #define RTAS_OUT_PARAM_ERROR -3 > #define RTAS_OUT_NOT_SUPPORTED -3 > +#define RTAS_OUT_TOKEN_OPENED -4 > +#define RTAS_OUT_CLOSE_ERROR -4 > #define RTAS_OUT_NOT_AUTHORIZED -9002 > > /* RTAS tokens */ > @@ -455,8 +460,10 @@ int spapr_allocate_irq_block(int num, bool lsi, bool > msi); > #define RTAS_IBM_SET_SLOT_RESET (RTAS_TOKEN_BASE + 0x23) > #define RTAS_IBM_CONFIGURE_PE (RTAS_TOKEN_BASE + 0x24) > #define RTAS_IBM_SLOT_ERROR_DETAIL (RTAS_TOKEN_BASE + 0x25) > +#define RTAS_IBM_OPEN_ERRINJCT (RTAS_TOKEN_BASE + 0x26) > +#define RTAS_IBM_CLOSE_ERRINJCT (RTAS_TOKEN_BASE + 0x27) > > -#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x26) > +#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x28) > > /* RTAS ibm,get-system-parameter token values */ > #define RTAS_SYSPARM_SPLPAR_CHARACTERISTICS 20 -- 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
pgpTK5wgyE_T3.pgp
Description: PGP signature
