drivers: hv: vmbus: replace deprecated mmap hook with mmap_prepare

The f_op->mmap interface is deprecated, so update the vmbus driver to use
its successor, mmap_prepare.

This updates all callbacks which referenced the function pointer
hv_mmap_ring_buffer to instead reference hv_mmap_prepare_ring_buffer,
utilising the newly introduced compat_set_desc_from_vma() and
__compat_vma_mmap() to be able to implement this change.

The UIO HV generic driver is the only user of hv_create_ring_sysfs(),
which is the only function which references
vmbus_channel->mmap_prepare_ring_buffer which, in turn, is the only
external interface to hv_mmap_prepare_ring_buffer.

This patch therefore updates this caller to use mmap_prepare instead,
which also previously used vm_iomap_memory(), so this change replaces it
with its mmap_prepare equivalent, mmap_action_simple_ioremap().

[akpm@linux-foundation.org: restore struct vmbus_channel comment, per Michael Kelley]
Link: https://lkml.kernel.org/r/05467cb62267d750e5c770147517d4df0246cda6.1774045440.git.ljs@kernel.org
Signed-off-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Tested-by: Michael Kelley <mhklinux@outlook.com>
Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Bodo Stroesser <bostroesser@gmail.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Clemens Ladisch <clemens@ladisch.de>
Cc: David Hildenbrand <david@kernel.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Dexuan Cui <decui@microsoft.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Jann Horn <jannh@google.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: K. Y. Srinivasan <kys@microsoft.com>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Long Li <longli@microsoft.com>
Cc: Marc Dionne <marc.dionne@auristor.com>
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Miquel Raynal <miquel.raynal@bootlin.com>
Cc: Pedro Falcato <pfalcato@suse.de>
Cc: Richard Weinberger <richard@nod.at>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vignesh Raghavendra <vigneshr@ti.com>
Cc: Wei Liu <wei.liu@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Lorenzo Stoakes (Oracle)
2026-03-20 22:39:44 +00:00
committed by Andrew Morton
parent 668937b7b2
commit f98cb7ca4a
4 changed files with 29 additions and 21 deletions

View File

@@ -545,8 +545,8 @@ static inline int hv_debug_add_dev_dir(struct hv_device *dev)
/* Create and remove sysfs entry for memory mapped ring buffers for a channel */
int hv_create_ring_sysfs(struct vmbus_channel *channel,
int (*hv_mmap_ring_buffer)(struct vmbus_channel *channel,
struct vm_area_struct *vma));
int (*hv_mmap_prepare_ring_buffer)(struct vmbus_channel *channel,
struct vm_area_desc *desc));
int hv_remove_ring_sysfs(struct vmbus_channel *channel);
#endif /* _HYPERV_VMBUS_H */

View File

@@ -1951,12 +1951,19 @@ static int hv_mmap_ring_buffer_wrapper(struct file *filp, struct kobject *kobj,
struct vm_area_struct *vma)
{
struct vmbus_channel *channel = container_of(kobj, struct vmbus_channel, kobj);
struct vm_area_desc desc;
int err;
/*
* hv_(create|remove)_ring_sysfs implementation ensures that mmap_ring_buffer
* is not NULL.
* hv_(create|remove)_ring_sysfs implementation ensures that
* mmap_prepare_ring_buffer is not NULL.
*/
return channel->mmap_ring_buffer(channel, vma);
compat_set_desc_from_vma(&desc, filp, vma);
err = channel->mmap_prepare_ring_buffer(channel, &desc);
if (err)
return err;
return __compat_vma_mmap(&desc, vma);
}
static struct bin_attribute chan_attr_ring_buffer = {
@@ -2048,13 +2055,13 @@ static const struct kobj_type vmbus_chan_ktype = {
/**
* hv_create_ring_sysfs() - create "ring" sysfs entry corresponding to ring buffers for a channel.
* @channel: Pointer to vmbus_channel structure
* @hv_mmap_ring_buffer: function pointer for initializing the function to be called on mmap of
* @hv_mmap_prepare_ring_buffer: function pointer for initializing the function to be called on mmap
* channel's "ring" sysfs node, which is for the ring buffer of that channel.
* Function pointer is of below type:
* int (*hv_mmap_ring_buffer)(struct vmbus_channel *channel,
* struct vm_area_struct *vma))
* This has a pointer to the channel and a pointer to vm_area_struct,
* used for mmap, as arguments.
* int (*hv_mmap_prepare_ring_buffer)(struct vmbus_channel *channel,
* struct vm_area_desc *desc))
* This has a pointer to the channel and a pointer to vm_area_desc,
* used for mmap_prepare, as arguments.
*
* Sysfs node for ring buffer of a channel is created along with other fields, however its
* visibility is disabled by default. Sysfs creation needs to be controlled when the use-case
@@ -2071,12 +2078,12 @@ static const struct kobj_type vmbus_chan_ktype = {
* Returns 0 on success or error code on failure.
*/
int hv_create_ring_sysfs(struct vmbus_channel *channel,
int (*hv_mmap_ring_buffer)(struct vmbus_channel *channel,
struct vm_area_struct *vma))
int (*hv_mmap_prepare_ring_buffer)(struct vmbus_channel *channel,
struct vm_area_desc *desc))
{
struct kobject *kobj = &channel->kobj;
channel->mmap_ring_buffer = hv_mmap_ring_buffer;
channel->mmap_prepare_ring_buffer = hv_mmap_prepare_ring_buffer;
channel->ring_sysfs_visible = true;
return sysfs_update_group(kobj, &vmbus_chan_group);
@@ -2098,7 +2105,7 @@ int hv_remove_ring_sysfs(struct vmbus_channel *channel)
channel->ring_sysfs_visible = false;
ret = sysfs_update_group(kobj, &vmbus_chan_group);
channel->mmap_ring_buffer = NULL;
channel->mmap_prepare_ring_buffer = NULL;
return ret;
}
EXPORT_SYMBOL_GPL(hv_remove_ring_sysfs);

View File

@@ -154,15 +154,16 @@ static void hv_uio_rescind(struct vmbus_channel *channel)
* The ring buffer is allocated as contiguous memory by vmbus_open
*/
static int
hv_uio_ring_mmap(struct vmbus_channel *channel, struct vm_area_struct *vma)
hv_uio_ring_mmap_prepare(struct vmbus_channel *channel, struct vm_area_desc *desc)
{
void *ring_buffer = page_address(channel->ringbuffer_page);
if (channel->state != CHANNEL_OPENED_STATE)
return -ENODEV;
return vm_iomap_memory(vma, virt_to_phys(ring_buffer),
channel->ringbuffer_pagecount << PAGE_SHIFT);
mmap_action_simple_ioremap(desc, virt_to_phys(ring_buffer),
channel->ringbuffer_pagecount << PAGE_SHIFT);
return 0;
}
/* Callback from VMBUS subsystem when new channel created. */
@@ -183,7 +184,7 @@ hv_uio_new_channel(struct vmbus_channel *new_sc)
}
set_channel_read_mode(new_sc, HV_CALL_ISR);
ret = hv_create_ring_sysfs(new_sc, hv_uio_ring_mmap);
ret = hv_create_ring_sysfs(new_sc, hv_uio_ring_mmap_prepare);
if (ret) {
dev_err(device, "sysfs create ring bin file failed; %d\n", ret);
vmbus_close(new_sc);
@@ -366,7 +367,7 @@ hv_uio_probe(struct hv_device *dev,
* or decoupled from uio_hv_generic probe. Userspace programs can make use of inotify
* APIs to make sure that ring is created.
*/
hv_create_ring_sysfs(channel, hv_uio_ring_mmap);
hv_create_ring_sysfs(channel, hv_uio_ring_mmap_prepare);
hv_set_drvdata(dev, pdata);

View File

@@ -1015,8 +1015,8 @@ struct vmbus_channel {
/* The max size of a packet on this channel */
u32 max_pkt_size;
/* function to mmap ring buffer memory to the channel's sysfs ring attribute */
int (*mmap_ring_buffer)(struct vmbus_channel *channel, struct vm_area_struct *vma);
/* function to mmap ring buffer memory to the channel's sysfs ring attribute */
int (*mmap_prepare_ring_buffer)(struct vmbus_channel *channel, struct vm_area_desc *desc);
/* boolean to control visibility of sysfs for ring buffer */
bool ring_sysfs_visible;