Re: Can somebody expalin the __copy_user?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Jim!

As you seem to already have understood, the first three line naively copies
'size' bytes from 'from' to 'to'. I write "naively" because it might happen
that the copy fails; then a memory exception would occur. A memory fault
could occur for several reasons having there own way to handle the fault.
The extra code used in '__copy_user' is one way to handle simple errors.

The kernel contains a table (in section '__ex_table') containing entries (X,
Y) saying that if an error occurs at address X, then jump to address Y. The
entries declared in the '__copy_user' code thus say that if a memory error
occurs when executing the code at the label '0:', the handler should return
to (and then execute) the code at the label '3:', calculating the actual
number of copied bytes (I think :-). Likewise, an error at '1:' makes the
handler return to '2:', just skipping any more copying.

The pseudoinstruction '.previous' just tells the assembler to put the
following code/data in the section used before the current section, probably
the '.text' section.

Labels like '0:', '1:', ... are "local labels", which can be used several
times for different locations in the same code. They are then referenced by
'0b', '1f', ... meaning "label 0 searching backwards" and "label 1 searching
forwards" respectively.

  /Per

(By trying to explain something to someone else, you actually mostly explain
it to yourself.)


Split-up code:

 #define __copy_user(to,from,size)     \
do {         \
 int __d0, __d1;       \
 __asm__ __volatile__(      \

Naive copying code:
  "0: rep; movsl\n"     \
  " movl %3,%0\n"     \
  "1: rep; movsb\n"     \
  "2:\n"       \

Fixup code:
  ".section .fixup,\"ax\"\n"    \
  "3: lea 0(%3,%0,4),%0\n"    \
  " jmp 2b\n"     \
  ".previous\n"      \

Exception table:
  ".section __ex_table,\"a\"\n"    \
  " .align 4\n"     \
  " .long 0b,3b\n"     \
  " .long 1b,2b\n"     \
  ".previous"      \

"Arguments":
  : "=&c"(size), "=&D" (__d0), "=&S" (__d1)  \
  : "r"(size & 3), "0"(size / 4), "1"(to), "2"(from) \
  : "memory");      \
} while (0)

--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
IRC Channel:   irc.openprojects.net / #kernelnewbies
Web Page:      http://www.kernelnewbies.org/



[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux