lkml.org 
[lkml]   [1998]   [Nov]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: virt_to_bus and >1G of memory (was MAX_DMA_ADDRESS ...)
On Thu, Nov 12, 1998 at 09:07:38AM +0000, Linus Torvalds wrote:
> But the one using logical operations is safer in the presense of old
> drivers that don't do the right thing. There are some historical
> drivers that may mix physical and virtual addresses, and just masking
> off (or turning on) the high bits makes them work even though they
> shouldn't.
>
> For 2.3.x we definitely want to use the +-PAGE_OFFSET version.

There are indeed lots of mistakes, bugs and pitfalls with the existing
implementation.

One thing I've seen in some drivers is that virt_to_bus doesn't work on
a user-space address, _or_ an address in a module. So some drivers do
some pte lookups to get the right value. Those things don't work on
addresses in kernel space (because of 4M pages), but they do work on
addresses in a kernel module!

Fair enough technically, but the information that an address is (or may
be) in paged space isn't made very clear as these values are passed
around. unsigned longs are also passed around as virtual addresses from
time to time, which only makes things more confusing.

Then there are drivers which do virt_to_bus and bus_to_virt willy-nilly.
I'm under the impression from IO-mapping.txt that not every bus address
has a valid virt address. (Need ioremap in _some_, poorly specified
cases). And not every virt address has a valid bus address. But the
translation macros never return error codes and don't, in general, even
check the address ranges. Though some do (e.g. some ARM ones).

I'm of the opinion that (1) the address translation functions should at
least check the address ranges and print loud messages when they're
wrong (this can be done efficiently with a test and branch like the
locking functions); (2) all drivers should use ioremap/iounmap, which
should not do anything when the bus addresses are in the directly
addressable range.

Another possibility is to wrap the various address types in a struct,
just like the debugging code for pte_t et al.

E.g., ioaddr_t (bus), physaddr_t (CPU physical), kaddr_t (kernel
virtual), uaddr_t (user space) and char * (anything addressable in the
kernel -- all or kaddr_t and user-space and module addresses). Or some
other scheme.

I understand EGCS is getting better at treating structs containing a
single field as efficiently is plain old longs, so it might be
reasonably to enforce this typing. That would catch a lot of
translation errors.

Er, there's always C++ to automate conversions... Didn't think so ;-)

-- Jamie

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:45    [W:0.041 / U:0.576 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site