Date: Wed, 17 Dec 2025 21:31:44 +0000 From: Vladimir Kondratyev <wulf@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: df49fd8efa1a - main - LinuxKPI: Implement vmap_pfn Message-ID: <69432140.44b43.40043075@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by wulf: URL: https://cgit.FreeBSD.org/src/commit/?id=df49fd8efa1a885089488458df0e7e88c9649c90 commit df49fd8efa1a885089488458df0e7e88c9649c90 Author: Vladimir Kondratyev <wulf@FreeBSD.org> AuthorDate: 2025-12-17 21:31:11 +0000 Commit: Vladimir Kondratyev <wulf@FreeBSD.org> CommitDate: 2025-12-17 21:31:11 +0000 LinuxKPI: Implement vmap_pfn Required by i915kms to support recent discrete graphics cards. MFC after: 1 week Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D54225 --- sys/compat/linuxkpi/common/include/linux/vmalloc.h | 3 + sys/compat/linuxkpi/common/src/linux_page.c | 65 ++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/sys/compat/linuxkpi/common/include/linux/vmalloc.h b/sys/compat/linuxkpi/common/include/linux/vmalloc.h index 00650a2df9b6..a7f77f090755 100644 --- a/sys/compat/linuxkpi/common/include/linux/vmalloc.h +++ b/sys/compat/linuxkpi/common/include/linux/vmalloc.h @@ -35,8 +35,11 @@ #define VM_MAP 0x0000 #define PAGE_KERNEL 0x0000 +#define vmap_pfn(...) linuxkpi_vmap_pfn(__VA_ARGS__) + void *vmap(struct page **pages, unsigned int count, unsigned long flags, int prot); +void *linuxkpi_vmap_pfn(unsigned long *pfns, unsigned int count, int prot); void vunmap(void *addr); #endif /* _LINUXKPI_LINUX_VMALLOC_H_ */ diff --git a/sys/compat/linuxkpi/common/src/linux_page.c b/sys/compat/linuxkpi/common/src/linux_page.c index 57ca1401b912..82f3a2a4639f 100644 --- a/sys/compat/linuxkpi/common/src/linux_page.c +++ b/sys/compat/linuxkpi/common/src/linux_page.c @@ -341,6 +341,16 @@ static struct mtx vmmaplock; int is_vmalloc_addr(const void *addr) { + struct vmmap *vmmap; + + mtx_lock(&vmmaplock); + LIST_FOREACH(vmmap, &vmmaphead[VM_HASH(addr)], vm_next) + if (addr == vmmap->vm_addr) + break; + mtx_unlock(&vmmaplock); + if (vmmap != NULL) + return (1); + return (vtoslab((vm_offset_t)addr & ~UMA_SLAB_MASK) != NULL); } @@ -418,6 +428,61 @@ vmap(struct page **pages, unsigned int count, unsigned long flags, int prot) return ((void *)off); } +#define VMAP_MAX_CHUNK_SIZE (65536U / sizeof(struct vm_page)) /* KMEM_ZMAX */ + +void * +linuxkpi_vmap_pfn(unsigned long *pfns, unsigned int count, int prot) +{ + vm_page_t m, *ma, fma; + vm_offset_t off, coff; + vm_paddr_t pa; + vm_memattr_t attr; + size_t size; + unsigned int i, c, chunk; + + size = ptoa(count); + off = kva_alloc(size); + if (off == 0) + return (NULL); + vmmap_add((void *)off, size); + + chunk = MIN(count, VMAP_MAX_CHUNK_SIZE); + attr = pgprot2cachemode(prot); + ma = malloc(chunk * sizeof(vm_page_t), M_TEMP, M_WAITOK | M_ZERO); + fma = NULL; + c = 0; + coff = off; + for (i = 0; i < count; i++) { + pa = IDX_TO_OFF(pfns[i]); + m = PHYS_TO_VM_PAGE(pa); + if (m == NULL) { + if (fma == NULL) + fma = malloc(chunk * sizeof(struct vm_page), + M_TEMP, M_WAITOK | M_ZERO); + m = fma + c; + vm_page_initfake(m, pa, attr); + } else { + pmap_page_set_memattr(m, attr); + } + ma[c] = m; + c++; + if (c == chunk || i == count - 1) { + pmap_qenter(coff, ma, c); + if (i == count - 1) + break; + coff += ptoa(c); + c = 0; + memset(ma, 0, chunk * sizeof(vm_page_t)); + if (fma != NULL) + memset(fma, 0, chunk * sizeof(struct vm_page)); + } + } + free(fma, M_TEMP); + free(ma, M_TEMP); + + return ((void *)off); +} + void vunmap(void *addr) {help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69432140.44b43.40043075>
