<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/">
  <channel rdf:about="http://blog.gmane.org/gmane.linux.kernel.cross-arch">
    <title>gmane.linux.kernel.cross-arch</title>
    <link>http://blog.gmane.org/gmane.linux.kernel.cross-arch</link>
    <description/>
    <syn:updatePeriod>hourly</syn:updatePeriod>
    <syn:updateFrequency>1</syn:updateFrequency>
    <syn:updateBase>1901-01-01T00:00+00:00</syn:updateBase>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14256"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14255"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14252"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14249"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14248"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14247"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14246"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14245"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14244"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14243"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14242"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14241"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14240"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14239"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14238"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14237"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14236"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14235"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14234"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14233"/>
      </rdf:Seq>
    </items>
    <image rdf:resource="http://gmane.org/img/gmane-25t.png"/>
    <textinput rdf:resource=""/>
  </channel>
  <image rdf:about="http://gmane.org/img/gmane-25t.png">
    <title>Gmane</title>
    <url>http://gmane.org/img/gmane-25t.png</url>
    <link>http://gmane.org</link>
  </image>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14256">
    <title>Re: [PATCH 1/4] [-next] Makefile: Do not call cc-option before including the arch's Makefile</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14256</link>
    <description>&lt;pre&gt;Dne 20.5.2012 11:27, Sam Ravnborg napsal(a):

The first patch has to go to the tip tree, where the CONFIG_READABLE_ASM
option is introduced. The remaining patches can go to the individual
arch trees, I see Geert already pushed the m68k one.

Michal
&lt;/pre&gt;</description>
    <dc:creator>Michal Marek</dc:creator>
    <dc:date>2012-05-25T12:29:40</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14255">
    <title>[PATCH 1/1] openrisc: use generic strncpy_from_user</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14255</link>
    <description>&lt;pre&gt;
As per commits 2922585b93294d47172a765115e0dbc1bfe1be19
("lib: Sparc's strncpy_from_user is generic enough, move under lib/"),
92ae03f2ef99fbc23bfa9080d6b58f25227bd7ef ("x86: merge 32/64-bit versions
of 'strncpy_from_user()' and speed it up"), and corresponding
discussion on linux-arch.

Signed-off-by: Jonas Bonn &amp;lt;jonas&amp;lt; at &amp;gt;southpole.se&amp;gt;
---

Hi Linus,

Here's a single patch update to the OpenRISC arch to use the new
strncpy_from_user implementation.  Hope it's ok to send it as a
single patch and not as a pull request; let me know otherwise.

Thanks,
Jonas

 arch/openrisc/Kconfig               |    1 +
 arch/openrisc/include/asm/uaccess.h |   10 ++-----
 arch/openrisc/lib/string.S          |   52 -----------------------------------
 3 files changed, 4 insertions(+), 59 deletions(-)

diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
index da4ccd1..ee4d124 100644
--- a/arch/openrisc/Kconfig
+++ b/arch/openrisc/Kconfig
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -19,6 +19,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; config OPENRISC
 select GENERIC_CPU_DEVICES
 select GENERIC_ATOMIC64
 select GENERIC_CLOCKEVENTS
+select GENERIC_STRNCPY_FROM_USER
 
 config MMU
 def_bool y
diff --git a/arch/openrisc/include/asm/uaccess.h b/arch/openrisc/include/asm/uaccess.h
index f5abaa0..04b93de 100644
--- a/arch/openrisc/include/asm/uaccess.h
+++ b/arch/openrisc/include/asm/uaccess.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -313,14 +313,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; clear_user(void *addr, unsigned long size)
 return size;
 }
 
-extern int __strncpy_from_user(char *dst, const char *src, long count);
+#define user_addr_max() \
+(segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL)
 
-static inline long strncpy_from_user(char *dst, const char *src, long count)
-{
-if (access_ok(VERIFY_READ, src, 1))
-return __strncpy_from_user(dst, src, count);
-return -EFAULT;
-}
+extern long strncpy_from_user(char *dest, const char __user *src, long count);
 
 /*
  * Return the size of a string (including the ending 0)
diff --git a/arch/openrisc/lib/string.S b/arch/openrisc/lib/string.S
index 465f04b..8ceb11e 100644
--- a/arch/openrisc/lib/string.S
+++ b/arch/openrisc/lib/string.S
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -104,58 +104,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; __clear_user:
 .long 9b, 99b// write fault
 .previous
 
-/*
- * long strncpy_from_user(char *dst, const char *src, long count)
- *
- *
- */
-.global__strncpy_from_user
-__strncpy_from_user:
-l.addi  r1,r1,-16
-l.sw    0(r1),r6
-l.sw    4(r1),r5
-l.sw    8(r1),r4
-l.sw    12(r1),r3
-
-l.addi  r11,r5,0
-2:  l.sfeq  r5,r0
-l.bf    1f
-l.addi  r5,r5,-1
-8:    l.lbz   r6,0(r4)
-l.sfeq  r6,r0
-l.bf    1f
-9:    l.sb    0(r3),r6
-l.addi  r3,r3,1
-l.j     2b
-l.addi  r4,r4,1
-1:
-l.lwz   r6,0(r1)
-l.addi  r5,r5,1
-l.sub   r11,r11,r5              // r11 holds the return value
-
-l.lwz   r6,0(r1)
-l.lwz   r5,4(r1)
-l.lwz   r4,8(r1)
-l.lwz   r3,12(r1)
-l.jr    r9
-l.addi  r1,r1,16
-
-.section .fixup, "ax"
-99:
-l.movhi r11,hi(-EFAULT)
-l.ori   r11,r11,lo(-EFAULT)
-
-l.lwz   r6,0(r1)
-l.lwz   r5,4(r1)
-l.lwz   r4,8(r1)
-l.lwz   r3,12(r1)
-l.jrr9
-l.addi  r1,r1,16
-.previous
-
-.section __ex_table, "a"
-.long 8b, 99b// read fault
-.previous
 
 /*
  * extern int __strnlen_user(const char *str, long len, unsigned long top);
&lt;/pre&gt;</description>
    <dc:creator>Jonas Bonn</dc:creator>
    <dc:date>2012-05-25T06:24:49</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14252">
    <title>[PATCH 2/3 v2] kernel: Move REPEAT_BYTE definition into linux/kernel.h</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14252</link>
    <description>&lt;pre&gt;
And make sure that everything using it explicitly includes
that header file.

Signed-off-by: David S. Miller &amp;lt;davem&amp;lt; at &amp;gt;davemloft.net&amp;gt;
---
 arch/sparc/lib/usercopy.c             |    3 +--
 arch/x86/include/asm/word-at-a-time.h |    4 ++--
 fs/namei.c                            |    1 +
 include/linux/kernel.h                |    2 ++
 4 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/sparc/lib/usercopy.c b/arch/sparc/lib/usercopy.c
index f61ed82..0b12e91 100644
--- a/arch/sparc/lib/usercopy.c
+++ b/arch/sparc/lib/usercopy.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,5 +1,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include &amp;lt;linux/module.h&amp;gt;
 #include &amp;lt;linux/uaccess.h&amp;gt;
+#include &amp;lt;linux/kernel.h&amp;gt;
 #include &amp;lt;linux/errno.h&amp;gt;
 #include &amp;lt;linux/bug.h&amp;gt;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -11,8 +12,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void copy_from_user_overflow(void)
 }
 EXPORT_SYMBOL(copy_from_user_overflow);
 
-#define REPEAT_BYTE(x)((~0ul / 0xff) * (x))
-
 static inline long find_zero(unsigned long mask)
 {
 long byte = 0;
diff --git a/arch/x86/include/asm/word-at-a-time.h b/arch/x86/include/asm/word-at-a-time.h
index e58f03b..ae03fac 100644
--- a/arch/x86/include/asm/word-at-a-time.h
+++ b/arch/x86/include/asm/word-at-a-time.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,6 +1,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #ifndef _ASM_WORD_AT_A_TIME_H
 #define _ASM_WORD_AT_A_TIME_H
 
+#include &amp;lt;linux/kernel.h&amp;gt;
+
 /*
  * This is largely generic for little-endian machines, but the
  * optimal byte mask counting is probably going to be something
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -35,8 +37,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline long count_masked_bytes(long mask)
 
 #endif
 
-#define REPEAT_BYTE(x)((~0ul / 0xff) * (x))
-
 /* Return the high bit set in the first byte that is a zero */
 static inline unsigned long has_zero(unsigned long a)
 {
diff --git a/fs/namei.c b/fs/namei.c
index f9e883c..8d2ba42 100644
--- a/fs/namei.c
+++ b/fs/namei.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -16,6 +16,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 #include &amp;lt;linux/init.h&amp;gt;
 #include &amp;lt;linux/export.h&amp;gt;
+#include &amp;lt;linux/kernel.h&amp;gt;
 #include &amp;lt;linux/slab.h&amp;gt;
 #include &amp;lt;linux/fs.h&amp;gt;
 #include &amp;lt;linux/namei.h&amp;gt;
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 645231c..fbe9bfa 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -38,6 +38,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 #define STACK_MAGIC0xdeadbeef
 
+#define REPEAT_BYTE(x)((~0ul / 0xff) * (x))
+
 #define ALIGN(x, a)__ALIGN_KERNEL((x), (a))
 #define __ALIGN_MASK(x, mask)__ALIGN_KERNEL_MASK((x), (mask))
 #define PTR_ALIGN(p, a)((typeof(p))ALIGN((unsigned long)(p), (a)))
&lt;/pre&gt;</description>
    <dc:creator>David Miller</dc:creator>
    <dc:date>2012-05-24T20:26:19</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14249">
    <title>Re: [PATCH 1/3] sparc: Increase portability of strncpy_from_user() implementation.</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14249</link>
    <description>&lt;pre&gt;From: Linus Torvalds &amp;lt;torvalds&amp;lt; at &amp;gt;linux-foundation.org&amp;gt;
Date: Thu, 24 May 2012 09:04:27 -0700


Ok, I'll make this adjustment.
&lt;/pre&gt;</description>
    <dc:creator>David Miller</dc:creator>
    <dc:date>2012-05-24T20:04:36</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14248">
    <title>Re: [PATCH 3/3] lib: Sparc's strncpy_from_user is generic enough, move under lib/</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14248</link>
    <description>&lt;pre&gt;From: David Howells &amp;lt;dhowells&amp;lt; at &amp;gt;redhat.com&amp;gt;
Date: Thu, 24 May 2012 17:10:48 +0100


Thanks I'll fix that up.
&lt;/pre&gt;</description>
    <dc:creator>David Miller</dc:creator>
    <dc:date>2012-05-24T19:53:22</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14247">
    <title>Re: [PATCH 3/3] lib: Sparc's strncpy_from_user is generic enough, move under lib/</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14247</link>
    <description>&lt;pre&gt;

Contingent on removing the extraneous semicolon:

Acked-by: David Howells &amp;lt;dhowells&amp;lt; at &amp;gt;redhat.com&amp;gt;
&lt;/pre&gt;</description>
    <dc:creator>David Howells</dc:creator>
    <dc:date>2012-05-24T17:17:52</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14246">
    <title>Re: Arch maintainers Ahoy!</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14246</link>
    <description>&lt;pre&gt;

No, I didn't phrase the paragraph above very well, so let me rephrase: I think
Dave's patch is _good_[*] and that BSF/BSR would _not_ be usable for it.

I was thinking that reordering the bytes on LE might help, but no, it doesn't
as Dave's algorithm works equally well, no matter on the order the bytes are
in.

David

[*] Barring an extraneous semicolon already pointed out
&lt;/pre&gt;</description>
    <dc:creator>David Howells</dc:creator>
    <dc:date>2012-05-24T17:16:46</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14245">
    <title>Re: Arch maintainers Ahoy!</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14245</link>
    <description>&lt;pre&gt;
David, I don't think you've followed this saga very well.

That word-at-a-time algorithm *comes* from x86. Literally. The code is
90% pure copies from arch/x86/lib/usercopy.c.

We *know* how the code should be written on little-endian, AND IT IS
BOTH BETTER AND FASTER there.

Seriously. Little-endian is *superior* for string handling. No
questions. In fact, anybody who thinks that big-endian is better for
*anything* is seriously deluded these days.

Also, BSF is too damn slow. It's slow as hell on most older x86 chips,
and it's pointless. You can do clever tricks (again - only on
little-endian) that do it portably without it. Grep for
count_masked_bytes in the current tree, which does need a fast
multiplier on 64-bit, but fast multipliers are way more common than
the fast bit scan instructions.

I'd love to use a population count instruction, but efficient popc
instructions are simply not widely enough available. And the bsf
instruction is very slow on old x86 microarchitectures.

                  Linus
&lt;/pre&gt;</description>
    <dc:creator>Linus Torvalds</dc:creator>
    <dc:date>2012-05-24T16:56:34</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14244">
    <title>Re: Arch maintainers Ahoy!</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14244</link>
    <description>&lt;pre&gt;

I didn't suggest it was free, but it might be cheaper.  Besides x86/x86_64 has
BSF/BSR instructions - though having played with Dave's algorithm some, I
don't think they're usable for this.

My suggestion assumes that there would be zeros beyond the terminal NUL, which
isn't something you can rely on.

David
&lt;/pre&gt;</description>
    <dc:creator>David Howells</dc:creator>
    <dc:date>2012-05-24T16:45:29</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14243">
    <title>Re: [PATCH 1/3] sparc: Increase portability of strncpy_from_user() implementation.</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14243</link>
    <description>&lt;pre&gt;SH-4A processors fall under this. All of them support efficient 32-bit
unaligned loads but no stores at all or loads of any other size. Having
said that, the compiler isn't exactly brilliant at figuring out when to
emit them, so I'd probably still have to do it by hand.
&lt;/pre&gt;</description>
    <dc:creator>Paul Mundt</dc:creator>
    <dc:date>2012-05-24T16:25:00</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14242">
    <title>Re: [PATCH 3/3] lib: Sparc's strncpy_from_user is generic enough, move under lib/</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14242</link>
    <description>&lt;pre&gt;

You've an extra semicolon there.

David
&lt;/pre&gt;</description>
    <dc:creator>David Howells</dc:creator>
    <dc:date>2012-05-24T16:10:48</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14241">
    <title>Re: [PATCH 1/3] sparc: Increase portability of strncpy_from_user() implementation.</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14241</link>
    <description>&lt;pre&gt;
Btw, this would have been much cleaner with something like

   #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
      #define IS_UNALIGNED(src,dst) 0
   #else
      #define IS_UNALIGNED(src,dst) (((long)(src) | (long)(dst)) &amp;amp;
(sizeof(long) - 1))
   #endif

and then just

     if (IS_UNALIGNED(src,dst))
        goto byte_at_a_time;

in the source code. Those #ifdef's in the middle of the code really
are horribly ugly, and are unnecessary.

Besides, some architecture may actually have ok unaligned loads, and
just horrible unaligned stores, and it would be easier with that kind
of abstraction.

Not a big deal, but I thought I'd point it out when I shuddered when I
looked at it.

                      Linus
&lt;/pre&gt;</description>
    <dc:creator>Linus Torvalds</dc:creator>
    <dc:date>2012-05-24T16:04:27</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14240">
    <title>Re: Arch maintainers Ahoy!</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14240</link>
    <description>&lt;pre&gt;
First off, the *last* thing you want to do is go to big-endian mode.
All the bit counting gets *much* more complicated, and your argument
that it's "free" on some architectures is pointless, since it is only
free on the architectures that have the *least* users.

Secondly, it's not "likely a single instruction" on LE, neither is
ffs. It can be, but it's often one of the slower instructions.

Many architectures will have - but only in their most recent uarch
versions - popcount or similar, and if you're little-endian, that
would be what you want. Except we already figured out faster versions
for little-endian based on multiplication or a few add/shift
operations.

                        Linus
&lt;/pre&gt;</description>
    <dc:creator>Linus Torvalds</dc:creator>
    <dc:date>2012-05-24T15:53:20</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14239">
    <title>Re: Arch maintainers Ahoy!</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14239</link>
    <description>&lt;pre&gt;
Linus Torvalds &amp;lt;torvalds&amp;lt; at &amp;gt;linux-foundation.org&amp;gt; wrote:



Could you use cpu_to_be32/64() and then ffs()?  That ought to work for both
variants of endianness.  The cpu_to_beXX() should be a noop on BE and is
likely to be a single instruction on LE.  The meat of ffs() is usually a
single instruction, though it may have to have zero-detect logic added.

David
&lt;/pre&gt;</description>
    <dc:creator>David Howells</dc:creator>
    <dc:date>2012-05-24T09:40:16</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14238">
    <title>Re: Arch maintainers Ahoy!</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14238</link>
    <description>&lt;pre&gt;From: Paul Mackerras &amp;lt;paulus&amp;lt; at &amp;gt;samba.org&amp;gt;
Date: Thu, 24 May 2012 15:25:45 +1000


I know, guess whose glibc strlen asm I got these formulas from?
:-)


I'm sure a powerpc person can cons up a patch that does that once
my stuff goes in, and test it too.
&lt;/pre&gt;</description>
    <dc:creator>David Miller</dc:creator>
    <dc:date>2012-05-24T05:56:40</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14237">
    <title>Re: Arch maintainers Ahoy!</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14237</link>
    <description>&lt;pre&gt;

Sounds good, thanks for doing this.  On PowerPC we have the "count
leading zeroes" instructions we could use to find the position of the
leftmost zero byte, so if you can conveniently make the find_zero()
function overridable, that would be good.

Paul.
&lt;/pre&gt;</description>
    <dc:creator>Paul Mackerras</dc:creator>
    <dc:date>2012-05-24T05:25:45</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14236">
    <title>[PATCH 3/3] lib: Sparc's strncpy_from_user is generic enough, move under lib/</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14236</link>
    <description>&lt;pre&gt;
To use this, an architecture simply needs to:

1) Provide a user_addr_max() implementation via asm/uaccess.h

2) Add "select GENERIC_STRNCPY_FROM_USER" to their arch Kcnfig

3) Remove the existing strncpy_from_user() implementation and symbol
   exports their architecture had.

Signed-off-by: David S. Miller &amp;lt;davem&amp;lt; at &amp;gt;davemloft.net&amp;gt;
---
 arch/sparc/Kconfig        |    1 +
 arch/sparc/lib/usercopy.c |  138 --------------------------------------------
 lib/Kconfig               |    3 +
 lib/Makefile              |    2 +
 lib/strncpy_from_user.c   |  140 +++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 146 insertions(+), 138 deletions(-)
 create mode 100644 lib/strncpy_from_user.c

diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 051af37..2247423 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -32,6 +32,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; config SPARC
 select HAVE_NMI_WATCHDOG if SPARC64
 select HAVE_BPF_JIT
 select GENERIC_SMP_IDLE_THREAD
+select GENERIC_STRNCPY_FROM_USER
 
 config SPARC32
 def_bool !64BIT
diff --git a/arch/sparc/lib/usercopy.c b/arch/sparc/lib/usercopy.c
index 3d3bef9..5c4284c 100644
--- a/arch/sparc/lib/usercopy.c
+++ b/arch/sparc/lib/usercopy.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,147 +1,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include &amp;lt;linux/module.h&amp;gt;
-#include &amp;lt;linux/uaccess.h&amp;gt;
 #include &amp;lt;linux/kernel.h&amp;gt;
-#include &amp;lt;linux/errno.h&amp;gt;
 #include &amp;lt;linux/bug.h&amp;gt;
 
-#include &amp;lt;asm/byteorder.h&amp;gt;
-
 void copy_from_user_overflow(void)
 {
 WARN(1, "Buffer overflow detected!\n");
 }
 EXPORT_SYMBOL(copy_from_user_overflow);
-
-static inline long find_zero(unsigned long mask)
-{
-long byte = 0;
-
-#ifdef __BIG_ENDIAN
-#ifdef CONFIG_64BIT
-if (mask &amp;gt;&amp;gt; 32)
-mask &amp;gt;&amp;gt;= 32;
-else
-byte = 4;
-#endif
-if (mask &amp;gt;&amp;gt; 16)
-mask &amp;gt;&amp;gt;= 16;
-else
-byte += 2;
-return (mask &amp;gt;&amp;gt; 8) ? byte : byte + 1;
-#else
-#ifdef CONFIG_64BIT
-if (!((unsigned int) mask)) {
-mask &amp;gt;&amp;gt;= 32;
-byte = 4;
-}
-#endif
-if (!(mask &amp;amp; 0xffff)) {
-mask &amp;gt;&amp;gt;= 16;
-byte += 2;
-}
-return (mask &amp;amp; 0xff) ? byte : byte + 1;
-#endif
-}
-
-/*
- * Do a strncpy, return length of string without final '\0'.
- * 'count' is the user-supplied count (return 'count' if we
- * hit it), 'max' is the address space maximum (and we return
- * -EFAULT if we hit it).
- */
-static inline long do_strncpy_from_user(char *dst, const char __user *src, long count, unsigned long max)
-{
-const unsigned long high_bits = REPEAT_BYTE(0xfe) + 1;
-const unsigned long low_bits = REPEAT_BYTE(0x7f);
-long res = 0;
-
-/*
- * Truncate 'max' to the user-specified limit, so that
- * we only have one limit we need to check in the loop
- */
-if (max &amp;gt; count)
-max = count;
-#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
-if (((long) dst | (long) src) &amp;amp; (sizeof(long) - 1))
-goto byte_at_a_time;
-#endif
-while (max &amp;gt;= sizeof(unsigned long)) {
-unsigned long c, v, rhs;
-
-/* Fall back to byte-at-a-time if we get a page fault */
-if (unlikely(__get_user(c,(unsigned long __user *)(src+res))))
-break;
-rhs = c | low_bits;
-v = (c + high_bits) &amp;amp; ~rhs;
-*(unsigned long *)(dst+res) = c;
-if (v) {
-v = (c &amp;amp; low_bits) + low_bits;;
-v = ~(v | rhs);
-return res + find_zero(v);
-}
-res += sizeof(unsigned long);
-max -= sizeof(unsigned long);
-}
-#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
-byte_at_a_time:
-#endif
-while (max) {
-char c;
-
-if (unlikely(__get_user(c,src+res)))
-return -EFAULT;
-dst[res] = c;
-if (!c)
-return res;
-res++;
-max--;
-}
-
-/*
- * Uhhuh. We hit 'max'. But was that the user-specified maximum
- * too? If so, that's ok - we got as much as the user asked for.
- */
-if (res &amp;gt;= count)
-return res;
-
-/*
- * Nope: we hit the address space limit, and we still had more
- * characters the caller would have wanted. That's an EFAULT.
- */
-return -EFAULT;
-}
-
-/**
- * strncpy_from_user: - Copy a NUL terminated string from userspace.
- * &amp;lt; at &amp;gt;dst:   Destination address, in kernel space.  This buffer must be at
- *         least &amp;lt; at &amp;gt;count bytes long.
- * &amp;lt; at &amp;gt;src:   Source address, in user space.
- * &amp;lt; at &amp;gt;count: Maximum number of bytes to copy, including the trailing NUL.
- *
- * Copies a NUL-terminated string from userspace to kernel space.
- *
- * On success, returns the length of the string (not including the trailing
- * NUL).
- *
- * If access to userspace fails, returns -EFAULT (some data may have been
- * copied).
- *
- * If &amp;lt; at &amp;gt;count is smaller than the length of the string, copies &amp;lt; at &amp;gt;count bytes
- * and returns &amp;lt; at &amp;gt;count.
- */
-long strncpy_from_user(char *dst, const char __user *src, long count)
-{
-unsigned long max_addr, src_addr;
-
-if (unlikely(count &amp;lt;= 0))
-return 0;
-
-max_addr = user_addr_max();
-src_addr = (unsigned long)src;
-if (likely(src_addr &amp;lt; max_addr)) {
-unsigned long max = max_addr - src_addr;
-return do_strncpy_from_user(dst, src, count, max);
-}
-return -EFAULT;
-}
-EXPORT_SYMBOL(strncpy_from_user);
diff --git a/lib/Kconfig b/lib/Kconfig
index 4a8aba2..49cb463 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -16,6 +16,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; config BITREVERSE
 config RATIONAL
 boolean
 
+config GENERIC_STRNCPY_FROM_USER
+bool
+
 config GENERIC_FIND_FIRST_BIT
 bool
 
diff --git a/lib/Makefile b/lib/Makefile
index 18515f0..57538b4 100644
--- a/lib/Makefile
+++ b/lib/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -123,6 +123,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; obj-$(CONFIG_SIGNATURE) += digsig.o
 
 obj-$(CONFIG_CLZ_TAB) += clz_tab.o
 
+obj-$(CONFIG_GENERIC_STRNCPY_FROM_USER) += strncpy_from_user.o
+
 hostprogs-y:= gen_crc32table
 clean-files:= crc32table.h
 
diff --git a/lib/strncpy_from_user.c b/lib/strncpy_from_user.c
new file mode 100644
index 0000000..278de4a
--- /dev/null
+++ b/lib/strncpy_from_user.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,140 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+#include &amp;lt;linux/module.h&amp;gt;
+#include &amp;lt;linux/uaccess.h&amp;gt;
+#include &amp;lt;linux/kernel.h&amp;gt;
+#include &amp;lt;linux/errno.h&amp;gt;
+
+#include &amp;lt;asm/byteorder.h&amp;gt;
+
+static inline long find_zero(unsigned long mask)
+{
+long byte = 0;
+
+#ifdef __BIG_ENDIAN
+#ifdef CONFIG_64BIT
+if (mask &amp;gt;&amp;gt; 32)
+mask &amp;gt;&amp;gt;= 32;
+else
+byte = 4;
+#endif
+if (mask &amp;gt;&amp;gt; 16)
+mask &amp;gt;&amp;gt;= 16;
+else
+byte += 2;
+return (mask &amp;gt;&amp;gt; 8) ? byte : byte + 1;
+#else
+#ifdef CONFIG_64BIT
+if (!((unsigned int) mask)) {
+mask &amp;gt;&amp;gt;= 32;
+byte = 4;
+}
+#endif
+if (!(mask &amp;amp; 0xffff)) {
+mask &amp;gt;&amp;gt;= 16;
+byte += 2;
+}
+return (mask &amp;amp; 0xff) ? byte : byte + 1;
+#endif
+}
+
+/*
+ * Do a strncpy, return length of string without final '\0'.
+ * 'count' is the user-supplied count (return 'count' if we
+ * hit it), 'max' is the address space maximum (and we return
+ * -EFAULT if we hit it).
+ */
+static inline long do_strncpy_from_user(char *dst, const char __user *src, long count, unsigned long max)
+{
+const unsigned long high_bits = REPEAT_BYTE(0xfe) + 1;
+const unsigned long low_bits = REPEAT_BYTE(0x7f);
+long res = 0;
+
+/*
+ * Truncate 'max' to the user-specified limit, so that
+ * we only have one limit we need to check in the loop
+ */
+if (max &amp;gt; count)
+max = count;
+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+if (((long) dst | (long) src) &amp;amp; (sizeof(long) - 1))
+goto byte_at_a_time;
+#endif
+while (max &amp;gt;= sizeof(unsigned long)) {
+unsigned long c, v, rhs;
+
+/* Fall back to byte-at-a-time if we get a page fault */
+if (unlikely(__get_user(c,(unsigned long __user *)(src+res))))
+break;
+rhs = c | low_bits;
+v = (c + high_bits) &amp;amp; ~rhs;
+*(unsigned long *)(dst+res) = c;
+if (v) {
+v = (c &amp;amp; low_bits) + low_bits;;
+v = ~(v | rhs);
+return res + find_zero(v);
+}
+res += sizeof(unsigned long);
+max -= sizeof(unsigned long);
+}
+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+byte_at_a_time:
+#endif
+while (max) {
+char c;
+
+if (unlikely(__get_user(c,src+res)))
+return -EFAULT;
+dst[res] = c;
+if (!c)
+return res;
+res++;
+max--;
+}
+
+/*
+ * Uhhuh. We hit 'max'. But was that the user-specified maximum
+ * too? If so, that's ok - we got as much as the user asked for.
+ */
+if (res &amp;gt;= count)
+return res;
+
+/*
+ * Nope: we hit the address space limit, and we still had more
+ * characters the caller would have wanted. That's an EFAULT.
+ */
+return -EFAULT;
+}
+
+/**
+ * strncpy_from_user: - Copy a NUL terminated string from userspace.
+ * &amp;lt; at &amp;gt;dst:   Destination address, in kernel space.  This buffer must be at
+ *         least &amp;lt; at &amp;gt;count bytes long.
+ * &amp;lt; at &amp;gt;src:   Source address, in user space.
+ * &amp;lt; at &amp;gt;count: Maximum number of bytes to copy, including the trailing NUL.
+ *
+ * Copies a NUL-terminated string from userspace to kernel space.
+ *
+ * On success, returns the length of the string (not including the trailing
+ * NUL).
+ *
+ * If access to userspace fails, returns -EFAULT (some data may have been
+ * copied).
+ *
+ * If &amp;lt; at &amp;gt;count is smaller than the length of the string, copies &amp;lt; at &amp;gt;count bytes
+ * and returns &amp;lt; at &amp;gt;count.
+ */
+long strncpy_from_user(char *dst, const char __user *src, long count)
+{
+unsigned long max_addr, src_addr;
+
+if (unlikely(count &amp;lt;= 0))
+return 0;
+
+max_addr = user_addr_max();
+src_addr = (unsigned long)src;
+if (likely(src_addr &amp;lt; max_addr)) {
+unsigned long max = max_addr - src_addr;
+return do_strncpy_from_user(dst, src, count, max);
+}
+return -EFAULT;
+}
+EXPORT_SYMBOL(strncpy_from_user);
&lt;/pre&gt;</description>
    <dc:creator>David Miller</dc:creator>
    <dc:date>2012-05-24T03:34:40</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14235">
    <title>[PATCH 1/3] sparc: Increase portability of strncpy_from_user() implementation.</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14235</link>
    <description>&lt;pre&gt;
Hide details of maximum user address calculation in a new
asm/uaccess.h interface named user_addr_max().

Provide little-endian implementation in find_zero(), which should work
but can probably be improved.

Guard alignment check using CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS.

Signed-off-by: David S. Miller &amp;lt;davem&amp;lt; at &amp;gt;davemloft.net&amp;gt;
---
 arch/sparc/include/asm/uaccess.h |    3 +++
 arch/sparc/lib/usercopy.c        |   28 ++++++++++++++++++++++------
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/arch/sparc/include/asm/uaccess.h b/arch/sparc/include/asm/uaccess.h
index 42a28cf..20c2acb 100644
--- a/arch/sparc/include/asm/uaccess.h
+++ b/arch/sparc/include/asm/uaccess.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6,6 +6,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include &amp;lt;asm/uaccess_32.h&amp;gt;
 #endif
 
+#define user_addr_max() \
+(segment_eq(get_fs(), USER_DS) ? STACK_TOP : ~0UL)
+
 extern long strncpy_from_user(char *dest, const char __user *src, long count);
 
 #endif
diff --git a/arch/sparc/lib/usercopy.c b/arch/sparc/lib/usercopy.c
index 87f9645..9ba59ef 100644
--- a/arch/sparc/lib/usercopy.c
+++ b/arch/sparc/lib/usercopy.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3,6 +3,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include &amp;lt;linux/errno.h&amp;gt;
 #include &amp;lt;linux/bug.h&amp;gt;
 
+#include &amp;lt;asm/byteorder.h&amp;gt;
+
 void copy_from_user_overflow(void)
 {
 WARN(1, "Buffer overflow detected!\n");
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -14,6 +16,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; EXPORT_SYMBOL(copy_from_user_overflow);
 static inline long find_zero(unsigned long mask)
 {
 long byte = 0;
+
+#ifdef __BIG_ENDIAN
 #ifdef CONFIG_64BIT
 if (mask &amp;gt;&amp;gt; 32)
 mask &amp;gt;&amp;gt;= 32;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -25,6 +29,19 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline long find_zero(unsigned long mask)
 else
 byte += 2;
 return (mask &amp;gt;&amp;gt; 8) ? byte : byte + 1;
+#else
+#ifdef CONFIG_64BIT
+if (!((unsigned int) mask)) {
+mask &amp;gt;&amp;gt;= 32;
+byte = 4;
+}
+#endif
+if (!(mask &amp;amp; 0xffff)) {
+mask &amp;gt;&amp;gt;= 16;
+byte += 2;
+}
+return (mask &amp;amp; 0xff) ? byte : byte + 1;
+#endif
 }
 
 /*
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -45,10 +62,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline long do_strncpy_from_user(char *dst, const char __user *src, long
  */
 if (max &amp;gt; count)
 max = count;
-
+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
 if (((long) dst | (long) src) &amp;amp; (sizeof(long) - 1))
 goto byte_at_a_time;
-
+#endif
 while (max &amp;gt;= sizeof(unsigned long)) {
 unsigned long c, v, rhs;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -66,8 +83,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline long do_strncpy_from_user(char *dst, const char __user *src, long
 res += sizeof(unsigned long);
 max -= sizeof(unsigned long);
 }
-
+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
 byte_at_a_time:
+#endif
 while (max) {
 char c;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -119,9 +137,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; long strncpy_from_user(char *dst, const char __user *src, long count)
 if (unlikely(count &amp;lt;= 0))
 return 0;
 
-max_addr = ~0UL;
-if (likely(segment_eq(get_fs(), USER_DS)))
-max_addr = STACK_TOP;
+max_addr = user_addr_max();
 src_addr = (unsigned long)src;
 if (likely(src_addr &amp;lt; max_addr)) {
 unsigned long max = max_addr - src_addr;
&lt;/pre&gt;</description>
    <dc:creator>David Miller</dc:creator>
    <dc:date>2012-05-24T03:34:30</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14234">
    <title>[PATCH 2/3] kernel: Move REPEAT_BYTE definition into linux/kernel.h</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14234</link>
    <description>&lt;pre&gt;
And make sure that everything using it explicitly includes
that header file.

Signed-off-by: David S. Miller &amp;lt;davem&amp;lt; at &amp;gt;davemloft.net&amp;gt;
---
 arch/sparc/lib/usercopy.c             |    3 +--
 arch/x86/include/asm/word-at-a-time.h |    4 ++--
 fs/namei.c                            |    1 +
 include/linux/kernel.h                |    2 ++
 4 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/sparc/lib/usercopy.c b/arch/sparc/lib/usercopy.c
index 9ba59ef..3d3bef9 100644
--- a/arch/sparc/lib/usercopy.c
+++ b/arch/sparc/lib/usercopy.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,5 +1,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include &amp;lt;linux/module.h&amp;gt;
 #include &amp;lt;linux/uaccess.h&amp;gt;
+#include &amp;lt;linux/kernel.h&amp;gt;
 #include &amp;lt;linux/errno.h&amp;gt;
 #include &amp;lt;linux/bug.h&amp;gt;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -11,8 +12,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void copy_from_user_overflow(void)
 }
 EXPORT_SYMBOL(copy_from_user_overflow);
 
-#define REPEAT_BYTE(x)((~0ul / 0xff) * (x))
-
 static inline long find_zero(unsigned long mask)
 {
 long byte = 0;
diff --git a/arch/x86/include/asm/word-at-a-time.h b/arch/x86/include/asm/word-at-a-time.h
index e58f03b..ae03fac 100644
--- a/arch/x86/include/asm/word-at-a-time.h
+++ b/arch/x86/include/asm/word-at-a-time.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,6 +1,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #ifndef _ASM_WORD_AT_A_TIME_H
 #define _ASM_WORD_AT_A_TIME_H
 
+#include &amp;lt;linux/kernel.h&amp;gt;
+
 /*
  * This is largely generic for little-endian machines, but the
  * optimal byte mask counting is probably going to be something
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -35,8 +37,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline long count_masked_bytes(long mask)
 
 #endif
 
-#define REPEAT_BYTE(x)((~0ul / 0xff) * (x))
-
 /* Return the high bit set in the first byte that is a zero */
 static inline unsigned long has_zero(unsigned long a)
 {
diff --git a/fs/namei.c b/fs/namei.c
index f9e883c..8d2ba42 100644
--- a/fs/namei.c
+++ b/fs/namei.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -16,6 +16,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 #include &amp;lt;linux/init.h&amp;gt;
 #include &amp;lt;linux/export.h&amp;gt;
+#include &amp;lt;linux/kernel.h&amp;gt;
 #include &amp;lt;linux/slab.h&amp;gt;
 #include &amp;lt;linux/fs.h&amp;gt;
 #include &amp;lt;linux/namei.h&amp;gt;
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 645231c..fbe9bfa 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -38,6 +38,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 #define STACK_MAGIC0xdeadbeef
 
+#define REPEAT_BYTE(x)((~0ul / 0xff) * (x))
+
 #define ALIGN(x, a)__ALIGN_KERNEL((x), (a))
 #define __ALIGN_MASK(x, mask)__ALIGN_KERNEL_MASK((x), (mask))
 #define PTR_ALIGN(p, a)((typeof(p))ALIGN((unsigned long)(p), (a)))
&lt;/pre&gt;</description>
    <dc:creator>David Miller</dc:creator>
    <dc:date>2012-05-24T03:34:35</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14233">
    <title>[PATCH 0/3] Make sparc's strncpy_from_user() generic.</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14233</link>
    <description>&lt;pre&gt;
Ok, this is against my current sparc GIT tree at:

git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc.git

After these changes it should definitely be usable by any
architecture.

If there are no major objections I can push this out to my sparc tree
and ask Linus to pull all of this work in.

Afterwards we can tweak it to use the x86 word-at-a-time tricks if we
want.

Thanks.
&lt;/pre&gt;</description>
    <dc:creator>David Miller</dc:creator>
    <dc:date>2012-05-24T03:34:18</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14232">
    <title>Re: Arch maintainers Ahoy!</title>
    <link>http://permalink.gmane.org/gmane.linux.kernel.cross-arch/14232</link>
    <description>&lt;pre&gt;From: Linus Torvalds &amp;lt;torvalds&amp;lt; at &amp;gt;linux-foundation.org&amp;gt;
Date: Wed, 23 May 2012 14:01:26 -0700


Ok, now confirmed, the following patch generates the best code I've
been able to get out of GCC thus far, and it's tested too.

Therefore, I'll push this out to my sparc tree.

Next, I'll try to add the abstractions et al. necessary to put this
under the top-level lib/ so others can use it too.

diff --git a/arch/sparc/lib/usercopy.c b/arch/sparc/lib/usercopy.c
index 851cb75..78c363f 100644
--- a/arch/sparc/lib/usercopy.c
+++ b/arch/sparc/lib/usercopy.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -17,29 +17,20 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline unsigned long has_zero(unsigned long a)
 return ((a - REPEAT_BYTE(0x01)) &amp;amp; ~a) &amp;amp; REPEAT_BYTE(0x80);
 }
 
-static inline long find_zero(unsigned long c)
+static inline long find_zero(unsigned long mask)
 {
+long byte = 0;
 #ifdef CONFIG_64BIT
-if (!(c &amp;amp; 0xff00000000000000UL))
-return 0;
-if (!(c &amp;amp; 0x00ff000000000000UL))
-return 1;
-if (!(c &amp;amp; 0x0000ff0000000000UL))
-return 2;
-if (!(c &amp;amp; 0x000000ff00000000UL))
-return 3;
-#define __OFF 4
-#else
-#define __OFF 0
+if (mask &amp;gt;&amp;gt; 32)
+mask &amp;gt;&amp;gt;= 32;
+else
+byte = 4;
 #endif
-if (!(c &amp;amp; 0xff000000))
-return __OFF + 0;
-if (!(c &amp;amp; 0x00ff0000))
-return __OFF + 1;
-if (!(c &amp;amp; 0x0000ff00))
-return __OFF + 2;
-return __OFF + 3;
-#undef __OFF
+if (mask &amp;gt;&amp;gt; 16)
+mask &amp;gt;&amp;gt;= 16;
+else
+byte += 2;
+return (mask &amp;gt;&amp;gt; 8) ? byte : byte + 1;
 }
 
 /*
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -50,6 +41,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline long find_zero(unsigned long c)
  */
 static inline long do_strncpy_from_user(char *dst, const char __user *src, long count, unsigned long max)
 {
+const unsigned long high_bits = REPEAT_BYTE(0xfe) + 1;
+const unsigned long low_bits = REPEAT_BYTE(0x7f);
 long res = 0;
 
 /*
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -63,14 +56,19 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline long do_strncpy_from_user(char *dst, const char __user *src, long
 goto byte_at_a_time;
 
 while (max &amp;gt;= sizeof(unsigned long)) {
-unsigned long c;
+unsigned long c, v, rhs;
 
 /* Fall back to byte-at-a-time if we get a page fault */
 if (unlikely(__get_user(c,(unsigned long __user *)(src+res))))
 break;
+rhs = c | low_bits;
+v = (c + high_bits) &amp;amp; ~rhs;
 *(unsigned long *)(dst+res) = c;
-if (has_zero(c))
-return res + find_zero(c);
+if (v) {
+v = (c &amp;amp; low_bits) + low_bits;;
+v = ~(v | rhs);
+return res + find_zero(v);
+}
 res += sizeof(unsigned long);
 max -= sizeof(unsigned long);
 }
&lt;/pre&gt;</description>
    <dc:creator>David Miller</dc:creator>
    <dc:date>2012-05-24T02:11:50</dc:date>
  </item>
  <textinput rdf:about="http://search.gmane.org/?group=$group=gmane.linux.kernel.cross-arch">
    <title>Search Engine</title>
    <description>Search the mailing list at Gmane</description>
    <name>query</name>
    <link>http://search.gmane.org/?group=$group=gmane.linux.kernel.cross-arch</link>
  </textinput>
</rdf:RDF>

