I've been using this function in my linux device driver. This is to pin user pages for user virtual address (required number of pages) and get kernel address of it. By the ways, it was used in linux-5.4.21. (I think this method may have some problem. but it worked so I was using it)
static unsigned long uvirt_to_kvirt_ppin(unsigned long uvirt, unsigned long length, struct page *pages)
{
int res;
int offs;
uint64_t *kvpaddr;
uint64_t kvaddr;
uint64_t paddr;
offs = uvirt % PAGE_SIZE;
down_read(¤t->mm->mmap_sem);
res = get_user_pages( uvirt, length>>PAGE_SHIFT, FOLL_WRITE, &pages, NULL);
if (res) {
kvpaddr = kmap(pages);
kvaddr = ((unsigned long long int)(kvpaddr)+offs);
paddr = page_to_phys(pages) + offs;
}
else {
printk("get_user_pages failed! res = %x\n", res);
return -1;
}
up_read(¤t->mm->mmap_sem);
return kvaddr;
}
But today, when I was trying to build the module now against kernel 5.10.0-rc5, I met with this error message. This means as kernel was upgraded, the structure mm_struct was chagned.
/home/ckim/prj/abdsn/ab21sim/ab21tsim/QEMU/qemu_test/test_ldd_vanila/axpu_ldd_kc.c: In function ??uvirt_to_kvirt_ppin??:
/home/ckim/prj/abdsn/ab21sim/ab21tsim/QEMU/qemu_test/test_ldd_vanila/axpu_ldd_kc.c:246:26: error: ??struct mm_struct?? has no member named ??mmap_sem??; did you mean ??mmap_base???
246 | down_read(¤t->mm->mmap_sem);
| ^~~~~~~~
| mmap_base
/home/ckim/prj/abdsn/ab21sim/ab21tsim/QEMU/qemu_test/test_ldd_vanila/axpu_ldd_kc.c:257:27: error: ??struct mm_struct?? has no member named ??mmap_sem??; did you mean ??mmap_base???
257 | up_read(¤t->mm->mmap_sem);
| ^~~~~~~~
| mmap_base
How should I change it for 5.10.0-rc5? I searched the use of get_user_pages in 5.10.0-rc5 but there seems to be no locking around it. So, can I just remove the down_read and up_read lines? Probably I'll just go with it.(removing the lines).