[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251220040446.274991-10-houtao@huaweicloud.com>
Date: Sat, 20 Dec 2025 12:04:42 +0800
From: Hou Tao <houtao@...weicloud.com>
To: linux-kernel@...r.kernel.org
Cc: linux-pci@...r.kernel.org,
linux-mm@...ck.org,
linux-nvme@...ts.infradead.org,
Bjorn Helgaas <bhelgaas@...gle.com>,
Logan Gunthorpe <logang@...tatee.com>,
Alistair Popple <apopple@...dia.com>,
Leon Romanovsky <leonro@...dia.com>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Tejun Heo <tj@...nel.org>,
"Rafael J . Wysocki" <rafael@...nel.org>,
Danilo Krummrich <dakr@...nel.org>,
Andrew Morton <akpm@...ux-foundation.org>,
David Hildenbrand <david@...nel.org>,
Lorenzo Stoakes <lorenzo.stoakes@...cle.com>,
Keith Busch <kbusch@...nel.org>,
Jens Axboe <axboe@...nel.dk>,
Christoph Hellwig <hch@....de>,
Sagi Grimberg <sagi@...mberg.me>,
houtao1@...wei.com
Subject: [PATCH 09/13] PCI/P2PDMA: support get_unmapped_area to return aligned vaddr
From: Hou Tao <houtao1@...wei.com>
P2PDMA memory already supports compound page. When mmapping the P2PDMA
memory in the userspace, the mmap procedure needs to use an aligned
virtual address to match the alignment of P2PDMA memory. Therefore,
implement get_unmapped_area for p2pdma memory to return an aligned
virtual address.
Signed-off-by: Hou Tao <houtao1@...wei.com>
---
drivers/pci/p2pdma.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index 7180dea4855c..e97f5da73458 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -90,6 +90,44 @@ static ssize_t published_show(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RO(published);
+static unsigned long p2pmem_get_unmapped_area(struct file *filp, struct kobject *kobj,
+ const struct bin_attribute *attr,
+ unsigned long uaddr, unsigned long len,
+ unsigned long pgoff, unsigned long flags)
+{
+ struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
+ struct pci_p2pdma *p2pdma;
+ unsigned long aligned_len;
+ unsigned long addr;
+ unsigned long align;
+
+ if (pgoff)
+ return -EINVAL;
+
+ rcu_read_lock();
+ p2pdma = rcu_dereference(pdev->p2pdma);
+ if (!p2pdma) {
+ rcu_read_unlock();
+ return -ENODEV;
+ }
+ align = p2pdma->align;
+ rcu_read_unlock();
+
+ /* Fixed address */
+ if (uaddr)
+ goto out;
+
+ aligned_len = len + align;
+ if (aligned_len < len)
+ goto out;
+
+ addr = mm_get_unmapped_area(filp, uaddr, aligned_len, pgoff, flags);
+ if (!IS_ERR_VALUE(addr))
+ return round_up(addr, align);
+out:
+ return mm_get_unmapped_area(filp, uaddr, len, pgoff, flags);
+}
+
static int p2pmem_alloc_mmap(struct file *filp, struct kobject *kobj,
const struct bin_attribute *attr, struct vm_area_struct *vma)
{
@@ -175,6 +213,7 @@ static int p2pmem_alloc_mmap(struct file *filp, struct kobject *kobj,
static const struct bin_attribute p2pmem_alloc_attr = {
.attr = { .name = "allocate", .mode = 0660 },
.mmap = p2pmem_alloc_mmap,
+ .get_unmapped_area = p2pmem_get_unmapped_area,
/*
* Some places where we want to call mmap (ie. python) will check
* that the file size is greater than the mmap size before allowing
--
2.29.2
Powered by blists - more mailing lists