sh: use the new generic strnlen_user() function
This discards both the _32 and _64 versions in favour of the consolidated generic one. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
@@ -104,6 +104,9 @@ struct __large_struct { unsigned long buf[100]; };
|
||||
|
||||
extern long strncpy_from_user(char *dest, const char __user *src, long count);
|
||||
|
||||
extern __must_check long strlen_user(const char __user *str);
|
||||
extern __must_check long strnlen_user(const char __user *str, long n);
|
||||
|
||||
/* Generic arbitrary sized copy. */
|
||||
/* Return the number of bytes NOT copied */
|
||||
__kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n);
|
||||
@@ -165,43 +168,6 @@ copy_to_user(void __user *to, const void *from, unsigned long n)
|
||||
return __copy_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* strnlen_user: - Get the size of a string in user space.
|
||||
* @s: The string to measure.
|
||||
* @n: The maximum valid length
|
||||
*
|
||||
* Context: User context only. This function may sleep.
|
||||
*
|
||||
* Get the size of a NUL-terminated string in user space.
|
||||
*
|
||||
* Returns the size of the string INCLUDING the terminating NUL.
|
||||
* On exception, returns 0.
|
||||
* If the string is too long, returns a value greater than @n.
|
||||
*/
|
||||
static inline long strnlen_user(const char __user *s, long n)
|
||||
{
|
||||
if (!__addr_ok(s))
|
||||
return 0;
|
||||
else
|
||||
return __strnlen_user(s, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* strlen_user: - Get the size of a string in user space.
|
||||
* @str: The string to measure.
|
||||
*
|
||||
* Context: User context only. This function may sleep.
|
||||
*
|
||||
* Get the size of a NUL-terminated string in user space.
|
||||
*
|
||||
* Returns the size of the string INCLUDING the terminating NUL.
|
||||
* On exception, returns 0.
|
||||
*
|
||||
* If there is a limit on the length of a valid string, you may wish to
|
||||
* consider using strnlen_user() instead.
|
||||
*/
|
||||
#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
|
||||
|
||||
/*
|
||||
* The exception table consists of pairs of addresses: the first is the
|
||||
* address of an instruction that is allowed to fault, and the second is
|
||||
|
||||
@@ -170,40 +170,4 @@ __asm__ __volatile__( \
|
||||
|
||||
extern void __put_user_unknown(void);
|
||||
|
||||
/*
|
||||
* Return the size of a string (including the ending 0 even when we have
|
||||
* exceeded the maximum string length).
|
||||
*/
|
||||
static inline long __strnlen_user(const char __user *__s, long __n)
|
||||
{
|
||||
unsigned long res;
|
||||
unsigned long __dummy;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1:\t"
|
||||
"mov.b @(%0,%3), %1\n\t"
|
||||
"cmp/eq %4, %0\n\t"
|
||||
"bt/s 2f\n\t"
|
||||
" add #1, %0\n\t"
|
||||
"tst %1, %1\n\t"
|
||||
"bf 1b\n\t"
|
||||
"2:\n"
|
||||
".section .fixup,\"ax\"\n"
|
||||
"3:\n\t"
|
||||
"mov.l 4f, %1\n\t"
|
||||
"jmp @%1\n\t"
|
||||
" mov #0, %0\n"
|
||||
".balign 4\n"
|
||||
"4: .long 2b\n"
|
||||
".previous\n"
|
||||
".section __ex_table,\"a\"\n"
|
||||
" .balign 4\n"
|
||||
" .long 1b,3b\n"
|
||||
".previous"
|
||||
: "=z" (res), "=&r" (__dummy)
|
||||
: "0" (0), "r" (__s), "r" (__n)
|
||||
: "t");
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* __ASM_SH_UACCESS_32_H */
|
||||
|
||||
@@ -84,6 +84,4 @@ extern long __put_user_asm_l(void *, long);
|
||||
extern long __put_user_asm_q(void *, long);
|
||||
extern void __put_user_unknown(void);
|
||||
|
||||
extern long __strnlen_user(const char *__s, long __n);
|
||||
|
||||
#endif /* __ASM_SH_UACCESS_64_H */
|
||||
|
||||
53
arch/sh/include/asm/word-at-a-time.h
Normal file
53
arch/sh/include/asm/word-at-a-time.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifndef __ASM_SH_WORD_AT_A_TIME_H
|
||||
#define __ASM_SH_WORD_AT_A_TIME_H
|
||||
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
# include <asm-generic/word-at-a-time.h>
|
||||
#else
|
||||
/*
|
||||
* Little-endian version cribbed from x86.
|
||||
*/
|
||||
struct word_at_a_time {
|
||||
const unsigned long one_bits, high_bits;
|
||||
};
|
||||
|
||||
#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) }
|
||||
|
||||
/* Carl Chatfield / Jan Achrenius G+ version for 32-bit */
|
||||
static inline long count_masked_bytes(long mask)
|
||||
{
|
||||
/* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */
|
||||
long a = (0x0ff0001+mask) >> 23;
|
||||
/* Fix the 1 for 00 case */
|
||||
return a & mask;
|
||||
}
|
||||
|
||||
/* Return nonzero if it has a zero */
|
||||
static inline unsigned long has_zero(unsigned long a, unsigned long *bits, const struct word_at_a_time *c)
|
||||
{
|
||||
unsigned long mask = ((a - c->one_bits) & ~a) & c->high_bits;
|
||||
*bits = mask;
|
||||
return mask;
|
||||
}
|
||||
|
||||
static inline unsigned long prep_zero_mask(unsigned long a, unsigned long bits, const struct word_at_a_time *c)
|
||||
{
|
||||
return bits;
|
||||
}
|
||||
|
||||
static inline unsigned long create_zero_mask(unsigned long bits)
|
||||
{
|
||||
bits = (bits - 1) & ~bits;
|
||||
return bits >> 7;
|
||||
}
|
||||
|
||||
/* The mask we created is directly usable as a bytemask */
|
||||
#define zero_bytemask(mask) (mask)
|
||||
|
||||
static inline unsigned long find_zero(unsigned long mask)
|
||||
{
|
||||
return count_masked_bytes(mask);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user