linux-xlnx kernel updating from 3.17.0 to 5.15.0, get_fs(), set_fs() macros

536 Views Asked by At

I am new to kernel driver development and I am trying update kernel version of a legacy project.

Example code is below

#include <linux/uaccess.h>

struct file *file_open(const char *path, int flags, int rights)
{
    struct file *filptr = NULL;
    int err = 0;
    oldfs = get_fs();
    set_fs(get_ds());
    filptr = filp_open(path, flags, rights);
    if (IS_ERR(filptr)) {
        err = PTR_ERR(filptr);
        return NULL;
     }
    return filptr;
}

void file_close(struct file *file)
{
    int retval = filp_close(file, NULL);
    printk("file_close retval: %d\n",retval);
    set_fs(oldfs);
}

I am having below implicit declaration of get_fs() and set_fs() macros.

/driver.c: In function 'file_open':
/driver.c:593:27: error: implicit declaration of function 'get_fs'; did you mean 'get_bh'? [-Werror=implicit-function-declaration]
  593 |     oldfs = (mm_segment_t)get_fs();
      |                           ^~~~~~
      |                           get_bh
/driver.c:593:5: error: conversion to non-scalar type requested
  593 |     oldfs = (mm_segment_t)get_fs();
      |     ^~~~~
/driver.c:594:5: error: implicit declaration of function 'set_fs'; did you mean 'sget_fc'? [-Werror=implicit-function-declaration]
  594 |     set_fs(get_ds());
      |     ^~~~~~
      |     sget_fc
/driver.c:594:12: error: implicit declaration of function 'get_ds'; did you mean 'get_bh'? [-Werror=implicit-function-declaration]
  594 |     set_fs(get_ds());
      |            ^~~~~~

get_fs() and set_fs() macros have been removed from arm architecture <asm/uaccess.h> user access header file. But they are still defined in <asm-generic/uaccess.h> header. I couldn't find if it is proper to use generic user access apis in <asm-generic/uaccess.h> header file. If include both headers, I get redefinition warnings and errors.

./include/asm-generic/uaccess.h:129: warning: "access_ok" redefined
  129 | #define access_ok(addr, size) __access_ok((unsigned long)(addr),(size))
      | 
In file included from ./include/linux/uaccess.h:11,
                 from ./include/linux/sched/task.h:11,
                 from ./include/linux/sched/signal.h:9,
                 from ./include/linux/rcuwait.h:6,
                 from ./include/linux/percpu-rwsem.h:7,
                 from ./include/linux/fs.h:33,
                 from ./include/linux/highmem.h:5,
                 from ./include/linux/bvec.h:10,
                 from ./include/linux/blk_types.h:10,
                 from ./include/linux/genhd.h:19,
                 from ./include/linux/blkdev.h:8,
                 from driver.c:6:
./arch/arm/include/asm/uaccess.h:251: note: this is the location of the previous definition
  251 | #define access_ok(addr, size)   (__range_ok(addr, size) == 0)
      | 
./include/asm-generic/uaccess.h:148: warning: "__put_user" redefined
  148 | #define __put_user(x, ptr) \
      | 
./arch/arm/include/asm/uaccess.h:378: note: this is the location of the previous definition
  378 | #define __put_user(x, ptr) put_user(x, ptr)
      | 
./include/asm-generic/uaccess.h:168: warning: "put_user" redefined
  168 | #define put_user(x, ptr)                                        \
      | 
./arch/arm/include/asm/uaccess.h:366: note: this is the location of the previous definition
  366 | #define put_user(x, ptr)                                                \
      | 
./include/asm-generic/uaccess.h:190: warning: "__get_user" redefined
  190 | #define __get_user(x, ptr)                                      \
      | 
./arch/arm/include/asm/uaccess.h:260: note: this is the location of the previous definition
  260 | #define __get_user(x, ptr) get_user(x, ptr)
      | 
./include/asm-generic/uaccess.h:230: warning: "get_user" redefined
  230 | #define get_user(x, ptr)                                        \
      | 
./arch/arm/include/asm/uaccess.h:213: note: this is the location of the previous definition
  213 | #define get_user(x, p)                                                  \
      | 
./include/asm-generic/uaccess.h:256:1: error: redefinition of '__clear_user'
  256 | __clear_user(void __user *to, unsigned long n)
      | ^~~~~~~~~~~~
./arch/arm/include/asm/uaccess.h:562:1: note: previous definition of '__clear_user' with type 'long unsigned int(void *, long unsigned int)'
  562 | __clear_user(void __user *addr, unsigned long n)
      | ^~~~~~~~~~~~
./include/asm-generic/uaccess.h:264:1: error: redefinition of 'clear_user'
  264 | clear_user(void __user *to, unsigned long n)
      | ^~~~~~~~~~
./arch/arm/include/asm/uaccess.h:588:42: note: previous definition of 'clear_user' with type 'long unsigned int(void *, long unsigned int)'
  588 | static inline unsigned long __must_check clear_user(void __user *to, unsigned long n)
      |                                          ^~~~~~~~~~

So as I understood, for arm architecture only one header must be included. After kernel version 4.11 recommended way to include architecture specific headers is with <linux/uaccess.h> header. And this header includes <asm/uaccess.h>. So I infer <asm-generic/uaccess.h> should not included directly.

But other architectures still have get_fs() and set_fs() macros available in their headers.

As I understand these macros are setter/getter for thread address space defined in thread_info structure. But arm architecture's struct thread_info definition does not define this field.

I would like to ask if these macros usage is deprecated for arm arch. Is there any way to access thread adress space for arm architecture. Where should I look, any hint is appreciated.

0

There are 0 best solutions below