diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-10-07 08:52:42 (GMT) |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-10-07 08:52:42 (GMT) |
commit | 79c7c7acd25689b1d7669bdb33fb3cb7c64541fe (patch) | |
tree | f8d5dc80466d2637c32f6be70c287986cca59273 | |
parent | 3f5e4a311619533bfc742f2d8e04510334dd0dd5 (diff) | |
parent | 990486c8af044f89bddfbde1d1cf9fde449bedbf (diff) | |
download | linux-79c7c7acd25689b1d7669bdb33fb3cb7c64541fe.tar.xz |
Merge branch 'strscpy' of git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile
Pull strscpy fixes from Chris Metcalf :
"This patch series fixes up a couple of architecture issues where
strscpy wasn't configured correctly (missing on h8300, duplicating
local and asm-generic copies on powerpc and tile).
It also adds a use of zero_bytemask() to the final store for strscpy
to avoid writing uninitialized data to the destination. However, to
make this work we had to add support for zero_bytemask() to the two
architectures that didn't have it (alpha and tile), because they were
providing their own local copies, but didn't provide the
zero_bytemask() that was previously only required when building with
CONFIG_DCACHE_WORD_ACCESS"
[ Side note: there is still no actual users of strscpy except for the
one preexisting use in arch/tile that predates the generic version.
So this is all about fixing the infrastructure so that we eventually
can start using it. - Linus ]
* 'strscpy' of git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile:
strscpy: zero any trailing garbage bytes in the destination
word-at-a-time.h: support zero_bytemask() on alpha and tile
word-at-a-time.h: fix some Kbuild files
-rw-r--r-- | arch/alpha/include/asm/word-at-a-time.h | 2 | ||||
-rw-r--r-- | arch/h8300/include/asm/Kbuild | 1 | ||||
-rw-r--r-- | arch/powerpc/include/asm/Kbuild | 1 | ||||
-rw-r--r-- | arch/tile/include/asm/Kbuild | 1 | ||||
-rw-r--r-- | arch/tile/include/asm/word-at-a-time.h | 8 | ||||
-rw-r--r-- | lib/string.c | 3 |
6 files changed, 12 insertions, 4 deletions
diff --git a/arch/alpha/include/asm/word-at-a-time.h b/arch/alpha/include/asm/word-at-a-time.h index 6b340d0..902e6ab 100644 --- a/arch/alpha/include/asm/word-at-a-time.h +++ b/arch/alpha/include/asm/word-at-a-time.h @@ -52,4 +52,6 @@ static inline unsigned long find_zero(unsigned long bits) #endif } +#define zero_bytemask(mask) ((2ul << (find_zero(mask) * 8)) - 1) + #endif /* _ASM_WORD_AT_A_TIME_H */ diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild index 70e6ae1..373cb23 100644 --- a/arch/h8300/include/asm/Kbuild +++ b/arch/h8300/include/asm/Kbuild @@ -73,4 +73,5 @@ generic-y += uaccess.h generic-y += ucontext.h generic-y += unaligned.h generic-y += vga.h +generic-y += word-at-a-time.h generic-y += xor.h diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild index ac16629..ab9f4e0 100644 --- a/arch/powerpc/include/asm/Kbuild +++ b/arch/powerpc/include/asm/Kbuild @@ -7,4 +7,3 @@ generic-y += mcs_spinlock.h generic-y += preempt.h generic-y += rwsem.h generic-y += vtime.h -generic-y += word-at-a-time.h diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild index 0b6cacaa..ba35c41 100644 --- a/arch/tile/include/asm/Kbuild +++ b/arch/tile/include/asm/Kbuild @@ -40,5 +40,4 @@ generic-y += termbits.h generic-y += termios.h generic-y += trace_clock.h generic-y += types.h -generic-y += word-at-a-time.h generic-y += xor.h diff --git a/arch/tile/include/asm/word-at-a-time.h b/arch/tile/include/asm/word-at-a-time.h index 9e5ce0d..b66a693 100644 --- a/arch/tile/include/asm/word-at-a-time.h +++ b/arch/tile/include/asm/word-at-a-time.h @@ -6,7 +6,7 @@ struct word_at_a_time { /* unused */ }; #define WORD_AT_A_TIME_CONSTANTS {} -/* Generate 0x01 byte values for non-zero bytes using a SIMD instruction. */ +/* Generate 0x01 byte values for zero bytes using a SIMD instruction. */ static inline unsigned long has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) { @@ -33,4 +33,10 @@ static inline long find_zero(unsigned long mask) #endif } +#ifdef __BIG_ENDIAN +#define zero_bytemask(mask) (~1ul << (63 - __builtin_clzl(mask))) +#else +#define zero_bytemask(mask) ((2ul << __builtin_ctzl(mask)) - 1) +#endif + #endif /* _ASM_WORD_AT_A_TIME_H */ diff --git a/lib/string.c b/lib/string.c index 8dbb7b1..84775ba 100644 --- a/lib/string.c +++ b/lib/string.c @@ -203,12 +203,13 @@ ssize_t strscpy(char *dest, const char *src, size_t count) unsigned long c, data; c = *(unsigned long *)(src+res); - *(unsigned long *)(dest+res) = c; if (has_zero(c, &data, &constants)) { data = prep_zero_mask(c, data, &constants); data = create_zero_mask(data); + *(unsigned long *)(dest+res) = c & zero_bytemask(data); return res + find_zero(data); } + *(unsigned long *)(dest+res) = c; res += sizeof(unsigned long); count -= sizeof(unsigned long); max -= sizeof(unsigned long); |