mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-29 23:53:32 +00:00
58ccf0190d
The new facility adds a bunch of wrappers that abstract how an IOVA range is represented in a bitmap that is granulated by a given page_size. So it translates all the lifting of dealing with user pointers into its corresponding kernel addresses backing said user memory into doing finally the (non-atomic) bitmap ops to change various bits. The formula for the bitmap is: data[(iova / page_size) / 64] & (1ULL << (iova % 64)) Where 64 is the number of bits in a unsigned long (depending on arch) It introduces an IOVA iterator that uses a windowing scheme to minimize the pinning overhead, as opposed to pinning it on demand 4K at a time. Assuming a 4K kernel page and 4K requested page size, we can use a single kernel page to hold 512 page pointers, mapping 2M of bitmap, representing 64G of IOVA space. An example usage of these helpers for a given @base_iova, @page_size, @length and __user @data: bitmap = iova_bitmap_alloc(base_iova, page_size, length, data); if (IS_ERR(bitmap)) return -ENOMEM; ret = iova_bitmap_for_each(bitmap, arg, dirty_reporter_fn); iova_bitmap_free(bitmap); Each iteration of the @dirty_reporter_fn is called with a unique @iova and @length argument, indicating the current range available through the iova_bitmap. The @dirty_reporter_fn uses iova_bitmap_set() to mark dirty areas (@iova_length) within that provided range, as following: iova_bitmap_set(bitmap, iova, iova_length); The facility is intended to be used for user bitmaps representing dirtied IOVAs by IOMMU (via IOMMUFD) and PCI Devices (via vfio-pci). Signed-off-by: Joao Martins <joao.m.martins@oracle.com> Signed-off-by: Yishai Hadas <yishaih@nvidia.com> Link: https://lore.kernel.org/r/20220908183448.195262-5-yishaih@nvidia.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
26 lines
771 B
C
26 lines
771 B
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (c) 2022, Oracle and/or its affiliates.
|
|
* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved
|
|
*/
|
|
#ifndef _IOVA_BITMAP_H_
|
|
#define _IOVA_BITMAP_H_
|
|
|
|
#include <linux/types.h>
|
|
|
|
struct iova_bitmap;
|
|
|
|
typedef int (*iova_bitmap_fn_t)(struct iova_bitmap *bitmap,
|
|
unsigned long iova, size_t length,
|
|
void *opaque);
|
|
|
|
struct iova_bitmap *iova_bitmap_alloc(unsigned long iova, size_t length,
|
|
unsigned long page_size,
|
|
u64 __user *data);
|
|
void iova_bitmap_free(struct iova_bitmap *bitmap);
|
|
int iova_bitmap_for_each(struct iova_bitmap *bitmap, void *opaque,
|
|
iova_bitmap_fn_t fn);
|
|
void iova_bitmap_set(struct iova_bitmap *bitmap,
|
|
unsigned long iova, size_t length);
|
|
|
|
#endif
|