diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/include/asm/Kbuild linux-libre-4.9-rc7-gnu/arch/alpha/include/asm/Kbuild
--- linux-libre-4.8-gnu/arch/alpha/include/asm/Kbuild	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/include/asm/Kbuild	2016-11-27 16:08:04.000000000 -0500
@@ -3,6 +3,7 @@
 generic-y += clkdev.h
 generic-y += cputime.h
 generic-y += exec.h
+generic-y += export.h
 generic-y += irq_work.h
 generic-y += mcs_spinlock.h
 generic-y += mm-arch-hooks.h
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/include/asm/uaccess.h linux-libre-4.9-rc7-gnu/arch/alpha/include/asm/uaccess.h
--- linux-libre-4.8-gnu/arch/alpha/include/asm/uaccess.h	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/include/asm/uaccess.h	2016-11-27 16:08:04.000000000 -0500
@@ -396,11 +396,12 @@ copy_to_user(void __user *to, const void
 extern inline long
 copy_from_user(void *to, const void __user *from, long n)
 {
+	long res = n;
 	if (likely(__access_ok((unsigned long)from, n, get_fs())))
-		n = __copy_tofrom_user_nocheck(to, (__force void *)from, n);
-	else
-		memset(to, 0, n);
-	return n;
+		res = __copy_from_user_inatomic(to, from, n);
+	if (unlikely(res))
+		memset(to + (n - res), 0, res);
+	return res;
 }
 
 extern void __do_clear_user(void);
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/include/uapi/asm/mman.h linux-libre-4.9-rc7-gnu/arch/alpha/include/uapi/asm/mman.h
--- linux-libre-4.8-gnu/arch/alpha/include/uapi/asm/mman.h	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/include/uapi/asm/mman.h	2016-11-27 16:08:04.000000000 -0500
@@ -78,4 +78,9 @@
 #define MAP_HUGE_SHIFT	26
 #define MAP_HUGE_MASK	0x3f
 
+#define PKEY_DISABLE_ACCESS	0x1
+#define PKEY_DISABLE_WRITE	0x2
+#define PKEY_ACCESS_MASK	(PKEY_DISABLE_ACCESS |\
+				 PKEY_DISABLE_WRITE)
+
 #endif /* __ALPHA_MMAN_H__ */
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/Kconfig linux-libre-4.9-rc7-gnu/arch/alpha/Kconfig
--- linux-libre-4.8-gnu/arch/alpha/Kconfig	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/Kconfig	2016-11-27 16:08:04.000000000 -0500
@@ -15,7 +15,6 @@ config ALPHA
 	select GENERIC_IRQ_SHOW
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
-	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select AUDIT_ARCH
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_SMP_IDLE_THREAD
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/kernel/alpha_ksyms.c linux-libre-4.9-rc7-gnu/arch/alpha/kernel/alpha_ksyms.c
--- linux-libre-4.8-gnu/arch/alpha/kernel/alpha_ksyms.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/kernel/alpha_ksyms.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,102 +0,0 @@
-/*
- * linux/arch/alpha/kernel/alpha_ksyms.c
- *
- * Export the alpha-specific functions that are needed for loadable
- * modules.
- */
-
-#include <linux/module.h>
-#include <asm/console.h>
-#include <asm/uaccess.h>
-#include <asm/checksum.h>
-#include <asm/fpu.h>
-#include <asm/machvec.h>
-
-#include <linux/syscalls.h>
-
-/* these are C runtime functions with special calling conventions: */
-extern void __divl (void);
-extern void __reml (void);
-extern void __divq (void);
-extern void __remq (void);
-extern void __divlu (void);
-extern void __remlu (void);
-extern void __divqu (void);
-extern void __remqu (void);
-
-EXPORT_SYMBOL(alpha_mv);
-EXPORT_SYMBOL(callback_getenv);
-EXPORT_SYMBOL(callback_setenv);
-EXPORT_SYMBOL(callback_save_env);
-
-/* platform dependent support */
-EXPORT_SYMBOL(strcat);
-EXPORT_SYMBOL(strcpy);
-EXPORT_SYMBOL(strlen);
-EXPORT_SYMBOL(strncpy);
-EXPORT_SYMBOL(strncat);
-EXPORT_SYMBOL(strchr);
-EXPORT_SYMBOL(strrchr);
-EXPORT_SYMBOL(memmove);
-EXPORT_SYMBOL(__memcpy);
-EXPORT_SYMBOL(__memset);
-EXPORT_SYMBOL(___memset);
-EXPORT_SYMBOL(__memsetw);
-EXPORT_SYMBOL(__constant_c_memset);
-EXPORT_SYMBOL(copy_page);
-EXPORT_SYMBOL(clear_page);
-
-EXPORT_SYMBOL(alpha_read_fp_reg);
-EXPORT_SYMBOL(alpha_read_fp_reg_s);
-EXPORT_SYMBOL(alpha_write_fp_reg);
-EXPORT_SYMBOL(alpha_write_fp_reg_s);
-
-/* Networking helper routines. */
-EXPORT_SYMBOL(csum_tcpudp_magic);
-EXPORT_SYMBOL(ip_compute_csum);
-EXPORT_SYMBOL(ip_fast_csum);
-EXPORT_SYMBOL(csum_partial_copy_nocheck);
-EXPORT_SYMBOL(csum_partial_copy_from_user);
-EXPORT_SYMBOL(csum_ipv6_magic);
-
-#ifdef CONFIG_MATHEMU_MODULE
-extern long (*alpha_fp_emul_imprecise)(struct pt_regs *, unsigned long);
-extern long (*alpha_fp_emul) (unsigned long pc);
-EXPORT_SYMBOL(alpha_fp_emul_imprecise);
-EXPORT_SYMBOL(alpha_fp_emul);
-#endif
-
-/*
- * The following are specially called from the uaccess assembly stubs.
- */
-EXPORT_SYMBOL(__copy_user);
-EXPORT_SYMBOL(__do_clear_user);
-
-/* 
- * SMP-specific symbols.
- */
-
-#ifdef CONFIG_SMP
-EXPORT_SYMBOL(_atomic_dec_and_lock);
-#endif /* CONFIG_SMP */
-
-/*
- * The following are special because they're not called
- * explicitly (the C compiler or assembler generates them in
- * response to division operations).  Fortunately, their
- * interface isn't gonna change any time soon now, so it's OK
- * to leave it out of version control.
- */
-# undef memcpy
-# undef memset
-EXPORT_SYMBOL(__divl);
-EXPORT_SYMBOL(__divlu);
-EXPORT_SYMBOL(__divq);
-EXPORT_SYMBOL(__divqu);
-EXPORT_SYMBOL(__reml);
-EXPORT_SYMBOL(__remlu);
-EXPORT_SYMBOL(__remq);
-EXPORT_SYMBOL(__remqu);
-EXPORT_SYMBOL(memcpy);
-EXPORT_SYMBOL(memset);
-EXPORT_SYMBOL(memchr);
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/kernel/machvec_impl.h linux-libre-4.9-rc7-gnu/arch/alpha/kernel/machvec_impl.h
--- linux-libre-4.8-gnu/arch/alpha/kernel/machvec_impl.h	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/kernel/machvec_impl.h	2016-11-27 16:08:04.000000000 -0500
@@ -144,9 +144,11 @@
    else beforehand.  Fine.  We'll do it ourselves.  */
 #if 0
 #define ALIAS_MV(system) \
-  struct alpha_machine_vector alpha_mv __attribute__((alias(#system "_mv")));
+  struct alpha_machine_vector alpha_mv __attribute__((alias(#system "_mv"))); \
+  EXPORT_SYMBOL(alpha_mv);
 #else
 #define ALIAS_MV(system) \
-  asm(".global alpha_mv\nalpha_mv = " #system "_mv");
+  asm(".global alpha_mv\nalpha_mv = " #system "_mv"); \
+  EXPORT_SYMBOL(alpha_mv);
 #endif
 #endif /* GENERIC */
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/kernel/Makefile linux-libre-4.9-rc7-gnu/arch/alpha/kernel/Makefile
--- linux-libre-4.8-gnu/arch/alpha/kernel/Makefile	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/kernel/Makefile	2016-11-27 16:08:04.000000000 -0500
@@ -8,7 +8,7 @@ ccflags-y	:= -Wno-sign-compare
 
 obj-y    := entry.o traps.o process.o osf_sys.o irq.o \
 	    irq_alpha.o signal.o setup.o ptrace.o time.o \
-	    alpha_ksyms.o systbls.o err_common.o io.o
+	    systbls.o err_common.o io.o
 
 obj-$(CONFIG_VGA_HOSE)	+= console.o
 obj-$(CONFIG_SMP)	+= smp.o
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/kernel/ptrace.c linux-libre-4.9-rc7-gnu/arch/alpha/kernel/ptrace.c
--- linux-libre-4.8-gnu/arch/alpha/kernel/ptrace.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/kernel/ptrace.c	2016-11-27 16:08:04.000000000 -0500
@@ -157,14 +157,16 @@ put_reg(struct task_struct *task, unsign
 static inline int
 read_int(struct task_struct *task, unsigned long addr, int * data)
 {
-	int copied = access_process_vm(task, addr, data, sizeof(int), 0);
+	int copied = access_process_vm(task, addr, data, sizeof(int),
+			FOLL_FORCE);
 	return (copied == sizeof(int)) ? 0 : -EIO;
 }
 
 static inline int
 write_int(struct task_struct *task, unsigned long addr, int data)
 {
-	int copied = access_process_vm(task, addr, &data, sizeof(int), 1);
+	int copied = access_process_vm(task, addr, &data, sizeof(int),
+			FOLL_FORCE | FOLL_WRITE);
 	return (copied == sizeof(int)) ? 0 : -EIO;
 }
 
@@ -281,7 +283,8 @@ long arch_ptrace(struct task_struct *chi
 	/* When I and D space are separate, these will need to be fixed.  */
 	case PTRACE_PEEKTEXT: /* read word at location addr. */
 	case PTRACE_PEEKDATA:
-		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+		copied = access_process_vm(child, addr, &tmp, sizeof(tmp),
+				FOLL_FORCE);
 		ret = -EIO;
 		if (copied != sizeof(tmp))
 			break;
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/kernel/setup.c linux-libre-4.9-rc7-gnu/arch/alpha/kernel/setup.c
--- linux-libre-4.8-gnu/arch/alpha/kernel/setup.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/kernel/setup.c	2016-11-27 16:08:04.000000000 -0500
@@ -115,6 +115,7 @@ unsigned long alpha_agpgart_size = DEFAU
 
 #ifdef CONFIG_ALPHA_GENERIC
 struct alpha_machine_vector alpha_mv;
+EXPORT_SYMBOL(alpha_mv);
 #endif
 
 #ifndef alpha_using_srm
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/kernel/vmlinux.lds.S linux-libre-4.9-rc7-gnu/arch/alpha/kernel/vmlinux.lds.S
--- linux-libre-4.8-gnu/arch/alpha/kernel/vmlinux.lds.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/kernel/vmlinux.lds.S	2016-11-27 16:08:04.000000000 -0500
@@ -22,6 +22,7 @@ SECTIONS
 		HEAD_TEXT
 		TEXT_TEXT
 		SCHED_TEXT
+		CPUIDLE_TEXT
 		LOCK_TEXT
 		*(.fixup)
 		*(.gnu.warning)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/callback_srm.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/callback_srm.S
--- linux-libre-4.8-gnu/arch/alpha/lib/callback_srm.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/callback_srm.S	2016-11-27 16:08:04.000000000 -0500
@@ -3,6 +3,7 @@
  */
 
 #include <asm/console.h>
+#include <asm/export.h>
 
 .text
 #define HWRPB_CRB_OFFSET 0xc0
@@ -92,6 +93,10 @@ CALLBACK(reset_env, CCB_RESET_ENV, 4)
 CALLBACK(save_env, CCB_SAVE_ENV, 1)
 CALLBACK(pswitch, CCB_PSWITCH, 3)
 CALLBACK(bios_emul, CCB_BIOS_EMUL, 5)
+
+EXPORT_SYMBOL(callback_getenv)
+EXPORT_SYMBOL(callback_setenv)
+EXPORT_SYMBOL(callback_save_env)
 	
 .data
 __alpha_using_srm:		# For use by bootpheader
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/checksum.c linux-libre-4.9-rc7-gnu/arch/alpha/lib/checksum.c
--- linux-libre-4.8-gnu/arch/alpha/lib/checksum.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/checksum.c	2016-11-27 16:08:04.000000000 -0500
@@ -48,6 +48,7 @@ __sum16 csum_tcpudp_magic(__be32 saddr,
 		(__force u64)saddr + (__force u64)daddr +
 		(__force u64)sum + ((len + proto) << 8));
 }
+EXPORT_SYMBOL(csum_tcpudp_magic);
 
 __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
 			  __u32 len, __u8 proto, __wsum sum)
@@ -144,6 +145,7 @@ __sum16 ip_fast_csum(const void *iph, un
 {
 	return (__force __sum16)~do_csum(iph,ihl*4);
 }
+EXPORT_SYMBOL(ip_fast_csum);
 
 /*
  * computes the checksum of a memory block at buff, length len,
@@ -178,3 +180,4 @@ __sum16 ip_compute_csum(const void *buff
 {
 	return (__force __sum16)~from64to16(do_csum(buff,len));
 }
+EXPORT_SYMBOL(ip_compute_csum);
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/clear_page.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/clear_page.S
--- linux-libre-4.8-gnu/arch/alpha/lib/clear_page.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/clear_page.S	2016-11-27 16:08:04.000000000 -0500
@@ -3,7 +3,7 @@
  *
  * Zero an entire page.
  */
-
+#include <asm/export.h>
 	.text
 	.align 4
 	.global clear_page
@@ -37,3 +37,4 @@ clear_page:
 	nop
 
 	.end clear_page
+	EXPORT_SYMBOL(clear_page)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/clear_user.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/clear_user.S
--- linux-libre-4.8-gnu/arch/alpha/lib/clear_user.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/clear_user.S	2016-11-27 16:08:04.000000000 -0500
@@ -24,6 +24,7 @@
  * Clobbers:
  *	$1,$2,$3,$4,$5,$6
  */
+#include <asm/export.h>
 
 /* Allow an exception for an insn; exit if we get one.  */
 #define EX(x,y...)			\
@@ -111,3 +112,4 @@ $exception:
 	ret	$31, ($28), 1	# .. e1 :
 
 	.end __do_clear_user
+	EXPORT_SYMBOL(__do_clear_user)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/copy_page.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/copy_page.S
--- linux-libre-4.8-gnu/arch/alpha/lib/copy_page.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/copy_page.S	2016-11-27 16:08:04.000000000 -0500
@@ -3,7 +3,7 @@
  *
  * Copy an entire page.
  */
-
+#include <asm/export.h>
 	.text
 	.align 4
 	.global copy_page
@@ -47,3 +47,4 @@ copy_page:
 	nop
 
 	.end copy_page
+	EXPORT_SYMBOL(copy_page)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/copy_user.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/copy_user.S
--- linux-libre-4.8-gnu/arch/alpha/lib/copy_user.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/copy_user.S	2016-11-27 16:08:04.000000000 -0500
@@ -26,6 +26,8 @@
  *	$1,$2,$3,$4,$5,$6,$7
  */
 
+#include <asm/export.h>
+
 /* Allow an exception for an insn; exit if we get one.  */
 #define EXI(x,y...)			\
 	99: x,##y;			\
@@ -124,22 +126,9 @@ $65:
 	bis $31,$31,$0
 $41:
 $35:
-$exitout:
-	ret $31,($28),1
-
 $exitin:
-	/* A stupid byte-by-byte zeroing of the rest of the output
-	   buffer.  This cures security holes by never leaving 
-	   random kernel data around to be copied elsewhere.  */
-
-	mov $0,$1
-$101:
-	EXO ( ldq_u $2,0($6) )
-	subq $1,1,$1
-	mskbl $2,$6,$2
-	EXO ( stq_u $2,0($6) )
-	addq $6,1,$6
-	bgt $1,$101
+$exitout:
 	ret $31,($28),1
 
 	.end __copy_user
+EXPORT_SYMBOL(__copy_user)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/csum_ipv6_magic.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/csum_ipv6_magic.S
--- linux-libre-4.8-gnu/arch/alpha/lib/csum_ipv6_magic.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/csum_ipv6_magic.S	2016-11-27 16:08:04.000000000 -0500
@@ -12,6 +12,7 @@
  * added by Ivan Kokshaysky <ink@jurassic.park.msu.ru>
  */
 
+#include <asm/export.h>
 	.globl csum_ipv6_magic
 	.align 4
 	.ent csum_ipv6_magic
@@ -113,3 +114,4 @@ csum_ipv6_magic:
 	ret			# .. e1 :
 
 	.end csum_ipv6_magic
+	EXPORT_SYMBOL(csum_ipv6_magic)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/csum_partial_copy.c linux-libre-4.9-rc7-gnu/arch/alpha/lib/csum_partial_copy.c
--- linux-libre-4.8-gnu/arch/alpha/lib/csum_partial_copy.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/csum_partial_copy.c	2016-11-27 16:08:04.000000000 -0500
@@ -374,6 +374,7 @@ csum_partial_copy_from_user(const void _
 	}
 	return (__force __wsum)checksum;
 }
+EXPORT_SYMBOL(csum_partial_copy_from_user);
 
 __wsum
 csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
@@ -386,3 +387,4 @@ csum_partial_copy_nocheck(const void *sr
 	set_fs(oldfs);
 	return checksum;
 }
+EXPORT_SYMBOL(csum_partial_copy_nocheck);
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/dec_and_lock.c linux-libre-4.9-rc7-gnu/arch/alpha/lib/dec_and_lock.c
--- linux-libre-4.8-gnu/arch/alpha/lib/dec_and_lock.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/dec_and_lock.c	2016-11-27 16:08:04.000000000 -0500
@@ -7,6 +7,7 @@
 
 #include <linux/spinlock.h>
 #include <linux/atomic.h>
+#include <linux/export.h>
 
   asm (".text					\n\
 	.global _atomic_dec_and_lock		\n\
@@ -39,3 +40,4 @@ static int __used atomic_dec_and_lock_1(
 	spin_unlock(lock);
 	return 0;
 }
+EXPORT_SYMBOL(_atomic_dec_and_lock);
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/divide.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/divide.S
--- linux-libre-4.8-gnu/arch/alpha/lib/divide.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/divide.S	2016-11-27 16:08:04.000000000 -0500
@@ -45,6 +45,7 @@
  *	$28 - compare status
  */
 
+#include <asm/export.h>
 #define halt .long 0
 
 /*
@@ -151,6 +152,7 @@ ufunction:
 	addq	$30,STACK,$30
 	ret	$31,($23),1
 	.end	ufunction
+EXPORT_SYMBOL(ufunction)
 
 /*
  * Uhh.. Ugly signed division. I'd rather not have it at all, but
@@ -193,3 +195,4 @@ sfunction:
 	addq	$30,STACK,$30
 	ret	$31,($23),1
 	.end	sfunction
+EXPORT_SYMBOL(sfunction)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/ev67-strcat.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev67-strcat.S
--- linux-libre-4.8-gnu/arch/alpha/lib/ev67-strcat.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev67-strcat.S	2016-11-27 16:08:04.000000000 -0500
@@ -19,7 +19,7 @@
  * string once.
  */
 
-
+#include <asm/export.h>
 	.text
 
 	.align 4
@@ -52,3 +52,4 @@ $found:	cttz	$2, $3		# U0 :
 	br	__stxcpy	# L0 :
 
 	.end strcat
+	EXPORT_SYMBOL(strcat)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/ev67-strchr.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev67-strchr.S
--- linux-libre-4.8-gnu/arch/alpha/lib/ev67-strchr.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev67-strchr.S	2016-11-27 16:08:04.000000000 -0500
@@ -15,7 +15,7 @@
  *	L	- lower subcluster; L0 - subcluster L0; L1 - subcluster L1
  * Try not to change the actual algorithm if possible for consistency.
  */
-
+#include <asm/export.h>
 #include <asm/regdef.h>
 
 	.set noreorder
@@ -86,3 +86,4 @@ $found:	negq    t0, t1		# E : clear all
 	ret			# L0 :
 
 	.end strchr
+	EXPORT_SYMBOL(strchr)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/ev67-strlen.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev67-strlen.S
--- linux-libre-4.8-gnu/arch/alpha/lib/ev67-strlen.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev67-strlen.S	2016-11-27 16:08:04.000000000 -0500
@@ -17,7 +17,7 @@
  *	U	- upper subcluster; U0 - subcluster U0; U1 - subcluster U1
  *	L	- lower subcluster; L0 - subcluster L0; L1 - subcluster L1
  */
-
+#include <asm/export.h>
 	.set noreorder
 	.set noat
 
@@ -47,3 +47,4 @@ $found:
 	ret	$31, ($26)	# L0 :
 
 	.end	strlen
+	EXPORT_SYMBOL(strlen)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/ev67-strncat.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev67-strncat.S
--- linux-libre-4.8-gnu/arch/alpha/lib/ev67-strncat.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev67-strncat.S	2016-11-27 16:08:04.000000000 -0500
@@ -20,7 +20,7 @@
  * Try not to change the actual algorithm if possible for consistency.
  */
 
-
+#include <asm/export.h>
 	.text
 
 	.align 4
@@ -92,3 +92,4 @@ $zerocount:
 	ret			# L0 :
 
 	.end strncat
+	EXPORT_SYMBOL(strncat)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/ev67-strrchr.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev67-strrchr.S
--- linux-libre-4.8-gnu/arch/alpha/lib/ev67-strrchr.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev67-strrchr.S	2016-11-27 16:08:04.000000000 -0500
@@ -18,7 +18,7 @@
  *	L	- lower subcluster; L0 - subcluster L0; L1 - subcluster L1
  */
 
-
+#include <asm/export.h>
 #include <asm/regdef.h>
 
 	.set noreorder
@@ -107,3 +107,4 @@ $eos:
 	nop
 
 	.end strrchr
+	EXPORT_SYMBOL(strrchr)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/ev6-clear_page.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev6-clear_page.S
--- linux-libre-4.8-gnu/arch/alpha/lib/ev6-clear_page.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev6-clear_page.S	2016-11-27 16:08:04.000000000 -0500
@@ -3,7 +3,7 @@
  *
  * Zero an entire page.
  */
-
+#include <asm/export.h>
         .text
         .align 4
         .global clear_page
@@ -52,3 +52,4 @@ clear_page:
 	nop
 
 	.end clear_page
+	EXPORT_SYMBOL(clear_page)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/ev6-clear_user.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev6-clear_user.S
--- linux-libre-4.8-gnu/arch/alpha/lib/ev6-clear_user.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev6-clear_user.S	2016-11-27 16:08:04.000000000 -0500
@@ -43,6 +43,7 @@
  *	want to leave a hole (and we also want to avoid repeating lots of work)
  */
 
+#include <asm/export.h>
 /* Allow an exception for an insn; exit if we get one.  */
 #define EX(x,y...)			\
 	99: x,##y;			\
@@ -222,4 +223,4 @@ $exception:			# Destination for exceptio
 	nop			# .. E  .. ..	:
 	ret	$31, ($28), 1	# L0 .. .. ..	: L U L U
 	.end __do_clear_user
-
+	EXPORT_SYMBOL(__do_clear_user)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/ev6-copy_page.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev6-copy_page.S
--- linux-libre-4.8-gnu/arch/alpha/lib/ev6-copy_page.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev6-copy_page.S	2016-11-27 16:08:04.000000000 -0500
@@ -56,7 +56,7 @@
    destination pages are in the dcache, but it is my guess that this is
    less important than the dcache miss case.  */
 
-
+#include <asm/export.h>
 	.text
 	.align 4
 	.global copy_page
@@ -201,3 +201,4 @@ copy_page:
 	nop
 
 	.end copy_page
+	EXPORT_SYMBOL(copy_page)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/ev6-copy_user.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev6-copy_user.S
--- linux-libre-4.8-gnu/arch/alpha/lib/ev6-copy_user.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev6-copy_user.S	2016-11-27 16:08:04.000000000 -0500
@@ -37,6 +37,7 @@
  *	L	- lower subcluster; L0 - subcluster L0; L1 - subcluster L1
  */
 
+#include <asm/export.h>
 /* Allow an exception for an insn; exit if we get one.  */
 #define EXI(x,y...)			\
 	99: x,##y;			\
@@ -227,33 +228,12 @@ $dirtyentry:
 	bgt $0,$onebyteloop	# U  .. .. ..	: U L U L
 
 $zerolength:
+$exitin:
 $exitout:			# Destination for exception recovery(?)
 	nop			# .. .. .. E
 	nop			# .. .. E  ..
 	nop			# .. E  .. ..
 	ret $31,($28),1		# L0 .. .. ..	: L U L U
 
-$exitin:
-
-	/* A stupid byte-by-byte zeroing of the rest of the output
-	   buffer.  This cures security holes by never leaving 
-	   random kernel data around to be copied elsewhere.  */
-
-	nop
-	nop
-	nop
-	mov	$0,$1
-
-$101:
-	EXO ( stb $31,0($6) )	# L
-	subq $1,1,$1		# E
-	addq $6,1,$6		# E
-	bgt $1,$101		# U
-
-	nop
-	nop
-	nop
-	ret $31,($28),1		# L0
-
 	.end __copy_user
-
+	EXPORT_SYMBOL(__copy_user)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/ev6-csum_ipv6_magic.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev6-csum_ipv6_magic.S
--- linux-libre-4.8-gnu/arch/alpha/lib/ev6-csum_ipv6_magic.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev6-csum_ipv6_magic.S	2016-11-27 16:08:04.000000000 -0500
@@ -52,6 +52,7 @@
  * may cause additional delay in rare cases (load-load replay traps).
  */
 
+#include <asm/export.h>
 	.globl csum_ipv6_magic
 	.align 4
 	.ent csum_ipv6_magic
@@ -148,3 +149,4 @@ csum_ipv6_magic:
 	ret			# L0 : L U L U
 
 	.end csum_ipv6_magic
+	EXPORT_SYMBOL(csum_ipv6_magic)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/ev6-divide.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev6-divide.S
--- linux-libre-4.8-gnu/arch/alpha/lib/ev6-divide.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev6-divide.S	2016-11-27 16:08:04.000000000 -0500
@@ -55,6 +55,7 @@
  * Try not to change the actual algorithm if possible for consistency.
  */
 
+#include <asm/export.h>
 #define halt .long 0
 
 /*
@@ -205,6 +206,7 @@ ufunction:
 	addq	$30,STACK,$30		# E :
 	ret	$31,($23),1		# L0 : L U U L
 	.end	ufunction
+EXPORT_SYMBOL(ufunction)
 
 /*
  * Uhh.. Ugly signed division. I'd rather not have it at all, but
@@ -257,3 +259,4 @@ sfunction:
 	addq	$30,STACK,$30		# E :
 	ret	$31,($23),1		# L0 : L U U L
 	.end	sfunction
+EXPORT_SYMBOL(sfunction)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/ev6-memchr.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev6-memchr.S
--- linux-libre-4.8-gnu/arch/alpha/lib/ev6-memchr.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev6-memchr.S	2016-11-27 16:08:04.000000000 -0500
@@ -27,7 +27,7 @@
  *	L	- lower subcluster; L0 - subcluster L0; L1 - subcluster L1
  * Try not to change the actual algorithm if possible for consistency.
  */
-
+#include <asm/export.h>
         .set noreorder
         .set noat
 
@@ -189,3 +189,4 @@ $not_found:
 	ret			# L0 :
 
         .end memchr
+	EXPORT_SYMBOL(memchr)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/ev6-memcpy.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev6-memcpy.S
--- linux-libre-4.8-gnu/arch/alpha/lib/ev6-memcpy.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev6-memcpy.S	2016-11-27 16:08:04.000000000 -0500
@@ -19,7 +19,7 @@
  * Temp usage notes:
  *	$1,$2,		- scratch
  */
-
+#include <asm/export.h>
 	.set noreorder
 	.set noat
 
@@ -242,6 +242,7 @@ $nomoredata:
 	nop				# E :
 
 	.end memcpy
+	EXPORT_SYMBOL(memcpy)
 
 /* For backwards module compatibility.  */
 __memcpy = memcpy
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/ev6-memset.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev6-memset.S
--- linux-libre-4.8-gnu/arch/alpha/lib/ev6-memset.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/ev6-memset.S	2016-11-27 16:08:04.000000000 -0500
@@ -26,7 +26,7 @@
  * as fixes will need to be made in multiple places.  The performance gain
  * is worth it.
  */
-
+#include <asm/export.h>
 	.set noat
 	.set noreorder
 .text
@@ -229,6 +229,7 @@ end_b:
 	nop
 	ret $31,($26),1		# L0 :
 	.end ___memset
+	EXPORT_SYMBOL(___memset)
 
 	/*
 	 * This is the original body of code, prior to replication and
@@ -406,6 +407,7 @@ end:
 	nop
 	ret $31,($26),1		# L0 :
 	.end __constant_c_memset
+	EXPORT_SYMBOL(__constant_c_memset)
 
 	/*
 	 * This is a replicant of the __constant_c_memset code, rescheduled
@@ -594,6 +596,9 @@ end_w:
 	ret $31,($26),1		# L0 :
 
 	.end __memsetw
+	EXPORT_SYMBOL(__memsetw)
 
 memset = ___memset
 __memset = ___memset
+	EXPORT_SYMBOL(memset)
+	EXPORT_SYMBOL(__memset)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/fpreg.c linux-libre-4.9-rc7-gnu/arch/alpha/lib/fpreg.c
--- linux-libre-4.8-gnu/arch/alpha/lib/fpreg.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/fpreg.c	2016-11-27 16:08:04.000000000 -0500
@@ -4,6 +4,9 @@
  * (C) Copyright 1998 Linus Torvalds
  */
 
+#include <linux/compiler.h>
+#include <linux/export.h>
+
 #if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
 #define STT(reg,val)  asm volatile ("ftoit $f"#reg",%0" : "=r"(val));
 #else
@@ -52,6 +55,7 @@ alpha_read_fp_reg (unsigned long reg)
 	}
 	return val;
 }
+EXPORT_SYMBOL(alpha_read_fp_reg);
 
 #if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
 #define LDT(reg,val)  asm volatile ("itoft %0,$f"#reg : : "r"(val));
@@ -97,6 +101,7 @@ alpha_write_fp_reg (unsigned long reg, u
 	      case 31: LDT(31, val); break;
 	}
 }
+EXPORT_SYMBOL(alpha_write_fp_reg);
 
 #if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
 #define STS(reg,val)  asm volatile ("ftois $f"#reg",%0" : "=r"(val));
@@ -146,6 +151,7 @@ alpha_read_fp_reg_s (unsigned long reg)
 	}
 	return val;
 }
+EXPORT_SYMBOL(alpha_read_fp_reg_s);
 
 #if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
 #define LDS(reg,val)  asm volatile ("itofs %0,$f"#reg : : "r"(val));
@@ -191,3 +197,4 @@ alpha_write_fp_reg_s (unsigned long reg,
 	      case 31: LDS(31, val); break;
 	}
 }
+EXPORT_SYMBOL(alpha_write_fp_reg_s);
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/memchr.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/memchr.S
--- linux-libre-4.8-gnu/arch/alpha/lib/memchr.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/memchr.S	2016-11-27 16:08:04.000000000 -0500
@@ -31,7 +31,7 @@ For correctness consider that:
       - only minimum number of quadwords may be accessed
       - the third argument is an unsigned long
 */
-
+#include <asm/export.h>
         .set noreorder
         .set noat
 
@@ -162,3 +162,4 @@ $not_found:
 	ret			# .. e1 :
 
         .end memchr
+	EXPORT_SYMBOL(memchr)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/memcpy.c linux-libre-4.9-rc7-gnu/arch/alpha/lib/memcpy.c
--- linux-libre-4.8-gnu/arch/alpha/lib/memcpy.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/memcpy.c	2016-11-27 16:08:04.000000000 -0500
@@ -16,6 +16,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/export.h>
 
 /*
  * This should be done in one go with ldq_u*2/mask/stq_u. Do it
@@ -158,6 +159,4 @@ void * memcpy(void * dest, const void *s
 	__memcpy_unaligned_up ((unsigned long) dest, (unsigned long) src, n);
 	return dest;
 }
-
-/* For backward modules compatibility, define __memcpy.  */
-asm("__memcpy = memcpy; .globl __memcpy");
+EXPORT_SYMBOL(memcpy);
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/memmove.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/memmove.S
--- linux-libre-4.8-gnu/arch/alpha/lib/memmove.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/memmove.S	2016-11-27 16:08:04.000000000 -0500
@@ -6,7 +6,7 @@
  * This is hand-massaged output from the original memcpy.c.  We defer to
  * memcpy whenever possible; the backwards copy loops are not unrolled.
  */
-        
+#include <asm/export.h>        
 	.set noat
 	.set noreorder
 	.text
@@ -179,3 +179,4 @@ $egress:
 	nop
 
 	.end memmove
+	EXPORT_SYMBOL(memmove)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/memset.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/memset.S
--- linux-libre-4.8-gnu/arch/alpha/lib/memset.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/memset.S	2016-11-27 16:08:04.000000000 -0500
@@ -13,7 +13,7 @@
  * The scheduling comments are according to the EV5 documentation (and done by 
  * hand, so they might well be incorrect, please do tell me about it..)
  */
-
+#include <asm/export.h>
 	.set noat
 	.set noreorder
 .text
@@ -106,6 +106,8 @@ within_one_quad:
 end:
 	ret $31,($26),1		/* E1 */
 	.end ___memset
+EXPORT_SYMBOL(___memset)
+EXPORT_SYMBOL(__constant_c_memset)
 
 	.align 5
 	.ent __memsetw
@@ -122,6 +124,9 @@ __memsetw:
 	br __constant_c_memset	/* .. E1 */
 
 	.end __memsetw
+EXPORT_SYMBOL(__memsetw)
 
 memset = ___memset
 __memset = ___memset
+	EXPORT_SYMBOL(memset)
+	EXPORT_SYMBOL(__memset)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/strcat.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/strcat.S
--- linux-libre-4.8-gnu/arch/alpha/lib/strcat.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/strcat.S	2016-11-27 16:08:04.000000000 -0500
@@ -4,6 +4,7 @@
  *
  * Append a null-terminated string from SRC to DST.
  */
+#include <asm/export.h>
 
 	.text
 
@@ -50,3 +51,4 @@ $found:	negq    $2, $3		# clear all but
 	br	__stxcpy
 
 	.end strcat
+EXPORT_SYMBOL(strcat);
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/strchr.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/strchr.S
--- linux-libre-4.8-gnu/arch/alpha/lib/strchr.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/strchr.S	2016-11-27 16:08:04.000000000 -0500
@@ -5,7 +5,7 @@
  * Return the address of a given character within a null-terminated
  * string, or null if it is not found.
  */
-
+#include <asm/export.h>
 #include <asm/regdef.h>
 
 	.set noreorder
@@ -68,3 +68,4 @@ $retnull:
 	ret			# .. e1 :
 
 	.end strchr
+	EXPORT_SYMBOL(strchr)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/strcpy.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/strcpy.S
--- linux-libre-4.8-gnu/arch/alpha/lib/strcpy.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/strcpy.S	2016-11-27 16:08:04.000000000 -0500
@@ -5,7 +5,7 @@
  * Copy a null-terminated string from SRC to DST.  Return a pointer
  * to the null-terminator in the source.
  */
-
+#include <asm/export.h>
 	.text
 
 	.align 3
@@ -21,3 +21,4 @@ strcpy:
 	br	__stxcpy	# do the copy
 
 	.end strcpy
+	EXPORT_SYMBOL(strcpy)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/strlen.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/strlen.S
--- linux-libre-4.8-gnu/arch/alpha/lib/strlen.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/strlen.S	2016-11-27 16:08:04.000000000 -0500
@@ -11,7 +11,7 @@
  *	  do this instead of the 9 instructions that
  *	  binary search needs).
  */
-
+#include <asm/export.h>
 	.set noreorder
 	.set noat
 
@@ -55,3 +55,4 @@ done:	subq	$0, $16, $0
 	ret	$31, ($26)
 
 	.end	strlen
+	EXPORT_SYMBOL(strlen)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/strncat.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/strncat.S
--- linux-libre-4.8-gnu/arch/alpha/lib/strncat.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/strncat.S	2016-11-27 16:08:04.000000000 -0500
@@ -9,7 +9,7 @@
  * past count, whereas libc may write to count+1.  This follows the generic
  * implementation in lib/string.c and is, IMHO, more sensible.
  */
-
+#include <asm/export.h>
 	.text
 
 	.align 3
@@ -82,3 +82,4 @@ $zerocount:
 	ret
 
 	.end strncat
+	EXPORT_SYMBOL(strncat)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/strncpy.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/strncpy.S
--- linux-libre-4.8-gnu/arch/alpha/lib/strncpy.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/strncpy.S	2016-11-27 16:08:04.000000000 -0500
@@ -10,7 +10,7 @@
  * version has cropped that bit o' nastiness as well as assuming that
  * __stxncpy is in range of a branch.
  */
-
+#include <asm/export.h>
 	.set noat
 	.set noreorder
 
@@ -79,3 +79,4 @@ $zerolen:
 	ret
 
 	.end	strncpy
+	EXPORT_SYMBOL(strncpy)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/alpha/lib/strrchr.S linux-libre-4.9-rc7-gnu/arch/alpha/lib/strrchr.S
--- linux-libre-4.8-gnu/arch/alpha/lib/strrchr.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/alpha/lib/strrchr.S	2016-11-27 16:08:04.000000000 -0500
@@ -5,7 +5,7 @@
  * Return the address of the last occurrence of a given character
  * within a null-terminated string, or null if it is not found.
  */
-
+#include <asm/export.h>
 #include <asm/regdef.h>
 
 	.set noreorder
@@ -85,3 +85,4 @@ $retnull:
 	ret			# .. e1 :
 
 	.end strrchr
+	EXPORT_SYMBOL(strrchr)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/boot/dts/abilis_tb100_dvk.dts linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/abilis_tb100_dvk.dts
--- linux-libre-4.8-gnu/arch/arc/boot/dts/abilis_tb100_dvk.dts	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/abilis_tb100_dvk.dts	2016-11-27 16:08:04.000000000 -0500
@@ -24,6 +24,7 @@
 /include/ "abilis_tb100.dtsi"
 
 / {
+	model = "abilis,tb100";
 	chosen {
 		bootargs = "earlycon=uart8250,mmio32,0xff100000,9600n8 console=ttyS0,9600n8";
 	};
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/boot/dts/abilis_tb101_dvk.dts linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/abilis_tb101_dvk.dts
--- linux-libre-4.8-gnu/arch/arc/boot/dts/abilis_tb101_dvk.dts	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/abilis_tb101_dvk.dts	2016-11-27 16:08:04.000000000 -0500
@@ -24,6 +24,7 @@
 /include/ "abilis_tb101.dtsi"
 
 / {
+	model = "abilis,tb101";
 	chosen {
 		bootargs = "earlycon=uart8250,mmio32,0xff100000,9600n8 console=ttyS0,9600n8";
 	};
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/boot/dts/axc001.dtsi linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/axc001.dtsi
--- linux-libre-4.8-gnu/arch/arc/boot/dts/axc001.dtsi	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/axc001.dtsi	2016-11-27 16:08:04.000000000 -0500
@@ -71,7 +71,7 @@
 			reg-io-width = <4>;
 		};
 
-		arcpmu0: pmu {
+		arcpct0: pct {
 			compatible = "snps,arc700-pct";
 		};
 	};
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/boot/dts/axs101.dts linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/axs101.dts
--- linux-libre-4.8-gnu/arch/arc/boot/dts/axs101.dts	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/axs101.dts	2016-11-27 16:08:04.000000000 -0500
@@ -13,6 +13,7 @@
 /include/ "axs10x_mb.dtsi"
 
 / {
+	model = "snps,axs101";
 	compatible = "snps,axs101", "snps,arc-sdp";
 
 	chosen {
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/boot/dts/axs103.dts linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/axs103.dts
--- linux-libre-4.8-gnu/arch/arc/boot/dts/axs103.dts	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/axs103.dts	2016-11-27 16:08:04.000000000 -0500
@@ -16,6 +16,7 @@
 /include/ "axs10x_mb.dtsi"
 
 / {
+	model = "snps,axs103";
 	compatible = "snps,axs103", "snps,arc-sdp";
 
 	chosen {
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/boot/dts/axs103_idu.dts linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/axs103_idu.dts
--- linux-libre-4.8-gnu/arch/arc/boot/dts/axs103_idu.dts	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/axs103_idu.dts	2016-11-27 16:08:04.000000000 -0500
@@ -16,6 +16,7 @@
 /include/ "axs10x_mb.dtsi"
 
 / {
+	model = "snps,axs103-smp";
 	compatible = "snps,axs103", "snps,arc-sdp";
 
 	chosen {
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/boot/dts/nsim_700.dts linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/nsim_700.dts
--- linux-libre-4.8-gnu/arch/arc/boot/dts/nsim_700.dts	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/nsim_700.dts	2016-11-27 16:08:04.000000000 -0500
@@ -10,6 +10,7 @@
 /include/ "skeleton.dtsi"
 
 / {
+	model = "snps,nsim";
 	compatible = "snps,nsim";
 	#address-cells = <1>;
 	#size-cells = <1>;
@@ -68,7 +69,7 @@
 			};
 		};
 
-		arcpmu0: pmu {
+		arcpct0: pct {
 			compatible = "snps,arc700-pct";
 		};
 	};
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/boot/dts/nsim_hs.dts linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/nsim_hs.dts
--- linux-libre-4.8-gnu/arch/arc/boot/dts/nsim_hs.dts	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/nsim_hs.dts	2016-11-27 16:08:04.000000000 -0500
@@ -10,6 +10,7 @@
 /include/ "skeleton_hs.dtsi"
 
 / {
+	model = "snps,nsim_hs";
 	compatible = "snps,nsim_hs";
 	#address-cells = <2>;
 	#size-cells = <2>;
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/boot/dts/nsim_hs_idu.dts linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/nsim_hs_idu.dts
--- linux-libre-4.8-gnu/arch/arc/boot/dts/nsim_hs_idu.dts	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/nsim_hs_idu.dts	2016-11-27 16:08:04.000000000 -0500
@@ -10,6 +10,7 @@
 /include/ "skeleton_hs_idu.dtsi"
 
 / {
+	model = "snps,nsim_hs-smp";
 	compatible = "snps,nsim_hs";
 	interrupt-parent = <&core_intc>;
 
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/boot/dts/nsimosci.dts linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/nsimosci.dts
--- linux-libre-4.8-gnu/arch/arc/boot/dts/nsimosci.dts	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/nsimosci.dts	2016-11-27 16:08:04.000000000 -0500
@@ -10,6 +10,7 @@
 /include/ "skeleton.dtsi"
 
 / {
+	model = "snps,nsimosci";
 	compatible = "snps,nsimosci";
 	#address-cells = <1>;
 	#size-cells = <1>;
@@ -82,5 +83,9 @@
 			reg = <0xf0003000 0x44>;
 			interrupts = <7>;
 		};
+
+		arcpct0: pct {
+			compatible = "snps,arc700-pct";
+		};
 	};
 };
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/boot/dts/nsimosci_hs.dts linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/nsimosci_hs.dts
--- linux-libre-4.8-gnu/arch/arc/boot/dts/nsimosci_hs.dts	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/nsimosci_hs.dts	2016-11-27 16:08:04.000000000 -0500
@@ -10,6 +10,7 @@
 /include/ "skeleton_hs.dtsi"
 
 / {
+	model = "snps,nsimosci_hs";
 	compatible = "snps,nsimosci_hs";
 	#address-cells = <1>;
 	#size-cells = <1>;
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/boot/dts/nsimosci_hs_idu.dts linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/nsimosci_hs_idu.dts
--- linux-libre-4.8-gnu/arch/arc/boot/dts/nsimosci_hs_idu.dts	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/nsimosci_hs_idu.dts	2016-11-27 16:08:04.000000000 -0500
@@ -10,6 +10,7 @@
 /include/ "skeleton_hs_idu.dtsi"
 
 / {
+	model = "snps,nsimosci_hs-smp";
 	compatible = "snps,nsimosci_hs";
 	#address-cells = <1>;
 	#size-cells = <1>;
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/boot/dts/vdk_hs38.dts linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/vdk_hs38.dts
--- linux-libre-4.8-gnu/arch/arc/boot/dts/vdk_hs38.dts	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/vdk_hs38.dts	2016-11-27 16:08:04.000000000 -0500
@@ -13,6 +13,7 @@
 /include/ "vdk_axs10x_mb.dtsi"
 
 / {
+	model = "snps,vdk_archs";
 	compatible = "snps,axs103";
 
 	chosen {
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/boot/dts/vdk_hs38_smp.dts linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/vdk_hs38_smp.dts
--- linux-libre-4.8-gnu/arch/arc/boot/dts/vdk_hs38_smp.dts	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/vdk_hs38_smp.dts	2016-11-27 16:08:04.000000000 -0500
@@ -13,6 +13,7 @@
 /include/ "vdk_axs10x_mb.dtsi"
 
 / {
+	model = "snps,vdk_archs-smp";
 	compatible = "snps,axs103";
 
 	chosen {
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/boot/dts/zebu_hs.dts linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/zebu_hs.dts
--- linux-libre-4.8-gnu/arch/arc/boot/dts/zebu_hs.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/zebu_hs.dts	2016-11-27 16:08:04.000000000 -0500
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016-2014 Synopsys, Inc. (www.synopsys.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+/include/ "skeleton_hs.dtsi"
+
+/ {
+	model = "snps,zebu_hs";
+	compatible = "snps,zebu_hs";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&core_intc>;
+
+	memory {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>;	/* 512 */
+	};
+
+	chosen {
+		bootargs = "earlycon=uart8250,mmio32,0xf0000000,115200n8 console=ttyS0,115200n8 debug print-fatal-signals=1";
+	};
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	fpga {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		/* child and parent address space 1:1 mapped */
+		ranges;
+
+		core_clk: core_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <50000000>;
+		};
+
+		core_intc: interrupt-controller {
+			compatible = "snps,archs-intc";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		uart0: serial@f0000000 {
+			compatible = "ns8250";
+			reg = <0xf0000000 0x2000>;
+			interrupts = <24>;
+			clock-frequency = <50000000>;
+			baud = <115200>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			no-loopback-test = <1>;
+		};
+
+		arcpct0: pct {
+			compatible = "snps,archs-pct";
+			#interrupt-cells = <1>;
+			interrupts = <20>;
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/boot/dts/zebu_hs_idu.dts linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/zebu_hs_idu.dts
--- linux-libre-4.8-gnu/arch/arc/boot/dts/zebu_hs_idu.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-4.9-rc7-gnu/arch/arc/boot/dts/zebu_hs_idu.dts	2016-11-27 16:08:04.000000000 -0500
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2016-2014 Synopsys, Inc. (www.synopsys.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+/include/ "skeleton_hs_idu.dtsi"
+
+/ {
+	model = "snps,zebu_hs-smp";
+	compatible = "snps,zebu_hs";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&core_intc>;
+
+	memory {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>;	/* 512 */
+	};
+
+	chosen {
+		bootargs = "earlycon=uart8250,mmio32,0xf0000000,115200n8 console=ttyS0,115200n8 debug";
+	};
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	fpga {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		/* child and parent address space 1:1 mapped */
+		ranges;
+
+		core_clk: core_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <50000000>;	/* 50 MHZ */
+		};
+
+		core_intc: interrupt-controller {
+			compatible = "snps,archs-intc";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+/*			interrupts = <16 17 18 19 20 21 22 23 24 25>; */
+		};
+
+		idu_intc: idu-interrupt-controller {
+			compatible = "snps,archs-idu-intc";
+			interrupt-controller;
+			interrupt-parent = <&core_intc>;
+			/* <hwirq  distribution>
+			distribution: 0=RR; 1=cpu0, 2=cpu1, 4=cpu2, 8=cpu3 */
+			#interrupt-cells = <2>;
+			interrupts = <24 25 26 27 28 29 30 31>;
+
+		};
+
+		uart0: serial@f0000000 {
+			/* compatible = "ns8250"; Doesn't use FIFOs */
+			compatible = "ns16550a";
+			reg = <0xf0000000 0x2000>;
+			interrupt-parent = <&idu_intc>;
+			/* interrupts = <0 1>;  DEST=1*/
+			/* interrupts = <0 2>;  DEST=2*/
+			interrupts = <0 0>;  /* RR*/
+			clock-frequency = <50000000>;
+			baud = <115200>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			no-loopback-test = <1>;
+		};
+
+		arcpct0: pct {
+			compatible = "snps,archs-pct";
+			#interrupt-cells = <1>;
+			interrupts = <20>;
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/boot/Makefile linux-libre-4.9-rc7-gnu/arch/arc/boot/Makefile
--- linux-libre-4.8-gnu/arch/arc/boot/Makefile	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/boot/Makefile	2016-11-27 16:08:04.000000000 -0500
@@ -14,9 +14,15 @@ UIMAGE_ENTRYADDR   = $(LINUX_START_TEXT)
 
 suffix-y := bin
 suffix-$(CONFIG_KERNEL_GZIP)	:= gz
+suffix-$(CONFIG_KERNEL_LZMA)	:= lzma
 
-targets += uImage uImage.bin uImage.gz
-extra-y += vmlinux.bin vmlinux.bin.gz
+targets += uImage
+targets += uImage.bin
+targets += uImage.gz
+targets += uImage.lzma
+extra-y += vmlinux.bin
+extra-y += vmlinux.bin.gz
+extra-y += vmlinux.bin.lzma
 
 $(obj)/vmlinux.bin: vmlinux FORCE
 	$(call if_changed,objcopy)
@@ -24,12 +30,18 @@ $(obj)/vmlinux.bin: vmlinux FORCE
 $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,gzip)
 
+$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
+	$(call if_changed,lzma)
+
 $(obj)/uImage.bin: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,uimage,none)
 
 $(obj)/uImage.gz: $(obj)/vmlinux.bin.gz FORCE
 	$(call if_changed,uimage,gzip)
 
+$(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma FORCE
+	$(call if_changed,uimage,lzma)
+
 $(obj)/uImage: $(obj)/uImage.$(suffix-y)
 	@ln -sf $(notdir $<) $@
 	@echo '  Image $@ is ready'
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/configs/axs101_defconfig linux-libre-4.9-rc7-gnu/arch/arc/configs/axs101_defconfig
--- linux-libre-4.8-gnu/arch/arc/configs/axs101_defconfig	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/configs/axs101_defconfig	2016-11-27 16:08:04.000000000 -0500
@@ -18,6 +18,9 @@ CONFIG_PERF_EVENTS=y
 # CONFIG_SLUB_DEBUG is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_ARC_PLAT_AXS10X=y
 CONFIG_AXS101=y
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/configs/axs103_defconfig linux-libre-4.9-rc7-gnu/arch/arc/configs/axs103_defconfig
--- linux-libre-4.8-gnu/arch/arc/configs/axs103_defconfig	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/configs/axs103_defconfig	2016-11-27 16:08:04.000000000 -0500
@@ -18,6 +18,9 @@ CONFIG_PERF_EVENTS=y
 # CONFIG_SLUB_DEBUG is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_ARC_PLAT_AXS10X=y
 CONFIG_AXS103=y
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/configs/axs103_smp_defconfig linux-libre-4.9-rc7-gnu/arch/arc/configs/axs103_smp_defconfig
--- linux-libre-4.8-gnu/arch/arc/configs/axs103_smp_defconfig	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/configs/axs103_smp_defconfig	2016-11-27 16:08:04.000000000 -0500
@@ -18,6 +18,9 @@ CONFIG_PERF_EVENTS=y
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_ARC_PLAT_AXS10X=y
 CONFIG_AXS103=y
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/configs/nsim_700_defconfig linux-libre-4.9-rc7-gnu/arch/arc/configs/nsim_700_defconfig
--- linux-libre-4.8-gnu/arch/arc/configs/nsim_700_defconfig	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/configs/nsim_700_defconfig	2016-11-27 16:08:04.000000000 -0500
@@ -14,6 +14,7 @@ CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE="../arc_initramfs/"
 CONFIG_KALLSYMS_ALL=y
 CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
 # CONFIG_SLUB_DEBUG is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_KPROBES=y
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/configs/nsim_hs_defconfig linux-libre-4.9-rc7-gnu/arch/arc/configs/nsim_hs_defconfig
--- linux-libre-4.8-gnu/arch/arc/configs/nsim_hs_defconfig	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/configs/nsim_hs_defconfig	2016-11-27 16:08:04.000000000 -0500
@@ -11,13 +11,17 @@ CONFIG_NAMESPACES=y
 # CONFIG_UTS_NS is not set
 # CONFIG_PID_NS is not set
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/"
+CONFIG_INITRAMFS_SOURCE="../../arc_initramfs_hs/"
 CONFIG_KALLSYMS_ALL=y
 CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
 # CONFIG_SLUB_DEBUG is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_KPROBES=y
 CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
 # CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/configs/nsim_hs_smp_defconfig linux-libre-4.9-rc7-gnu/arch/arc/configs/nsim_hs_smp_defconfig
--- linux-libre-4.8-gnu/arch/arc/configs/nsim_hs_smp_defconfig	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/configs/nsim_hs_smp_defconfig	2016-11-27 16:08:04.000000000 -0500
@@ -12,10 +12,14 @@ CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/"
 CONFIG_KALLSYMS_ALL=y
 CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
 # CONFIG_SLUB_DEBUG is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_KPROBES=y
 CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
 # CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/configs/nsimosci_defconfig linux-libre-4.9-rc7-gnu/arch/arc/configs/nsimosci_defconfig
--- linux-libre-4.8-gnu/arch/arc/configs/nsimosci_defconfig	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/configs/nsimosci_defconfig	2016-11-27 16:08:04.000000000 -0500
@@ -14,6 +14,7 @@ CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE="../arc_initramfs/"
 CONFIG_KALLSYMS_ALL=y
 CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
 # CONFIG_SLUB_DEBUG is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_KPROBES=y
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/configs/nsimosci_hs_defconfig linux-libre-4.9-rc7-gnu/arch/arc/configs/nsimosci_hs_defconfig
--- linux-libre-4.8-gnu/arch/arc/configs/nsimosci_hs_defconfig	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/configs/nsimosci_hs_defconfig	2016-11-27 16:08:04.000000000 -0500
@@ -14,6 +14,7 @@ CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/"
 CONFIG_KALLSYMS_ALL=y
 CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
 # CONFIG_SLUB_DEBUG is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_KPROBES=y
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/configs/nsimosci_hs_smp_defconfig linux-libre-4.9-rc7-gnu/arch/arc/configs/nsimosci_hs_smp_defconfig
--- linux-libre-4.8-gnu/arch/arc/configs/nsimosci_hs_smp_defconfig	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/configs/nsimosci_hs_smp_defconfig	2016-11-27 16:08:04.000000000 -0500
@@ -10,6 +10,7 @@ CONFIG_IKCONFIG_PROC=y
 # CONFIG_PID_NS is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/"
+CONFIG_PERF_EVENTS=y
 # CONFIG_COMPAT_BRK is not set
 CONFIG_KPROBES=y
 CONFIG_MODULES=y
@@ -34,7 +35,6 @@ CONFIG_INET=y
 # CONFIG_INET_XFRM_MODE_TRANSPORT is not set
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
 # CONFIG_IPV6 is not set
 # CONFIG_WIRELESS is not set
 CONFIG_DEVTMPFS=y
@@ -72,7 +72,6 @@ CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_HWMON is not set
 CONFIG_DRM=y
 CONFIG_DRM_ARCPGU=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_LOGO=y
 # CONFIG_HID is not set
 # CONFIG_USB_SUPPORT is not set
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/configs/zebu_hs_defconfig linux-libre-4.9-rc7-gnu/arch/arc/configs/zebu_hs_defconfig
--- linux-libre-4.8-gnu/arch/arc/configs/zebu_hs_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-4.9-rc7-gnu/arch/arc/configs/zebu_hs_defconfig	2016-11-27 16:08:04.000000000 -0500
@@ -0,0 +1,86 @@
+CONFIG_DEFAULT_HOSTNAME="ARCLinux"
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="../../arc_initramfs_hs/"
+CONFIG_EXPERT=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARC_PLAT_SIM=y
+CONFIG_ISA_ARCV2=y
+CONFIG_ARC_BUILTIN_DTB_NAME="zebu_hs"
+CONFIG_PREEMPT=y
+# CONFIG_COMPACTION is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=y
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_BLK_DEV is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_MOUSE_PS2_TOUCHKIT=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_ARC_PS2=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+# CONFIG_HID is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_PREEMPT is not set
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/configs/zebu_hs_smp_defconfig linux-libre-4.9-rc7-gnu/arch/arc/configs/zebu_hs_smp_defconfig
--- linux-libre-4.8-gnu/arch/arc/configs/zebu_hs_smp_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-4.9-rc7-gnu/arch/arc/configs/zebu_hs_smp_defconfig	2016-11-27 16:08:04.000000000 -0500
@@ -0,0 +1,89 @@
+CONFIG_DEFAULT_HOSTNAME="ARCLinux"
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="../../arc_initramfs_hs/"
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARC_PLAT_SIM=y
+CONFIG_ISA_ARCV2=y
+CONFIG_SMP=y
+CONFIG_ARC_BUILTIN_DTB_NAME="zebu_hs_idu"
+CONFIG_PREEMPT=y
+# CONFIG_COMPACTION is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=y
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_BLK_DEV is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_MOUSE_PS2_TOUCHKIT=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_ARC_PS2=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+# CONFIG_HID is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_LOCKUP_DETECTOR=y
+# CONFIG_DEBUG_PREEMPT is not set
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/include/asm/arcregs.h linux-libre-4.9-rc7-gnu/arch/arc/include/asm/arcregs.h
--- linux-libre-4.8-gnu/arch/arc/include/asm/arcregs.h	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/include/asm/arcregs.h	2016-11-27 16:08:04.000000000 -0500
@@ -43,12 +43,14 @@
 #define STATUS_AE_BIT		5	/* Exception active */
 #define STATUS_DE_BIT		6	/* PC is in delay slot */
 #define STATUS_U_BIT		7	/* User/Kernel mode */
+#define STATUS_Z_BIT            11
 #define STATUS_L_BIT		12	/* Loop inhibit */
 
 /* These masks correspond to the status word(STATUS_32) bits */
 #define STATUS_AE_MASK		(1<<STATUS_AE_BIT)
 #define STATUS_DE_MASK		(1<<STATUS_DE_BIT)
 #define STATUS_U_MASK		(1<<STATUS_U_BIT)
+#define STATUS_Z_MASK		(1<<STATUS_Z_BIT)
 #define STATUS_L_MASK		(1<<STATUS_L_BIT)
 
 /*
@@ -95,7 +97,7 @@
 /* Auxiliary registers */
 #define AUX_IDENTITY		4
 #define AUX_INTR_VEC_BASE	0x25
-#define AUX_NON_VOL		0x5e
+#define AUX_VOL			0x5e
 
 /*
  * Floating Pt Registers
@@ -240,14 +242,6 @@ struct bcr_extn_xymem {
 #endif
 };
 
-struct bcr_perip {
-#ifdef CONFIG_CPU_BIG_ENDIAN
-	unsigned int start:8, pad2:8, sz:8, ver:8;
-#else
-	unsigned int ver:8, sz:8, pad2:8, start:8;
-#endif
-};
-
 struct bcr_iccm_arcompact {
 #ifdef CONFIG_CPU_BIG_ENDIAN
 	unsigned int base:16, pad:5, sz:3, ver:8;
@@ -357,10 +351,11 @@ struct cpuinfo_arc {
 	struct cpuinfo_arc_bpu bpu;
 	struct bcr_identity core;
 	struct bcr_isa isa;
+	const char *details, *name;
 	unsigned int vec_base;
 	struct cpuinfo_arc_ccm iccm, dccm;
 	struct {
-		unsigned int swap:1, norm:1, minmax:1, barrel:1, crc:1, pad1:3,
+		unsigned int swap:1, norm:1, minmax:1, barrel:1, crc:1, swape:1, pad1:2,
 			     fpu_sp:1, fpu_dp:1, pad2:6,
 			     debug:1, ap:1, smart:1, rtt:1, pad3:4,
 			     timer0:1, timer1:1, rtc:1, gfrc:1, pad4:4;
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/include/asm/atomic.h linux-libre-4.9-rc7-gnu/arch/arc/include/asm/atomic.h
--- linux-libre-4.8-gnu/arch/arc/include/asm/atomic.h	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/include/asm/atomic.h	2016-11-27 16:08:04.000000000 -0500
@@ -20,6 +20,7 @@
 #ifndef CONFIG_ARC_PLAT_EZNPS
 
 #define atomic_read(v)  READ_ONCE((v)->counter)
+#define ATOMIC_INIT(i)	{ (i) }
 
 #ifdef CONFIG_ARC_HAS_LLSC
 
@@ -284,6 +285,7 @@ static inline int atomic_fetch_##op(int
 ATOMIC_OPS(add, +=, CTOP_INST_AADD_DI_R2_R2_R3)
 #define atomic_sub(i, v) atomic_add(-(i), (v))
 #define atomic_sub_return(i, v) atomic_add_return(-(i), (v))
+#define atomic_fetch_sub(i, v) atomic_fetch_add(-(i), (v))
 
 #undef ATOMIC_OPS
 #define ATOMIC_OPS(op, c_op, asm_op)					\
@@ -292,6 +294,7 @@ ATOMIC_OPS(add, +=, CTOP_INST_AADD_DI_R2
 
 ATOMIC_OPS(and, &=, CTOP_INST_AAND_DI_R2_R2_R3)
 #define atomic_andnot(mask, v) atomic_and(~(mask), (v))
+#define atomic_fetch_andnot(mask, v) atomic_fetch_and(~(mask), (v))
 ATOMIC_OPS(or, |=, CTOP_INST_AOR_DI_R2_R2_R3)
 ATOMIC_OPS(xor, ^=, CTOP_INST_AXOR_DI_R2_R2_R3)
 
@@ -343,10 +346,266 @@ ATOMIC_OPS(xor, ^=, CTOP_INST_AXOR_DI_R2
 
 #define atomic_add_negative(i, v)	(atomic_add_return(i, v) < 0)
 
-#define ATOMIC_INIT(i)			{ (i) }
+
+#ifdef CONFIG_GENERIC_ATOMIC64
 
 #include <asm-generic/atomic64.h>
 
-#endif
+#else	/* Kconfig ensures this is only enabled with needed h/w assist */
+
+/*
+ * ARCv2 supports 64-bit exclusive load (LLOCKD) / store (SCONDD)
+ *  - The address HAS to be 64-bit aligned
+ *  - There are 2 semantics involved here:
+ *    = exclusive implies no interim update between load/store to same addr
+ *    = both words are observed/updated together: this is guaranteed even
+ *      for regular 64-bit load (LDD) / store (STD). Thus atomic64_set()
+ *      is NOT required to use LLOCKD+SCONDD, STD suffices
+ */
+
+typedef struct {
+	aligned_u64 counter;
+} atomic64_t;
+
+#define ATOMIC64_INIT(a) { (a) }
+
+static inline long long atomic64_read(const atomic64_t *v)
+{
+	unsigned long long val;
+
+	__asm__ __volatile__(
+	"	ldd   %0, [%1]	\n"
+	: "=r"(val)
+	: "r"(&v->counter));
+
+	return val;
+}
+
+static inline void atomic64_set(atomic64_t *v, long long a)
+{
+	/*
+	 * This could have been a simple assignment in "C" but would need
+	 * explicit volatile. Otherwise gcc optimizers could elide the store
+	 * which borked atomic64 self-test
+	 * In the inline asm version, memory clobber needed for exact same
+	 * reason, to tell gcc about the store.
+	 *
+	 * This however is not needed for sibling atomic64_add() etc since both
+	 * load/store are explicitly done in inline asm. As long as API is used
+	 * for each access, gcc has no way to optimize away any load/store
+	 */
+	__asm__ __volatile__(
+	"	std   %0, [%1]	\n"
+	:
+	: "r"(a), "r"(&v->counter)
+	: "memory");
+}
+
+#define ATOMIC64_OP(op, op1, op2)					\
+static inline void atomic64_##op(long long a, atomic64_t *v)		\
+{									\
+	unsigned long long val;						\
+									\
+	__asm__ __volatile__(						\
+	"1:				\n"				\
+	"	llockd  %0, [%1]	\n"				\
+	"	" #op1 " %L0, %L0, %L2	\n"				\
+	"	" #op2 " %H0, %H0, %H2	\n"				\
+	"	scondd   %0, [%1]	\n"				\
+	"	bnz     1b		\n"				\
+	: "=&r"(val)							\
+	: "r"(&v->counter), "ir"(a)					\
+	: "cc");						\
+}									\
+
+#define ATOMIC64_OP_RETURN(op, op1, op2)		        	\
+static inline long long atomic64_##op##_return(long long a, atomic64_t *v)	\
+{									\
+	unsigned long long val;						\
+									\
+	smp_mb();							\
+									\
+	__asm__ __volatile__(						\
+	"1:				\n"				\
+	"	llockd   %0, [%1]	\n"				\
+	"	" #op1 " %L0, %L0, %L2	\n"				\
+	"	" #op2 " %H0, %H0, %H2	\n"				\
+	"	scondd   %0, [%1]	\n"				\
+	"	bnz     1b		\n"				\
+	: [val] "=&r"(val)						\
+	: "r"(&v->counter), "ir"(a)					\
+	: "cc");	/* memory clobber comes from smp_mb() */	\
+									\
+	smp_mb();							\
+									\
+	return val;							\
+}
+
+#define ATOMIC64_FETCH_OP(op, op1, op2)		        		\
+static inline long long atomic64_fetch_##op(long long a, atomic64_t *v)	\
+{									\
+	unsigned long long val, orig;					\
+									\
+	smp_mb();							\
+									\
+	__asm__ __volatile__(						\
+	"1:				\n"				\
+	"	llockd   %0, [%2]	\n"				\
+	"	" #op1 " %L1, %L0, %L3	\n"				\
+	"	" #op2 " %H1, %H0, %H3	\n"				\
+	"	scondd   %1, [%2]	\n"				\
+	"	bnz     1b		\n"				\
+	: "=&r"(orig), "=&r"(val)					\
+	: "r"(&v->counter), "ir"(a)					\
+	: "cc");	/* memory clobber comes from smp_mb() */	\
+									\
+	smp_mb();							\
+									\
+	return orig;							\
+}
+
+#define ATOMIC64_OPS(op, op1, op2)					\
+	ATOMIC64_OP(op, op1, op2)					\
+	ATOMIC64_OP_RETURN(op, op1, op2)				\
+	ATOMIC64_FETCH_OP(op, op1, op2)
+
+#define atomic64_andnot atomic64_andnot
+
+ATOMIC64_OPS(add, add.f, adc)
+ATOMIC64_OPS(sub, sub.f, sbc)
+ATOMIC64_OPS(and, and, and)
+ATOMIC64_OPS(andnot, bic, bic)
+ATOMIC64_OPS(or, or, or)
+ATOMIC64_OPS(xor, xor, xor)
+
+#undef ATOMIC64_OPS
+#undef ATOMIC64_FETCH_OP
+#undef ATOMIC64_OP_RETURN
+#undef ATOMIC64_OP
+
+static inline long long
+atomic64_cmpxchg(atomic64_t *ptr, long long expected, long long new)
+{
+	long long prev;
+
+	smp_mb();
+
+	__asm__ __volatile__(
+	"1:	llockd  %0, [%1]	\n"
+	"	brne    %L0, %L2, 2f	\n"
+	"	brne    %H0, %H2, 2f	\n"
+	"	scondd  %3, [%1]	\n"
+	"	bnz     1b		\n"
+	"2:				\n"
+	: "=&r"(prev)
+	: "r"(ptr), "ir"(expected), "r"(new)
+	: "cc");	/* memory clobber comes from smp_mb() */
+
+	smp_mb();
+
+	return prev;
+}
+
+static inline long long atomic64_xchg(atomic64_t *ptr, long long new)
+{
+	long long prev;
+
+	smp_mb();
+
+	__asm__ __volatile__(
+	"1:	llockd  %0, [%1]	\n"
+	"	scondd  %2, [%1]	\n"
+	"	bnz     1b		\n"
+	"2:				\n"
+	: "=&r"(prev)
+	: "r"(ptr), "r"(new)
+	: "cc");	/* memory clobber comes from smp_mb() */
+
+	smp_mb();
+
+	return prev;
+}
+
+/**
+ * atomic64_dec_if_positive - decrement by 1 if old value positive
+ * @v: pointer of type atomic64_t
+ *
+ * The function returns the old value of *v minus 1, even if
+ * the atomic variable, v, was not decremented.
+ */
+
+static inline long long atomic64_dec_if_positive(atomic64_t *v)
+{
+	long long val;
+
+	smp_mb();
+
+	__asm__ __volatile__(
+	"1:	llockd  %0, [%1]	\n"
+	"	sub.f   %L0, %L0, 1	# w0 - 1, set C on borrow\n"
+	"	sub.c   %H0, %H0, 1	# if C set, w1 - 1\n"
+	"	brlt    %H0, 0, 2f	\n"
+	"	scondd  %0, [%1]	\n"
+	"	bnz     1b		\n"
+	"2:				\n"
+	: "=&r"(val)
+	: "r"(&v->counter)
+	: "cc");	/* memory clobber comes from smp_mb() */
+
+	smp_mb();
+
+	return val;
+}
+
+/**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * if (v != u) { v += a; ret = 1} else {ret = 0}
+ * Returns 1 iff @v was not @u (i.e. if add actually happened)
+ */
+static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
+{
+	long long val;
+	int op_done;
+
+	smp_mb();
+
+	__asm__ __volatile__(
+	"1:	llockd  %0, [%2]	\n"
+	"	mov	%1, 1		\n"
+	"	brne	%L0, %L4, 2f	# continue to add since v != u \n"
+	"	breq.d	%H0, %H4, 3f	# return since v == u \n"
+	"	mov	%1, 0		\n"
+	"2:				\n"
+	"	add.f   %L0, %L0, %L3	\n"
+	"	adc     %H0, %H0, %H3	\n"
+	"	scondd  %0, [%2]	\n"
+	"	bnz     1b		\n"
+	"3:				\n"
+	: "=&r"(val), "=&r" (op_done)
+	: "r"(&v->counter), "r"(a), "r"(u)
+	: "cc");	/* memory clobber comes from smp_mb() */
+
+	smp_mb();
+
+	return op_done;
+}
+
+#define atomic64_add_negative(a, v)	(atomic64_add_return((a), (v)) < 0)
+#define atomic64_inc(v)			atomic64_add(1LL, (v))
+#define atomic64_inc_return(v)		atomic64_add_return(1LL, (v))
+#define atomic64_inc_and_test(v)	(atomic64_inc_return(v) == 0)
+#define atomic64_sub_and_test(a, v)	(atomic64_sub_return((a), (v)) == 0)
+#define atomic64_dec(v)			atomic64_sub(1LL, (v))
+#define atomic64_dec_return(v)		atomic64_sub_return(1LL, (v))
+#define atomic64_dec_and_test(v)	(atomic64_dec_return((v)) == 0)
+#define atomic64_inc_not_zero(v)	atomic64_add_unless((v), 1LL, 0LL)
+
+#endif	/* !CONFIG_GENERIC_ATOMIC64 */
+
+#endif	/* !__ASSEMBLY__ */
 
 #endif
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/include/asm/cache.h linux-libre-4.9-rc7-gnu/arch/arc/include/asm/cache.h
--- linux-libre-4.8-gnu/arch/arc/include/asm/cache.h	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/include/asm/cache.h	2016-11-27 16:08:04.000000000 -0500
@@ -53,8 +53,8 @@ extern void arc_cache_init(void);
 extern char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len);
 extern void read_decode_cache_bcr(void);
 
-extern int ioc_exists;
-extern unsigned long perip_base;
+extern int ioc_enable;
+extern unsigned long perip_base, perip_end;
 
 #endif	/* !__ASSEMBLY__ */
 
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/include/asm/dwarf.h linux-libre-4.9-rc7-gnu/arch/arc/include/asm/dwarf.h
--- linux-libre-4.8-gnu/arch/arc/include/asm/dwarf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-4.9-rc7-gnu/arch/arc/include/asm/dwarf.h	2016-11-27 16:08:04.000000000 -0500
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016-17 Synopsys, Inc. (www.synopsys.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _ASM_ARC_DWARF_H
+#define _ASM_ARC_DWARF_H
+
+#ifdef __ASSEMBLY__
+
+#ifdef ARC_DW2_UNWIND_AS_CFI
+
+#define CFI_STARTPROC	.cfi_startproc
+#define CFI_ENDPROC	.cfi_endproc
+#define CFI_DEF_CFA	.cfi_def_cfa
+#define CFI_REGISTER	.cfi_register
+#define CFI_REL_OFFSET	.cfi_rel_offset
+#define CFI_UNDEFINED	.cfi_undefined
+
+#else
+
+#define CFI_IGNORE	#
+
+#define CFI_STARTPROC	CFI_IGNORE
+#define CFI_ENDPROC	CFI_IGNORE
+#define CFI_DEF_CFA	CFI_IGNORE
+#define CFI_REGISTER	CFI_IGNORE
+#define CFI_REL_OFFSET	CFI_IGNORE
+#define CFI_UNDEFINED	CFI_IGNORE
+
+#endif	/* !ARC_DW2_UNWIND_AS_CFI */
+
+#endif	/* __ASSEMBLY__ */
+
+#endif	/* _ASM_ARC_DWARF_H */
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/include/asm/elf.h linux-libre-4.9-rc7-gnu/arch/arc/include/asm/elf.h
--- linux-libre-4.8-gnu/arch/arc/include/asm/elf.h	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/include/asm/elf.h	2016-11-27 16:08:04.000000000 -0500
@@ -23,8 +23,7 @@
 /* ARC Relocations (kernel Modules only) */
 #define  R_ARC_32		0x4
 #define  R_ARC_32_ME		0x1B
-#define  R_ARC_S25H_PCREL	0x10
-#define  R_ARC_S25W_PCREL	0x11
+#define  R_ARC_32_PCREL		0x31
 
 /*to set parameters in the core dumps */
 #define ELF_ARCH		EM_ARCOMPACT
@@ -55,7 +54,7 @@ extern int elf_check_arch(const struct e
  * the loader.  We need to make sure that it is out of the way of the program
  * that it will "exec", and that there is sufficient room for the brk.
  */
-#define ELF_ET_DYN_BASE		(2 * TASK_SIZE / 3)
+#define ELF_ET_DYN_BASE		(2UL * TASK_SIZE / 3)
 
 /*
  * When the program starts, a1 contains a pointer to a function to be
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/include/asm/irqflags-arcv2.h linux-libre-4.9-rc7-gnu/arch/arc/include/asm/irqflags-arcv2.h
--- linux-libre-4.8-gnu/arch/arc/include/asm/irqflags-arcv2.h	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/include/asm/irqflags-arcv2.h	2016-11-27 16:08:04.000000000 -0500
@@ -112,7 +112,7 @@ static inline long arch_local_save_flags
 	 */
 	temp = (1 << 5) |
 		((!!(temp & STATUS_IE_MASK)) << CLRI_STATUS_IE_BIT) |
-		(temp & CLRI_STATUS_E_MASK);
+		((temp >> 1) & CLRI_STATUS_E_MASK);
 	return temp;
 }
 
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/include/asm/Kbuild linux-libre-4.9-rc7-gnu/arch/arc/include/asm/Kbuild
--- linux-libre-4.8-gnu/arch/arc/include/asm/Kbuild	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/include/asm/Kbuild	2016-11-27 16:08:04.000000000 -0500
@@ -25,6 +25,7 @@ generic-y += mcs_spinlock.h
 generic-y += mm-arch-hooks.h
 generic-y += mman.h
 generic-y += msgbuf.h
+generic-y += msi.h
 generic-y += param.h
 generic-y += parport.h
 generic-y += pci.h
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/include/asm/linkage.h linux-libre-4.9-rc7-gnu/arch/arc/include/asm/linkage.h
--- linux-libre-4.8-gnu/arch/arc/include/asm/linkage.h	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/include/asm/linkage.h	2016-11-27 16:08:04.000000000 -0500
@@ -9,6 +9,8 @@
 #ifndef __ASM_LINKAGE_H
 #define __ASM_LINKAGE_H
 
+#include <asm/dwarf.h>
+
 #ifdef __ASSEMBLY__
 
 #define ASM_NL		 `	/* use '`' to mark new line in macro */
@@ -32,6 +34,16 @@
 #endif
 .endm
 
+#define ENTRY_CFI(name)		\
+	.globl name ASM_NL	\
+	ALIGN ASM_NL 		\
+	name: ASM_NL		\
+	CFI_STARTPROC ASM_NL
+
+#define END_CFI(name) 		\
+	CFI_ENDPROC ASM_NL	\
+	.size name, .-name
+
 #else	/* !__ASSEMBLY__ */
 
 #ifdef CONFIG_ARC_HAS_ICCM
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/include/asm/mcip.h linux-libre-4.9-rc7-gnu/arch/arc/include/asm/mcip.h
--- linux-libre-4.8-gnu/arch/arc/include/asm/mcip.h	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/include/asm/mcip.h	2016-11-27 16:08:04.000000000 -0500
@@ -55,6 +55,22 @@ struct mcip_cmd {
 #define IDU_M_DISTRI_DEST		0x2
 };
 
+struct mcip_bcr {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+		unsigned int pad3:8,
+			     idu:1, llm:1, num_cores:6,
+			     iocoh:1,  gfrc:1, dbg:1, pad2:1,
+			     msg:1, sem:1, ipi:1, pad:1,
+			     ver:8;
+#else
+		unsigned int ver:8,
+			     pad:1, ipi:1, sem:1, msg:1,
+			     pad2:1, dbg:1, gfrc:1, iocoh:1,
+			     num_cores:6, llm:1, idu:1,
+			     pad3:8;
+#endif
+};
+
 /*
  * MCIP programming model
  *
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/include/asm/module.h linux-libre-4.9-rc7-gnu/arch/arc/include/asm/module.h
--- linux-libre-4.8-gnu/arch/arc/include/asm/module.h	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/include/asm/module.h	2016-11-27 16:08:04.000000000 -0500
@@ -18,6 +18,7 @@
 struct mod_arch_specific {
 	void *unw_info;
 	int unw_sec_idx;
+	const char *secstr;
 };
 #endif
 
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/include/asm/perf_event.h linux-libre-4.9-rc7-gnu/arch/arc/include/asm/perf_event.h
--- linux-libre-4.8-gnu/arch/arc/include/asm/perf_event.h	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/include/asm/perf_event.h	2016-11-27 16:08:04.000000000 -0500
@@ -118,6 +118,9 @@ static const char * const arc_pmu_ev_hw_
 	[PERF_COUNT_ARC_ICM] = "icm",		/* I-cache Miss */
 	[PERF_COUNT_ARC_EDTLB] = "edtlb",	/* D-TLB Miss */
 	[PERF_COUNT_ARC_EITLB] = "eitlb",	/* I-TLB Miss */
+
+	[PERF_COUNT_HW_CACHE_REFERENCES] = "imemrdc",	/* Instr: mem read cached */
+	[PERF_COUNT_HW_CACHE_MISSES] = "dclm",		/* D-cache Load Miss */
 };
 
 #define C(_x)			PERF_COUNT_HW_CACHE_##_x
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/include/asm/setup.h linux-libre-4.9-rc7-gnu/arch/arc/include/asm/setup.h
--- linux-libre-4.8-gnu/arch/arc/include/asm/setup.h	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/include/asm/setup.h	2016-11-27 16:08:04.000000000 -0500
@@ -27,11 +27,6 @@ struct id_to_str {
 	const char *str;
 };
 
-struct cpuinfo_data {
-	struct id_to_str info;
-	int up_range;
-};
-
 extern int root_mountflags, end_mem;
 
 void setup_processor(void);
@@ -43,5 +38,6 @@ void __init setup_arch_memory(void);
 #define IS_USED_RUN(v)		((v) ? "" : "(not used) ")
 #define IS_USED_CFG(cfg)	IS_USED_RUN(IS_ENABLED(cfg))
 #define IS_AVAIL2(v, s, cfg)	IS_AVAIL1(v, s), IS_AVAIL1(v, IS_USED_CFG(cfg))
+#define IS_AVAIL3(v, v2, s)	IS_AVAIL1(v, s), IS_AVAIL1(v, IS_DISABLED_RUN(v2))
 
 #endif /* __ASMARC_SETUP_H */
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/include/asm/smp.h linux-libre-4.9-rc7-gnu/arch/arc/include/asm/smp.h
--- linux-libre-4.8-gnu/arch/arc/include/asm/smp.h	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/include/asm/smp.h	2016-11-27 16:08:04.000000000 -0500
@@ -37,9 +37,9 @@ extern const char *arc_platform_smp_cpui
  * API expected BY platform smp code (FROM arch smp code)
  *
  * smp_ipi_irq_setup:
- *	Takes @cpu and @irq to which the arch-common ISR is hooked up
+ *	Takes @cpu and @hwirq to which the arch-common ISR is hooked up
  */
-extern int smp_ipi_irq_setup(int cpu, int irq);
+extern int smp_ipi_irq_setup(int cpu, irq_hw_number_t hwirq);
 
 /*
  * struct plat_smp_ops	- SMP callbacks provided by platform to ARC SMP
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/include/asm/syscalls.h linux-libre-4.9-rc7-gnu/arch/arc/include/asm/syscalls.h
--- linux-libre-4.8-gnu/arch/arc/include/asm/syscalls.h	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/include/asm/syscalls.h	2016-11-27 16:08:04.000000000 -0500
@@ -17,6 +17,7 @@ int sys_clone_wrapper(int, int, int, int
 int sys_cacheflush(uint32_t, uint32_t uint32_t);
 int sys_arc_settls(void *);
 int sys_arc_gettls(void);
+int sys_arc_usr_cmpxchg(int *, int, int);
 
 #include <asm-generic/syscalls.h>
 
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/include/uapi/asm/unistd.h linux-libre-4.9-rc7-gnu/arch/arc/include/uapi/asm/unistd.h
--- linux-libre-4.8-gnu/arch/arc/include/uapi/asm/unistd.h	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/include/uapi/asm/unistd.h	2016-11-27 16:08:04.000000000 -0500
@@ -27,18 +27,19 @@
 
 #define NR_syscalls	__NR_syscalls
 
+/* Generic syscall (fs/filesystems.c - lost in asm-generic/unistd.h */
+#define __NR_sysfs		(__NR_arch_specific_syscall + 3)
+
 /* ARC specific syscall */
 #define __NR_cacheflush		(__NR_arch_specific_syscall + 0)
 #define __NR_arc_settls		(__NR_arch_specific_syscall + 1)
 #define __NR_arc_gettls		(__NR_arch_specific_syscall + 2)
+#define __NR_arc_usr_cmpxchg	(__NR_arch_specific_syscall + 4)
 
 __SYSCALL(__NR_cacheflush, sys_cacheflush)
 __SYSCALL(__NR_arc_settls, sys_arc_settls)
 __SYSCALL(__NR_arc_gettls, sys_arc_gettls)
-
-
-/* Generic syscall (fs/filesystems.c - lost in asm-generic/unistd.h */
-#define __NR_sysfs		(__NR_arch_specific_syscall + 3)
+__SYSCALL(__NR_arc_usr_cmpxchg, sys_arc_usr_cmpxchg)
 __SYSCALL(__NR_sysfs, sys_sysfs)
 
 #undef __SYSCALL
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/Kconfig linux-libre-4.9-rc7-gnu/arch/arc/Kconfig
--- linux-libre-4.8-gnu/arch/arc/Kconfig	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/Kconfig	2016-11-27 16:08:04.000000000 -0500
@@ -13,7 +13,7 @@ config ARC
 	select CLKSRC_OF
 	select CLONE_BACKWARDS
 	select COMMON_CLK
-	select GENERIC_ATOMIC64
+	select GENERIC_ATOMIC64 if !ISA_ARCV2 || !(ARC_HAS_LL64 && ARC_HAS_LLSC)
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_FIND_FIRST_BIT
 	# for now, we don't need GENERIC_IRQ_PROBE, CONFIG_GENERIC_IRQ_CHIP
@@ -41,6 +41,8 @@ config ARC
 	select PERF_USE_VMALLOC
 	select HAVE_DEBUG_STACKOVERFLOW
 	select HAVE_GENERIC_DMA_COHERENT
+	select HAVE_KERNEL_GZIP
+	select HAVE_KERNEL_LZMA
 
 config MIGHT_HAVE_PCI
 	bool
@@ -186,14 +188,6 @@ if SMP
 config ARC_HAS_COH_CACHES
 	def_bool n
 
-config ARC_MCIP
-	bool "ARConnect Multicore IP (MCIP) Support "
-	depends on ISA_ARCV2
-	help
-	  This IP block enables SMP in ARC-HS38 cores.
-	  It provides for cross-core interrupts, multi-core debug
-	  hardware semaphores, shared memory,....
-
 config NR_CPUS
 	int "Maximum number of CPUs (2-4096)"
 	range 2 4096
@@ -211,6 +205,15 @@ config ARC_SMP_HALT_ON_RESET
 
 endif	#SMP
 
+config ARC_MCIP
+	bool "ARConnect Multicore IP (MCIP) Support "
+	depends on ISA_ARCV2
+	default y if SMP
+	help
+	  This IP block enables SMP in ARC-HS38 cores.
+	  It provides for cross-core interrupts, multi-core debug
+	  hardware semaphores, shared memory,....
+
 menuconfig ARC_CACHE
 	bool "Enable Cache Support"
 	default y
@@ -353,8 +356,8 @@ endchoice
 
 config NODES_SHIFT
 	int "Maximum NUMA Nodes (as a power of 2)"
-	default "1" if !DISCONTIGMEM
-	default "2" if DISCONTIGMEM
+	default "0" if !DISCONTIGMEM
+	default "1" if DISCONTIGMEM
 	depends on NEED_MULTIPLE_NODES
 	---help---
 	  Accessing memory beyond 1GB (with or w/o PAE) requires 2 memory
@@ -537,14 +540,6 @@ config ARC_DBG_TLB_PARANOIA
 	bool "Paranoia Checks in Low Level TLB Handlers"
 	default n
 
-config ARC_DBG_TLB_MISS_COUNT
-	bool "Profile TLB Misses"
-	default n
-	select DEBUG_FS
-	help
-	  Counts number of I and D TLB Misses and exports them via Debugfs
-	  The counters can be cleared via Debugfs as well
-
 endif
 
 config ARC_UBOOT_SUPPORT
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/kernel/ctx_sw_asm.S linux-libre-4.9-rc7-gnu/arch/arc/kernel/ctx_sw_asm.S
--- linux-libre-4.8-gnu/arch/arc/kernel/ctx_sw_asm.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/kernel/ctx_sw_asm.S	2016-11-27 16:08:04.000000000 -0500
@@ -23,6 +23,7 @@
 	.global __switch_to
 	.type   __switch_to, @function
 __switch_to:
+	CFI_STARTPROC
 
 	/* Save regs on kernel mode stack of task */
 	st.a    blink, [sp, -4]
@@ -59,4 +60,4 @@ __switch_to:
 	ld.ab   blink, [sp, 4]
 	j       [blink]
 
-END(__switch_to)
+END_CFI(__switch_to)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/kernel/devtree.c linux-libre-4.9-rc7-gnu/arch/arc/kernel/devtree.c
--- linux-libre-4.8-gnu/arch/arc/kernel/devtree.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/kernel/devtree.c	2016-11-27 16:08:04.000000000 -0500
@@ -31,6 +31,8 @@ static void __init arc_set_early_base_ba
 		arc_base_baud = 166666666;	/* Fixed 166.6MHz clk (TB10x) */
 	else if (of_flat_dt_is_compatible(dt_root, "snps,arc-sdp"))
 		arc_base_baud = 33333333;	/* Fixed 33MHz clk (AXS10x) */
+	else if (of_flat_dt_is_compatible(dt_root, "ezchip,arc-nps"))
+		arc_base_baud = 800000000;      /* Fixed 800MHz clk (NPS) */
 	else
 		arc_base_baud = 50000000;	/* Fixed default 50MHz */
 }
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/kernel/entry.S linux-libre-4.9-rc7-gnu/arch/arc/kernel/entry.S
--- linux-libre-4.8-gnu/arch/arc/kernel/entry.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/kernel/entry.S	2016-11-27 16:08:04.000000000 -0500
@@ -35,7 +35,7 @@ ENTRY(sys_clone_wrapper)
 	btst r10, TIF_SYSCALL_TRACE
 	bnz  tracesys_exit
 
-	b ret_from_system_call
+	b .Lret_from_system_call
 END(sys_clone_wrapper)
 
 ENTRY(ret_from_fork)
@@ -61,18 +61,6 @@ ENTRY(ret_from_fork)
 	b    ret_from_exception
 END(ret_from_fork)
 
-#ifdef CONFIG_ARC_DW2_UNWIND
-; Workaround for bug 94179 (STAR ):
-; Despite -fasynchronous-unwind-tables, linker is not making dwarf2 unwinder
-; section (.debug_frame) as loadable. So we force it here.
-; This also fixes STAR 9000487933 where the prev-workaround (objcopy --setflag)
-; would not work after a clean build due to kernel build system dependencies.
-.section .debug_frame, "wa",@progbits
-
-; Reset to .text as this file is included in entry-<isa>.S
-.section .text, "ax",@progbits
-#endif
-
 ;################### Non TLB Exception Handling #############################
 
 ; ---------------------------------------------
@@ -260,20 +248,18 @@ ENTRY(EV_Trap)
 	; syscall num shd not exceed the total system calls avail
 	cmp     r8,  NR_syscalls
 	mov.hi  r0, -ENOSYS
-	bhi     ret_from_system_call
+	bhi     .Lret_from_system_call
 
 	; Offset into the syscall_table and call handler
 	ld.as   r9,[sys_call_table, r8]
 	jl      [r9]        ; Entry into Sys Call Handler
 
-	; fall through to ret_from_system_call
-END(EV_Trap)
-
-ENTRY(ret_from_system_call)
+.Lret_from_system_call:
 
 	st  r0, [sp, PT_r0]     ; sys call return value in pt_regs
 
-	; fall through yet again to ret_from_exception
+	; fall through to ret_from_exception
+END(EV_Trap)
 
 ;############# Return from Intr/Excp/Trap (Linux Specifics) ##############
 ;
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/kernel/intc-arcv2.c linux-libre-4.9-rc7-gnu/arch/arc/kernel/intc-arcv2.c
--- linux-libre-4.8-gnu/arch/arc/kernel/intc-arcv2.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/kernel/intc-arcv2.c	2016-11-27 16:08:04.000000000 -0500
@@ -74,7 +74,7 @@ void arc_init_IRQ(void)
 	tmp = read_aux_reg(0xa);
 	tmp |= STATUS_AD_MASK | (irq_prio << 1);
 	tmp &= ~STATUS_IE_MASK;
-	asm volatile("flag %0	\n"::"r"(tmp));
+	asm volatile("kflag %0	\n"::"r"(tmp));
 }
 
 static void arcv2_irq_mask(struct irq_data *data)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/kernel/mcip.c linux-libre-4.9-rc7-gnu/arch/arc/kernel/mcip.c
--- linux-libre-4.8-gnu/arch/arc/kernel/mcip.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/kernel/mcip.c	2016-11-27 16:08:04.000000000 -0500
@@ -15,11 +15,12 @@
 #include <asm/mcip.h>
 #include <asm/setup.h>
 
-static char smp_cpuinfo_buf[128];
-static int idu_detected;
-
 static DEFINE_RAW_SPINLOCK(mcip_lock);
 
+#ifdef CONFIG_SMP
+
+static char smp_cpuinfo_buf[128];
+
 static void mcip_setup_per_cpu(int cpu)
 {
 	smp_ipi_irq_setup(cpu, IPI_IRQ);
@@ -86,21 +87,7 @@ static void mcip_ipi_clear(int irq)
 
 static void mcip_probe_n_setup(void)
 {
-	struct mcip_bcr {
-#ifdef CONFIG_CPU_BIG_ENDIAN
-		unsigned int pad3:8,
-			     idu:1, llm:1, num_cores:6,
-			     iocoh:1,  gfrc:1, dbg:1, pad2:1,
-			     msg:1, sem:1, ipi:1, pad:1,
-			     ver:8;
-#else
-		unsigned int ver:8,
-			     pad:1, ipi:1, sem:1, msg:1,
-			     pad2:1, dbg:1, gfrc:1, iocoh:1,
-			     num_cores:6, llm:1, idu:1,
-			     pad3:8;
-#endif
-	} mp;
+	struct mcip_bcr mp;
 
 	READ_BCR(ARC_REG_MCIP_BCR, mp);
 
@@ -114,7 +101,6 @@ static void mcip_probe_n_setup(void)
 		IS_AVAIL1(mp.gfrc, "GFRC"));
 
 	cpuinfo_arc700[0].extn.gfrc = mp.gfrc;
-	idu_detected = mp.idu;
 
 	if (mp.dbg) {
 		__mcip_cmd_data(CMD_DEBUG_SET_SELECT, 0, 0xf);
@@ -130,6 +116,8 @@ struct plat_smp_ops plat_smp_ops = {
 	.ipi_clear	= mcip_ipi_clear,
 };
 
+#endif
+
 /***************************************************************************
  * ARCv2 Interrupt Distribution Unit (IDU)
  *
@@ -193,6 +181,8 @@ idu_irq_set_affinity(struct irq_data *da
 {
 	unsigned long flags;
 	cpumask_t online;
+	unsigned int destination_bits;
+	unsigned int distribution_mode;
 
 	/* errout if no online cpu per @cpumask */
 	if (!cpumask_and(&online, cpumask, cpu_online_mask))
@@ -200,8 +190,15 @@ idu_irq_set_affinity(struct irq_data *da
 
 	raw_spin_lock_irqsave(&mcip_lock, flags);
 
-	idu_set_dest(data->hwirq, cpumask_bits(&online)[0]);
-	idu_set_mode(data->hwirq, IDU_M_TRIG_LEVEL, IDU_M_DISTRI_RR);
+	destination_bits = cpumask_bits(&online)[0];
+	idu_set_dest(data->hwirq, destination_bits);
+
+	if (ffs(destination_bits) == fls(destination_bits))
+		distribution_mode = IDU_M_DISTRI_DEST;
+	else
+		distribution_mode = IDU_M_DISTRI_RR;
+
+	idu_set_mode(data->hwirq, IDU_M_TRIG_LEVEL, distribution_mode);
 
 	raw_spin_unlock_irqrestore(&mcip_lock, flags);
 
@@ -219,16 +216,15 @@ static struct irq_chip idu_irq_chip = {
 
 };
 
-static int idu_first_irq;
+static irq_hw_number_t idu_first_hwirq;
 
 static void idu_cascade_isr(struct irq_desc *desc)
 {
-	struct irq_domain *domain = irq_desc_get_handler_data(desc);
-	unsigned int core_irq = irq_desc_get_irq(desc);
-	unsigned int idu_irq;
+	struct irq_domain *idu_domain = irq_desc_get_handler_data(desc);
+	irq_hw_number_t core_hwirq = irqd_to_hwirq(irq_desc_get_irq_data(desc));
+	irq_hw_number_t idu_hwirq = core_hwirq - idu_first_hwirq;
 
-	idu_irq = core_irq - idu_first_irq;
-	generic_handle_irq(irq_find_mapping(domain, idu_irq));
+	generic_handle_irq(irq_find_mapping(idu_domain, idu_hwirq));
 }
 
 static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hwirq)
@@ -294,9 +290,12 @@ idu_of_init(struct device_node *intc, st
 	struct irq_domain *domain;
 	/* Read IDU BCR to confirm nr_irqs */
 	int nr_irqs = of_irq_count(intc);
-	int i, irq;
+	int i, virq;
+	struct mcip_bcr mp;
 
-	if (!idu_detected)
+	READ_BCR(ARC_REG_MCIP_BCR, mp);
+
+	if (!mp.idu)
 		panic("IDU not detected, but DeviceTree using it");
 
 	pr_info("MCIP: IDU referenced from Devicetree %d irqs\n", nr_irqs);
@@ -312,11 +311,11 @@ idu_of_init(struct device_node *intc, st
 		 * however we need it to get the parent virq and set IDU handler
 		 * as first level isr
 		 */
-		irq = irq_of_parse_and_map(intc, i);
+		virq = irq_of_parse_and_map(intc, i);
 		if (!i)
-			idu_first_irq = irq;
+			idu_first_hwirq = irqd_to_hwirq(irq_get_irq_data(virq));
 
-		irq_set_chained_handler_and_data(irq, idu_cascade_isr, domain);
+		irq_set_chained_handler_and_data(virq, idu_cascade_isr, domain);
 	}
 
 	__mcip_cmd(CMD_IDU_ENABLE, 0);
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/kernel/module.c linux-libre-4.9-rc7-gnu/arch/arc/kernel/module.c
--- linux-libre-4.8-gnu/arch/arc/kernel/module.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/kernel/module.c	2016-11-27 16:08:04.000000000 -0500
@@ -22,30 +22,17 @@ static inline void arc_write_me(unsigned
 	*(addr + 1) = (value & 0xffff);
 }
 
-/* ARC specific section quirks - before relocation loop in generic loader
- *
- * For dwarf unwinding out of modules, this needs to
- * 1. Ensure the .debug_frame is allocatable (ARC Linker bug: despite
- *    -fasynchronous-unwind-tables it doesn't).
- * 2. Since we are iterating thru sec hdr tbl anyways, make a note of
- *    the exact section index, for later use.
+/*
+ * This gets called before relocation loop in generic loader
+ * Make a note of the section index of unwinding section
  */
 int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
 			      char *secstr, struct module *mod)
 {
 #ifdef CONFIG_ARC_DW2_UNWIND
-	int i;
-
 	mod->arch.unw_sec_idx = 0;
 	mod->arch.unw_info = NULL;
-
-	for (i = 1; i < hdr->e_shnum; i++) {
-		if (strcmp(secstr+sechdrs[i].sh_name, ".debug_frame") == 0) {
-			sechdrs[i].sh_flags |= SHF_ALLOC;
-			mod->arch.unw_sec_idx = i;
-			break;
-		}
-	}
+	mod->arch.secstr = secstr;
 #endif
 	return 0;
 }
@@ -64,29 +51,33 @@ int apply_relocate_add(Elf32_Shdr *sechd
 		       unsigned int relsec,	/* sec index for relo sec */
 		       struct module *module)
 {
-	int i, n;
+	int i, n, relo_type;
 	Elf32_Rela *rel_entry = (void *)sechdrs[relsec].sh_addr;
 	Elf32_Sym *sym_entry, *sym_sec;
-	Elf32_Addr relocation;
-	Elf32_Addr location;
-	Elf32_Addr sec_to_patch;
-	int relo_type;
+	Elf32_Addr relocation, location, tgt_addr;
+	unsigned int tgtsec;
 
-	sec_to_patch = sechdrs[sechdrs[relsec].sh_info].sh_addr;
+	/*
+	 * @relsec has relocations e.g. .rela.init.text
+	 * @tgtsec is section to patch e.g. .init.text
+	 */
+	tgtsec = sechdrs[relsec].sh_info;
+	tgt_addr = sechdrs[tgtsec].sh_addr;
 	sym_sec = (Elf32_Sym *) sechdrs[symindex].sh_addr;
 	n = sechdrs[relsec].sh_size / sizeof(*rel_entry);
 
-	pr_debug("\n========== Module Sym reloc ===========================\n");
-	pr_debug("Section to fixup %x\n", sec_to_patch);
+	pr_debug("\nSection to fixup %s @%x\n",
+		 module->arch.secstr + sechdrs[tgtsec].sh_name, tgt_addr);
 	pr_debug("=========================================================\n");
-	pr_debug("rela->r_off | rela->addend | sym->st_value | ADDR | VALUE\n");
+	pr_debug("r_off\tr_add\tst_value ADDRESS  VALUE\n");
 	pr_debug("=========================================================\n");
 
 	/* Loop thru entries in relocation section */
 	for (i = 0; i < n; i++) {
+		const char *s;
 
 		/* This is where to make the change */
-		location = sec_to_patch + rel_entry[i].r_offset;
+		location = tgt_addr + rel_entry[i].r_offset;
 
 		/* This is the symbol it is referring to.  Note that all
 		   undefined symbols have been resolved.  */
@@ -94,10 +85,15 @@ int apply_relocate_add(Elf32_Shdr *sechd
 
 		relocation = sym_entry->st_value + rel_entry[i].r_addend;
 
-		pr_debug("\t%x\t\t%x\t\t%x  %x %x [%s]\n",
-			rel_entry[i].r_offset, rel_entry[i].r_addend,
-			sym_entry->st_value, location, relocation,
-			strtab + sym_entry->st_name);
+		if (sym_entry->st_name == 0 && ELF_ST_TYPE (sym_entry->st_info) == STT_SECTION) {
+			s = module->arch.secstr + sechdrs[sym_entry->st_shndx].sh_name;
+		} else {
+			s = strtab + sym_entry->st_name;
+		}
+
+		pr_debug("   %x\t%x\t%x %x %x [%s]\n",
+			 rel_entry[i].r_offset, rel_entry[i].r_addend,
+			 sym_entry->st_value, location, relocation, s);
 
 		/* This assumes modules are built with -mlong-calls
 		 * so any branches/jumps are absolute 32 bit jmps
@@ -106,14 +102,20 @@ int apply_relocate_add(Elf32_Shdr *sechd
 		 */
 		relo_type = ELF32_R_TYPE(rel_entry[i].r_info);
 
-		if (likely(R_ARC_32_ME == relo_type))
+		if (likely(R_ARC_32_ME == relo_type))	/* ME ( S + A ) */
 			arc_write_me((unsigned short *)location, relocation);
-		else if (R_ARC_32 == relo_type)
+		else if (R_ARC_32 == relo_type)		/* ( S + A ) */
 			*((Elf32_Addr *) location) = relocation;
+		else if (R_ARC_32_PCREL == relo_type)	/* ( S + A ) - PDATA ) */
+			*((Elf32_Addr *) location) = relocation - location;
 		else
 			goto relo_err;
 
 	}
+
+	if (strcmp(module->arch.secstr+sechdrs[tgtsec].sh_name, ".eh_frame") == 0)
+		module->arch.unw_sec_idx = tgtsec;
+
 	return 0;
 
 relo_err:
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/kernel/perf_event.c linux-libre-4.9-rc7-gnu/arch/arc/kernel/perf_event.c
--- linux-libre-4.8-gnu/arch/arc/kernel/perf_event.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/kernel/perf_event.c	2016-11-27 16:08:04.000000000 -0500
@@ -179,8 +179,8 @@ static int arc_pmu_event_init(struct per
 		if (arc_pmu->ev_hw_idx[event->attr.config] < 0)
 			return -ENOENT;
 		hwc->config |= arc_pmu->ev_hw_idx[event->attr.config];
-		pr_debug("init event %d with h/w %d \'%s\'\n",
-			 (int) event->attr.config, (int) hwc->config,
+		pr_debug("init event %d with h/w %08x \'%s\'\n",
+			 (int)event->attr.config, (int)hwc->config,
 			 arc_pmu_ev_hw_map[event->attr.config]);
 		return 0;
 
@@ -189,6 +189,8 @@ static int arc_pmu_event_init(struct per
 		if (ret < 0)
 			return ret;
 		hwc->config |= arc_pmu->ev_hw_idx[ret];
+		pr_debug("init cache event with h/w %08x \'%s\'\n",
+			 (int)hwc->config, arc_pmu_ev_hw_map[ret]);
 		return 0;
 	default:
 		return -ENOENT;
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/kernel/process.c linux-libre-4.9-rc7-gnu/arch/arc/kernel/process.c
--- linux-libre-4.8-gnu/arch/arc/kernel/process.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/kernel/process.c	2016-11-27 16:08:04.000000000 -0500
@@ -41,6 +41,41 @@ SYSCALL_DEFINE0(arc_gettls)
 	return task_thread_info(current)->thr_ptr;
 }
 
+SYSCALL_DEFINE3(arc_usr_cmpxchg, int *, uaddr, int, expected, int, new)
+{
+	struct pt_regs *regs = current_pt_regs();
+	int uval = -EFAULT;
+
+	/*
+	 * This is only for old cores lacking LLOCK/SCOND, which by defintion
+	 * can't possibly be SMP. Thus doesn't need to be SMP safe.
+	 * And this also helps reduce the overhead for serializing in
+	 * the UP case
+	 */
+	WARN_ON_ONCE(IS_ENABLED(CONFIG_SMP));
+
+	/* Z indicates to userspace if operation succeded */
+	regs->status32 &= ~STATUS_Z_MASK;
+
+	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
+		return -EFAULT;
+
+	preempt_disable();
+
+	if (__get_user(uval, uaddr))
+		goto done;
+
+	if (uval == expected) {
+		if (!__put_user(new, uaddr))
+			regs->status32 |= STATUS_Z_MASK;
+	}
+
+done:
+	preempt_enable();
+
+	return uval;
+}
+
 void arch_cpu_idle(void)
 {
 	/* sleep, but enable all interrupts before committing */
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/kernel/setup.c linux-libre-4.9-rc7-gnu/arch/arc/kernel/setup.c
--- linux-libre-4.8-gnu/arch/arc/kernel/setup.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/kernel/setup.c	2016-11-27 16:08:04.000000000 -0500
@@ -40,6 +40,29 @@ struct task_struct *_current_task[NR_CPU
 
 struct cpuinfo_arc cpuinfo_arc700[NR_CPUS];
 
+static const struct id_to_str arc_cpu_rel[] = {
+#ifdef CONFIG_ISA_ARCOMPACT
+	{ 0x34, "R4.10"},
+	{ 0x35, "R4.11"},
+#else
+	{ 0x51, "R2.0" },
+	{ 0x52, "R2.1" },
+	{ 0x53, "R3.0" },
+#endif
+	{ 0x00, NULL   }
+};
+
+static const struct id_to_str arc_cpu_nm[] = {
+#ifdef CONFIG_ISA_ARCOMPACT
+	{ 0x20, "ARC 600"   },
+	{ 0x30, "ARC 770"   },  /* 750 identified seperately */
+#else
+	{ 0x40, "ARC EM"  },
+	{ 0x50, "ARC HS38"  },
+#endif
+	{ 0x00, "Unknown"   }
+};
+
 static void read_decode_ccm_bcr(struct cpuinfo_arc *cpu)
 {
 	if (is_isa_arcompact()) {
@@ -92,11 +115,26 @@ static void read_arc_build_cfg_regs(void
 	struct bcr_timer timer;
 	struct bcr_generic bcr;
 	struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
+	const struct id_to_str *tbl;
+
 	FIX_PTR(cpu);
 
 	READ_BCR(AUX_IDENTITY, cpu->core);
 	READ_BCR(ARC_REG_ISA_CFG_BCR, cpu->isa);
 
+	for (tbl = &arc_cpu_rel[0]; tbl->id != 0; tbl++) {
+		if (cpu->core.family == tbl->id) {
+			cpu->details = tbl->str;
+			break;
+		}
+	}
+
+	for (tbl = &arc_cpu_nm[0]; tbl->id != 0; tbl++) {
+		if ((cpu->core.family & 0xF0) == tbl->id)
+			break;
+	}
+	cpu->name = tbl->str;
+
 	READ_BCR(ARC_REG_TIMERS_BCR, timer);
 	cpu->extn.timer0 = timer.t0;
 	cpu->extn.timer1 = timer.t1;
@@ -111,6 +149,9 @@ static void read_arc_build_cfg_regs(void
 	cpu->extn.swap = read_aux_reg(ARC_REG_SWAP_BCR) ? 1 : 0;        /* 1,3 */
 	cpu->extn.crc = read_aux_reg(ARC_REG_CRC_BCR) ? 1 : 0;
 	cpu->extn.minmax = read_aux_reg(ARC_REG_MIXMAX_BCR) > 1 ? 1 : 0; /* 2 */
+	cpu->extn.swape = (cpu->core.family >= 0x34) ? 1 :
+				IS_ENABLED(CONFIG_ARC_HAS_SWAPE);
+
 	READ_BCR(ARC_REG_XY_MEM_BCR, cpu->extn_xymem);
 
 	/* Read CCM BCRs for boot reporting even if not enabled in Kconfig */
@@ -160,63 +201,38 @@ static void read_arc_build_cfg_regs(void
 	cpu->extn.rtt = bcr.ver ? 1 : 0;
 
 	cpu->extn.debug = cpu->extn.ap | cpu->extn.smart | cpu->extn.rtt;
-}
 
-static const struct cpuinfo_data arc_cpu_tbl[] = {
-#ifdef CONFIG_ISA_ARCOMPACT
-	{ {0x20, "ARC 600"      }, 0x2F},
-	{ {0x30, "ARC 700"      }, 0x33},
-	{ {0x34, "ARC 700 R4.10"}, 0x34},
-	{ {0x35, "ARC 700 R4.11"}, 0x35},
-#else
-	{ {0x50, "ARC HS38 R2.0"}, 0x51},
-	{ {0x52, "ARC HS38 R2.1"}, 0x52},
-#endif
-	{ {0x00, NULL		} }
-};
+	/* some hacks for lack of feature BCR info in old ARC700 cores */
+	if (is_isa_arcompact()) {
+		if (!cpu->isa.ver)	/* ISA BCR absent, use Kconfig info */
+			cpu->isa.atomic = IS_ENABLED(CONFIG_ARC_HAS_LLSC);
+		else
+			cpu->isa.atomic = cpu->isa.atomic1;
 
+		cpu->isa.be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN);
+
+		 /* there's no direct way to distinguish 750 vs. 770 */
+		if (unlikely(cpu->core.family < 0x34 || cpu->mmu.ver < 3))
+			cpu->name = "ARC750";
+	}
+}
 
 static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
 {
 	struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id];
 	struct bcr_identity *core = &cpu->core;
-	const struct cpuinfo_data *tbl;
-	char *isa_nm;
-	int i, be, atomic;
-	int n = 0;
+	int i, n = 0;
 
 	FIX_PTR(cpu);
 
-	if (is_isa_arcompact()) {
-		isa_nm = "ARCompact";
-		be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN);
-
-		atomic = cpu->isa.atomic1;
-		if (!cpu->isa.ver)	/* ISA BCR absent, use Kconfig info */
-			atomic = IS_ENABLED(CONFIG_ARC_HAS_LLSC);
-	} else {
-		isa_nm = "ARCv2";
-		be = cpu->isa.be;
-		atomic = cpu->isa.atomic;
-	}
-
 	n += scnprintf(buf + n, len - n,
 		       "\nIDENTITY\t: ARCVER [%#02x] ARCNUM [%#02x] CHIPID [%#4x]\n",
 		       core->family, core->cpu_id, core->chip_id);
 
-	for (tbl = &arc_cpu_tbl[0]; tbl->info.id != 0; tbl++) {
-		if ((core->family >= tbl->info.id) &&
-		    (core->family <= tbl->up_range)) {
-			n += scnprintf(buf + n, len - n,
-				       "processor [%d]\t: %s (%s ISA) %s\n",
-				       cpu_id, tbl->info.str, isa_nm,
-				       IS_AVAIL1(be, "[Big-Endian]"));
-			break;
-		}
-	}
-
-	if (tbl->info.id == 0)
-		n += scnprintf(buf + n, len - n, "UNKNOWN ARC Processor\n");
+	n += scnprintf(buf + n, len - n, "processor [%d]\t: %s %s (%s ISA) %s\n",
+		       cpu_id, cpu->name, cpu->details,
+		       is_isa_arcompact() ? "ARCompact" : "ARCv2",
+		       IS_AVAIL1(cpu->isa.be, "[Big-Endian]"));
 
 	n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ",
 		       IS_AVAIL1(cpu->extn.timer0, "Timer0 "),
@@ -225,7 +241,7 @@ static char *arc_cpu_mumbojumbo(int cpu_
 				 CONFIG_ARC_HAS_RTC));
 
 	n += i = scnprintf(buf + n, len - n, "%s%s%s%s%s",
-			   IS_AVAIL2(atomic, "atomic ", CONFIG_ARC_HAS_LLSC),
+			   IS_AVAIL2(cpu->isa.atomic, "atomic ", CONFIG_ARC_HAS_LLSC),
 			   IS_AVAIL2(cpu->isa.ldd, "ll64 ", CONFIG_ARC_HAS_LL64),
 			   IS_AVAIL1(cpu->isa.unalign, "unalign (not used)"));
 
@@ -252,7 +268,7 @@ static char *arc_cpu_mumbojumbo(int cpu_
 		       IS_AVAIL1(cpu->extn.swap, "swap "),
 		       IS_AVAIL1(cpu->extn.minmax, "minmax "),
 		       IS_AVAIL1(cpu->extn.crc, "crc "),
-		       IS_AVAIL2(1, "swape", CONFIG_ARC_HAS_SWAPE));
+		       IS_AVAIL2(cpu->extn.swape, "swape", CONFIG_ARC_HAS_SWAPE));
 
 	if (cpu->bpu.ver)
 		n += scnprintf(buf + n, len - n,
@@ -271,9 +287,7 @@ static char *arc_extn_mumbojumbo(int cpu
 
 	FIX_PTR(cpu);
 
-	n += scnprintf(buf + n, len - n,
-		       "Vector Table\t: %#x\nUncached Base\t: %#lx\n",
-		       cpu->vec_base, perip_base);
+	n += scnprintf(buf + n, len - n, "Vector Table\t: %#x\n", cpu->vec_base);
 
 	if (cpu->extn.fpu_sp || cpu->extn.fpu_dp)
 		n += scnprintf(buf + n, len - n, "FPU\t\t: %s%s\n",
@@ -506,7 +520,7 @@ static void *c_start(struct seq_file *m,
 	 * way to pass it w/o having to kmalloc/free a 2 byte string.
 	 * Encode cpu-id as 0xFFcccc, which is decoded by show routine.
 	 */
-	return *pos < num_possible_cpus() ? cpu_to_ptr(*pos) : NULL;
+	return *pos < nr_cpu_ids ? cpu_to_ptr(*pos) : NULL;
 }
 
 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/kernel/signal.c linux-libre-4.9-rc7-gnu/arch/arc/kernel/signal.c
--- linux-libre-4.8-gnu/arch/arc/kernel/signal.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/kernel/signal.c	2016-11-27 16:08:04.000000000 -0500
@@ -107,13 +107,13 @@ static int restore_usr_regs(struct pt_re
 	struct user_regs_struct uregs;
 
 	err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
-	if (!err)
-		set_current_blocked(&set);
-
 	err |= __copy_from_user(&uregs.scratch,
 				&(sf->uc.uc_mcontext.regs.scratch),
 				sizeof(sf->uc.uc_mcontext.regs.scratch));
+	if (err)
+		return err;
 
+	set_current_blocked(&set);
 	regs->bta	= uregs.scratch.bta;
 	regs->lp_start	= uregs.scratch.lp_start;
 	regs->lp_end	= uregs.scratch.lp_end;
@@ -138,7 +138,7 @@ static int restore_usr_regs(struct pt_re
 	regs->r0	= uregs.scratch.r0;
 	regs->sp	= uregs.scratch.sp;
 
-	return err;
+	return 0;
 }
 
 static inline int is_do_ss_needed(unsigned int magic)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/kernel/smp.c linux-libre-4.9-rc7-gnu/arch/arc/kernel/smp.c
--- linux-libre-4.8-gnu/arch/arc/kernel/smp.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/kernel/smp.c	2016-11-27 16:08:04.000000000 -0500
@@ -22,6 +22,7 @@
 #include <linux/atomic.h>
 #include <linux/cpumask.h>
 #include <linux/reboot.h>
+#include <linux/irqdomain.h>
 #include <asm/processor.h>
 #include <asm/setup.h>
 #include <asm/mach_desc.h>
@@ -67,11 +68,13 @@ void __init smp_prepare_cpus(unsigned in
 	int i;
 
 	/*
-	 * Initialise the present map, which describes the set of CPUs
-	 * actually populated at the present time.
+	 * if platform didn't set the present map already, do it now
+	 * boot cpu is set to present already by init/main.c
 	 */
-	for (i = 0; i < max_cpus; i++)
-		set_cpu_present(i, true);
+	if (num_present_cpus() <= 1) {
+		for (i = 0; i < max_cpus; i++)
+			set_cpu_present(i, true);
+	}
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)
@@ -351,20 +354,24 @@ irqreturn_t do_IPI(int irq, void *dev_id
  */
 static DEFINE_PER_CPU(int, ipi_dev);
 
-int smp_ipi_irq_setup(int cpu, int irq)
+int smp_ipi_irq_setup(int cpu, irq_hw_number_t hwirq)
 {
 	int *dev = per_cpu_ptr(&ipi_dev, cpu);
+	unsigned int virq = irq_find_mapping(NULL, hwirq);
+
+	if (!virq)
+		panic("Cannot find virq for root domain and hwirq=%lu", hwirq);
 
 	/* Boot cpu calls request, all call enable */
 	if (!cpu) {
 		int rc;
 
-		rc = request_percpu_irq(irq, do_IPI, "IPI Interrupt", dev);
+		rc = request_percpu_irq(virq, do_IPI, "IPI Interrupt", dev);
 		if (rc)
-			panic("Percpu IRQ request failed for %d\n", irq);
+			panic("Percpu IRQ request failed for %u\n", virq);
 	}
 
-	enable_percpu_irq(irq, 0);
+	enable_percpu_irq(virq, 0);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/kernel/time.c linux-libre-4.9-rc7-gnu/arch/arc/kernel/time.c
--- linux-libre-4.8-gnu/arch/arc/kernel/time.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/kernel/time.c	2016-11-27 16:08:04.000000000 -0500
@@ -152,14 +152,17 @@ static cycle_t arc_read_rtc(struct clock
 		cycle_t  full;
 	} stamp;
 
-
-	__asm__ __volatile(
-	"1:						\n"
-	"	lr		%0, [AUX_RTC_LOW]	\n"
-	"	lr		%1, [AUX_RTC_HIGH]	\n"
-	"	lr		%2, [AUX_RTC_CTRL]	\n"
-	"	bbit0.nt	%2, 31, 1b		\n"
-	: "=r" (stamp.low), "=r" (stamp.high), "=r" (status));
+	/*
+	 * hardware has an internal state machine which tracks readout of
+	 * low/high and updates the CTRL.status if
+	 *  - interrupt/exception taken between the two reads
+	 *  - high increments after low has been read
+	 */
+	do {
+		stamp.low = read_aux_reg(AUX_RTC_LOW);
+		stamp.high = read_aux_reg(AUX_RTC_HIGH);
+		status = read_aux_reg(AUX_RTC_CTRL);
+	} while (!(status & _BITUL(31)));
 
 	return stamp.full;
 }
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/kernel/troubleshoot.c linux-libre-4.9-rc7-gnu/arch/arc/kernel/troubleshoot.c
--- linux-libre-4.8-gnu/arch/arc/kernel/troubleshoot.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/kernel/troubleshoot.c	2016-11-27 16:08:04.000000000 -0500
@@ -237,113 +237,3 @@ void show_kernel_fault_diag(const char *
 	if (!user_mode(regs))
 		show_stacktrace(current, regs);
 }
-
-#ifdef CONFIG_DEBUG_FS
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/mount.h>
-#include <linux/pagemap.h>
-#include <linux/init.h>
-#include <linux/namei.h>
-#include <linux/debugfs.h>
-
-static struct dentry *test_dentry;
-static struct dentry *test_dir;
-static struct dentry *test_u32_dentry;
-
-static u32 clr_on_read = 1;
-
-#ifdef CONFIG_ARC_DBG_TLB_MISS_COUNT
-u32 numitlb, numdtlb, num_pte_not_present;
-
-static int fill_display_data(char *kbuf)
-{
-	size_t num = 0;
-	num += sprintf(kbuf + num, "I-TLB Miss %x\n", numitlb);
-	num += sprintf(kbuf + num, "D-TLB Miss %x\n", numdtlb);
-	num += sprintf(kbuf + num, "PTE not present %x\n", num_pte_not_present);
-
-	if (clr_on_read)
-		numitlb = numdtlb = num_pte_not_present = 0;
-
-	return num;
-}
-
-static int tlb_stats_open(struct inode *inode, struct file *file)
-{
-	file->private_data = (void *)__get_free_page(GFP_KERNEL);
-	return 0;
-}
-
-/* called on user read(): display the counters */
-static ssize_t tlb_stats_output(struct file *file,	/* file descriptor */
-				char __user *user_buf,	/* user buffer */
-				size_t len,		/* length of buffer */
-				loff_t *offset)		/* offset in the file */
-{
-	size_t num;
-	char *kbuf = (char *)file->private_data;
-
-	/* All of the data can he shoved in one iteration */
-	if (*offset != 0)
-		return 0;
-
-	num = fill_display_data(kbuf);
-
-	/* simple_read_from_buffer() is helper for copy to user space
-	   It copies up to @2 (num) bytes from kernel buffer @4 (kbuf) at offset
-	   @3 (offset) into the user space address starting at @1 (user_buf).
-	   @5 (len) is max size of user buffer
-	 */
-	return simple_read_from_buffer(user_buf, num, offset, kbuf, len);
-}
-
-/* called on user write : clears the counters */
-static ssize_t tlb_stats_clear(struct file *file, const char __user *user_buf,
-			       size_t length, loff_t *offset)
-{
-	numitlb = numdtlb = num_pte_not_present = 0;
-	return length;
-}
-
-static int tlb_stats_close(struct inode *inode, struct file *file)
-{
-	free_page((unsigned long)(file->private_data));
-	return 0;
-}
-
-static const struct file_operations tlb_stats_file_ops = {
-	.read = tlb_stats_output,
-	.write = tlb_stats_clear,
-	.open = tlb_stats_open,
-	.release = tlb_stats_close
-};
-#endif
-
-static int __init arc_debugfs_init(void)
-{
-	test_dir = debugfs_create_dir("arc", NULL);
-
-#ifdef CONFIG_ARC_DBG_TLB_MISS_COUNT
-	test_dentry = debugfs_create_file("tlb_stats", 0444, test_dir, NULL,
-					  &tlb_stats_file_ops);
-#endif
-
-	test_u32_dentry =
-	    debugfs_create_u32("clr_on_read", 0444, test_dir, &clr_on_read);
-
-	return 0;
-}
-
-module_init(arc_debugfs_init);
-
-static void __exit arc_debugfs_exit(void)
-{
-	debugfs_remove(test_u32_dentry);
-	debugfs_remove(test_dentry);
-	debugfs_remove(test_dir);
-}
-module_exit(arc_debugfs_exit);
-
-#endif
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/kernel/unwind.c linux-libre-4.9-rc7-gnu/arch/arc/kernel/unwind.c
--- linux-libre-4.8-gnu/arch/arc/kernel/unwind.c	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/kernel/unwind.c	2016-11-27 16:08:04.000000000 -0500
@@ -111,6 +111,8 @@ UNW_REGISTER_INFO};
 #define DW_EH_PE_indirect 0x80
 #define DW_EH_PE_omit     0xff
 
+#define CIE_ID	0
+
 typedef unsigned long uleb128_t;
 typedef signed long sleb128_t;
 
@@ -232,6 +234,7 @@ void __init arc_unwind_init(void)
 
 static const u32 bad_cie, not_fde;
 static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *);
+static const u32 *__cie_for_fde(const u32 *fde);
 static signed fde_pointer_type(const u32 *cie);
 
 struct eh_frame_hdr_table_entry {
@@ -338,10 +341,9 @@ static void init_unwind_hdr(struct unwin
 	for (fde = table->address, tableSize = table->size, n = 0;
 	     tableSize;
 	     tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
-		/* const u32 *cie = fde + 1 - fde[1] / sizeof(*fde); */
-		const u32 *cie = (const u32 *)(fde[1]);
+		const u32 *cie = __cie_for_fde(fde);
 
-		if (fde[1] == 0xffffffff)
+		if (fde[1] == CIE_ID)
 			continue;	/* this is a CIE */
 		ptr = (const u8 *)(fde + 2);
 		header->table[n].start = read_pointer(&ptr,
@@ -504,6 +506,15 @@ static sleb128_t get_sleb128(const u8 **
 	return value;
 }
 
+static const u32 *__cie_for_fde(const u32 *fde)
+{
+	const u32 *cie;
+
+	cie = fde + 1 - fde[1] / sizeof(*fde);
+
+	return cie;
+}
+
 static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *table)
 {
 	const u32 *cie;
@@ -511,19 +522,18 @@ static const u32 *cie_for_fde(const u32
 	if (!*fde || (*fde & (sizeof(*fde) - 1)))
 		return &bad_cie;
 
-	if (fde[1] == 0xffffffff)
+	if (fde[1] == CIE_ID)
 		return &not_fde;	/* this is a CIE */
 
 	if ((fde[1] & (sizeof(*fde) - 1)))
 /* || fde[1] > (unsigned long)(fde + 1) - (unsigned long)table->address) */
 		return NULL;	/* this is not a valid FDE */
 
-	/* cie = fde + 1 - fde[1] / sizeof(*fde); */
-	cie = (u32 *) fde[1];
+	cie = __cie_for_fde(fde);
 
 	if (*cie <= sizeof(*cie) + 4 || *cie >= fde[1] - sizeof(*fde)
 	    || (*cie & (sizeof(*cie) - 1))
-	    || (cie[1] != 0xffffffff))
+	    || (cie[1] != CIE_ID))
 		return NULL;	/* this is not a (valid) CIE */
 	return cie;
 }
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/kernel/vmlinux.lds.S linux-libre-4.9-rc7-gnu/arch/arc/kernel/vmlinux.lds.S
--- linux-libre-4.8-gnu/arch/arc/kernel/vmlinux.lds.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/kernel/vmlinux.lds.S	2016-11-27 16:08:04.000000000 -0500
@@ -82,14 +82,6 @@ SECTIONS
 
 	PERCPU_SECTION(L1_CACHE_BYTES)
 
-	/*
-	 * .exit.text is discard at runtime, not link time, to deal with
-	 * references from .debug_frame
-	 * It will be init freed, being inside [__init_start : __init_end]
-	 */
-	.exit.text : { EXIT_TEXT }
-	.exit.data : { EXIT_DATA }
-
 	. = ALIGN(PAGE_SIZE);
 	__init_end = .;
 
@@ -97,6 +89,7 @@ SECTIONS
 		_text = .;
 		TEXT_TEXT
 		SCHED_TEXT
+		CPUIDLE_TEXT
 		LOCK_TEXT
 		KPROBES_TEXT
 		*(.fixup)
@@ -120,18 +113,13 @@ SECTIONS
 
 #ifdef CONFIG_ARC_DW2_UNWIND
 	. = ALIGN(PAGE_SIZE);
-	.debug_frame  : {
+	.eh_frame  : {
 		__start_unwind = .;
-		*(.debug_frame)
+		*(.eh_frame)
 		__end_unwind = .;
 	}
-	/*
-	 * gcc 4.8 generates this for -fasynchonous-unwind-tables,
-	 * while we still use the .debug_frame based unwinder
-	 */
-	/DISCARD/ : {	*(.eh_frame) }
 #else
-	/DISCARD/ : {	*(.debug_frame) }
+	/DISCARD/ : {	*(.eh_frame) }
 #endif
 
 	NOTES
@@ -148,7 +136,7 @@ SECTIONS
 	}
 
 #ifndef CONFIG_DEBUG_INFO
-	/* open-coded because we need .debug_frame seperately for unwinding */
+	/DISCARD/ : { *(.debug_frame) }
 	/DISCARD/ : { *(.debug_aranges) }
 	/DISCARD/ : { *(.debug_pubnames) }
 	/DISCARD/ : { *(.debug_info) }
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/lib/memcmp.S linux-libre-4.9-rc7-gnu/arch/arc/lib/memcmp.S
--- linux-libre-4.8-gnu/arch/arc/lib/memcmp.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/lib/memcmp.S	2016-11-27 16:08:04.000000000 -0500
@@ -16,7 +16,7 @@
 #define SHIFT r2
 #endif
 
-ENTRY(memcmp)
+ENTRY_CFI(memcmp)
 	or	r12,r0,r1
 	asl_s	r12,r12,30
 	sub	r3,r2,1
@@ -149,4 +149,4 @@ ENTRY(memcmp)
 .Lnil:
 	j_s.d	[blink]
 	mov	r0,0
-END(memcmp)
+END_CFI(memcmp)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/lib/memcpy-700.S linux-libre-4.9-rc7-gnu/arch/arc/lib/memcpy-700.S
--- linux-libre-4.8-gnu/arch/arc/lib/memcpy-700.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/lib/memcpy-700.S	2016-11-27 16:08:04.000000000 -0500
@@ -8,7 +8,7 @@
 
 #include <linux/linkage.h>
 
-ENTRY(memcpy)
+ENTRY_CFI(memcpy)
 	or	r3,r0,r1
 	asl_s	r3,r3,30
 	mov_s	r5,r0
@@ -63,4 +63,4 @@ ENTRY(memcpy)
 .Lendbloop:
 	j_s.d	[blink]
 	stb	r12,[r5,0]
-END(memcpy)
+END_CFI(memcpy)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/lib/memcpy-archs.S linux-libre-4.9-rc7-gnu/arch/arc/lib/memcpy-archs.S
--- linux-libre-4.8-gnu/arch/arc/lib/memcpy-archs.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/lib/memcpy-archs.S	2016-11-27 16:08:04.000000000 -0500
@@ -40,7 +40,7 @@
 # define ZOLAND			0xF
 #endif
 
-ENTRY(memcpy)
+ENTRY_CFI(memcpy)
 	prefetch [r1]		; Prefetch the read location
 	prefetchw [r0]		; Prefetch the write location
 	mov.f	0, r2
@@ -233,4 +233,4 @@ ENTRY(memcpy)
 .Lcopybytewise_3:
 	j	[blink]
 
-END(memcpy)
+END_CFI(memcpy)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/lib/memset-archs.S linux-libre-4.9-rc7-gnu/arch/arc/lib/memset-archs.S
--- linux-libre-4.8-gnu/arch/arc/lib/memset-archs.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/lib/memset-archs.S	2016-11-27 16:08:04.000000000 -0500
@@ -10,7 +10,7 @@
 
 #undef PREALLOC_NOT_AVAIL
 
-ENTRY(memset)
+ENTRY_CFI(memset)
 	prefetchw [r0]		; Prefetch the write location
 	mov.f	0, r2
 ;;; if size is zero
@@ -112,11 +112,11 @@ ENTRY(memset)
 
 	j	[blink]
 
-END(memset)
+END_CFI(memset)
 
-ENTRY(memzero)
+ENTRY_CFI(memzero)
     ; adjust bzero args to memset args
     mov r2, r1
     b.d  memset    ;tail call so need to tinker with blink
     mov r1, 0
-END(memzero)
+END_CFI(memzero)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/lib/memset.S linux-libre-4.9-rc7-gnu/arch/arc/lib/memset.S
--- linux-libre-4.8-gnu/arch/arc/lib/memset.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/lib/memset.S	2016-11-27 16:08:04.000000000 -0500
@@ -10,7 +10,7 @@
 
 #define SMALL	7 /* Must be at least 6 to deal with alignment/loop issues.  */
 
-ENTRY(memset)
+ENTRY_CFI(memset)
 	mov_s	r4,r0
 	or	r12,r0,r2
 	bmsk.f	r12,r12,1
@@ -46,14 +46,14 @@ ENTRY(memset)
 	stb.ab	r1,[r4,1]
 .Ltiny_end:
 	j_s	[blink]
-END(memset)
+END_CFI(memset)
 
 ; memzero: @r0 = mem, @r1 = size_t
 ; memset:  @r0 = mem, @r1 = char, @r2 = size_t
 
-ENTRY(memzero)
+ENTRY_CFI(memzero)
     ; adjust bzero args to memset args
     mov r2, r1
     mov r1, 0
     b  memset    ;tail call so need to tinker with blink
-END(memzero)
+END_CFI(memzero)
diff -druNp --no-dereference linux-libre-4.8-gnu/arch/arc/lib/strchr-700.S linux-libre-4.9-rc7-gnu/arch/arc/lib/strchr-700.S
--- linux-libre-4.8-gnu/arch/arc/lib/strchr-700.S	2016-10-02 19:24:33.000000000 -0400
+++ linux-libre-4.9-rc7-gnu/arch/arc/lib/strchr-700.S	2016-11-27 16:08:04.000000000 -0500
@@ -13,7 +13,7 @@
 
 #include <linux/linkage.h>
 
-ENTRY(strchr)
+ENTRY_CFI(strchr)
 	extb_s	r1,r1
 	asl	r5,r1,8
 	bmsk	r2,r0,1
@@ -130,4 +130,4 @@ ENTRY(strchr)
 	j_s.d	[blink]
 	mov.mi	r0,0
 #endif /* ENDIAN */
-