diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index d345c712c6ca192705b2b637768c6532ffc234f1..2671fd46ea8568f3db7944e5f89a91f2e1eff0a5 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -340,7 +340,8 @@ void show_registers(struct pt_regs *regs)
 void handle_BUG(struct pt_regs *regs)
 { 
 	struct bug_frame f;
-	char tmp;
+	long len;
+	const char *prefix = "";
 
 	if (user_mode(regs))
 		return; 
@@ -350,10 +351,15 @@ void handle_BUG(struct pt_regs *regs)
 	if (f.filename >= 0 ||
 	    f.ud2[0] != 0x0f || f.ud2[1] != 0x0b) 
 		return;
-	if (__get_user(tmp, (char *)(long)f.filename))
+	len = __strnlen_user((char *)(long)f.filename, PATH_MAX) - 1;
+	if (len < 0 || len >= PATH_MAX)
 		f.filename = (int)(long)"unmapped filename";
+	else if (len > 50) {
+		f.filename += len - 50;
+		prefix = "...";
+	}
 	printk("----------- [cut here ] --------- [please bite here ] ---------\n");
-	printk(KERN_ALERT "Kernel BUG at %.50s:%d\n", (char *)(long)f.filename, f.line);
+	printk(KERN_ALERT "Kernel BUG at %s%.50s:%d\n", prefix, (char *)(long)f.filename, f.line);
 } 
 
 #ifdef CONFIG_BUG
diff --git a/arch/x86_64/lib/usercopy.c b/arch/x86_64/lib/usercopy.c
index db8abba1ad819901a1a327465cb1d2fe7061cd5f..9bc2c295818e3c2d2faa97ecee0e17a336843b48 100644
--- a/arch/x86_64/lib/usercopy.c
+++ b/arch/x86_64/lib/usercopy.c
@@ -109,14 +109,11 @@ unsigned long clear_user(void __user *to, unsigned long n)
  * Return 0 on exception, a value greater than N if too long
  */
 
-long strnlen_user(const char __user *s, long n)
+long __strnlen_user(const char __user *s, long n)
 {
 	long res = 0;
 	char c;
 
-	if (!access_ok(VERIFY_READ, s, n))
-		return 0;
-
 	while (1) {
 		if (res>n)
 			return n+1;
@@ -129,6 +126,13 @@ long strnlen_user(const char __user *s, long n)
 	}
 }
 
+long strnlen_user(const char __user *s, long n)
+{
+	if (!access_ok(VERIFY_READ, s, n))
+		return 0;
+	return __strnlen_user(s, n);
+}
+
 long strlen_user(const char __user *s)
 {
 	long res = 0;
diff --git a/include/asm-x86_64/uaccess.h b/include/asm-x86_64/uaccess.h
index 1bb8b8a24436b2387a348b8d0ae880e14d61c6c6..2892c4b7a28b01769bd25c88b7a5e9065e7e8a15 100644
--- a/include/asm-x86_64/uaccess.h
+++ b/include/asm-x86_64/uaccess.h
@@ -348,6 +348,7 @@ static inline int __copy_in_user(void __user *dst, const void __user *src, unsig
 long strncpy_from_user(char *dst, const char __user *src, long count);
 long __strncpy_from_user(char *dst, const char __user *src, long count);
 long strnlen_user(const char __user *str, long n);
+long __strnlen_user(const char __user *str, long n);
 long strlen_user(const char __user *str);
 unsigned long clear_user(void __user *mem, unsigned long len);
 unsigned long __clear_user(void __user *mem, unsigned long len);