Skip to content

Commit

Permalink
Merge branch 'strscpy' of git://git.kernel.org/pub/scm/linux/kernel/g…
Browse files Browse the repository at this point in the history
…it/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
  • Loading branch information
Linus Torvalds committed Oct 7, 2015
2 parents 3f5e4a3 + 990486c commit 79c7c7a
Show file tree
Hide file tree
Showing 6 changed files with 12 additions and 4 deletions.
2 changes: 2 additions & 0 deletions arch/alpha/include/asm/word-at-a-time.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
1 change: 1 addition & 0 deletions arch/h8300/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 0 additions & 1 deletion arch/powerpc/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 0 additions & 1 deletion arch/tile/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -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
8 changes: 7 additions & 1 deletion arch/tile/include/asm/word-at-a-time.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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 */
3 changes: 2 additions & 1 deletion lib/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 79c7c7a

Please sign in to comment.