diff options
author | Aurora pro automerger <aurora-pro-automerger@google.com> | 2022-08-30 17:43:48 +0000 |
---|---|---|
committer | John Scheible <johnscheible@google.com> | 2022-09-07 17:20:42 +0000 |
commit | 33208ffbc5e55846af03bcf708d7c91ed2934e4a (patch) | |
tree | 22da1d4a2504281ea7a7b3abcba8f9e3e3b08ac8 | |
parent | 261baf5aa92fe1fb8a0a30d7e971117ed5b36de9 (diff) | |
download | gs201-33208ffbc5e55846af03bcf708d7c91ed2934e4a.tar.gz |
[Copybara Auto Merge]
gxp: Protect telemetry status in vd start/stop
Bug: 234674375
GitOrigin-RevId: 5240c24d481643bb6836a6ee05c28d03d12dc152
Change-Id: I851bff5b6446ee684b2d9776a6f74bdbf99b2598
-rw-r--r-- | gxp-telemetry.c | 26 | ||||
-rw-r--r-- | gxp-vd.c | 11 |
2 files changed, 30 insertions, 7 deletions
diff --git a/gxp-telemetry.c b/gxp-telemetry.c index 93b301b..7eb18cb 100644 --- a/gxp-telemetry.c +++ b/gxp-telemetry.c @@ -390,6 +390,11 @@ int gxp_telemetry_enable(struct gxp_dev *gxp, u8 type) uint core, virt_core; struct gxp_virtual_device *vd; + /* + * `vd_semaphore` cannot be acquired while holding the telemetry lock, + * so acquire it here before locking the telemetry lock. + */ + down_read(&gxp->vd_semaphore); mutex_lock(&gxp->telemetry_mgr->lock); switch (type) { @@ -410,7 +415,6 @@ int gxp_telemetry_enable(struct gxp_dev *gxp, u8 type) } /* Map the buffers for any cores already running */ - down_read(&gxp->vd_semaphore); for (core = 0; core < GXP_NUM_CORES; core++) { vd = gxp->core_to_vd[core]; if (vd != NULL) { @@ -438,7 +442,7 @@ int gxp_telemetry_enable(struct gxp_dev *gxp, u8 type) refcount_inc(&data->ref_count); data->is_enabled = true; - goto up_sem; + goto out; err: while (core--) { vd = gxp->core_to_vd[core]; @@ -450,10 +454,9 @@ err: } } -up_sem: - up_read(&gxp->vd_semaphore); out: mutex_unlock(&gxp->telemetry_mgr->lock); + up_read(&gxp->vd_semaphore); return ret; } @@ -499,7 +502,14 @@ static int notify_core_and_wait_for_disable(struct gxp_dev *gxp, uint core, msecs_to_jiffies(10)); retries_left--; + /* + * No function may attempt to acquire the `vd_semaphore` while + * holding the telemetry lock, so it must be released, then + * re-acquired once the `vd_semaphore` is held. + */ + mutex_unlock(&gxp->telemetry_mgr->lock); down_read(&gxp->vd_semaphore); + mutex_lock(&gxp->telemetry_mgr->lock); } /* @@ -604,13 +614,17 @@ int gxp_telemetry_disable(struct gxp_dev *gxp, u8 type) { int ret; - mutex_lock(&gxp->telemetry_mgr->lock); + /* + * `vd_semaphore` cannot be acquired while holding the telemetry lock, + * so acquire it here before locking the telemetry lock. + */ down_read(&gxp->vd_semaphore); + mutex_lock(&gxp->telemetry_mgr->lock); ret = telemetry_disable_locked(gxp, type); - up_read(&gxp->vd_semaphore); mutex_unlock(&gxp->telemetry_mgr->lock); + up_read(&gxp->vd_semaphore); return ret; } @@ -166,6 +166,8 @@ static int map_telemetry_buffers(struct gxp_dev *gxp, int ret = 0; struct buffer_data *buff_data; + mutex_lock(&gxp->telemetry_mgr->lock); + /* Map logging buffers if logging is enabled */ buff_data = gxp->telemetry_mgr->logging_buff_data; if (buff_data && buff_data->is_enabled) { @@ -174,7 +176,7 @@ static int map_telemetry_buffers(struct gxp_dev *gxp, buff_data->size, buff_data->buffer_daddrs[core], 0); /* Don't bother checking tracing if logging fails */ if (ret) - return ret; + goto out; } /* Map tracing buffers if tracing is enabled */ @@ -194,6 +196,9 @@ static int map_telemetry_buffers(struct gxp_dev *gxp, } } +out: + mutex_unlock(&gxp->telemetry_mgr->lock); + return ret; } @@ -203,6 +208,8 @@ static void unmap_telemetry_buffers(struct gxp_dev *gxp, { struct buffer_data *buff_data; + mutex_lock(&gxp->telemetry_mgr->lock); + buff_data = gxp->telemetry_mgr->logging_buff_data; if (buff_data && buff_data->is_enabled) gxp_dma_unmap_allocated_coherent_buffer( @@ -214,6 +221,8 @@ static void unmap_telemetry_buffers(struct gxp_dev *gxp, gxp_dma_unmap_allocated_coherent_buffer( gxp, vd, BIT(virt_core), buff_data->size, buff_data->buffer_daddrs[core]); + + mutex_unlock(&gxp->telemetry_mgr->lock); } static int map_debug_dump_buffer(struct gxp_dev *gxp, |