'结构mm_struct'没有名为“mmap_sem”的成员从 5.4.21 切换到 5.10.0-rc5 后模块构建中出现错误

发布于 2025-01-16 23:16:24 字数 1830 浏览 4 评论 0原文

我一直在我的 Linux 设备驱动程序中使用这个函数。这是为了将用户页面固定为用户虚拟地址(所需的页面数量)并获取其内核地址。顺便说一下,它是在linux-5.4.21中使用的。 (我认为这个方法可能有一些问题。但它有效,所以我正在使用它)

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(&current->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(&current->mm->mmap_sem);
    return kvaddr;
}

但是今天,当我尝试针对内核 5.10.0-rc5 构建模块时,我遇到了此错误消息。这意味着随着内核的升级,mm_struct 结构发生了变化。

/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(&current->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(&current->mm->mmap_sem);
      |                           ^~~~~~~~
      |                           mmap_base

我应该如何更改它以适应 5.10.0-rc5?我在 5.10.0-rc5 中搜索了 get_user_pages 的使用,但似乎没有锁定。那么,我可以删除 down_read 和 up_read 行吗? 也许我会继续下去。(删除线条)。

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 way, 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).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

别忘他 2025-01-23 23:16:24

在 Linux 内核 5.8 中,struct mm_structmmap_sem 成员被重命名为 mmap_lock,并添加了新的 mmap 锁定 API。

你可以这样做:

#include <linux/mm.h>
#ifndef MMAP_LOCK_INITIALIZER

/* Define mmap locking API for pre-5.8 kernels. */

/* This one should not be needed in a driver. */
static inline void mmap_init_lock(struct mm_struct *mm)
{
       init_rwsem(&mm->mmap_sem);
}

static inline void mmap_write_lock(struct mm_struct *mm)
{
       down_write(&mm->mmap_sem);
}

static inline int mmap_write_lock_killable(struct mm_struct *mm)
{
       return down_write_killable(&mm->mmap_sem);
}

static inline bool mmap_write_trylock(struct mm_struct *mm)
{
       return down_write_trylock(&mm->mmap_sem) != 0;
}

static inline void mmap_write_unlock(struct mm_struct *mm)
{
       up_write(&mm->mmap_sem);
}

static inline void mmap_write_downgrade(struct mm_struct *mm)
{
       downgrade_write(&mm->mmap_sem);
}

static inline void mmap_read_lock(struct mm_struct *mm)
{
       down_read(&mm->mmap_sem);
}

static inline int mmap_read_lock_killable(struct mm_struct *mm)
{
       return down_read_killable(&mm->mmap_sem);
}

static inline bool mmap_read_trylock(struct mm_struct *mm)
{
       return down_read_trylock(&mm->mmap_sem) != 0;
}

static inline void mmap_read_unlock(struct mm_struct *mm)
{
       up_read(&mm->mmap_sem);
}

#endif /* MMAP_LOCK_INITIALIZER */

然后将 down_read(¤t->mm->mmap_sem); 替换为 mmap_read_lock(current->mm); 并替换up_read(¤t->mm->mmap_sem);mmap_read_unlock(current->mm);

In Linux kernel 5.8, the mmap_sem member of struct mm_struct was renamed to mmap_lock and a new mmap locking API was added.

You could do something like this:

#include <linux/mm.h>
#ifndef MMAP_LOCK_INITIALIZER

/* Define mmap locking API for pre-5.8 kernels. */

/* This one should not be needed in a driver. */
static inline void mmap_init_lock(struct mm_struct *mm)
{
       init_rwsem(&mm->mmap_sem);
}

static inline void mmap_write_lock(struct mm_struct *mm)
{
       down_write(&mm->mmap_sem);
}

static inline int mmap_write_lock_killable(struct mm_struct *mm)
{
       return down_write_killable(&mm->mmap_sem);
}

static inline bool mmap_write_trylock(struct mm_struct *mm)
{
       return down_write_trylock(&mm->mmap_sem) != 0;
}

static inline void mmap_write_unlock(struct mm_struct *mm)
{
       up_write(&mm->mmap_sem);
}

static inline void mmap_write_downgrade(struct mm_struct *mm)
{
       downgrade_write(&mm->mmap_sem);
}

static inline void mmap_read_lock(struct mm_struct *mm)
{
       down_read(&mm->mmap_sem);
}

static inline int mmap_read_lock_killable(struct mm_struct *mm)
{
       return down_read_killable(&mm->mmap_sem);
}

static inline bool mmap_read_trylock(struct mm_struct *mm)
{
       return down_read_trylock(&mm->mmap_sem) != 0;
}

static inline void mmap_read_unlock(struct mm_struct *mm)
{
       up_read(&mm->mmap_sem);
}

#endif /* MMAP_LOCK_INITIALIZER */

Then replace down_read(¤t->mm->mmap_sem); with mmap_read_lock(current->mm); and replace up_read(¤t->mm->mmap_sem); with mmap_read_unlock(current->mm);.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文