All of lore.kernel.org
 help / color / mirror / Atom feed
* Address translation
@ 2000-11-21 14:41 Rubén Gallardo Fructuoso
  2000-11-21 17:20 ` Jeff Dike
  0 siblings, 1 reply; 19+ messages in thread
From: Rubén Gallardo Fructuoso @ 2000-11-21 14:41 UTC (permalink / raw)
  To: Linux-Kernel

	Hi everybody!

	I'm developing a module of file system filter and I have a question about
it. Does anybody know a function or method in order to translate an user
space pointer into a valid pointer in kernel mode?

	I'd like to avoid copying data (such as the 'copy_to_user' and
'copy_from_user' functions do) because it slows down my system.

	Thanks in advance,
	Rubén.



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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Address translation
  2000-11-21 14:41 Address translation Rubén Gallardo Fructuoso
@ 2000-11-21 17:20 ` Jeff Dike
  0 siblings, 0 replies; 19+ messages in thread
From: Jeff Dike @ 2000-11-21 17:20 UTC (permalink / raw)
  To: Rub n Gallardo Fructuoso; +Cc: Linux-Kernel

ruben@trymedia.com said:
> Does anybody know a function or method in order to translate an user
> space pointer into a valid pointer in kernel mode?

> 	I'd like to avoid copying data (such as the 'copy_to_user' and
> 'copy_from_user' functions do) because it slows down my system. 

The reason that everyone else uses copy_{to,from}_user is that there is no way 
to guarantee that the userspace pointer is valid.  That memory may have been 
swapped out.  The copy macros are prepared to fault the memory in.  The rest 
of the kernel is not.

				Jeff


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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Address translation
@ 2000-11-22 21:39 Keir Fraser
  2000-11-23  0:49 ` Pavel Machek
  2000-11-23 20:23 ` Andreas Bombe
  0 siblings, 2 replies; 19+ messages in thread
From: Keir Fraser @ 2000-11-22 21:39 UTC (permalink / raw)
  To: linux-kernel; +Cc: Keir.Fraser

> The reason that everyone else uses copy_{to,from}_user is that there
> is no way to guarantee that the userspace pointer is valid. That
> memory may have been swapped out. The copy macros are prepared to
> fault the memory in. The rest of the kernel is not.
>
> Jeff

I may be wrong on this, but I thought that copy_{to,from}_user are
only necessary if the address range you are accessing might cause a
fault which Linux cannot handle (ie. one which would cause the
application to segfault if it accessed that memory). If it is only a
matter of paging the memory in (and you are _sure_ the address range is
otherwise valid) I think the access macros are unnecessary. I would be
*very* glad if someone could confirm this, or shoot me down. :)

For instance, a kernel module I am writing allocates some memory in
the current process's address space as follows:

    down(&mm->mmap_sem);
    s->table = (void **)get_unmapped_area(0, SIZEOF_TABLE);
    if ( s->table != NULL )
        do_brk((unsigned long)s->table, SIZEOF_TABLE);
    up(&mm->mmap_sem);

Some questions:
 (1) In a "top half" thread, can I now access this memory without the
     access macros (since I know the address range is valid)?
 (2) Can I also access this memory from an interrupt/exception
     context, or must I lock it? (ie. can faults be handled from such
     a context) 
 (3) Is the above code sensible at all, or barking? It took me a while
     to figure that the above would work, and I think/hope it is the
     most elegant way to share memory between kernel and a process.

 Thanks in advance for any info!
 -- Keir Fraser

PS. Please cc me directly (kaf24@cl.cam.ac.uk) with any replies.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Address translation
  2000-11-22 21:39 Address translation Keir Fraser
@ 2000-11-23  0:49 ` Pavel Machek
  2000-11-23 20:23 ` Andreas Bombe
  1 sibling, 0 replies; 19+ messages in thread
From: Pavel Machek @ 2000-11-23  0:49 UTC (permalink / raw)
  To: Keir Fraser; +Cc: linux-kernel

Hi!

> otherwise valid) I think the access macros are unnecessary. I would be
> *very* glad if someone could confirm this, or shoot me down. :)
> 
> For instance, a kernel module I am writing allocates some memory in
> the current process's address space as follows:
> 
>     down(&mm->mmap_sem);
>     s->table = (void **)get_unmapped_area(0, SIZEOF_TABLE);
>     if ( s->table != NULL )
>         do_brk((unsigned long)s->table, SIZEOF_TABLE);
>     up(&mm->mmap_sem);
> 
> Some questions:
>  (1) In a "top half" thread, can I now access this memory without the
>      access macros (since I know the address range is valid)?
>  (2) Can I also access this memory from an interrupt/exception
>      context, or must I lock it? (ie. can faults be handled from such
>      a context) 

poof! I've shooted you.

You may definitely access such memory from interrupt.

-- 
Philips Velo 1: 1"x4"x8", 300gram, 60, 12MB, 40bogomips, linux, mutt,
details at http://atrey.karlin.mff.cuni.cz/~pavel/velo/index.html.

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Address translation
  2000-11-22 21:39 Address translation Keir Fraser
  2000-11-23  0:49 ` Pavel Machek
@ 2000-11-23 20:23 ` Andreas Bombe
  2000-11-23 21:04   ` Bjorn Wesen
  1 sibling, 1 reply; 19+ messages in thread
From: Andreas Bombe @ 2000-11-23 20:23 UTC (permalink / raw)
  To: Keir Fraser; +Cc: linux-kernel

On Wed, Nov 22, 2000 at 09:39:51PM +0000, Keir Fraser wrote:
> > The reason that everyone else uses copy_{to,from}_user is that there
> > is no way to guarantee that the userspace pointer is valid. That
> > memory may have been swapped out. The copy macros are prepared to
> > fault the memory in. The rest of the kernel is not.
> >
> > Jeff
> 
> I may be wrong on this, but I thought that copy_{to,from}_user are
> only necessary if the address range you are accessing might cause a
> fault which Linux cannot handle (ie. one which would cause the
> application to segfault if it accessed that memory). If it is only a
> matter of paging the memory in (and you are _sure_ the address range is
> otherwise valid) I think the access macros are unnecessary. I would be
> *very* glad if someone could confirm this, or shoot me down. :)

It is wrong.  copy_*_user handle the page faults, whether they are good
faults (swapped out, copy on write) or bad faults (illegal access).
Without these macros you get the "unable to handle kernel page fault"
oops message if a fault occurs.

> For instance, a kernel module I am writing allocates some memory in
> the current process's address space as follows:
> 
>     down(&mm->mmap_sem);
>     s->table = (void **)get_unmapped_area(0, SIZEOF_TABLE);
>     if ( s->table != NULL )
>         do_brk((unsigned long)s->table, SIZEOF_TABLE);
>     up(&mm->mmap_sem);
> 
> Some questions:
>  (1) In a "top half" thread, can I now access this memory without the
>      access macros (since I know the address range is valid)?

The address is valid, the pages probably aren't.  In fact, extending the
address space only creates read-only mappings to the global zeroed page
if I remember right.

>  (2) Can I also access this memory from an interrupt/exception
>      context, or must I lock it? (ie. can faults be handled from such
>      a context) 

You can't even use copy_*_user in this context (since the current user
space might be any process, even kernel threads that have no user space
at all).

For access to user memory from interrupt context at all and to access
user memory without the uaccess macros, you have to lock them down in
memory, with map_user_kiobuf().  This is only recommended if you want
hardware to DMA to/from buffers provided by user space.

>  (3) Is the above code sensible at all, or barking? It took me a while
>      to figure that the above would work, and I think/hope it is the
>      most elegant way to share memory between kernel and a process.

It will fail quickly, probably taking the kernel down with it.

The most elegant way to share memory between user and kernel is to
allocate the memory in the kernel and map it to user space (by
implementing mmap  on the kernel side for the file used for
communication).

-- 
 Andreas E. Bombe <andreas.bombe@munich.netsurf.de>    DSA key 0x04880A44
http://home.pages.de/~andreas.bombe/    http://linux1394.sourceforge.net/
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Address translation
  2000-11-23 20:23 ` Andreas Bombe
@ 2000-11-23 21:04   ` Bjorn Wesen
  2000-11-24 23:28     ` Andreas Bombe
  0 siblings, 1 reply; 19+ messages in thread
From: Bjorn Wesen @ 2000-11-23 21:04 UTC (permalink / raw)
  To: Andreas Bombe; +Cc: Keir Fraser, linux-kernel

On Thu, 23 Nov 2000, Andreas Bombe wrote:
> > I may be wrong on this, but I thought that copy_{to,from}_user are
> > only necessary if the address range you are accessing might cause a
> > fault which Linux cannot handle (ie. one which would cause the
> > application to segfault if it accessed that memory). If it is only a
> 
> It is wrong.  copy_*_user handle the page faults, whether they are good
> faults (swapped out, copy on write) or bad faults (illegal access).
> Without these macros you get the "unable to handle kernel page fault"
> oops message if a fault occurs.

Yes but only if it's a real fault, not if the address range actually is
a valid VMA which needs paging, COW'ing or related OS ops. copy_*_user
does not do the access in any different way than a "manual" access or
memcpy does, it just adds a .fixup section that tells the do_page_fault
handler that it should not segfault the kernel itself if the copy takes a
big fault at any point, instead it should jump to the fixup which makes
the copy routine return an error message.

However, the fixup stuff is not in-line with the copy code so there should
be absolutely no penalty using copy_*_user instead of a memcpy
(provided the copy_*_user is as optimized as the memcpy code), and it's
dangerous to assume anything about pages visible in user-space, they might
be unmapped by another thread while you're doing that memcpy etc.

> >  (1) In a "top half" thread, can I now access this memory without the
> >      access macros (since I know the address range is valid)?
> 
> The address is valid, the pages probably aren't.  In fact, extending the
> address space only creates read-only mappings to the global zeroed page
> if I remember right.

But it does not matter that the pages aren't there physically, any kind of
access (including an access from kernel-mode) will bring about the same
COW/change-on-write mechanism as copy_to_user or a user-mode access would.

The problem is rather that between your do_brk and when you access the
pages, a thread in the process might do an unmap or brk to remove the
mapping, then you crash the kernel.

> >  (2) Can I also access this memory from an interrupt/exception
> >      context, or must I lock it? (ie. can faults be handled from such
> >      a context) 
> 
> You can't even use copy_*_user in this context (since the current user
> space might be any process, even kernel threads that have no user space
> at all).
> 
> For access to user memory from interrupt context at all and to access
> user memory without the uaccess macros, you have to lock them down in
> memory, with map_user_kiobuf().  This is only recommended if you want
> hardware to DMA to/from buffers provided by user space.

Yup, if you are in the wrong context or in an interrupt context you'll die
horribly if you try to access user-pages that aren't there:

        if (in_interrupt() || !mm)
                goto no_context;

So you need to 1) make sure the pages are in physical memory and 2) make
sure the pages won't get removed from under your feet at any time and 3)
access them using their physical address

> >  (3) Is the above code sensible at all, or barking? It took me a while
> >      to figure that the above would work, and I think/hope it is the
> >      most elegant way to share memory between kernel and a process.
> 
> It will fail quickly, probably taking the kernel down with it.
> 
> The most elegant way to share memory between user and kernel is to
> allocate the memory in the kernel and map it to user space (by
> implementing mmap  on the kernel side for the file used for
> communication).

Agreed, but that does not cut it for some applications. For example, let's
say you want to grab 16 MB of video frames without copying them from that
mmap area to your malloc'ed 16 MB (let's say your CPU takes a pretty big
hit doing that extra memcpy) and you'd like to DMA directly into the
user-pages. 

You can of course make the kernel grab 16 MB worth of pages for you and
then mmap them into the process, but the kernel driver would be pretty
hooked to that demanding user process then.. 

Actually I'm trying to figure out the best way to do a similar thing for
some hardware we have - I have incoming DMA data containing JPG grabs, and
I want to cache images in a user-mode daemon, which will send pictures
from the cache out on TCP. The images might be generated with many
different JPG settings so they need right tags in the cache etc. 

Before when we ran on a chip without MMU this was easy - that user-mode
buffer was a contigous physical area which I could DMA directly in. But
now when we're going to a CPU with MMU, it gets more complicated of course
:) 

I have figured the options are

1) let the kernel driver have a buffer big enough for a single grab, mmap
this into user-space and do the memcpy into the cache (might be fast
enough, but our chip isn't super on memcpy's..)

2) let the kernel driver lock down the user-pages in an access and DMA
directly into them, and take abuse from QA when we get a race in the
driver vs VM system and it freaks out

3) let the kernel driver handle the complete cache including tags for the
frames in it, and make a more advanced interface between the driver and
the user-mode daemon

I think 3 would be easier to get stable than 2, if 1 is not fast enough..
oh well I'll just have to try all of them out :) 

-BW

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Address translation
  2000-11-23 21:04   ` Bjorn Wesen
@ 2000-11-24 23:28     ` Andreas Bombe
  0 siblings, 0 replies; 19+ messages in thread
From: Andreas Bombe @ 2000-11-24 23:28 UTC (permalink / raw)
  To: Bjorn Wesen; +Cc: Keir Fraser, linux-kernel

On Thu, Nov 23, 2000 at 10:04:18PM +0100, Bjorn Wesen wrote:
> On Thu, 23 Nov 2000, Andreas Bombe wrote:
> > > I may be wrong on this, but I thought that copy_{to,from}_user are
> > > only necessary if the address range you are accessing might cause a
> > > fault which Linux cannot handle (ie. one which would cause the
> > > application to segfault if it accessed that memory). If it is only a
> > 
> > It is wrong.  copy_*_user handle the page faults, whether they are good
> > faults (swapped out, copy on write) or bad faults (illegal access).
> > Without these macros you get the "unable to handle kernel page fault"
> > oops message if a fault occurs.
> 
> Yes but only if it's a real fault, not if the address range actually is
> a valid VMA which needs paging, COW'ing or related OS ops. copy_*_user
> does not do the access in any different way than a "manual" access or
> memcpy does, it just adds a .fixup section that tells the do_page_fault
> handler that it should not segfault the kernel itself if the copy takes a
> big fault at any point, instead it should jump to the fixup which makes
> the copy routine return an error message.

You're right, I remembered wrong.

> > >  (1) In a "top half" thread, can I now access this memory without the
> > >      access macros (since I know the address range is valid)?
> > 
> > The address is valid, the pages probably aren't.  In fact, extending the
> > address space only creates read-only mappings to the global zeroed page
> > if I remember right.
> 
> But it does not matter that the pages aren't there physically, any kind of
> access (including an access from kernel-mode) will bring about the same
> COW/change-on-write mechanism as copy_to_user or a user-mode access would.

However these faults can let you sleep (swap-in, or swap-out to make
room for a COW page).  That's defined for the uaccess macros, but might
come very unexpected with a memcpy.  Unexpected sleeps alone can make a
crash if the surrounding code does not allow it.

It's a moot point anyway, memcpy with user space is illegal.

-- 
 Andreas E. Bombe <andreas.bombe@munich.netsurf.de>    DSA key 0x04880A44
http://home.pages.de/~andreas.bombe/    http://linux1394.sourceforge.net/
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 19+ messages in thread

* address translation
@ 2003-05-15  3:50 Trevor Woerner
  0 siblings, 0 replies; 19+ messages in thread
From: Trevor Woerner @ 2003-05-15  3:50 UTC (permalink / raw)
  To: linuxppc-embedded


I want to setup a mapping so that when anything tries to read/write the
16 bytes of 0x1f0 - 0x1ff the actual physical memory that gets accessed
is 0xf7000000 - 0xf700000f.

I can't figure out what I need to call to get this done.

ioremap() is the exact opposite of what I want, and remap_page_range()
comes very close but aligns everything to the page boundary (in other
words, after I do the mapping, accessing 0x1f0 gives me 0xf70001f0
instead of 0xf7000000). I also tried using io_block_mapping(), which I
use in my platform io setup routine, but the MMU crashed with one of
those '###A' thingies. :-)

any suggestions, please?

	Trevor

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 19+ messages in thread

* address translation
@ 2003-05-15 11:29 Trevor Woerner
  2003-05-15 11:46 ` Gary Thomas
                   ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Trevor Woerner @ 2003-05-15 11:29 UTC (permalink / raw)
  To: linuxppc-dev


I want to setup a mapping so that when anything tries to read/write the
16 bytes at 0x1f0 - 0x1ff the actual physical memory that gets accessed
is 0xf7000000 - 0xf700000f.

I can't figure out what I need to call to get this done.

ioremap() is the exact opposite of what I want.

remap_page_range() comes very close but aligns everything to the page
boundary. In other words, after I do the mapping with either 0x1f0 or
0x0 as the virtual address, accessing 0x1f0 gives me 0xf70001f0 instead
of 0xf7000000. I don't want *page* translation, I need
*address-for-address* translation (if such a thing is possible). I
tried setting the physical address to 0xf7000000 - 0x1f0 but that
didn't work (I didn't think it would :-)

I think resetting _IO_BASE is just another page translation trick.

I also tried using io_block_mapping(), which I use in my platform io
setup routine, but the MMU crashed with one of those '###A' reports.

any suggestions, please?

        Trevor

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: address translation
  2003-05-15 11:29 Trevor Woerner
@ 2003-05-15 11:46 ` Gary Thomas
  2003-05-16  3:13   ` Trevor Woerner
  2003-05-15 12:13 ` Magnus Damm
  2003-05-15 14:05 ` Benjamin Herrenschmidt
  2 siblings, 1 reply; 19+ messages in thread
From: Gary Thomas @ 2003-05-15 11:46 UTC (permalink / raw)
  To: ppc339; +Cc: linuxppc-dev


On Thu, 2003-05-15 at 05:29, Trevor Woerner wrote:
> I want to setup a mapping so that when anything tries to read/write the
> 16 bytes at 0x1f0 - 0x1ff the actual physical memory that gets accessed
> is 0xf7000000 - 0xf700000f.
>
> I can't figure out what I need to call to get this done.
>
> ioremap() is the exact opposite of what I want.
>
> remap_page_range() comes very close but aligns everything to the page
> boundary. In other words, after I do the mapping with either 0x1f0 or
> 0x0 as the virtual address, accessing 0x1f0 gives me 0xf70001f0 instead
> of 0xf7000000. I don't want *page* translation, I need
> *address-for-address* translation (if such a thing is possible). I
> tried setting the physical address to 0xf7000000 - 0x1f0 but that
> didn't work (I didn't think it would :-)
>
> I think resetting _IO_BASE is just another page translation trick.
>
> I also tried using io_block_mapping(), which I use in my platform io
> setup routine, but the MMU crashed with one of those '###A' reports.
>

The memory management on the PowerPC does not have this capability.

I'd suggest rethinking how you are looking at this problem.
  * What is it that wants access to this specific range of physical
    memory in such a way?
Perhaps a specialized device driver would be a better choice.

--
Gary Thomas <gary@mlbassoc.com>
MLB Associates


** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: address translation
  2003-05-15 11:29 Trevor Woerner
  2003-05-15 11:46 ` Gary Thomas
@ 2003-05-15 12:13 ` Magnus Damm
  2003-05-16  3:14   ` Trevor Woerner
  2003-05-15 14:05 ` Benjamin Herrenschmidt
  2 siblings, 1 reply; 19+ messages in thread
From: Magnus Damm @ 2003-05-15 12:13 UTC (permalink / raw)
  To: ppc339; +Cc: linuxppc-dev


It sounds like you have some kind of memory mapped hardware like
an IDE device or a UART that in the PC world would be accessed
with in/out instructions. These instructions are mapped to a set
of macros/inline functions on a PC running Linux.
Once upon a time (I'm not sure how it works today) Linux for PowerPC
implemented all these in/out functions/macros using memory access to
a memory area could be mapped to one ore more physical addresses.

I don't think it is possible to remap individual bytes, you have to
stick with mapping one page at a time. And I think the in/out space
is limited to 64KBytes, and that gives you a maximum of 16 devices
if you use a pagesize of 4KByte.

I think the PCMCIA layer should be pretty flexible when it comes to
allocating addresses, maybe you could have a look at that.

/ magnus

On Thu, 15 May 2003 07:29:36 -0400
Trevor Woerner <ppc339@vtnet.ca> wrote:

>
> I want to setup a mapping so that when anything tries to read/write the
> 16 bytes at 0x1f0 - 0x1ff the actual physical memory that gets accessed
> is 0xf7000000 - 0xf700000f.
>
> I can't figure out what I need to call to get this done.
>
> ioremap() is the exact opposite of what I want.
>
> remap_page_range() comes very close but aligns everything to the page
> boundary. In other words, after I do the mapping with either 0x1f0 or
> 0x0 as the virtual address, accessing 0x1f0 gives me 0xf70001f0 instead
> of 0xf7000000. I don't want *page* translation, I need
> *address-for-address* translation (if such a thing is possible). I
> tried setting the physical address to 0xf7000000 - 0x1f0 but that
> didn't work (I didn't think it would :-)
>
> I think resetting _IO_BASE is just another page translation trick.
>
> I also tried using io_block_mapping(), which I use in my platform io
> setup routine, but the MMU crashed with one of those '###A' reports.
>
> any suggestions, please?
>
>         Trevor
>
>

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: address translation
  2003-05-15 11:29 Trevor Woerner
  2003-05-15 11:46 ` Gary Thomas
  2003-05-15 12:13 ` Magnus Damm
@ 2003-05-15 14:05 ` Benjamin Herrenschmidt
  2003-05-16  4:02   ` Trevor Woerner
  2 siblings, 1 reply; 19+ messages in thread
From: Benjamin Herrenschmidt @ 2003-05-15 14:05 UTC (permalink / raw)
  To: ppc339; +Cc: linuxppc-dev


On Thu, 2003-05-15 at 13:29, Trevor Woerner wrote:
> I want to setup a mapping so that when anything tries to read/write the
> 16 bytes at 0x1f0 - 0x1ff the actual physical memory that gets accessed
> is 0xf7000000 - 0xf700000f.

I would say you are taking the problem backward.

Tell us more about what you are doing. Looks like you have some IDE mapped
at 0xf7000000+. You need to tell IDE to use those. What kind of PPC CPU is
this ? IDE by default uses inx/outx accesses, which are relative to
_IO_BASE. So you just need to pass IDE some addresses that when offsetted
with _IO_BASE will fall in an ioremap'ed mapping of 0xf7000000

There is no MMU trick involved

Ben.


** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: address translation
  2003-05-15 11:46 ` Gary Thomas
@ 2003-05-16  3:13   ` Trevor Woerner
  0 siblings, 0 replies; 19+ messages in thread
From: Trevor Woerner @ 2003-05-16  3:13 UTC (permalink / raw)
  To: linuxppc-dev


On May 15, 2003 07:46 am, Gary Thomas wrote:
> On Thu, 2003-05-15 at 05:29, Trevor Woerner wrote:
> > I want to setup a mapping so that when anything tries to read/write
> > the 16 bytes at 0x1f0 - 0x1ff the actual physical memory that gets
> > accessed is 0xf7000000 - 0xf700000f.
>
> Perhaps a specialized device driver would be a better choice.

Unfortunately, that seems to be the path I'm going down.

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: address translation
  2003-05-15 12:13 ` Magnus Damm
@ 2003-05-16  3:14   ` Trevor Woerner
  0 siblings, 0 replies; 19+ messages in thread
From: Trevor Woerner @ 2003-05-16  3:14 UTC (permalink / raw)
  To: linuxppc-dev


On May 15, 2003 08:13 am, Magnus Damm wrote:
> I think the PCMCIA layer should be pretty flexible when it comes to
> allocating addresses, maybe you could have a look at that.

Thanks for your tips. This last one is ironic, considering it's PCMCIA
that I'm working with! :-)

	Trevor

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: address translation
  2003-05-15 14:05 ` Benjamin Herrenschmidt
@ 2003-05-16  4:02   ` Trevor Woerner
  2003-05-16  8:35     ` Geert Uytterhoeven
  2003-05-16  9:00     ` Benjamin Herrenschmidt
  0 siblings, 2 replies; 19+ messages in thread
From: Trevor Woerner @ 2003-05-16  4:02 UTC (permalink / raw)
  To: linuxppc-dev


On May 15, 2003 10:05 am, Benjamin Herrenschmidt wrote:
> On Thu, 2003-05-15 at 13:29, Trevor Woerner wrote:
> > I want to setup a mapping so that when anything tries to read/write
> > the 16 bytes at 0x1f0 - 0x1ff the actual physical memory that gets
> > accessed is 0xf7000000 - 0xf700000f.
>
> I would say you are taking the problem backward.

Yea, that sounds like me :-)

> Tell us more about what you are doing. Looks like you have some IDE
> mapped at 0xf7000000+. You need to tell IDE to use those. What kind
> of PPC CPU is this ?

I've got a PPC405gp-based device that has an on-board CompactFlash slot
into which CF cards can be inserted. But to save money there is no
PCMCIA controller, and the device is simply wired directly to 2 address
regions: 0xf7100000 for the attribute memory (which mostly holds config
information and the Card Information Structure (CIS) tuples) and
0xf7000000 which is where the card's ATA registers will show up (once a
card is inserted). If only it had been wired to 0xf70001f0...

The spec says these are supposed to be little endian, but I only get
meaningful data when I use big endian access (most devices on this
board appear to have been swapped in this way, e.g. RTC).

They want to be able to swap cards in and out, so I started with the
PCMCIA stuff. I've got the card detect interrupt working so inserting a
card will cause the ds.c, cs.c and all that other stuff to start
chugging along. I also twisted the cistpl.c code so it can successfully
read and parse the CIS structure.

But when it comes time to access the ATA registers I've hit a brick
wall. The default PCMCIA code keeps wanting to setup IO ranges at 0x1f0
and 0x3f6. So I've sliced out most of the configuration code from
ide-cs.c and have tried to "manually" set the ports start at 0xf000000
(0xf000000 + _IO_BASE = 0xf7000000). I don't think I've been too
successful. For one, the size of an io port is 'unsigned short' which
won't fit, so I changed that to 'unsigned int'.

This isn't a pci device, unfortunately, just straight memory-mapped. All
of the PCMCIA code expects this to be accessed using 2 IO windows with
ioremap()ping and so on. But because of the lack of wires I can only
access the device in "common-memory" mode (which the PCMCIA code isn't
setup to handle).

> IDE by default uses inx/outx accesses, which are
> relative to _IO_BASE. So you just need to pass IDE some addresses
> that when offsetted with _IO_BASE will fall in an ioremap'ed mapping
> of 0xf7000000

Ha! I spent most of the morning tracking this one down. I couldn't
figure out why, when I asked for 0xf700000, I kept getting illegal
accesses in the 0xdf000000 range (my _IO_BASE is set to 0xe8000000). So
now that I lie and ask for 0x0f000000 instead, the kernel stops
panicing :-)

> There is no MMU trick involved

Perhaps you can see why I was hopeful there was.

>From a cursory look at the ide.c code, it appears the kernel wants to
access the ATA registers one byte at a time. Unfortunately, because my
device is wired directly, I have to access it 16 bits at a time. So it
looks like I'm going to have to hack the ide.c code (or something like
it) to combine adjacent registers together before reading/writing.

Is it just me, or did the hard drive controllers of the 68k era
(drivers/ide/legacy/macide.c) have memory-mapped registers? I was
looking at their code today and it seems similar to what I'm looking
for (i think).

I can't help notice that in _2_4_devel, ide-cs.c has been moved to
drivers/ide/legacy. What is the intent here, what are we supposed to
use for cs cards?

> Ben.

p.s. are you coming to OLS again this year?

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: address translation
  2003-05-16  4:02   ` Trevor Woerner
@ 2003-05-16  8:35     ` Geert Uytterhoeven
  2003-05-16  9:00     ` Benjamin Herrenschmidt
  1 sibling, 0 replies; 19+ messages in thread
From: Geert Uytterhoeven @ 2003-05-16  8:35 UTC (permalink / raw)
  To: Trevor Woerner; +Cc: Linux/PPC Development


On Fri, 16 May 2003, Trevor Woerner wrote:
> >From a cursory look at the ide.c code, it appears the kernel wants to
> access the ATA registers one byte at a time. Unfortunately, because my
> device is wired directly, I have to access it 16 bits at a time. So it
> looks like I'm going to have to hack the ide.c code (or something like
> it) to combine adjacent registers together before reading/writing.

Which kernel are you using? In 2.4.21-rc2, you can easily override the
hwif->{IN,OUT}B() routines.

> Is it just me, or did the hard drive controllers of the 68k era
> (drivers/ide/legacy/macide.c) have memory-mapped registers? I was
> looking at their code today and it seems similar to what I'm looking
> for (i think).

Yes, on m68k all IDE interfaces are memory mapped (just like any other I/O).

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds


** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: address translation
  2003-05-16  4:02   ` Trevor Woerner
  2003-05-16  8:35     ` Geert Uytterhoeven
@ 2003-05-16  9:00     ` Benjamin Herrenschmidt
  1 sibling, 0 replies; 19+ messages in thread
From: Benjamin Herrenschmidt @ 2003-05-16  9:00 UTC (permalink / raw)
  To: ppc339; +Cc: linuxppc-dev


On Fri, 2003-05-16 at 06:02, Trevor Woerner wrote:

> But when it comes time to access the ATA registers I've hit a brick
> wall. The default PCMCIA code keeps wanting to setup IO ranges at 0x1f0
> and 0x3f6. So I've sliced out most of the configuration code from
> ide-cs.c and have tried to "manually" set the ports start at 0xf000000
> (0xf000000 + _IO_BASE = 0xf7000000). I don't think I've been too
> successful. For one, the size of an io port is 'unsigned short' which
> won't fit, so I changed that to 'unsigned int'.

What you can do is to setup different iops. Starting with 2.4.21,
the IDE layer let you change the accessor functions for a given
hwif. If you want to stick to an older kernel, you can tweak
the definition for IDE_INB etc...

Regarding address mappings, what you need is:

 - Provide a virtual mapping for f7000000. That is ioremap it
basically. The resulting virtual address will be called
ide_virt

 - Feed the IDE layer with a set of ports that start at

ide_virt - _IO_BASE

That way, when the IDE layer tries to do an inb() for example,
it will do an access to port + _IO_BASE, which will turn into
an access to port_offset + ide_virt - _IO_BASE + _IO_BASE,
that is port_offset + ide_virt, which is what you want.

> >From a cursory look at the ide.c code, it appears the kernel wants to
> access the ATA registers one byte at a time. Unfortunately, because my
> device is wired directly, I have to access it 16 bits at a time. So it
> looks like I'm going to have to hack the ide.c code (or something like
> it) to combine adjacent registers together before reading/writing.

Well. This is another issue. You basically need to redefine the
accessors IDE_INB/W etc... (or use custome iops in the hwif structure
for 2.4.21 and later kernels). Typically, you will do a 16 bits
access keeping only half of the read word for reads, or writing to
half of the 16 bits word for writes. There is nothing like accessing
2 registers at a time, registers will appear to be 16 bits each if
your bus is properly wired, it's just that IDE registers other than
the data register only contain 8 bits of useful data.

Also be careful that your HW engineers properly wired the ATA bus,
so that you don't have to byteswap the data. If this is done properly,
you will have to byteswap the control but not the data. That is
the "byte" access will work on the MSB of the 16 bits word while the
word accessors will do no byteswap. If you don't do that, then you'll
have problem with insw/outsw etc...

> Is it just me, or did the hard drive controllers of the 68k era
> (drivers/ide/legacy/macide.c) have memory-mapped registers? I was
> looking at their code today and it seems similar to what I'm looking
> for (i think).
>
> I can't help notice that in _2_4_devel, ide-cs.c has been moved to
> drivers/ide/legacy. What is the intent here, what are we supposed to
> use for cs cards?

We do mmio on powermac too. On pre 2.4.21, we did pointer tricks like
described above, on 2.4.21 and later, you can fill the hwif to use
different access functions for registers.

(look drivers/ide/ppc/pmac.c)

Ben.


** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 19+ messages in thread

* address translation
@ 2005-04-12 10:47 mani kandan
  2005-04-12 12:25 ` Henrik Nordstrom
  0 siblings, 1 reply; 19+ messages in thread
From: mani kandan @ 2005-04-12 10:47 UTC (permalink / raw)
  To: netfilter-devel

hello,

i am doing a project on  TCP connection passing.
where the socket is migrated from one server to
another.
the work was actually done by MR. Werner Almesberger.
http://tcpcp.sourceforge.net
here tcp connection details of a socket at server 1 is
dumped into file and, 
the socket created at second server is set with these
connection details.
now the packets destined to the first server has to be
redirected to second server. so i thought of using 
NAT and studied LVS and found that it is not helping 
me.
so i went for iptables.
i need to change the source and destination address of
a packet. so that the packets from the client are
re-routed to second server from  first server. at the
first server i want to change src address as first
server and dest address as second server of the packet
from client.

with iptables i was able to change the address from
the 
start of the connection. ie only for the connection as
whole. but i want to change address of the packet
sometime after the connection is established.is it
possible to do it and how to do it.
  
In documentation i found that address translation 
can only done for the first packet of the connection
and the following packets of that connection   

my question is whether it is possible to do address
translation in the intermediate state of connection.
i added the rule at the middle of the connection but
the address translation did not take place.

please can anyone help me in this


		
__________________________________ 
Do you Yahoo!? 
Read only the mail you want - Yahoo! Mail SpamGuard. 
http://promotions.yahoo.com/new_mail 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: address translation
  2005-04-12 10:47 address translation mani kandan
@ 2005-04-12 12:25 ` Henrik Nordstrom
  0 siblings, 0 replies; 19+ messages in thread
From: Henrik Nordstrom @ 2005-04-12 12:25 UTC (permalink / raw)
  To: mani kandan; +Cc: netfilter-devel

On Tue, 12 Apr 2005, mani kandan wrote:

> now the packets destined to the first server has to be
> redirected to second server. so i thought of using
> NAT and studied LVS and found that it is not helping
> me.

NAT/Address translation won't do any good here as it destroys the original 
address information in the IP header, and as a result the packet won't 
match the socket.

You need to use "direct routing" type forwarding, explicitly routing these 
packets to the new host.

Regards
Henrik

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2005-04-12 12:25 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2000-11-22 21:39 Address translation Keir Fraser
2000-11-23  0:49 ` Pavel Machek
2000-11-23 20:23 ` Andreas Bombe
2000-11-23 21:04   ` Bjorn Wesen
2000-11-24 23:28     ` Andreas Bombe
  -- strict thread matches above, loose matches on Subject: below --
2005-04-12 10:47 address translation mani kandan
2005-04-12 12:25 ` Henrik Nordstrom
2003-05-15 11:29 Trevor Woerner
2003-05-15 11:46 ` Gary Thomas
2003-05-16  3:13   ` Trevor Woerner
2003-05-15 12:13 ` Magnus Damm
2003-05-16  3:14   ` Trevor Woerner
2003-05-15 14:05 ` Benjamin Herrenschmidt
2003-05-16  4:02   ` Trevor Woerner
2003-05-16  8:35     ` Geert Uytterhoeven
2003-05-16  9:00     ` Benjamin Herrenschmidt
2003-05-15  3:50 Trevor Woerner
2000-11-21 14:41 Address translation Rubén Gallardo Fructuoso
2000-11-21 17:20 ` Jeff Dike

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.