diff options
author | Alexey Kardashevskiy <aik@ozlabs.ru> | 2019-05-23 14:22:02 +1000 |
---|---|---|
committer | Vasant Hegde <hegdevasant@linux.vnet.ibm.com> | 2019-06-08 16:12:05 +0530 |
commit | 2975e373127efcc948f3ac2f23be392a7d9d3065 (patch) | |
tree | 8b902cfd9c716296e6aa83dfeb00570daa7ef54a | |
parent | 944f242d5ceb9b59b338f6d62141e593ac7e6fd7 (diff) | |
download | skiboot-2975e373127efcc948f3ac2f23be392a7d9d3065.zip skiboot-2975e373127efcc948f3ac2f23be392a7d9d3065.tar.gz skiboot-2975e373127efcc948f3ac2f23be392a7d9d3065.tar.bz2 |
npu2: Reset PID wildcard and refcounter when mapped to LPID
[ Upstream commit 7c977c734e1c4d3be9a036a075798530d352d8e3 ]
Since 105d80f85b "npu2: Use unfiltered mode in XTS tables" we do not
register every PID in the XTS table so the table has one entry per LPID.
Then we added a reference counter to keep track of the entry use when
switching GPU between the host and guest systems (the "Fixes:" tag below).
The POWERNV platform setup creates such entries and references them
at the boot time when initializing IOMMUs and only removes it when
a GPU is passed through to a guest. This creates a problem as POWERNV
boots via kexec and no defererencing happens; the XTS table state remains
undefined. So when the host kernel boots, skiboot thinks there are valid
XTS entries and does not update the XTS table which breaks ATS.
This adds the reference counter and the XTS entry reset when a GPU is
assigned to LPID and we cannot rely on the kernel to clean that up.
Fixes: ba1d95a1d460 ("npu2: Add XTS_BDF_MAP wildcard refcount")
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Tested-by: Reza Arbab <arbab@linux.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
-rw-r--r-- | hw/npu2.c | 7 |
1 files changed, 7 insertions, 0 deletions
@@ -2233,6 +2233,13 @@ static int opal_npu_map_lpar(uint64_t phb_id, uint64_t bdf, uint64_t lparid, NPU2DBG(p, "XTS_BDF_MAP[%03d] = 0x%08llx\n", id, xts_bdf_lpar); npu2_write(p, NPU2_XTS_BDF_MAP + id*8, xts_bdf_lpar); + /* Reset wildcard in the PID map and the refcounter */ + if (npu2_read(p, NPU2_XTS_PID_MAP + id*0x20) || p->ctx_ref[id]) { + prlog(PR_INFO, "Resetting PID MAP for LPID %lld\n", lparid); + p->ctx_ref[id] = 0; + npu2_write(p, NPU2_XTS_PID_MAP + id*0x20, 0); + } + out: unlock(&p->lock); return rc; |