1

I am using sparse linux tool to clean the noise from the code. Suppose I have following struct defined in file abc.c as:

static struct check1 {
  void __iomem **base_regs;
};

In the same file abc.c. I have following line of code as well (Let X be a positive integer):

case 1:

static struct check1 *check1_var;
struct check2 {
   void* __iomem base= check1_var -->base_regs[X];
}

case 2:

struct check2 {
   void __iomem *base= check1_var-->base_regs[X];
}

In Case 1, I am getting the following warning

warning: incorrect type in initializer (different address spaces)

However, this warning get removed when i switched to case 2.

My Question is: What is the difference between void __iomem * and void* __iomem. In my view they should be the same ? Please help me out here, I am not getting why this warning get removed in case 2.

Amit Sharma
  • 1,987
  • 2
  • 18
  • 29
  • http://stackoverflow.com/questions/19100536/what-is-the-use-of-iomem-in-linux-while-writing-device-drivers – Anbu.Sankar Oct 29 '14 at 09:03
  • @ANBU.SANKAR Thanks for sharing it here. But I have gone through this, but didn't find my answer. As you can see in `struct check1` `base_regs` is also tagged with `__iomem` and in both case i am assigning the `__iomem` tagged pointer then what is the difference. ? – Amit Sharma Oct 29 '14 at 09:06
  • 2
    @AmitSharma Read this http://lwn.net/Articles/102232/. This shows a similar discussion https://lkml.org/lkml/2014/9/24/1187. – iqstatic Oct 29 '14 at 10:08
  • @iqstatic Thanks.!! No explanation in there.. looking for explanation – Amit Sharma Oct 29 '14 at 10:19
  • 1
    @AmitSharma That is the way it has to be. – iqstatic Oct 29 '14 at 10:20

1 Answers1

1

As stated in the link mentioned, the 2.6.9 kernel and later contains a series of changes designed to improve how the kernel works with I/O memory. The first of these is a new __iomem annotation used to mark pointers to I/O memory. These annotations work much like the __user markers, except that they reference a different address space.

The definition is as given below:

# define __user         __attribute__((noderef, address_space(1)))
# define __iomem        __attribute__((noderef, address_space(2)))

As with __user, the __iomem marker serves a documentation role in the kernel code; it is ignored by the compiler. When checking the code with sparse, however, developers will see a whole new set of warnings caused by code which mixes normal pointers with __iomem pointers, or which de-references those pointers.

void* __iomem and void __iomem * are not the same. The latter is the way it has to be done as by using __iomem you are providing the attribute to the base pointer.

iqstatic
  • 2,322
  • 3
  • 21
  • 39