summary refs log tree commit diff
path: root/arch/microblaze
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2017-05-02 19:52:17 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2017-07-03 18:44:02 -0400
commit468138d78510688fb5476f98d23f11ac6a63229a (patch)
tree5f235bc85343bf3f314201a1d281881625d67abe /arch/microblaze
parent2ea659a9ef488125eb46da6eb571de5eae5c43f6 (diff)
downloadlinux-468138d78510688fb5476f98d23f11ac6a63229a.tar.gz
binfmt_flat: flat_{get,put}_addr_from_rp() should be able to fail
on MMU targets EFAULT is possible here.  Make both return 0 or error,
passing what used to be the return value of flat_get_addr_from_rp()
by reference.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/microblaze')
-rw-r--r--arch/microblaze/include/asm/flat.h34
1 files changed, 17 insertions, 17 deletions
diff --git a/arch/microblaze/include/asm/flat.h b/arch/microblaze/include/asm/flat.h
index 6847c1512c7b..f23c3d266bae 100644
--- a/arch/microblaze/include/asm/flat.h
+++ b/arch/microblaze/include/asm/flat.h
@@ -32,29 +32,27 @@
  * reference
  */
 
-static inline unsigned long
-flat_get_addr_from_rp(unsigned long *rp, unsigned long relval,
-			unsigned long flags, unsigned long *persistent)
+static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
+					u32 *addr, u32 *persistent)
 {
-	unsigned long addr;
-	(void)flags;
+	u32 *p = (__force u32 *)rp;
 
 	/* Is it a split 64/32 reference? */
 	if (relval & 0x80000000) {
 		/* Grab the two halves of the reference */
-		unsigned long val_hi, val_lo;
+		u32 val_hi, val_lo;
 
-		val_hi = get_unaligned(rp);
-		val_lo = get_unaligned(rp+1);
+		val_hi = get_unaligned(p);
+		val_lo = get_unaligned(p+1);
 
 		/* Crack the address out */
-		addr = ((val_hi & 0xffff) << 16) + (val_lo & 0xffff);
+		*addr = ((val_hi & 0xffff) << 16) + (val_lo & 0xffff);
 	} else {
 		/* Get the address straight out */
-		addr = get_unaligned(rp);
+		*addr = get_unaligned(p);
 	}
 
-	return addr;
+	return 0;
 }
 
 /*
@@ -63,25 +61,27 @@ flat_get_addr_from_rp(unsigned long *rp, unsigned long relval,
  */
 
 static inline void
-flat_put_addr_at_rp(unsigned long *rp, unsigned long addr, unsigned long relval)
+flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 relval)
 {
+	u32 *p = (__force u32 *)rp;
 	/* Is this a split 64/32 reloc? */
 	if (relval & 0x80000000) {
 		/* Get the two "halves" */
-		unsigned long val_hi = get_unaligned(rp);
-		unsigned long val_lo = get_unaligned(rp + 1);
+		unsigned long val_hi = get_unaligned(p);
+		unsigned long val_lo = get_unaligned(p + 1);
 
 		/* insert the address */
 		val_hi = (val_hi & 0xffff0000) | addr >> 16;
 		val_lo = (val_lo & 0xffff0000) | (addr & 0xffff);
 
 		/* store the two halves back into memory */
-		put_unaligned(val_hi, rp);
-		put_unaligned(val_lo, rp+1);
+		put_unaligned(val_hi, p);
+		put_unaligned(val_lo, p+1);
 	} else {
 		/* Put it straight in, no messing around */
-		put_unaligned(addr, rp);
+		put_unaligned(addr, p);
 	}
+	return 0;
 }
 
 #define	flat_get_relocate_addr(rel)	(rel & 0x7fffffff)