summaryrefslogtreecommitdiff
path: root/include/linux/hyperv.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-10-29 12:39:45 -1000
committerLinus Torvalds <torvalds@linux-foundation.org>2026-10-29 12:39:45 -1000
commit9c7e3d59107e2daf204bf6bf87b6c448ca89defe (patch)
tree59e0a03cba2d5dc957b578b0afbb5e95a39fe0ee /include/linux/hyperv.h
parent1b8b67503725fa6deb3a4f00ea61f982bd00c152 (diff)
parent33b28f3b313353f11fc939e9a268605e66290d0b (diff)
Merge tag 'hyperv-next-signed-20261028' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux
Pull hyperv updates from Wei Liu: - Update to documents and code comments (Michael Kelley) - Harden Vmbus (Kameron Carr) - Rework MSHV driver page deposit logic (Mukesh Rathor) - Vmbus kexec bug fix (Shradha Gupta) - Miscellaneous bug fixes (Daehyeon Ko, Jiale Yao, Sasha Levin) * tag 'hyperv-next-signed-20261028' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux: Drivers: hv: Remove leftover support for old Hyper-V versions mshv: Remove unused *_old memory deposit functions mshv: Redesign hypervisor memory deposit logic mshv: Rename memory deposit memory functions to _old mshv_vtl: reject poll files with multiple waitqueues mshv_vtl: detach poll waiter on POLLFREE mshv_vtl: initialize poll file mutex before device registration Documentation: hyperv: Update information on guest CPU offlining Documentation: hyperv: Remove support for guests on Hyper-V 2012/2012R2 Drivers: hv: Run VMBus kexec cleanup from syscore shutdown kexec: Add helper to report an active kexec reboot tools: hv: remove unused rte_smp_mb() Documentation: hyperv: Update documentation for sending VMBus packets Drivers: hv: vmbus: Check ACPI companion before use Documentation: hyperv: Describe validation of the ring buffer indices Drivers: hv: vmbus: Keep the ring byte counts sane for a bad index Drivers: hv: vmbus: Compute ring byte counts from a caller-held snapshot Drivers: hv: vmbus: Use *_ONCE() to access shared ring buffer indices Drivers: hv: vmbus: Bounds check the shared ring buffer indices
Diffstat (limited to 'include/linux/hyperv.h')
-rw-r--r--include/linux/hyperv.h58
1 files changed, 45 insertions, 13 deletions
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index e61f9a4cb7c3..e85a1a043eac 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -209,31 +209,63 @@ struct hv_ring_buffer_info {
};
+/*
+ * The indices live in memory shared with the untrusted host, so check a
+ * snapshot of them before using it as an offset or to compute a byte count.
+ */
+static inline bool
+hv_ringbuffer_indices_invalid(const struct hv_ring_buffer_info *rbi,
+ u32 read_loc, u32 write_loc)
+{
+ return read_loc >= rbi->ring_datasize ||
+ write_loc >= rbi->ring_datasize;
+}
+
+/*
+ * Byte counts for a caller-supplied snapshot of the indices, so that the
+ * counts and the indices the caller goes on to use describe one state of the
+ * ring.
+ */
+static inline u32
+hv_ringbuffer_avail_write(const struct hv_ring_buffer_info *rbi,
+ u32 read_loc, u32 write_loc)
+{
+ u32 dsize = rbi->ring_datasize;
+
+ return write_loc >= read_loc ? dsize - (write_loc - read_loc) :
+ read_loc - write_loc;
+}
+
+static inline u32
+hv_ringbuffer_avail_read(const struct hv_ring_buffer_info *rbi,
+ u32 read_loc, u32 write_loc)
+{
+ return rbi->ring_datasize -
+ hv_ringbuffer_avail_write(rbi, read_loc, write_loc);
+}
+
static inline u32 hv_get_bytes_to_read(const struct hv_ring_buffer_info *rbi)
{
- u32 read_loc, write_loc, dsize, read;
+ u32 read_loc, write_loc;
- dsize = rbi->ring_datasize;
- read_loc = rbi->ring_buffer->read_index;
+ read_loc = READ_ONCE(rbi->ring_buffer->read_index);
write_loc = READ_ONCE(rbi->ring_buffer->write_index);
+ if (unlikely(hv_ringbuffer_indices_invalid(rbi, read_loc, write_loc)))
+ return 0;
- read = write_loc >= read_loc ? (write_loc - read_loc) :
- (dsize - read_loc) + write_loc;
-
- return read;
+ return hv_ringbuffer_avail_read(rbi, read_loc, write_loc);
}
static inline u32 hv_get_bytes_to_write(const struct hv_ring_buffer_info *rbi)
{
- u32 read_loc, write_loc, dsize, write;
+ u32 read_loc, write_loc;
- dsize = rbi->ring_datasize;
read_loc = READ_ONCE(rbi->ring_buffer->read_index);
- write_loc = rbi->ring_buffer->write_index;
+ write_loc = READ_ONCE(rbi->ring_buffer->write_index);
+ if (unlikely(hv_ringbuffer_indices_invalid(rbi, read_loc, write_loc)))
+ return 0;
- write = write_loc >= read_loc ? dsize - (write_loc - read_loc) :
- read_loc - write_loc;
- return write;
+ return hv_ringbuffer_avail_write(rbi, read_loc, write_loc);
}
static inline u32 hv_get_avail_to_write_percent(