From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0FAC859D63A; Tue, 8 Sep 2026 20:07:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788898035; cv=none; b=lDFBiYYhdyrp610jYB06M/ik3ueFvdkEJScw4GAL8zO9RpCYaab1z4ZUnA99cLtlT7kpYAXx5HzT6uxN6pUyuBok3JCMDaYo2AI+zksux1/cN5jnbeTM1xE2Cf6RJXPm0n4oGMOObLNPGpAIPKCQxK4d8y6nVOv9TJBo40bvOhE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788898035; c=relaxed/simple; bh=DvnDuvgsaeIMg1k0R/1O6RcBwGnMt/C+7lANJzJCM1I=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=o423Nwe7y8xbfg1MEt+IMY5c2VQiWILXem3MaxxOUhZbHYZiUHcdu46jWoEjp8T9fF3ieRJ4NHWBq3KI21RqDX3xcwErXMS2EdSMyl9GZ3Bltar1VF2jNtW4glfbwOtxQLPgysDVMFF23Hz/ftw0S0NsKVF1NX2P/OfhokIoQ4Y= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kN/btgh0; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="kN/btgh0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7CBD61F00A3D; Tue, 8 Sep 2026 20:06:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788898033; bh=/OHowaZfNnH6j5YLgvEYzRWeKR373+5I1ONZvwtiOGM=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=kN/btgh0eap/SzTnfSMyA1+JQMgNNTZgMm76v6K5xBzJeML5mC6bG1ehwUm074Wwt mu4BBs8HNe0Scxfm6+rZRxODax9ptXPYgz7B2VRoWj8rT2IIaLy/Cf4P9VNig+4yyC yOaismpmUijBljgnNHYEJwqhIK9m6OdzBDFFAG6yyCnuLxT6Xo+zf9WHbNsdJBH0Dk VXiJQ1zJjohovh+PxvEB01WbD/6CZKPV5fgwDx+/uK1/qaRGlUUCUss+MZaWX6yRbS RWufKT4bxmMVtAXkBT+1COQY8ZPY7lN1TDNimdMZuPtkgIZ5IZm7N3RznryoHsyHuE 3KSVVirl3z1hA== From: "Lorenzo Stoakes (ARM)" Date: Tue, 08 Sep 2026 21:01:14 +0100 Subject: [PATCH 10/39] infiniband: update hfi1 to use remap_vmalloc_range() Precedence: bulk X-Mailing-List: linux-trace-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260908-b4-mmap-prepare-vma-flag-sanify-v1-10-dacf19cce22b@kernel.org> References: <20260908-b4-mmap-prepare-vma-flag-sanify-v1-0-dacf19cce22b@kernel.org> In-Reply-To: <20260908-b4-mmap-prepare-vma-flag-sanify-v1-0-dacf19cce22b@kernel.org> To: Andrew Morton , "Liam R. Howlett" , Vlastimil Babka , Jann Horn , Pedro Falcato , David Hildenbrand , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Jonathan Corbet , Greg Kroah-Hartman , Dennis Dalessandro , Jason Gunthorpe , Leon Romanovsky , Paul Moore , Stephen Smalley , Jaroslav Kysela , Takashi Iwai , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi , Zi Yan , Baolin Wang , Nico Pache , Ryan Roberts , Dev Jain , Barry Song , Lance Yang , Usama Arif , Kiryl Shutsemau , Doug Gilbert , "James E.J. Bottomley" , "Martin K. Petersen" , Jaya Kumar , Simona Vetter , Helge Deller , Sebastian Reichel , John Hubbard , Peter Xu , Masami Hiramatsu , Oleg Nesterov , Peter Zijlstra , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Rik van Riel , Harry Yoo , Juri Lelli , Vincent Guittot , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Will Deacon , "Aneesh Kumar K.V" , Nick Piggin , Arnd Bergmann , Muchun Song , Oscar Salvador , "Matthew Wilcox (Oracle)" , Jan Kara , Marc Zyngier , Oliver Upton , Catalin Marinas , Madhavan Srinivasan , Anup Patel , Paul Walmsley , Palmer Dabbelt , Albert Ou , Christian Borntraeger , Janosch Frank , Claudio Imbrenda , Alexander Gordeev , Gerald Schaefer , Heiko Carstens , Vasily Gorbik , "David S. Miller" , Andreas Larsson , Alexander Viro , Christian Brauner , Matthew Brost , Joshua Hahn , Rakie Kim , Byungchul Park , Gregory Price , Ying Huang , Alistair Popple , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Baoquan He , Youngjun Park , Johannes Weiner , Qi Zheng , Shakeel Butt , Axel Rasmussen , Yuanchu Xie , Wei Xu , Xu Xin , Chengming Zhou , Michal Hocko , Miklos Szeredi Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-usb@vger.kernel.org, linux-rdma@vger.kernel.org, selinux@vger.kernel.org, linux-sound@vger.kernel.org, bpf@vger.kernel.org, linux-scsi@vger.kernel.org, linux-fbdev@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-trace-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, linux-arch@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, linux-s390@vger.kernel.org, sparclinux@vger.kernel.org, fuse-devel@lists.linux.dev, "Lorenzo Stoakes (ARM)" X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=9393; i=ljs@kernel.org; h=from:subject:message-id; bh=DvnDuvgsaeIMg1k0R/1O6RcBwGnMt/C+7lANJzJCM1I=; b=owGbwMvMwCV2fu7ZrsZH9SKMp9WSGLIWZG78/93P99pW//+K9zMzmHMuySj6SmXx3BA+HjfzV wS7XCpTRykLgxgXg6yYIsvzL+L7g0TC5nVe8HeDmcPKBDKEgYtTACZyVY7hf9XsAj25r/dzk15F roqSV7otOy9/9/WU1OyWLzedko5M5GD4X9X9cNIO4e7kGfU2x5Vf3GdOnV/C1Hfk99YTD/evFtv xnAUA X-Developer-Key: i=ljs@kernel.org; a=openpgp; fpr=E7F417BF5214569E89D04F46CF9DCD8A81E27F14 In cases which map chip memory from vmalloc()'d ranges, the hfi1 infiniband drivers currently installs a fault handler, and then smuggles the kernel virtual address of this range in vma->vm_pgoff. This is exposing KASLR-sensitive internal kernel state in the VMA, and is entirely unnecessary. Instead, use remap_vmalloc_range() to remap the VMA to the span, and eliminate the fault handler altogether. remap_vmalloc_range() checks that the VMA does not extend beyond the vmalloc area, and the driver already requires the VMA to exactly match the span of the memory being mapped, so this has no impact. The memory is all preallocated so not having a fault handler has no impact either, other than pre-mapping the ranges which is beneficial. We also remove the VM_IO flag as it's not appropriate here, and the VM_DONTEXPAND flag as remap_vmalloc_range() will set it (and also mark the range correctly as a mixed map). We also update the vmalloc paths to place the virtual kernel address in memvirt, rather than overloading the physical address memaddr. We predicate the vmalloc handling on the vmalloc flag before we check memvirt for the virtual address-derived PFN remap path, so this works fine. remap_vmalloc_range() requires that the vmalloc()'d areas were all allocated using vmalloc_user() - each of cq->comps, uctxt->subctxt_rcvegrbuf, uctxt->subctxt_rcvhdr_base, uctxt->subctxt_uregbase and dd->events were allocated this way, so that requirement is satisfied. We also remove VM_IO and VM_DONTEXPAND from the STATUS command, as these are both set on remap. Finally, we remove VM_DONTEXPAND from the PIO_BUFS, PIO_BUFS_SOP and UREGS commands, as these are also all set on remap. PIO_CRED retains it, as dma_mmap_coherent() may map via vm_insert_page() on the IOMMU-DMA path, which sets only VM_MIXEDMAP. Note that we retain expected behaviour throughout - the vmalloc remapped ranges set VM_MIXEDMAP | VM_DONTDUMP | VM_DONTEXPAND for each range. VM_IO was never appropriate as the ranges are explicitly not MMIO, and the reference to the v3.7 VM_RESERVED semantics map on to VM_MIXEDMAP | VM_DONTDUMP | VM_DONTEXPAND correctly - no core dump, unmergeable, no normal vm page for purposes of reclaim/migration/etc. There is a change in behaviour in that pages mapped using remap_vmalloc_range() will now have normal GUP-able pages, however this should have no impact as there is no reason not to allow this. Signed-off-by: Lorenzo Stoakes (ARM) --- drivers/infiniband/hw/hfi1/file_ops.c | 79 ++++++++++------------------------- 1 file changed, 22 insertions(+), 57 deletions(-) diff --git a/drivers/infiniband/hw/hfi1/file_ops.c b/drivers/infiniband/hw/hfi1/file_ops.c index dc548e6802e2..7119d734edc7 100644 --- a/drivers/infiniband/hw/hfi1/file_ops.c +++ b/drivers/infiniband/hw/hfi1/file_ops.c @@ -70,7 +70,6 @@ static int set_ctxt_pkey(struct hfi1_ctxtdata *uctxt, unsigned long arg); static int ctxt_reset(struct hfi1_ctxtdata *uctxt); static int manage_rcvq(struct hfi1_ctxtdata *uctxt, u16 subctxt, unsigned long arg); -static vm_fault_t vma_fault(struct vm_fault *vmf); static long hfi1_file_ioctl(struct file *fp, unsigned int cmd, unsigned long arg); @@ -85,10 +84,6 @@ static const struct file_operations hfi1_file_ops = { .llseek = noop_llseek, }; -static const struct vm_operations_struct vm_ops = { - .fault = vma_fault, -}; - /* * Types of memories mapped into user processes' space */ @@ -304,13 +299,13 @@ static ssize_t hfi1_write_iter(struct kiocb *kiocb, struct iov_iter *from) return reqs; } -static inline void mmap_cdbg(u16 ctxt, u8 subctxt, u8 type, u8 mapio, u8 vmf, +static inline void mmap_cdbg(u16 ctxt, u8 subctxt, u8 type, u8 mapio, u8 is_vmalloc, u64 memaddr, void *memvirt, dma_addr_t memdma, ssize_t memlen, struct vm_area_struct *vma) { hfi1_cdbg(PROC, - "%u:%u type:%u io/vf/dma:%d/%d/%d, addr:0x%llx, len:%lu(%lu), flags:0x%lx", - ctxt, subctxt, type, mapio, vmf, !!memdma, + "%u:%u type:%u io/vmalloc/dma:%d/%d/%d, addr:0x%llx, len:%lu(%lu), flags:0x%lx", + ctxt, subctxt, type, mapio, is_vmalloc, !!memdma, memaddr ?: (u64)memvirt, memlen, vma->vm_end - vma->vm_start, vma->vm_flags); } @@ -325,7 +320,7 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma) memaddr = 0; void *memvirt = NULL; dma_addr_t memdma = 0; - u8 subctxt, mapio = 0, vmf = 0, type; + u8 subctxt, mapio = 0, is_vmalloc = 0, type; ssize_t memlen = 0; int ret = 0; u16 ctxt; @@ -347,7 +342,7 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma) /* * vm_pgoff is used as a buffer selector cookie. Always mmap from * the beginning. - */ + */ vma->vm_pgoff = 0; flags = vma->vm_flags; @@ -366,7 +361,7 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma) */ memlen = PAGE_ALIGN(uctxt->sc->credits * PIO_BLOCK_SIZE); flags &= ~VM_MAYREAD; - flags |= VM_DONTCOPY | VM_DONTEXPAND; + flags |= VM_DONTCOPY; vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); mapio = 1; break; @@ -438,7 +433,7 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma) memvirt = uctxt->egrbufs.buffers[i].addr; memdma = uctxt->egrbufs.buffers[i].dma; vma->vm_end += memlen; - mmap_cdbg(ctxt, subctxt, type, mapio, vmf, memaddr, + mmap_cdbg(ctxt, subctxt, type, mapio, is_vmalloc, memaddr, memvirt, memdma, memlen, vma); ret = dma_mmap_coherent(&dd->pcidev->dev, vma, memvirt, memdma, memlen); @@ -467,7 +462,7 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma) * user registers. */ memlen = PAGE_SIZE; - flags |= VM_DONTCOPY | VM_DONTEXPAND; + flags |= VM_DONTCOPY; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); mapio = 1; break; @@ -476,15 +471,10 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma) * Use the page where this context's flags are. User level * knows where it's own bitmap is within the page. */ - memaddr = (unsigned long) - (dd->events + uctxt_offset(uctxt)) & PAGE_MASK; + memvirt = dd->events + uctxt_offset(uctxt); + memvirt = (void *)(((uintptr_t)memvirt) & PAGE_MASK); memlen = PAGE_SIZE; - /* - * v3.7 removes VM_RESERVED but the effect is kept by - * using VM_IO. - */ - flags |= VM_IO | VM_DONTEXPAND; - vmf = 1; + is_vmalloc = 1; break; case STATUS: if (flags & VM_WRITE) { @@ -493,7 +483,6 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma) } memaddr = kvirt_to_phys((void *)dd->status); memlen = PAGE_SIZE; - flags |= VM_IO | VM_DONTEXPAND; break; case RTAIL: if (!HFI1_CAP_IS_USET(DMA_RTAIL)) { @@ -514,23 +503,20 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma) flags &= ~VM_MAYWRITE; break; case SUBCTXT_UREGS: - memaddr = (u64)uctxt->subctxt_uregbase; + memvirt = uctxt->subctxt_uregbase; memlen = PAGE_SIZE; - flags |= VM_IO | VM_DONTEXPAND; - vmf = 1; + is_vmalloc = 1; break; case SUBCTXT_RCV_HDRQ: - memaddr = (u64)uctxt->subctxt_rcvhdr_base; + memvirt = uctxt->subctxt_rcvhdr_base; memlen = rcvhdrq_size(uctxt) * uctxt->subctxt_cnt; - flags |= VM_IO | VM_DONTEXPAND; - vmf = 1; + is_vmalloc = 1; break; case SUBCTXT_EGRBUF: - memaddr = (u64)uctxt->subctxt_rcvegrbuf; + memvirt = uctxt->subctxt_rcvegrbuf; memlen = uctxt->egrbufs.size * uctxt->subctxt_cnt; - flags |= VM_IO | VM_DONTEXPAND; flags &= ~VM_MAYWRITE; - vmf = 1; + is_vmalloc = 1; break; case SDMA_COMP: { struct hfi1_user_sdma_comp_q *cq = fd->cq; @@ -539,10 +525,9 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma) ret = -EFAULT; goto done; } - memaddr = (u64)cq->comps; + memvirt = cq->comps; memlen = PAGE_ALIGN(sizeof(*cq->comps) * cq->nentries); - flags |= VM_IO | VM_DONTEXPAND; - vmf = 1; + is_vmalloc = 1; break; } default: @@ -559,12 +544,10 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma) } vm_flags_reset(vma, flags); - mmap_cdbg(ctxt, subctxt, type, mapio, vmf, memaddr, memvirt, memdma, + mmap_cdbg(ctxt, subctxt, type, mapio, is_vmalloc, memaddr, memvirt, memdma, memlen, vma); - if (vmf) { - vma->vm_pgoff = PFN_DOWN(memaddr); - vma->vm_ops = &vm_ops; - ret = 0; + if (is_vmalloc) { + ret = remap_vmalloc_range(vma, memvirt, 0); } else if (memdma) { ret = dma_mmap_coherent(&dd->pcidev->dev, vma, memvirt, memdma, memlen); @@ -588,24 +571,6 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma) return ret; } -/* - * Local (non-chip) user memory is not mapped right away but as it is - * accessed by the user-level code. - */ -static vm_fault_t vma_fault(struct vm_fault *vmf) -{ - struct page *page; - - page = vmalloc_to_page((void *)(vmf->pgoff << PAGE_SHIFT)); - if (!page) - return VM_FAULT_SIGBUS; - - get_page(page); - vmf->page = page; - - return 0; -} - static __poll_t hfi1_poll(struct file *fp, struct poll_table_struct *pt) { struct hfi1_ctxtdata *uctxt; -- 2.55.0