Virtual addresses, ioremap, vmalloc, etc
Hello everyone,
I was wondering if someone could help clear my confusion.
In my company's legacy port (based on 3.4, dating back to 2.6) someone chose to map the first 16 MB of physical addresses using:
static struct map_desc tango_map_desc[] __initdata = {
{
.virtual = 0xf0000000,
.pfn =__phys_to_pfn(0),
.length = SZ_16M,
.type = MT_DEVICE,
},
};static void __init tango_map_io(void)
{
iotable_init(tango_map_desc, ARRAY_SIZE(tango_map_desc));
}Is the virtual address 0xf0000000 chosen arbitrary? Could I pick 0xf04200000 for example?
The same kernel, with no such boot-time mapping prints:
[ 0.000000] Memory: 641720K/655360K available (3135K kernel code, 109K rwdata, 1056K rodata, 3044K init, 218K bss, 13640K reserved, 0K cma-reserve) [ 0.000000] Virtual kernel memory layout: [ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB) [ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB) [ 0.000000] vmalloc : 0xe8800000 - 0xff000000 ( 360 MB) [ 0.000000] lowmem : 0xc0000000 - 0xe8000000 ( 640 MB)
It looks like 0xf0000000 is in the middle of the vmalloc space. Is it a good idea to "statically" map something there?
If I were to call ioremap(0, SZ_16M); at run-time, I would imagine the virtual address could be anywhere in the vmalloc space? There's no reason it would be 0xf0000000, right?
In short, is virtual address 0xf0000000 special in any way? (Other than being in the vmalloc space perhaps.)
For my own reference:
https://www.kernel.org/doc/Documentation/arm/memory.txt
Regards.
Quoted 16 lines · On Tuesday 01 December 2015 13:08:09 Mason wrote:
Hello everyone,
I was wondering if someone could help clear my confusion.
In my company's legacy port (based on 3.4, dating back to 2.6) someone chose to map the first 16 MB of physical addresses using:
static struct map_desc tango_map_desc[] __initdata = { { .virtual = 0xf0000000, .pfn =__phys_to_pfn(0), .length = SZ_16M, .type = MT_DEVICE, }, };
Quoted 7 lines
static void
__inittango_map_io(void){ iotable_init(tango_map_desc, ARRAY_SIZE(tango_map_desc)); }Is the virtual address
0xf0000000chosen arbitrary? Could I pick0xf04200000for example?
It is arbitrary, but normally should be naturally aligned.
Quoted 11 lines
The same kernel, with no such boot-time mapping prints:
[ 0.000000] Memory: 641720K/655360K available (3135K kernel code, 109K rwdata, 1056K rodata, 3044K init, 218K bss, 13640K reserved, 0K cma-reserve) [ 0.000000] Virtual kernel memory layout: [ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB) [ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB) [ 0.000000] vmalloc : 0xe8800000 - 0xff000000 ( 360 MB) [ 0.000000] lowmem : 0xc0000000 - 0xe8000000 ( 640 MB)It looks like
0xf0000000is in the middle of the vmalloc space. Is it a good idea to "statically" map something there?
We deal with that on a lof of platforms that still use a static mapping. I normally advocate not using that kind of mapping unless you can show a measurable performance difference on your platform.
Quoted 9 lines
If I were to call
ioremap(0, SZ_16M); at run-time, I would imagine the virtual address could be anywhere in the vmalloc space? There's no reason it would be0xf0000000, right?In short, is virtual address
0xf0000000special in any way? (Other than being in the vmalloc space perhaps.)For my own reference:
https://www.kernel.org/doc/Documentation/arm/memory.txt
I think 0xf0000000 is a common choice because that made an easy computation back in the days when most platforms used an io_p2v() to get a hardcoded virtual address, rather than calling ioremap as we do today.
Arnd
Quoted 50 lines · Arnd Bergmann
Quoted 16 lines · On Tuesday 01 December 2015 13:08:09 Mason wrote:
Hello everyone,
I was wondering if someone could help clear my confusion.
In my company's legacy port (based on 3.4, dating back to 2.6) someone chose to map the first 16 MB of physical addresses using:
static struct map_desc tango_map_desc[] __initdata = { { .virtual = 0xf0000000, .pfn =__phys_to_pfn(0), .length = SZ_16M, .type = MT_DEVICE, }, };Quoted 7 lines
static void
__inittango_map_io(void){ iotable_init(tango_map_desc, ARRAY_SIZE(tango_map_desc)); }Is the virtual address
0xf0000000chosen arbitrary? Could I pick0xf04200000for example?It is arbitrary, but normally should be naturally aligned.
Quoted 11 lines
The same kernel, with no such boot-time mapping prints:
[ 0.000000] Memory: 641720K/655360K available (3135K kernel code, 109K rwdata, 1056K rodata, 3044K init, 218K bss, 13640K reserved, 0K cma-reserve) [ 0.000000] Virtual kernel memory layout: [ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB) [ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB) [ 0.000000] vmalloc : 0xe8800000 - 0xff000000 ( 360 MB) [ 0.000000] lowmem : 0xc0000000 - 0xe8000000 ( 640 MB)It looks like
0xf0000000is in the middle of the vmalloc space. Is it a good idea to "statically" map something there?We deal with that on a lof of platforms that still use a static mapping. I normally advocate not using that kind of mapping unless you can show a measurable performance difference on your platform.
Quoted 7 lines
If I were to call
ioremap(0, SZ_16M); at run-time, I would imagine the virtual address could be anywhere in the vmalloc space? There's no reason it would be0xf0000000, right?In short, is virtual address
0xf0000000special in any way? (Other than being in the vmalloc space perhaps.)
Quoted 7 lines
Quoted 2 lines
For my own reference:
https://www.kernel.org/doc/Documentation/arm/memory.txtI think
0xf0000000is a common choice because that made an easy computation back in the days when most platforms used anio_p2v()to get a hardcoded virtual address, rather than calling ioremap as we do today.
Thanks for the detailed answer.
One more thing: when I configure earlyprintk, I'm supposed to provide physical AND virtual address of the UART.
If I'm not using a hard-coded P2V mapping, and instead rely on ioremap, how am I supposed to know the virtual address of the UART?
Regards.
Quoted 8 lines · On Tuesday 01 December 2015 15:35:34 Mason wrote:
Thanks for the detailed answer.
One more thing: when I configure earlyprintk, I'm supposed to provide physical AND virtual address of the UART.
If I'm not using a hard-coded P2V mapping, and instead rely on ioremap, how am I supposed to know the virtual address of the UART?
You can pick any number that has the correct alignment. Just keep using the same number that you get with the 0xf0000000 base, and it should be fine, the kernel will set up a section mapping for you.
Arnd
Quoted 61 lines · Mason
Quoted 50 lines · Arnd Bergmann
Quoted 16 lines · On Tuesday 01 December 2015 13:08:09 Mason wrote:
Hello everyone,
I was wondering if someone could help clear my confusion.
In my company's legacy port (based on 3.4, dating back to 2.6) someone chose to map the first 16 MB of physical addresses using:
static struct map_desc tango_map_desc[] __initdata = { { .virtual = 0xf0000000, .pfn =__phys_to_pfn(0), .length = SZ_16M, .type = MT_DEVICE, }, };Quoted 7 lines
static void
__inittango_map_io(void){ iotable_init(tango_map_desc, ARRAY_SIZE(tango_map_desc)); }Is the virtual address
0xf0000000chosen arbitrary? Could I pick0xf04200000for example?It is arbitrary, but normally should be naturally aligned.
Quoted 11 lines
The same kernel, with no such boot-time mapping prints:
[ 0.000000] Memory: 641720K/655360K available (3135K kernel code, 109K rwdata, 1056K rodata, 3044K init, 218K bss, 13640K reserved, 0K cma-reserve) [ 0.000000] Virtual kernel memory layout: [ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB) [ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB) [ 0.000000] vmalloc : 0xe8800000 - 0xff000000 ( 360 MB) [ 0.000000] lowmem : 0xc0000000 - 0xe8000000 ( 640 MB)It looks like
0xf0000000is in the middle of the vmalloc space. Is it a good idea to "statically" map something there?We deal with that on a lof of platforms that still use a static mapping. I normally advocate not using that kind of mapping unless you can show a measurable performance difference on your platform.
Quoted 7 lines
If I were to call
ioremap(0, SZ_16M); at run-time, I would imagine the virtual address could be anywhere in the vmalloc space? There's no reason it would be0xf0000000, right?In short, is virtual address
0xf0000000special in any way? (Other than being in the vmalloc space perhaps.)Quoted 7 lines
Quoted 2 lines
For my own reference:
https://www.kernel.org/doc/Documentation/arm/memory.txtI think
0xf0000000is a common choice because that made an easy computation back in the days when most platforms used anio_p2v()to get a hardcoded virtual address, rather than calling ioremap as we do today.Thanks for the detailed answer.
Quoted 8 lines
One more thing: when I configure earlyprintk, I'm supposed to provide physical AND virtual address of the UART.
If I'm not using a hard-coded P2V mapping, and instead rely on ioremap, how am I supposed to know the virtual address of the UART?
Regards.
I think you can use anything as long as it is correctly aligned (w.r.t MMU specification)
There is a specific mapping setup in arch/arm/kernel/head.S by the addruart macro
Quoted 16 lines · Mason
Hello everyone,
I was wondering if someone could help clear my confusion.
In my company's legacy port (based on 3.4, dating back to 2.6) someone chose to map the first 16 MB of physical addresses using:
static struct map_desc tango_map_desc[] __initdata = { { .virtual = 0xf0000000, .pfn =__phys_to_pfn(0), .length = SZ_16M, .type = MT_DEVICE, }, };
Quoted 7 lines
static void
__inittango_map_io(void){ iotable_init(tango_map_desc, ARRAY_SIZE(tango_map_desc)); }Is the virtual address
0xf0000000chosen arbitrary? Could I pick0xf04200000for example?
It is arbitrary, but the benefit of a static mapping is to enforce a specific alignment so the MMU entry can use larger page table elements and reduce TLB usage.
Quoted 11 lines
The same kernel, with no such boot-time mapping prints:
[ 0.000000] Memory: 641720K/655360K available (3135K kernel code, 109K rwdata, 1056K rodata, 3044K init, 218K bss, 13640K reserved, 0K cma-reserve) [ 0.000000] Virtual kernel memory layout: [ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB) [ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB) [ 0.000000] vmalloc : 0xe8800000 - 0xff000000 ( 360 MB) [ 0.000000] lowmem : 0xc0000000 - 0xe8000000 ( 640 MB)It looks like
0xf0000000is in the middle of the vmalloc space. Is it a good idea to "statically" map something there?
Yes. Static mappings are reused whenever you do a ioremap() that could match it.
Quoted 3 lines
If I were to call
ioremap(0, SZ_16M); at run-time, I would imagine the virtual address could be anywhere in the vmalloc space? There's no reason it would be0xf0000000, right?
Right. But if the static mapping is there, then ioremap() will return 0xf0000000.
Quoted 2 lines
In short, is virtual address
0xf0000000special in any way? (Other than being in the vmalloc space perhaps.)
It used to, but not anymore.
Nicolas