If __xchg() is not getting inlined the outline version of the function
will have a reference to __xchg_called_with_bad_pointer() which does not
exist remaining. Fixed by using BUILD_BUG_ON() to check for allowable
operand sizes.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Patchwork: http://patchwork.linux-mips.org/patch/705/
#ifndef _ASM_SYSTEM_H
#define _ASM_SYSTEM_H
#ifndef _ASM_SYSTEM_H
#define _ASM_SYSTEM_H
+#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/irqflags.h>
#include <linux/types.h>
#include <linux/irqflags.h>
#define __xchg_u64 __xchg_u64_unsupported_on_32bit_kernels
#endif
#define __xchg_u64 __xchg_u64_unsupported_on_32bit_kernels
#endif
-/* This function doesn't exist, so you'll get a linker error
- if something tries to do an invalid xchg(). */
-extern void __xchg_called_with_bad_pointer(void);
-
static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
{
switch (size) {
static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
{
switch (size) {
case 8:
return __xchg_u64(ptr, x);
}
case 8:
return __xchg_u64(ptr, x);
}
- __xchg_called_with_bad_pointer();
-#define xchg(ptr, x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
+#define xchg(ptr, x) \
+({ \
+ BUILD_BUG_ON(sizeof(*(ptr)) & ~0xc); \
+ \
+ ((__typeof__(*(ptr))) \
+ __xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))); \
+})
extern void set_handler(unsigned long offset, void *addr, unsigned long len);
extern void set_uncached_handler(unsigned long offset, void *addr, unsigned long len);
extern void set_handler(unsigned long offset, void *addr, unsigned long len);
extern void set_uncached_handler(unsigned long offset, void *addr, unsigned long len);