[Skiboot] [PATCH skiboot v2] npu2: Add XTS_BDF_MAP wildcard refcount

Reza Arbab arbab at linux.ibm.com
Wed Nov 21 07:18:32 AEDT 2018


On Tue, Nov 13, 2018 at 07:16:02PM +1100, Alexey Kardashevskiy wrote: 
>@@ -2097,6 +2096,11 @@ static int64_t opal_npu_init_context(uint64_t phb_id, int pasid __unused,
> 	}
>
> 	id = GETFIELD(NPU2_XTS_BDF_MAP_LPARSHORT, xts_bdf);
>+	if (id >= NPU2_XTS_BDF_MAP_SIZE) {
>+		NPU2ERR(p, "Out of bounds id=%d\n", id);
>+		id = OPAL_INTERNAL_ERROR;
>+		goto out;
>+	}
> 	NPU2DBG(p, "Found LPARSHORT = 0x%x for BDF = 0x%03llx\n", id, bdf);
>
> 	/* Enable this mapping for both real and virtual addresses */

It doesn't hurt to check, I guess, but I'm not sure how/if it's possible 
for this to happen.

>@@ -2129,14 +2133,20 @@ static int64_t opal_npu_init_context(uint64_t phb_id, int pasid __unused,
> 		    GETFIELD(NPU2_XTS_PID_MAP_MSR, xts_bdf_pid)) {
> 			NPU2ERR(p, "%s: Unexpected MSR value\n", __func__);
> 			id = OPAL_PARAMETER;
>+			goto out;
>+		} else if (!p->ctx_ref[id]) {
>+			NPU2ERR(p, "%s: Unexpected mapping\n", __func__);
>+			id = OPAL_INTERNAL_ERROR;
>+			goto out;

Same.

> 		}
>-
>-		goto out;
> 	}
>
> 	/* Write the entry */
>-	NPU2DBG(p, "XTS_PID_MAP[%03d] = 0x%08llx\n", id, xts_bdf_pid);
>-	npu2_write(p, NPU2_XTS_PID_MAP + id*0x20, xts_bdf_pid);
>+	if (!p->ctx_ref[id]) {
>+		NPU2DBG(p, "XTS_PID_MAP[%03d] = 0x%08llx\n", id, xts_bdf_pid);
>+		npu2_write(p, NPU2_XTS_PID_MAP + id*0x20, xts_bdf_pid);
>+	}
>+	++p->ctx_ref[id];
>
> 	if (!GETFIELD(NPU2_XTS_BDF_MAP_VALID, xts_bdf)) {
> 		xts_bdf = SETFIELD(NPU2_XTS_BDF_MAP_VALID, xts_bdf, 1);
>@@ -2155,7 +2165,7 @@ static int opal_npu_destroy_context(uint64_t phb_id, uint64_t pid __unused,
> 	struct phb *phb = pci_get_phb(phb_id);
> 	struct npu2 *p;
> 	uint64_t xts_bdf;
>-	int rc = 0;
>+	int rc = 0, id;
>
> 	if (!phb || phb->phb_type != phb_type_npu_v2)
> 		return OPAL_PARAMETER;
>@@ -2172,10 +2182,24 @@ static int opal_npu_destroy_context(uint64_t phb_id, uint64_t pid __unused,
> 	}
>
> 	/*
>-	 * The bdf/pid table only contains wildcard entries, so we don't
>-	 * need to remove anything here.
>+	 * The bdf/pid table contains wildcard entries and MSR bits which
>+	 * we need to clear between switching a device from a host to a guest
>+	 * or vice versa.
> 	 */
>-
>+	id = GETFIELD(NPU2_XTS_BDF_MAP_LPARSHORT, xts_bdf);
>+	if (id >= NPU2_XTS_BDF_MAP_SIZE) {
>+		NPU2ERR(p, "Out of bounds id=%d\n", id);
>+		rc = OPAL_INTERNAL_ERROR;

Same.

>+	} else {
>+		--p->ctx_ref[id];
>+		rc = p->ctx_ref[id]; /* For debug */
>+		if (p->ctx_ref[id] < 0) {
>+			rc = OPAL_INTERNAL_ERROR; /* Sanity check */

If somebody (for whatever reason) calls opal_npu_destroy_context() 
repeatedly for an already-destroyed ID, you don't want the refcount to 
go more and more negative.

I think instead of checking if it is negative afterwards, maybe check to 
see if it is zero before, and return OPAL_PARAMETER.

>+		} else if (!p->ctx_ref[id]) {
>+			NPU2DBG(p, "XTS_PID_MAP[%03d] = 0 (destroy)\n", id);
>+			npu2_write(p, NPU2_XTS_PID_MAP + id*0x20, 0);
>+		}
>+	}
> 	unlock(&p->lock);
> 	return rc;
> }


-- 
Reza Arbab



More information about the Skiboot mailing list