summaryrefslogtreecommitdiff
path: root/include/linux/hyperv.h
diff options
context:
space:
mode:
authorKimberly Brown <kimbrownkd@gmail.com>2019-03-14 23:05:15 +0300
committerSasha Levin <sashal@kernel.org>2019-04-11 01:58:56 +0300
commit14948e39445db674516ccabdf01090586ecfdc9b (patch)
treec7dde66befabf1f3d78652672c73ff0f1ec5ea62 /include/linux/hyperv.h
parent4713eb7b580a269f827ea82f4c25bebae963e0e8 (diff)
downloadlinux-14948e39445db674516ccabdf01090586ecfdc9b.tar.xz
Drivers: hv: vmbus: Fix race condition with new ring_buffer_info mutex
Fix a race condition that can result in a ring buffer pointer being set to null while a "_show" function is reading the ring buffer's data. This problem was discussed here: https://lkml.org/lkml/2018/10/18/779 To fix the race condition, add a new mutex lock to the "hv_ring_buffer_info" struct. Add a new function, "hv_ringbuffer_pre_init()", where a channel's inbound and outbound ring_buffer_info mutex locks are initialized. Acquire/release the locks in the "hv_ringbuffer_cleanup()" function, which is where the ring buffer pointers are set to null. Acquire/release the locks in the four channel-level "_show" functions that access ring buffer data. Remove the "const" qualifier from the "vmbus_channel" parameter and the "rbi" variable of the channel-level "_show" functions so that the locks can be acquired/released in these functions. Acquire/release the locks in hv_ringbuffer_get_debuginfo(). Remove the "const" qualifier from the "hv_ring_buffer_info" parameter so that the locks can be acquired/released in this function. Signed-off-by: Kimberly Brown <kimbrownkd@gmail.com> Reviewed-by: Michael Kelley <mikelley@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'include/linux/hyperv.h')
-rw-r--r--include/linux/hyperv.h7
1 files changed, 6 insertions, 1 deletions
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 64698ec8f2ac..8b9a93c99c9b 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -141,6 +141,11 @@ struct hv_ring_buffer_info {
u32 ring_datasize; /* < ring_size */
u32 priv_read_index;
+ /*
+ * The ring buffer mutex lock. This lock prevents the ring buffer from
+ * being freed while the ring buffer is being accessed.
+ */
+ struct mutex ring_buffer_mutex;
};
@@ -1206,7 +1211,7 @@ struct hv_ring_buffer_debug_info {
};
-int hv_ringbuffer_get_debuginfo(const struct hv_ring_buffer_info *ring_info,
+int hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
struct hv_ring_buffer_debug_info *debug_info);
/* Vmbus interface */