Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Getting the physical address of kmalloc's memory

898 views
Skip to first unread message

Armin

unread,
Nov 24, 2003, 11:59:46 AM11/24/03
to
No, this is not a 'google first' post. (Or at least I hope it isn't, because
I did spend some serious time already on this. :-) )

I work on ARM, and am writing a device driver. The problem is that I have a
peace of memory I dynamically allocate with kmalloc( ..,..,GPF_KERNEL). Now
our embedded device has a DMA-unit, which of course doesn't want to see the
return address of kmalloc, because it is virtual.

Now, the question is whether:

virt_to_phys( kmalloc_return_address )

gives me the physical address. Some posters at Google say 'yes', other say
'no' and again others say it depends on the platform. The latter therefore
doesn't sound logical.

On ARM, I suspect it is not, because my system violently crashes if I feed
this address to my DMA-unit. If I then take a fixed physical address and via
ioremap get a virtual address (actually a cookie, but on ARM this is
fortunately the same, which made testing easy), and do a virt_to_phys on
that cookie, I indeed don't get back my physical address. So this strengthes
me in my assumtion, virt_to_phys does something, but not what I hoped/some
believe ... (*)

So the first question is: What does virts_to_phys actually do (all all
platforms)?


Second question is, because I found the function consistent_alloc. This
function which is as I understood ARM and PPC only, and allocates a
uncached, but also unbuffered peace of memory (The latter is at least not
achived with kmalloc). However, it also gives me the hardware-address. So,
in my case this should solve the problem, but this still makes me wonder,
what developers on other platforms have to do to get a physical address of a
kmalloc-ed peace of memory.


So the second question: Does there exists a portable method at all?


Or am I missing somnething completely? In that case please educate me. :-)

Regards,

Armin

(*) Although it seems that for IA32 this behaviour is 'normal' in the way,
that virt_to_phys is not defibed for ioremap-ed addresses. However, in the
case - as on ARM - where cookies and virtual addresses are by luck
identical, this shouldn't matter since thevirt-to_phys function/macro cannot
tell of course whether it is a cookie or 'true' virtual address.

Pete Zaitcev

unread,
Nov 24, 2003, 12:51:14 PM11/24/03
to
On Mon, 24 Nov 2003 17:59:46 +0100, Armin wrote:

> No, this is not a 'google first' post. (Or at least I hope it isn't, because
> I did spend some serious time already on this. :-) )

Read /usr/src/linux/Documentation/DMA-mapping.txt.

> So the first question is: What does virts_to_phys actually do (all all
> platforms)?

Nothing that can be of any use to you. All uses of virt_to_phys
in drivers are bugs.

> Second question is, because I found the function consistent_alloc.

> [...]

Finally.

> what developers on other platforms have to do to get a physical address of a
> kmalloc-ed peace of memory.

Read /usr/src/linux/Documentation/DMA-mapping.txt .

> So the second question: Does there exists a portable method at all?

Yes.

> Or am I missing somnething completely? In that case please educate me. :-)

Umm, reading /usr/src/linux/Documentation/DMA-mapping.txt?

-- Pete

Jens.T...@physik.fu-berlin.de

unread,
Nov 24, 2003, 12:53:24 PM11/24/03
to
Armin <Armin.Gerri...@philips.com> wrote:
> I work on ARM, and am writing a device driver. The problem is that I have a
> peace of memory I dynamically allocate with kmalloc( ..,..,GPF_KERNEL). Now
> our embedded device has a DMA-unit, which of course doesn't want to see the
> return address of kmalloc, because it is virtual.

> Now, the question is whether:

> virt_to_phys( kmalloc_return_address )

> gives me the physical address. Some posters at Google say 'yes', other say
> 'no' and again others say it depends on the platform. The latter therefore
> doesn't sound logical.

You guess you don't need virt_to_phys() but virt_to_bus() when you
want to set up the devices DMA controller - virtual, phyiscal and
bus addresses can all be different and when you do DMA you need bus
addresses.
Regards, Jens
--
_ _____ _____
| ||_ _||_ _| Jens.T...@physik.fu-berlin.de
_ | | | | | |
| |_| | | | | | http://www.physik.fu-berlin.de/~toerring
\___/ens|_|homs|_|oerring

Armin Gerritsen

unread,
Nov 25, 2003, 5:38:35 AM11/25/03
to
> You guess you don't need virt_to_phys() but virt_to_bus() when you
> want to set up the devices DMA controller - virtual, phyiscal and
> bus addresses can all be different and when you do DMA you need bus
> addresses.
> Regards, Jens

Don't think so ... :-)

Look at the ARM headers:

/*
* These are *only* valid on the kernel direct mapped RAM memory.
*/
static inline unsigned long virt_to_phys(volatile void *x)
{
return __virt_to_phys((unsigned long)(x));
}

static inline void *phys_to_virt(unsigned long x)
{
return (void *)(__phys_to_virt((unsigned long)(x)));
}

and in some other file

#define __virt_to_bus(x) __virt_to_phys(x)
#define __bus_to_virt(x) __phys_to_virt(x)

:-)

Actually the "These are *only* valid on the kernel direct mapped RAM
memory." in combination with Pete's answer, explains it.

Regards,

Armin

PS You are right though that bus-addresses don't have to be the same, so it
is still a good advice for future googlers! (On our platform they are
however.)


Catalin Marinas

unread,
Nov 25, 2003, 6:16:54 AM11/25/03
to
Armin Gerritsen wrote:

>>You guess you don't need virt_to_phys() but virt_to_bus() when you
>>want to set up the devices DMA controller - virtual, phyiscal and
>>bus addresses can all be different and when you do DMA you need bus
>>addresses.
>> Regards, Jens
>
>
> Don't think so ... :-)
>
> Look at the ARM headers:

[...]

> Actually the "These are *only* valid on the kernel direct mapped RAM
> memory." in combination with Pete's answer, explains it.

Which ARM headers? For example, in include/asm-arm/arch-integrator/memory.h:

#define __virt_to_phys__is_a_macro
#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET)
#define __phys_to_virt__is_a_macro
#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET)

#define BUS_OFFSET (0x80000000UL)

#define __virt_to_bus__is_a_macro
#define __virt_to_bus(x) (x - PAGE_OFFSET + BUS_OFFSET)
#define __bus_to_virt__is_a_macro
#define __bus_to_virt(x) (x - BUS_OFFSET + PAGE_OFFSET)


virt_to_phys() and virt_to_bus() are *different*.

> PS You are right though that bus-addresses don't have to be the same, so it
> is still a good advice for future googlers! (On our platform they are
> however.)

But you did not specify the platform, only the CPU.

Regards,

Catalin

Armin Gerritsen

unread,
Nov 25, 2003, 7:24:18 AM11/25/03
to
>> PS You are right though that bus-addresses don't have to be the
>> same, so it is still a good advice for future googlers! (On our
>> platform they are however.)

> But you did not specify the platform, only the CPU.

You are right of course, they can be different or not. I wasn't trying to
suggest they are always identical.

But what actually matters is that virt_to_phys is NEVER a generic
conversion-routine between virtual and physical addresses. Of course it has
its use and probably also works for specific use-cases, but not for generic
conversion. Thanks to Pet's post I learned that now. On some platforms it
may work for specific cases, but not in general and not on all platforms.

For virt_to_bus something similar applies. Jens was right explaining that
there could be a difference. In my case it is not, but neither does it help
me get a dma-suitable address.

Sorry if I was unclear about that.

Armin


Armin Gerritsen

unread,
Nov 25, 2003, 9:40:36 AM11/25/03
to
Pete Zaitcev wrote:
> On Mon, 24 Nov 2003 17:59:46 +0100, Armin wrote:

>> No, this is not a 'google first' post. (Or at least I hope it isn't,
>> because I did spend some serious time already on this. :-) )

> Read /usr/src/linux/Documentation/DMA-mapping.txt.

Thanks, that solved it!

>> So the first question is: What does virts_to_phys actually do (all
>> all platforms)?

> Nothing that can be of any use to you. All uses of virt_to_phys
> in drivers are bugs.
>
>> Second question is, because I found the function consistent_alloc.
>> [...]

> Finally.

BTW It turned out that consistent_alloc is actually the implementation used
on ARM to implement the pci_xxx functions.

Regards,

Armin


0 new messages