summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuma copybara merger <zuma-automerger@google.com>2023-07-02 08:21:03 +0000
committerCopybara-Service <copybara-worker@google.com>2023-07-05 22:13:07 -0700
commitfb9aca91f2b733ed0d6231aec22bedc4ae9da6b4 (patch)
treeffbefde58113e03de7c594d4b619c66503360c25
parent8b9e35adca98df7cf86c2295a1a2e383bb4de502 (diff)
downloadrio-fb9aca91f2b733ed0d6231aec22bedc4ae9da6b4.tar.gz
[Copybara Auto Merge] Merge branch zuma into android14-gs-pixel-5.15-udc-d1
edgetpu: explicitly disable ctx on domain detach Tested: Astress + RGE FacenetMobile8BitV1 for 3 hours Bug: 277256378 (cherry picked from commit b548c3968987bb58a2b77ac87f9c7d201687e2bb) gcip: Always use irqsave for ACQUIRE_WAIT_LIST_LOCK In order to prevent deadlock causing by interrupt, always use irqsave when acquiring wait list lock. Bug: 288023845 Test: sh run.sh --chip rio --syz-reproduce Signed-off-by: Zuma copybara merger <zuma-automerger@google.com> GitOrigin-RevId: 4befbbeb309a41f80c02a3c49f494f2180138f5a Change-Id: Id012a56933c892a1e1964e61d6361819c4bfe1a8
-rw-r--r--drivers/edgetpu/edgetpu-google-iommu.c9
-rw-r--r--drivers/edgetpu/edgetpu-soc.h6
-rw-r--r--drivers/edgetpu/gcip-kernel-driver/drivers/gcip/gcip-mailbox.c5
-rw-r--r--drivers/edgetpu/mobile-soc-gsx01.c51
4 files changed, 54 insertions, 17 deletions
diff --git a/drivers/edgetpu/edgetpu-google-iommu.c b/drivers/edgetpu/edgetpu-google-iommu.c
index 1bc4a4e..4bf836f 100644
--- a/drivers/edgetpu/edgetpu-google-iommu.c
+++ b/drivers/edgetpu/edgetpu-google-iommu.c
@@ -19,6 +19,7 @@
#include "edgetpu-internal.h"
#include "edgetpu-mapping.h"
#include "edgetpu-mmu.h"
+#include "edgetpu-soc.h"
#if !defined(EDGETPU_NUM_PREALLOCATED_DOMAINS)
#define EDGETPU_NUM_PREALLOCATED_DOMAINS 0
@@ -553,6 +554,8 @@ int edgetpu_mmu_attach_domain(struct edgetpu_dev *etdev,
ret = -EBUSY;
goto err_detach;
}
+
+ edgetpu_soc_activate_context(etdev, pasid);
etiommu->gdomains[pasid] = gdomain;
etdomain->pasid = pasid;
return 0;
@@ -571,6 +574,12 @@ void edgetpu_mmu_detach_domain(struct edgetpu_dev *etdev,
return;
if (pasid <= 0 || pasid >= EDGETPU_NCONTEXTS)
return;
+
+ /*
+ * Deactivate the context before domain detaching to prevent speculative accesses from being
+ * issued to a disabled context.
+ */
+ edgetpu_soc_deactivate_context(etdev, pasid);
etiommu->gdomains[pasid] = NULL;
etdomain->pasid = IOMMU_PASID_INVALID;
iommu_aux_detach_device(etdomain->gdomain->domain, etdev->dev);
diff --git a/drivers/edgetpu/edgetpu-soc.h b/drivers/edgetpu/edgetpu-soc.h
index 1318726..c02c233 100644
--- a/drivers/edgetpu/edgetpu-soc.h
+++ b/drivers/edgetpu/edgetpu-soc.h
@@ -54,4 +54,10 @@ void edgetpu_soc_thermal_init(struct edgetpu_dev *etdev);
/* De-init thermal subsystem SoC specifics for TPU */
void edgetpu_soc_thermal_exit(struct edgetpu_dev *etdev);
+/* Activates the context of @pasid. */
+int edgetpu_soc_activate_context(struct edgetpu_dev *etdev, int pasid);
+
+/* Deactivates the context of @pasid. */
+void edgetpu_soc_deactivate_context(struct edgetpu_dev *etdev, int pasid);
+
#endif /* __EDGETPU_SOC_H__ */
diff --git a/drivers/edgetpu/gcip-kernel-driver/drivers/gcip/gcip-mailbox.c b/drivers/edgetpu/gcip-kernel-driver/drivers/gcip/gcip-mailbox.c
index afa67c8..cdc76b0 100644
--- a/drivers/edgetpu/gcip-kernel-driver/drivers/gcip/gcip-mailbox.c
+++ b/drivers/edgetpu/gcip-kernel-driver/drivers/gcip/gcip-mailbox.c
@@ -457,6 +457,7 @@ static void gcip_mailbox_flush_awaiter(struct gcip_mailbox *mailbox)
struct gcip_mailbox_wait_list_elem *cur, *nxt;
struct gcip_mailbox_resp_awaiter *awaiter;
struct list_head resps_to_flush;
+ unsigned long flags;
/* If mailbox->ops is NULL, the mailbox is already released. */
if (!mailbox->ops)
@@ -469,7 +470,7 @@ static void gcip_mailbox_flush_awaiter(struct gcip_mailbox *mailbox)
* handled already.
*/
INIT_LIST_HEAD(&resps_to_flush);
- ACQUIRE_WAIT_LIST_LOCK(false, NULL);
+ ACQUIRE_WAIT_LIST_LOCK(true, &flags);
list_for_each_entry_safe (cur, nxt, &mailbox->wait_list, list) {
list_del(&cur->list);
if (cur->awaiter) {
@@ -490,7 +491,7 @@ static void gcip_mailbox_flush_awaiter(struct gcip_mailbox *mailbox)
kfree(cur);
}
}
- RELEASE_WAIT_LIST_LOCK(false, 0);
+ RELEASE_WAIT_LIST_LOCK(true, flags);
/*
* Cancel the timeout timer of and free any responses that were still in
diff --git a/drivers/edgetpu/mobile-soc-gsx01.c b/drivers/edgetpu/mobile-soc-gsx01.c
index d247c06..62fdb03 100644
--- a/drivers/edgetpu/mobile-soc-gsx01.c
+++ b/drivers/edgetpu/mobile-soc-gsx01.c
@@ -60,8 +60,6 @@
#define SSMT_NS_READ_STREAM_VID_REG(base, n) ((base) + SSMT_NS_READ_STREAM_VID_OFFSET(n))
#define SSMT_NS_WRITE_STREAM_VID_REG(base, n) ((base) + SSMT_NS_WRITE_STREAM_VID_OFFSET(n))
-#define SSMT_BYPASS (1 << 31)
-
#define PLL_CON3_OFFSET 0x10c
#define PLL_DIV_M_POS 16
#define PLL_DIV_M_WIDTH 10
@@ -153,27 +151,28 @@ int edgetpu_soc_init(struct edgetpu_dev *etdev)
return 0;
}
-static void gsx01_setup_ssmt(struct edgetpu_dev *etdev)
+/* Caller ensures vid < EDGETPU_MAX_STREAM_ID. */
+static void set_ssmt_vid(struct edgetpu_dev *etdev, uint vid, uint val)
{
struct edgetpu_soc_data *soc_data = etdev->soc_data;
- int i, j;
-
- for (i = 0; i < soc_data->num_ssmts; i++)
- if (!soc_data->ssmt_base[i])
- return;
+ int i;
for (i = 0; i < soc_data->num_ssmts; i++) {
- etdev_dbg(etdev, "Setting up SSMT_D%d to feed-through mode\n", i);
-
- for (j = 0; j < EDGETPU_MAX_STREAM_ID; j++) {
- writel(SSMT_BYPASS,
- SSMT_NS_READ_STREAM_VID_REG(soc_data->ssmt_base[i], j));
- writel(SSMT_BYPASS,
- SSMT_NS_WRITE_STREAM_VID_REG(soc_data->ssmt_base[i], j));
+ if (soc_data->ssmt_base[i]) {
+ writel(val, SSMT_NS_READ_STREAM_VID_REG(soc_data->ssmt_base[i], vid));
+ writel(val, SSMT_NS_WRITE_STREAM_VID_REG(soc_data->ssmt_base[i], vid));
}
}
}
+static void gsx01_setup_ssmt(struct edgetpu_dev *etdev)
+{
+ int i;
+
+ for (i = 0; i < EDGETPU_MAX_STREAM_ID; i++)
+ set_ssmt_vid(etdev, i, 0);
+}
+
int edgetpu_soc_prepare_firmware(struct edgetpu_dev *etdev)
{
gsx01_setup_ssmt(etdev);
@@ -611,3 +610,25 @@ void edgetpu_soc_thermal_exit(struct edgetpu_dev *etdev)
if (etdev->soc_data->bcl_dev)
exynos_pm_qos_remove_notifier(PM_QOS_TPU_FREQ_MAX, nb);
}
+
+int edgetpu_soc_activate_context(struct edgetpu_dev *etdev, int pasid)
+{
+ const uint vid = pasid;
+
+ if (vid >= EDGETPU_MAX_STREAM_ID)
+ return -EINVAL;
+
+ set_ssmt_vid(etdev, vid, vid);
+
+ return 0;
+}
+
+void edgetpu_soc_deactivate_context(struct edgetpu_dev *etdev, int pasid)
+{
+ const uint vid = pasid;
+
+ if (vid >= EDGETPU_MAX_STREAM_ID)
+ return;
+
+ set_ssmt_vid(etdev, vid, 0);
+}