diff options
-rw-r--r-- | hw/ppc/spapr_drc.c | 21 | ||||
-rw-r--r-- | include/hw/ppc/spapr.h | 1 |
2 files changed, 22 insertions, 0 deletions
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 9ce844ab1e..faf8760d2e 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -66,6 +66,16 @@ static int set_isolation_state(sPAPRDRConnector *drc, DPRINTFN("drc: %x, set_isolation_state: %x", get_index(drc), state); + if (state == SPAPR_DR_ISOLATION_STATE_UNISOLATED) { + /* cannot unisolate a non-existant resource, and, or resources + * which are in an 'UNUSABLE' allocation state. (PAPR 2.7, 13.5.3.5) + */ + if (!drc->dev || + drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) { + return RTAS_OUT_NO_SUCH_INDICATOR; + } + } + drc->isolation_state = state; if (drc->isolation_state == SPAPR_DR_ISOLATION_STATE_ISOLATED) { @@ -107,6 +117,17 @@ static int set_allocation_state(sPAPRDRConnector *drc, DPRINTFN("drc: %x, set_allocation_state: %x", get_index(drc), state); + if (state == SPAPR_DR_ALLOCATION_STATE_USABLE) { + /* if there's no resource/device associated with the DRC, there's + * no way for us to put it in an allocation state consistent with + * being 'USABLE'. PAPR 2.7, 13.5.3.4 documents that this should + * result in an RTAS return code of -3 / "no such indicator" + */ + if (!drc->dev) { + return RTAS_OUT_NO_SUCH_INDICATOR; + } + } + if (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI) { drc->allocation_state = state; if (drc->awaiting_release && diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index cbe3463e32..8a0a74d5d9 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -409,6 +409,7 @@ 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_NO_SUCH_INDICATOR -3 #define RTAS_OUT_NOT_AUTHORIZED -9002 /* RTAS tokens */ |