aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/ppc/spapr_drc.c21
-rw-r--r--include/hw/ppc/spapr.h1
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 */