diff options
author | Zuma copybara merger <zuma-automerger@google.com> | 2023-07-02 08:21:03 +0000 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2023-07-05 22:13:07 -0700 |
commit | fb9aca91f2b733ed0d6231aec22bedc4ae9da6b4 (patch) | |
tree | ffbefde58113e03de7c594d4b619c66503360c25 | |
parent | 8b9e35adca98df7cf86c2295a1a2e383bb4de502 (diff) | |
download | rio-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.c | 9 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-soc.h | 6 | ||||
-rw-r--r-- | drivers/edgetpu/gcip-kernel-driver/drivers/gcip/gcip-mailbox.c | 5 | ||||
-rw-r--r-- | drivers/edgetpu/mobile-soc-gsx01.c | 51 |
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); +} |