aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Kardashevskiy <aik@ozlabs.ru>2018-12-04 15:41:55 +1100
committerStewart Smith <stewart@linux.ibm.com>2019-02-25 23:04:20 -0600
commitba1d95a1d460e0241d21561194c4cd06e518f329 (patch)
treee2eb8d60c289bc044e873a16aec392697798e71c
parentb821f8c2a8e38c18b0dd976b15f699d243a6099f (diff)
downloadskiboot-ba1d95a1d460e0241d21561194c4cd06e518f329.zip
skiboot-ba1d95a1d460e0241d21561194c4cd06e518f329.tar.gz
skiboot-ba1d95a1d460e0241d21561194c4cd06e518f329.tar.bz2
npu2: Add XTS_BDF_MAP wildcard refcount
Currently PID wildcard is programmed into the NPU once and never cleared up. This works for the bare metal as MSR does not change while the host OS is running. However with the device virtualization, we need to keep track of wildcard entries use and clear them up before switching a GPU from a host to a guest or vice versa. This adds refcount to a NPU2, one counter per wildcard entry. The index is a short lparid (4 bits long) which is allocated in opal_npu_map_lpar() and should be smaller than NPU2_XTS_BDF_MAP_SIZE (defined as 16). Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Acked-by: Reza Arbab <arbab@linux.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
-rw-r--r--hw/npu2.c46
-rw-r--r--include/npu2.h2
2 files changed, 32 insertions, 16 deletions
diff --git a/hw/npu2.c b/hw/npu2.c
index 0a7b157..488f85d 100644
--- a/hw/npu2.c
+++ b/hw/npu2.c
@@ -28,7 +28,6 @@
#include <ccan/str/str.h>
#include <ccan/array_size/array_size.h>
#include <affinity.h>
-#include <npu2-regs.h>
#include <npu2.h>
#include <lock.h>
#include <xscom.h>
@@ -2144,19 +2143,25 @@ 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;
}
-
- 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);
- if (!GETFIELD(NPU2_XTS_BDF_MAP_VALID, xts_bdf)) {
- xts_bdf = SETFIELD(NPU2_XTS_BDF_MAP_VALID, xts_bdf, 1);
- npu2_write(p, NPU2_XTS_BDF_MAP + id*8, xts_bdf);
+ if (!GETFIELD(NPU2_XTS_BDF_MAP_VALID, xts_bdf)) {
+ xts_bdf = SETFIELD(NPU2_XTS_BDF_MAP_VALID, xts_bdf, 1);
+ npu2_write(p, NPU2_XTS_BDF_MAP + id*8, xts_bdf);
+ }
}
+ ++p->ctx_ref[id];
out:
unlock(&p->lock);
@@ -2170,7 +2175,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 = OPAL_PARAMETER, id;
if (!phb || phb->phb_type != phb_type_npu_v2)
return OPAL_PARAMETER;
@@ -2183,14 +2188,23 @@ static int opal_npu_destroy_context(uint64_t phb_id, uint64_t pid __unused,
if (npu_table_search(p, NPU2_XTS_BDF_MAP, 8, NPU2_XTS_BDF_MAP_SIZE,
&xts_bdf, NPU2_XTS_BDF_MAP_BDF) < 0) {
NPU2ERR(p, "LPARID not associated with any GPU\n");
- rc = OPAL_PARAMETER;
+ } else {
+ /*
+ * 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 (p->ctx_ref[id]) {
+ --p->ctx_ref[id];
+ 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);
+ }
+ rc = OPAL_SUCCESS;
+ }
}
-
- /*
- * The bdf/pid table only contains wildcard entries, so we don't
- * need to remove anything here.
- */
-
unlock(&p->lock);
return rc;
}
diff --git a/include/npu2.h b/include/npu2.h
index 0e79e0e..cfa3b1f 100644
--- a/include/npu2.h
+++ b/include/npu2.h
@@ -19,6 +19,7 @@
#include <pci.h>
#include <phys-map.h>
+#include <npu2-regs.h>
/* Debugging options */
#define NPU2DBG(p, fmt, a...) prlog(PR_DEBUG, "NPU%d: " fmt, \
@@ -158,6 +159,7 @@ struct npu2 {
uint32_t total_devices;
struct npu2_dev *devices;
enum phys_map_type gpu_map_type;
+ int ctx_ref[NPU2_XTS_BDF_MAP_SIZE];
/* IODA cache */
uint64_t tve_cache[16];