--- /dev/null
+From 9cdd31e5913c1f86dce7e201b086155b3f24896b Mon Sep 17 00:00:00 2001
+From: Ludovic Desroches <ludovic.desroches@microchip.com>
+Date: Mon, 10 Apr 2017 10:25:16 +0200
+Subject: ARM: dts: at91: sama5d3_xplained: fix ADC vref
+
+From: Ludovic Desroches <ludovic.desroches@microchip.com>
+
+commit 9cdd31e5913c1f86dce7e201b086155b3f24896b upstream.
+
+The voltage reference for the ADC is not 3V but 3.3V since it is connected to
+VDDANA.
+
+Signed-off-by: Ludovic Desroches <ludovic.desroches@microchip.com>
+Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/boot/dts/at91-sama5d3_xplained.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm/boot/dts/at91-sama5d3_xplained.dts
++++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
+@@ -162,6 +162,7 @@
+ };
+
+ adc0: adc@f8018000 {
++ atmel,adc-vref = <3300>;
+ pinctrl-0 = <
+ &pinctrl_adc0_adtrg
+ &pinctrl_adc0_ad0
--- /dev/null
+From d3df1ec06353e51fc44563d2e7e18d42811af290 Mon Sep 17 00:00:00 2001
+From: Ludovic Desroches <ludovic.desroches@microchip.com>
+Date: Mon, 10 Apr 2017 10:25:17 +0200
+Subject: ARM: dts: at91: sama5d3_xplained: not all ADC channels are available
+
+From: Ludovic Desroches <ludovic.desroches@microchip.com>
+
+commit d3df1ec06353e51fc44563d2e7e18d42811af290 upstream.
+
+Remove ADC channels that are not available by default on the sama5d3_xplained
+board (resistor not populated) in order to not create confusion.
+
+Signed-off-by: Ludovic Desroches <ludovic.desroches@microchip.com>
+Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/boot/dts/at91-sama5d3_xplained.dts | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/arch/arm/boot/dts/at91-sama5d3_xplained.dts
++++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
+@@ -163,9 +163,9 @@
+
+ adc0: adc@f8018000 {
+ atmel,adc-vref = <3300>;
++ atmel,adc-channels-used = <0xfe>;
+ pinctrl-0 = <
+ &pinctrl_adc0_adtrg
+- &pinctrl_adc0_ad0
+ &pinctrl_adc0_ad1
+ &pinctrl_adc0_ad2
+ &pinctrl_adc0_ad3
+@@ -173,8 +173,6 @@
+ &pinctrl_adc0_ad5
+ &pinctrl_adc0_ad6
+ &pinctrl_adc0_ad7
+- &pinctrl_adc0_ad8
+- &pinctrl_adc0_ad9
+ >;
+ status = "okay";
+ };
--- /dev/null
+From f0e421b1bf7af97f026e1bb8bfe4c5a7a8c08f42 Mon Sep 17 00:00:00 2001
+From: Kristina Martsenko <kristina.martsenko@arm.com>
+Date: Wed, 3 May 2017 16:37:48 +0100
+Subject: arm64: documentation: document tagged pointer stack constraints
+
+From: Kristina Martsenko <kristina.martsenko@arm.com>
+
+commit f0e421b1bf7af97f026e1bb8bfe4c5a7a8c08f42 upstream.
+
+Some kernel features don't currently work if a task puts a non-zero
+address tag in its stack pointer, frame pointer, or frame record entries
+(FP, LR).
+
+For example, with a tagged stack pointer, the kernel can't deliver
+signals to the process, and the task is killed instead. As another
+example, with a tagged frame pointer or frame records, perf fails to
+generate call graphs or resolve symbols.
+
+For now, just document these limitations, instead of finding and fixing
+everything that doesn't work, as it's not known if anyone needs to use
+tags in these places anyway.
+
+In addition, as requested by Dave Martin, generalize the limitations
+into a general kernel address tag policy, and refactor
+tagged-pointers.txt to include it.
+
+Fixes: d50240a5f6ce ("arm64: mm: permit use of tagged pointers at EL0")
+Reviewed-by: Dave Martin <Dave.Martin@arm.com>
+Acked-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Kristina Martsenko <kristina.martsenko@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ Documentation/arm64/tagged-pointers.txt | 66 +++++++++++++++++++++++---------
+ 1 file changed, 49 insertions(+), 17 deletions(-)
+
+--- a/Documentation/arm64/tagged-pointers.txt
++++ b/Documentation/arm64/tagged-pointers.txt
+@@ -11,24 +11,56 @@ in AArch64 Linux.
+ The kernel configures the translation tables so that translations made
+ via TTBR0 (i.e. userspace mappings) have the top byte (bits 63:56) of
+ the virtual address ignored by the translation hardware. This frees up
+-this byte for application use, with the following caveats:
++this byte for application use.
+
+- (1) The kernel requires that all user addresses passed to EL1
+- are tagged with tag 0x00. This means that any syscall
+- parameters containing user virtual addresses *must* have
+- their top byte cleared before trapping to the kernel.
+-
+- (2) Non-zero tags are not preserved when delivering signals.
+- This means that signal handlers in applications making use
+- of tags cannot rely on the tag information for user virtual
+- addresses being maintained for fields inside siginfo_t.
+- One exception to this rule is for signals raised in response
+- to watchpoint debug exceptions, where the tag information
+- will be preserved.
+-
+- (3) Special care should be taken when using tagged pointers,
+- since it is likely that C compilers will not hazard two
+- virtual addresses differing only in the upper byte.
++
++Passing tagged addresses to the kernel
++--------------------------------------
++
++All interpretation of userspace memory addresses by the kernel assumes
++an address tag of 0x00.
++
++This includes, but is not limited to, addresses found in:
++
++ - pointer arguments to system calls, including pointers in structures
++ passed to system calls,
++
++ - the stack pointer (sp), e.g. when interpreting it to deliver a
++ signal,
++
++ - the frame pointer (x29) and frame records, e.g. when interpreting
++ them to generate a backtrace or call graph.
++
++Using non-zero address tags in any of these locations may result in an
++error code being returned, a (fatal) signal being raised, or other modes
++of failure.
++
++For these reasons, passing non-zero address tags to the kernel via
++system calls is forbidden, and using a non-zero address tag for sp is
++strongly discouraged.
++
++Programs maintaining a frame pointer and frame records that use non-zero
++address tags may suffer impaired or inaccurate debug and profiling
++visibility.
++
++
++Preserving tags
++---------------
++
++Non-zero tags are not preserved when delivering signals. This means that
++signal handlers in applications making use of tags cannot rely on the
++tag information for user virtual addresses being maintained for fields
++inside siginfo_t. One exception to this rule is for signals raised in
++response to watchpoint debug exceptions, where the tag information will
++be preserved.
+
+ The architecture prevents the use of a tagged PC, so the upper byte will
+ be set to a sign-extension of bit 55 on exception return.
++
++
++Other considerations
++--------------------
++
++Special care should be taken when using tagged pointers, since it is
++likely that C compilers will not hazard two virtual addresses differing
++only in the upper byte.
--- /dev/null
+From a06040d7a791a9177581dcf7293941bd92400856 Mon Sep 17 00:00:00 2001
+From: Mark Rutland <mark.rutland@arm.com>
+Date: Wed, 3 May 2017 16:09:35 +0100
+Subject: arm64: uaccess: ensure extension of access_ok() addr
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+commit a06040d7a791a9177581dcf7293941bd92400856 upstream.
+
+Our access_ok() simply hands its arguments over to __range_ok(), which
+implicitly assummes that the addr parameter is 64 bits wide. This isn't
+necessarily true for compat code, which might pass down a 32-bit address
+parameter.
+
+In these cases, we don't have a guarantee that the address has been zero
+extended to 64 bits, and the upper bits of the register may contain
+unknown values, potentially resulting in a suprious failure.
+
+Avoid this by explicitly casting the addr parameter to an unsigned long
+(as is done on other architectures), ensuring that the parameter is
+widened appropriately.
+
+Fixes: 0aea86a2176c ("arm64: User access library functions")
+Acked-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/include/asm/uaccess.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/include/asm/uaccess.h
++++ b/arch/arm64/include/asm/uaccess.h
+@@ -92,11 +92,12 @@ static inline void set_fs(mm_segment_t f
+ */
+ #define __range_ok(addr, size) \
+ ({ \
++ unsigned long __addr = (unsigned long __force)(addr); \
+ unsigned long flag, roksum; \
+ __chk_user_ptr(addr); \
+ asm("adds %1, %1, %3; ccmp %1, %4, #2, cc; cset %0, ls" \
+ : "=&r" (flag), "=&r" (roksum) \
+- : "1" (addr), "Ir" (size), \
++ : "1" (__addr), "Ir" (size), \
+ "r" (current_thread_info()->addr_limit) \
+ : "cc"); \
+ flag; \
--- /dev/null
+From fee960bed5e857eb126c4e56dd9ff85938356579 Mon Sep 17 00:00:00 2001
+From: Mark Rutland <mark.rutland@arm.com>
+Date: Wed, 3 May 2017 16:09:33 +0100
+Subject: arm64: xchg: hazard against entire exchange variable
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+commit fee960bed5e857eb126c4e56dd9ff85938356579 upstream.
+
+The inline assembly in __XCHG_CASE() uses a +Q constraint to hazard
+against other accesses to the memory location being exchanged. However,
+the pointer passed to the constraint is a u8 pointer, and thus the
+hazard only applies to the first byte of the location.
+
+GCC can take advantage of this, assuming that other portions of the
+location are unchanged, as demonstrated with the following test case:
+
+union u {
+ unsigned long l;
+ unsigned int i[2];
+};
+
+unsigned long update_char_hazard(union u *u)
+{
+ unsigned int a, b;
+
+ a = u->i[1];
+ asm ("str %1, %0" : "+Q" (*(char *)&u->l) : "r" (0UL));
+ b = u->i[1];
+
+ return a ^ b;
+}
+
+unsigned long update_long_hazard(union u *u)
+{
+ unsigned int a, b;
+
+ a = u->i[1];
+ asm ("str %1, %0" : "+Q" (*(long *)&u->l) : "r" (0UL));
+ b = u->i[1];
+
+ return a ^ b;
+}
+
+The linaro 15.08 GCC 5.1.1 toolchain compiles the above as follows when
+using -O2 or above:
+
+0000000000000000 <update_char_hazard>:
+ 0: d2800001 mov x1, #0x0 // #0
+ 4: f9000001 str x1, [x0]
+ 8: d2800000 mov x0, #0x0 // #0
+ c: d65f03c0 ret
+
+0000000000000010 <update_long_hazard>:
+ 10: b9400401 ldr w1, [x0,#4]
+ 14: d2800002 mov x2, #0x0 // #0
+ 18: f9000002 str x2, [x0]
+ 1c: b9400400 ldr w0, [x0,#4]
+ 20: 4a000020 eor w0, w1, w0
+ 24: d65f03c0 ret
+
+This patch fixes the issue by passing an unsigned long pointer into the
++Q constraint, as we do for our cmpxchg code. This may hazard against
+more than is necessary, but this is better than missing a necessary
+hazard.
+
+Fixes: 305d454aaa29 ("arm64: atomics: implement native {relaxed, acquire, release} atomics")
+Acked-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/include/asm/cmpxchg.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/include/asm/cmpxchg.h
++++ b/arch/arm64/include/asm/cmpxchg.h
+@@ -49,7 +49,7 @@ static inline unsigned long __xchg_case_
+ " swp" #acq_lse #rel #sz "\t%" #w "3, %" #w "0, %2\n" \
+ " nop\n" \
+ " " #nop_lse) \
+- : "=&r" (ret), "=&r" (tmp), "+Q" (*(u8 *)ptr) \
++ : "=&r" (ret), "=&r" (tmp), "+Q" (*(unsigned long *)ptr) \
+ : "r" (x) \
+ : cl); \
+ \
--- /dev/null
+From 2c4569ca26986d18243f282dd727da27e9adae4c Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Thu, 11 May 2017 13:54:11 +0200
+Subject: genirq: Fix chained interrupt data ordering
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit 2c4569ca26986d18243f282dd727da27e9adae4c upstream.
+
+irq_set_chained_handler_and_data() sets up the chained interrupt and then
+stores the handler data.
+
+That's racy against an immediate interrupt which gets handled before the
+store of the handler data happened. The handler will dereference a NULL
+pointer and crash.
+
+Cure it by storing handler data before installing the chained handler.
+
+Reported-by: Borislav Petkov <bp@alien8.de>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/irq/chip.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/irq/chip.c
++++ b/kernel/irq/chip.c
+@@ -810,8 +810,8 @@ irq_set_chained_handler_and_data(unsigne
+ if (!desc)
+ return;
+
+- __irq_do_set_handler(desc, handle, 1, NULL);
+ desc->irq_common_data.handler_data = data;
++ __irq_do_set_handler(desc, handle, 1, NULL);
+
+ irq_put_desc_busunlock(desc, flags);
+ }
--- /dev/null
+From f73a7eee900e95404b61408a23a1df5c5811704c Mon Sep 17 00:00:00 2001
+From: KarimAllah Ahmed <karahmed@amazon.de>
+Date: Fri, 5 May 2017 11:39:59 -0700
+Subject: iommu/vt-d: Flush the IOTLB to get rid of the initial kdump mappings
+
+From: KarimAllah Ahmed <karahmed@amazon.de>
+
+commit f73a7eee900e95404b61408a23a1df5c5811704c upstream.
+
+Ever since commit 091d42e43d ("iommu/vt-d: Copy translation tables from
+old kernel") the kdump kernel copies the IOMMU context tables from the
+previous kernel. Each device mappings will be destroyed once the driver
+for the respective device takes over.
+
+This unfortunately breaks the workflow of mapping and unmapping a new
+context to the IOMMU. The mapping function assumes that either:
+
+1) Unmapping did the proper IOMMU flushing and it only ever flush if the
+ IOMMU unit supports caching invalid entries.
+2) The system just booted and the initialization code took care of
+ flushing all IOMMU caches.
+
+This assumption is not true for the kdump kernel since the context
+tables have been copied from the previous kernel and translations could
+have been cached ever since. So make sure to flush the IOTLB as well
+when we destroy these old copied mappings.
+
+Cc: Joerg Roedel <joro@8bytes.org>
+Cc: David Woodhouse <dwmw2@infradead.org>
+Cc: David Woodhouse <dwmw@amazon.co.uk>
+Cc: Anthony Liguori <aliguori@amazon.com>
+Signed-off-by: KarimAllah Ahmed <karahmed@amazon.de>
+Acked-by: David Woodhouse <dwmw@amazon.co.uk>
+Fixes: 091d42e43d ("iommu/vt-d: Copy translation tables from old kernel")
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/intel-iommu.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/iommu/intel-iommu.c
++++ b/drivers/iommu/intel-iommu.c
+@@ -2005,11 +2005,14 @@ static int domain_context_mapping_one(st
+ if (context_copied(context)) {
+ u16 did_old = context_domain_id(context);
+
+- if (did_old >= 0 && did_old < cap_ndoms(iommu->cap))
++ if (did_old >= 0 && did_old < cap_ndoms(iommu->cap)) {
+ iommu->flush.flush_context(iommu, did_old,
+ (((u16)bus) << 8) | devfn,
+ DMA_CCMD_MASK_NOBIT,
+ DMA_CCMD_DEVICE_INVL);
++ iommu->flush.flush_iotlb(iommu, did_old, 0, 0,
++ DMA_TLB_DSI_FLUSH);
++ }
+ }
+
+ pgd = domain->pgd;
--- /dev/null
+From 3a158a62da0673db918b53ac1440845a5b64fd90 Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Tue, 2 May 2017 19:41:06 +0100
+Subject: metag/uaccess: Check access_ok in strncpy_from_user
+
+From: James Hogan <james.hogan@imgtec.com>
+
+commit 3a158a62da0673db918b53ac1440845a5b64fd90 upstream.
+
+The metag implementation of strncpy_from_user() doesn't validate the src
+pointer, which could allow reading of arbitrary kernel memory. Add a
+short access_ok() check to prevent that.
+
+Its still possible for it to read across the user/kernel boundary, but
+it will invariably reach a NUL character after only 9 bytes, leaking
+only a static kernel address being loaded into D0Re0 at the beginning of
+__start, which is acceptable for the immediate fix.
+
+Reported-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Cc: linux-metag@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/metag/include/asm/uaccess.h | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/arch/metag/include/asm/uaccess.h
++++ b/arch/metag/include/asm/uaccess.h
+@@ -194,8 +194,13 @@ do {
+ extern long __must_check __strncpy_from_user(char *dst, const char __user *src,
+ long count);
+
+-#define strncpy_from_user(dst, src, count) __strncpy_from_user(dst, src, count)
+-
++static inline long
++strncpy_from_user(char *dst, const char __user *src, long count)
++{
++ if (!access_ok(VERIFY_READ, src, 1))
++ return -EFAULT;
++ return __strncpy_from_user(dst, src, count);
++}
+ /*
+ * Return the size of a string (including the ending 0)
+ *
--- /dev/null
+From 8a8b56638bcac4e64cccc88bf95a0f9f4b19a2fb Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Fri, 28 Apr 2017 10:50:26 +0100
+Subject: metag/uaccess: Fix access_ok()
+
+From: James Hogan <james.hogan@imgtec.com>
+
+commit 8a8b56638bcac4e64cccc88bf95a0f9f4b19a2fb upstream.
+
+The __user_bad() macro used by access_ok() has a few corner cases
+noticed by Al Viro where it doesn't behave correctly:
+
+ - The kernel range check has off by 1 errors which permit access to the
+ first and last byte of the kernel mapped range.
+
+ - The kernel range check ends at LINCORE_BASE rather than
+ META_MEMORY_LIMIT, which is ineffective when the kernel is in global
+ space (an extremely uncommon configuration).
+
+There are a couple of other shortcomings here too:
+
+ - Access to the whole of the other address space is permitted (i.e. the
+ global half of the address space when the kernel is in local space).
+ This isn't ideal as it could theoretically still contain privileged
+ mappings set up by the bootloader.
+
+ - The size argument is unused, permitting user copies which start on
+ valid pages at the end of the user address range and cross the
+ boundary into the kernel address space (e.g. addr = 0x3ffffff0, size
+ > 0x10).
+
+It isn't very convenient to add size checks when disallowing certain
+regions, and it seems far safer to be sure and explicit about what
+userland is able to access, so invert the logic to allow certain regions
+instead, and fix the off by 1 errors and missing size checks. This also
+allows the get_fs() == KERNEL_DS check to be more easily optimised into
+the user address range case.
+
+We now have 3 such allowed regions:
+
+ - The user address range (incorporating the get_fs() == KERNEL_DS
+ check).
+
+ - NULL (some kernel code expects this to work, and we'll always catch
+ the fault anyway).
+
+ - The core code memory region.
+
+Fixes: 373cd784d0fc ("metag: Memory handling")
+Reported-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Cc: linux-metag@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/metag/include/asm/uaccess.h | 40 +++++++++++++++++++++++----------------
+ 1 file changed, 24 insertions(+), 16 deletions(-)
+
+--- a/arch/metag/include/asm/uaccess.h
++++ b/arch/metag/include/asm/uaccess.h
+@@ -28,24 +28,32 @@
+
+ #define segment_eq(a, b) ((a).seg == (b).seg)
+
+-#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
+-/*
+- * Explicitly allow NULL pointers here. Parts of the kernel such
+- * as readv/writev use access_ok to validate pointers, but want
+- * to allow NULL pointers for various reasons. NULL pointers are
+- * safe to allow through because the first page is not mappable on
+- * Meta.
+- *
+- * We also wish to avoid letting user code access the system area
+- * and the kernel half of the address space.
+- */
+-#define __user_bad(addr, size) (((addr) > 0 && (addr) < META_MEMORY_BASE) || \
+- ((addr) > PAGE_OFFSET && \
+- (addr) < LINCORE_BASE))
+-
+ static inline int __access_ok(unsigned long addr, unsigned long size)
+ {
+- return __kernel_ok || !__user_bad(addr, size);
++ /*
++ * Allow access to the user mapped memory area, but not the system area
++ * before it. The check extends to the top of the address space when
++ * kernel access is allowed (there's no real reason to user copy to the
++ * system area in any case).
++ */
++ if (likely(addr >= META_MEMORY_BASE && addr < get_fs().seg &&
++ size <= get_fs().seg - addr))
++ return true;
++ /*
++ * Explicitly allow NULL pointers here. Parts of the kernel such
++ * as readv/writev use access_ok to validate pointers, but want
++ * to allow NULL pointers for various reasons. NULL pointers are
++ * safe to allow through because the first page is not mappable on
++ * Meta.
++ */
++ if (!addr)
++ return true;
++ /* Allow access to core code memory area... */
++ if (addr >= LINCORE_CODE_BASE && addr <= LINCORE_CODE_LIMIT &&
++ size <= LINCORE_CODE_LIMIT + 1 - addr)
++ return true;
++ /* ... but no other areas. */
++ return false;
+ }
+
+ #define access_ok(type, addr, size) __access_ok((unsigned long)(addr), \
--- /dev/null
+From 8310d48b125d19fcd9521d83b8293e63eb1646aa Mon Sep 17 00:00:00 2001
+From: Keno Fischer <keno@juliacomputing.com>
+Date: Tue, 24 Jan 2017 15:17:48 -0800
+Subject: mm/huge_memory.c: respect FOLL_FORCE/FOLL_COW for thp
+
+From: Keno Fischer <keno@juliacomputing.com>
+
+commit 8310d48b125d19fcd9521d83b8293e63eb1646aa upstream.
+
+In commit 19be0eaffa3a ("mm: remove gup_flags FOLL_WRITE games from
+__get_user_pages()"), the mm code was changed from unsetting FOLL_WRITE
+after a COW was resolved to setting the (newly introduced) FOLL_COW
+instead. Simultaneously, the check in gup.c was updated to still allow
+writes with FOLL_FORCE set if FOLL_COW had also been set.
+
+However, a similar check in huge_memory.c was forgotten. As a result,
+remote memory writes to ro regions of memory backed by transparent huge
+pages cause an infinite loop in the kernel (handle_mm_fault sets
+FOLL_COW and returns 0 causing a retry, but follow_trans_huge_pmd bails
+out immidiately because `(flags & FOLL_WRITE) && !pmd_write(*pmd)` is
+true.
+
+While in this state the process is stil SIGKILLable, but little else
+works (e.g. no ptrace attach, no other signals). This is easily
+reproduced with the following code (assuming thp are set to always):
+
+ #include <assert.h>
+ #include <fcntl.h>
+ #include <stdint.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <sys/mman.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
+ #include <unistd.h>
+
+ #define TEST_SIZE 5 * 1024 * 1024
+
+ int main(void) {
+ int status;
+ pid_t child;
+ int fd = open("/proc/self/mem", O_RDWR);
+ void *addr = mmap(NULL, TEST_SIZE, PROT_READ,
+ MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
+ assert(addr != MAP_FAILED);
+ pid_t parent_pid = getpid();
+ if ((child = fork()) == 0) {
+ void *addr2 = mmap(NULL, TEST_SIZE, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
+ assert(addr2 != MAP_FAILED);
+ memset(addr2, 'a', TEST_SIZE);
+ pwrite(fd, addr2, TEST_SIZE, (uintptr_t)addr);
+ return 0;
+ }
+ assert(child == waitpid(child, &status, 0));
+ assert(WIFEXITED(status) && WEXITSTATUS(status) == 0);
+ return 0;
+ }
+
+Fix this by updating follow_trans_huge_pmd in huge_memory.c analogously
+to the update in gup.c in the original commit. The same pattern exists
+in follow_devmap_pmd. However, we should not be able to reach that
+check with FOLL_COW set, so add WARN_ONCE to make sure we notice if we
+ever do.
+
+[akpm@linux-foundation.org: coding-style fixes]
+Link: http://lkml.kernel.org/r/20170106015025.GA38411@juliacomputing.com
+Signed-off-by: Keno Fischer <keno@juliacomputing.com>
+Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Cc: Greg Thelen <gthelen@google.com>
+Cc: Nicholas Piggin <npiggin@gmail.com>
+Cc: Willy Tarreau <w@1wt.eu>
+Cc: Oleg Nesterov <oleg@redhat.com>
+Cc: Kees Cook <keescook@chromium.org>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+[AmitP: Minor refactoring of upstream changes for linux-3.18.y,
+ where follow_devmap_pmd() doesn't exist.]
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/huge_memory.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -1269,6 +1269,16 @@ out_unlock:
+ return ret;
+ }
+
++/*
++ * FOLL_FORCE can write to even unwritable pmd's, but only
++ * after we've gone through a COW cycle and they are dirty.
++ */
++static inline bool can_follow_write_pmd(pmd_t pmd, unsigned int flags)
++{
++ return pmd_write(pmd) ||
++ ((flags & FOLL_FORCE) && (flags & FOLL_COW) && pmd_dirty(pmd));
++}
++
+ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
+ unsigned long addr,
+ pmd_t *pmd,
+@@ -1279,7 +1289,7 @@ struct page *follow_trans_huge_pmd(struc
+
+ assert_spin_locked(pmd_lockptr(mm, pmd));
+
+- if (flags & FOLL_WRITE && !pmd_write(*pmd))
++ if (flags & FOLL_WRITE && !can_follow_write_pmd(*pmd, flags))
+ goto out;
+
+ /* Avoid dumping huge zero page */
--- /dev/null
+From fd615f69a18a9d4aa5ef02a1dc83f319f75da8e7 Mon Sep 17 00:00:00 2001
+From: LiuHailong <liu.hailong6@zte.com.cn>
+Date: Tue, 7 Feb 2017 10:35:52 +0800
+Subject: powerpc/64e: Fix hang when debugging programs with relocated kernel
+
+From: LiuHailong <liu.hailong6@zte.com.cn>
+
+commit fd615f69a18a9d4aa5ef02a1dc83f319f75da8e7 upstream.
+
+Debug interrupts can be taken during interrupt entry, since interrupt
+entry does not automatically turn them off. The kernel will check
+whether the faulting instruction is between [interrupt_base_book3e,
+__end_interrupts], and if so clear MSR[DE] and return.
+
+However, when the kernel is built with CONFIG_RELOCATABLE, it can't use
+LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e) and
+LOAD_REG_IMMEDIATE(r15,__end_interrupts), as they ignore relocation.
+Thus, if the kernel is actually running at a different address than it
+was built at, the address comparison will fail, and the exception entry
+code will hang at kernel_dbg_exc.
+
+r2(toc) is also not usable here, as r2 still holds data from the
+interrupted context, so LOAD_REG_ADDR() doesn't work either. So we use
+the *name@got* to get the EV of two labels directly.
+
+Test programs test.c shows as follows:
+int main(int argc, char *argv[])
+{
+ if (access("/proc/sys/kernel/perf_event_paranoid", F_OK) == -1)
+ printf("Kernel doesn't have perf_event support\n");
+}
+
+Steps to reproduce the bug, for example:
+ 1) ./gdb ./test
+ 2) (gdb) b access
+ 3) (gdb) r
+ 4) (gdb) s
+
+Signed-off-by: Liu Hailong <liu.hailong6@zte.com.cn>
+Signed-off-by: Jiang Xuexin <jiang.xuexin@zte.com.cn>
+Reviewed-by: Jiang Biao <jiang.biao2@zte.com.cn>
+Reviewed-by: Liu Song <liu.song11@zte.com.cn>
+Reviewed-by: Huang Jian <huang.jian@zte.com.cn>
+[scottwood: cleaned up commit message, and specified bad behavior
+ as a hang rather than an oops to correspond to mainline kernel behavior]
+Fixes: 1cb6e0649248 ("powerpc/book3e: support CONFIG_RELOCATABLE")
+Signed-off-by: Scott Wood <oss@buserror.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/exceptions-64e.S | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/arch/powerpc/kernel/exceptions-64e.S
++++ b/arch/powerpc/kernel/exceptions-64e.S
+@@ -735,8 +735,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+ andis. r15,r14,(DBSR_IC|DBSR_BT)@h
+ beq+ 1f
+
++#ifdef CONFIG_RELOCATABLE
++ ld r15,PACATOC(r13)
++ ld r14,interrupt_base_book3e@got(r15)
++ ld r15,__end_interrupts@got(r15)
++#else
+ LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
+ LOAD_REG_IMMEDIATE(r15,__end_interrupts)
++#endif
+ cmpld cr0,r10,r14
+ cmpld cr1,r10,r15
+ blt+ cr0,1f
+@@ -799,8 +805,14 @@ kernel_dbg_exc:
+ andis. r15,r14,(DBSR_IC|DBSR_BT)@h
+ beq+ 1f
+
++#ifdef CONFIG_RELOCATABLE
++ ld r15,PACATOC(r13)
++ ld r14,interrupt_base_book3e@got(r15)
++ ld r15,__end_interrupts@got(r15)
++#else
+ LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
+ LOAD_REG_IMMEDIATE(r15,__end_interrupts)
++#endif
+ cmpld cr0,r10,r14
+ cmpld cr1,r10,r15
+ blt+ cr0,1f
--- /dev/null
+From d93b0ac01a9ce276ec39644be47001873d3d183c Mon Sep 17 00:00:00 2001
+From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
+Date: Tue, 18 Apr 2017 22:08:17 +0530
+Subject: powerpc/book3s/mce: Move add_taint() later in virtual mode
+
+From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
+
+commit d93b0ac01a9ce276ec39644be47001873d3d183c upstream.
+
+machine_check_early() gets called in real mode. The very first time when
+add_taint() is called, it prints a warning which ends up calling opal
+call (that uses OPAL_CALL wrapper) for writing it to console. If we get a
+very first machine check while we are in opal we are doomed. OPAL_CALL
+overwrites the PACASAVEDMSR in r13 and in this case when we are done with
+MCE handling the original opal call will use this new MSR on it's way
+back to opal_return. This usually leads to unexpected behaviour or the
+kernel to panic. Instead move the add_taint() call later in the virtual
+mode where it is safe to call.
+
+This is broken with current FW level. We got lucky so far for not getting
+very first MCE hit while in OPAL. But easily reproducible on Mambo.
+
+Fixes: 27ea2c420cad ("powerpc: Set the correct kernel taint on machine check errors.")
+Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/mce.c | 2 ++
+ arch/powerpc/kernel/traps.c | 4 ++--
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+--- a/arch/powerpc/kernel/mce.c
++++ b/arch/powerpc/kernel/mce.c
+@@ -204,6 +204,8 @@ static void machine_check_process_queued
+ {
+ int index;
+
++ add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
++
+ /*
+ * For now just print it to console.
+ * TODO: log this error event to FSP or nvram.
+--- a/arch/powerpc/kernel/traps.c
++++ b/arch/powerpc/kernel/traps.c
+@@ -297,8 +297,6 @@ long machine_check_early(struct pt_regs
+
+ __this_cpu_inc(irq_stat.mce_exceptions);
+
+- add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
+-
+ if (cur_cpu_spec && cur_cpu_spec->machine_check_early)
+ handled = cur_cpu_spec->machine_check_early(regs);
+ return handled;
+@@ -704,6 +702,8 @@ void machine_check_exception(struct pt_r
+
+ __this_cpu_inc(irq_stat.mce_exceptions);
+
++ add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
++
+ /* See if any machine dependent calls. In theory, we would want
+ * to call the CPU first, and call the ppc_md. one if the CPU
+ * one returns a positive number. However there is existing code
--- /dev/null
+From 68baf692c435339e6295cb470ea5545cbc28160e Mon Sep 17 00:00:00 2001
+From: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
+Date: Mon, 17 Apr 2017 20:21:40 -0400
+Subject: powerpc/pseries: Fix of_node_put() underflow during DLPAR remove
+
+From: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
+
+commit 68baf692c435339e6295cb470ea5545cbc28160e upstream.
+
+Historically struct device_node references were tracked using a kref embedded as
+a struct field. Commit 75b57ecf9d1d ("of: Make device nodes kobjects so they
+show up in sysfs") (Mar 2014) refactored device_nodes to be kobjects such that
+the device tree could by more simply exposed to userspace using sysfs.
+
+Commit 0829f6d1f69e ("of: device_node kobject lifecycle fixes") (Mar 2014)
+followed up these changes to better control the kobject lifecycle and in
+particular the referecne counting via of_node_get(), of_node_put(), and
+of_node_init().
+
+A result of this second commit was that it introduced an of_node_put() call when
+a dynamic node is detached, in of_node_remove(), that removes the initial kobj
+reference created by of_node_init().
+
+Traditionally as the original dynamic device node user the pseries code had
+assumed responsibilty for releasing this final reference in its platform
+specific DLPAR detach code.
+
+This patch fixes a refcount underflow introduced by commit 0829f6d1f6, and
+recently exposed by the upstreaming of the recount API.
+
+Messages like the following are no longer seen in the kernel log with this
+patch following DLPAR remove operations of cpus and pci devices.
+
+ rpadlpar_io: slot PHB 72 removed
+ refcount_t: underflow; use-after-free.
+ ------------[ cut here ]------------
+ WARNING: CPU: 5 PID: 3335 at lib/refcount.c:128 refcount_sub_and_test+0xf4/0x110
+
+Fixes: 0829f6d1f69e ("of: device_node kobject lifecycle fixes")
+Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
+[mpe: Make change log commit references more verbose]
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/platforms/pseries/dlpar.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/arch/powerpc/platforms/pseries/dlpar.c
++++ b/arch/powerpc/platforms/pseries/dlpar.c
+@@ -280,7 +280,6 @@ int dlpar_detach_node(struct device_node
+ if (rc)
+ return rc;
+
+- of_node_put(dn); /* Must decrement the refcount */
+ return 0;
+ }
+
cx231xx-audio-fix-init-error-path.patch
cx231xx-audio-fix-null-deref-at-probe.patch
cx231xx-cards-fix-null-deref-at-probe.patch
+powerpc-book3s-mce-move-add_taint-later-in-virtual-mode.patch
+powerpc-pseries-fix-of_node_put-underflow-during-dlpar-remove.patch
+powerpc-64e-fix-hang-when-debugging-programs-with-relocated-kernel.patch
+arm-dts-at91-sama5d3_xplained-fix-adc-vref.patch
+arm-dts-at91-sama5d3_xplained-not-all-adc-channels-are-available.patch
+arm64-xchg-hazard-against-entire-exchange-variable.patch
+arm64-uaccess-ensure-extension-of-access_ok-addr.patch
+arm64-documentation-document-tagged-pointer-stack-constraints.patch
+xc2028-fix-use-after-free-bug-properly.patch
+mm-huge_memory.c-respect-foll_force-foll_cow-for-thp.patch
+staging-rtl8192e-fix-2-byte-alignment-of-register-bssidr.patch
+staging-rtl8192e-rtl92e_get_eeprom_size-fix-read-size-of-eprom_cmd.patch
+iommu-vt-d-flush-the-iotlb-to-get-rid-of-the-initial-kdump-mappings.patch
+metag-uaccess-fix-access_ok.patch
+metag-uaccess-check-access_ok-in-strncpy_from_user.patch
+stackprotector-increase-the-per-task-stack-canary-s-random-range-from-32-bits-to-64-bits-on-64-bit-platforms.patch
+uwb-fix-device-quirk-on-big-endian-hosts.patch
+genirq-fix-chained-interrupt-data-ordering.patch
--- /dev/null
+From 5ea30e4e58040cfd6434c2f33dc3ea76e2c15b05 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Thu, 4 May 2017 09:32:09 -0400
+Subject: stackprotector: Increase the per-task stack canary's random range from 32 bits to 64 bits on 64-bit platforms
+
+From: Daniel Micay <danielmicay@gmail.com>
+
+commit 5ea30e4e58040cfd6434c2f33dc3ea76e2c15b05 upstream.
+
+The stack canary is an 'unsigned long' and should be fully initialized to
+random data rather than only 32 bits of random data.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+Acked-by: Arjan van de Ven <arjan@linux.intel.com>
+Acked-by: Rik van Riel <riel@redhat.com>
+Acked-by: Kees Cook <keescook@chromium.org>
+Cc: Arjan van Ven <arjan@linux.intel.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: kernel-hardening@lists.openwall.com
+Link: http://lkml.kernel.org/r/20170504133209.3053-1-danielmicay@gmail.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/fork.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -368,7 +368,7 @@ static struct task_struct *dup_task_stru
+ set_task_stack_end_magic(tsk);
+
+ #ifdef CONFIG_CC_STACKPROTECTOR
+- tsk->stack_canary = get_random_int();
++ tsk->stack_canary = get_random_long();
+ #endif
+
+ /*
--- /dev/null
+From 867510bde14e7b7fc6dd0f50b48f6753cfbd227a Mon Sep 17 00:00:00 2001
+From: Malcolm Priestley <tvboxspy@gmail.com>
+Date: Thu, 11 May 2017 18:57:44 +0100
+Subject: staging: rtl8192e: fix 2 byte alignment of register BSSIDR.
+
+From: Malcolm Priestley <tvboxspy@gmail.com>
+
+commit 867510bde14e7b7fc6dd0f50b48f6753cfbd227a upstream.
+
+BSSIDR has two byte alignment on PCI ioremap correct the write
+by swapping to 16 bits first.
+
+This fixes a problem that the device associates fail because
+the filter is not set correctly.
+
+Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c
++++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c
+@@ -97,8 +97,9 @@ void rtl92e_set_reg(struct net_device *d
+
+ switch (variable) {
+ case HW_VAR_BSSID:
+- rtl92e_writel(dev, BSSIDR, ((u32 *)(val))[0]);
+- rtl92e_writew(dev, BSSIDR+2, ((u16 *)(val+2))[0]);
++ /* BSSIDR 2 byte alignment */
++ rtl92e_writew(dev, BSSIDR, *(u16 *)val);
++ rtl92e_writel(dev, BSSIDR + 2, *(u32 *)(val + 2));
+ break;
+
+ case HW_VAR_MEDIA_STATUS:
+@@ -963,8 +964,8 @@ static void _rtl92e_net_update(struct ne
+ rtl92e_config_rate(dev, &rate_config);
+ priv->dot11CurrentPreambleMode = PREAMBLE_AUTO;
+ priv->basic_rate = rate_config &= 0x15f;
+- rtl92e_writel(dev, BSSIDR, ((u32 *)net->bssid)[0]);
+- rtl92e_writew(dev, BSSIDR+4, ((u16 *)net->bssid)[2]);
++ rtl92e_writew(dev, BSSIDR, *(u16 *)net->bssid);
++ rtl92e_writel(dev, BSSIDR + 2, *(u32 *)(net->bssid + 2));
+
+ if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
+ rtl92e_writew(dev, ATIMWND, 2);
--- /dev/null
+From 90be652c9f157d44b9c2803f902a8839796c090d Mon Sep 17 00:00:00 2001
+From: Malcolm Priestley <tvboxspy@gmail.com>
+Date: Thu, 11 May 2017 18:57:45 +0100
+Subject: staging: rtl8192e: rtl92e_get_eeprom_size Fix read size of EPROM_CMD.
+
+From: Malcolm Priestley <tvboxspy@gmail.com>
+
+commit 90be652c9f157d44b9c2803f902a8839796c090d upstream.
+
+EPROM_CMD is 2 byte aligned on PCI map so calling with rtl92e_readl
+will return invalid data so use rtl92e_readw.
+
+The device is unable to select the right eeprom type.
+
+Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c
++++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c
+@@ -627,7 +627,7 @@ void rtl92e_get_eeprom_size(struct net_d
+ struct r8192_priv *priv = rtllib_priv(dev);
+
+ RT_TRACE(COMP_INIT, "===========>%s()\n", __func__);
+- curCR = rtl92e_readl(dev, EPROM_CMD);
++ curCR = rtl92e_readw(dev, EPROM_CMD);
+ RT_TRACE(COMP_INIT, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD,
+ curCR);
+ priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EEPROM_93C56 :
--- /dev/null
+From 41318a2b82f5d5fe1fb408f6d6e0b22aa557111d Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Fri, 12 May 2017 12:06:32 +0200
+Subject: uwb: fix device quirk on big-endian hosts
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 41318a2b82f5d5fe1fb408f6d6e0b22aa557111d upstream.
+
+Add missing endianness conversion when using the USB device-descriptor
+idProduct field to apply a hardware quirk.
+
+Fixes: 1ba47da52712 ("uwb: add the i1480 DFU driver")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/uwb/i1480/dfu/usb.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/uwb/i1480/dfu/usb.c
++++ b/drivers/uwb/i1480/dfu/usb.c
+@@ -341,6 +341,7 @@ error_submit_ep1:
+ static
+ int i1480_usb_probe(struct usb_interface *iface, const struct usb_device_id *id)
+ {
++ struct usb_device *udev = interface_to_usbdev(iface);
+ struct i1480_usb *i1480_usb;
+ struct i1480 *i1480;
+ struct device *dev = &iface->dev;
+@@ -352,8 +353,8 @@ int i1480_usb_probe(struct usb_interface
+ iface->cur_altsetting->desc.bInterfaceNumber);
+ goto error;
+ }
+- if (iface->num_altsetting > 1
+- && interface_to_usbdev(iface)->descriptor.idProduct == 0xbabe) {
++ if (iface->num_altsetting > 1 &&
++ le16_to_cpu(udev->descriptor.idProduct) == 0xbabe) {
+ /* Need altsetting #1 [HW QUIRK] or EP1 won't work */
+ result = usb_set_interface(interface_to_usbdev(iface), 0, 1);
+ if (result < 0)
--- /dev/null
+From 22a1e7783e173ab3d86018eb590107d68df46c11 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Thu, 17 Nov 2016 10:49:31 +0100
+Subject: xc2028: Fix use-after-free bug properly
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 22a1e7783e173ab3d86018eb590107d68df46c11 upstream.
+
+The commit 8dfbcc4351a0 ("[media] xc2028: avoid use after free") tried
+to address the reported use-after-free by clearing the reference.
+
+However, it's clearing the wrong pointer; it sets NULL to
+priv->ctrl.fname, but it's anyway overwritten by the next line
+memcpy(&priv->ctrl, p, sizeof(priv->ctrl)).
+
+OTOH, the actual code accessing the freed string is the strcmp() call
+with priv->fname:
+ if (!firmware_name[0] && p->fname &&
+ priv->fname && strcmp(p->fname, priv->fname))
+ free_firmware(priv);
+
+where priv->fname points to the previous file name, and this was
+already freed by kfree().
+
+For fixing the bug properly, this patch does the following:
+
+- Keep the copy of firmware file name in only priv->fname,
+ priv->ctrl.fname isn't changed;
+- The allocation is done only when the firmware gets loaded;
+- The kfree() is called in free_firmware() commonly
+
+Fixes: commit 8dfbcc4351a0 ('[media] xc2028: avoid use after free')
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/tuners/tuner-xc2028.c | 37 +++++++++++++++---------------------
+ 1 file changed, 16 insertions(+), 21 deletions(-)
+
+--- a/drivers/media/tuners/tuner-xc2028.c
++++ b/drivers/media/tuners/tuner-xc2028.c
+@@ -281,6 +281,14 @@ static void free_firmware(struct xc2028_
+ int i;
+ tuner_dbg("%s called\n", __func__);
+
++ /* free allocated f/w string */
++ if (priv->fname != firmware_name)
++ kfree(priv->fname);
++ priv->fname = NULL;
++
++ priv->state = XC2028_NO_FIRMWARE;
++ memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
++
+ if (!priv->firm)
+ return;
+
+@@ -291,9 +299,6 @@ static void free_firmware(struct xc2028_
+
+ priv->firm = NULL;
+ priv->firm_size = 0;
+- priv->state = XC2028_NO_FIRMWARE;
+-
+- memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
+ }
+
+ static int load_all_firmwares(struct dvb_frontend *fe,
+@@ -884,9 +889,8 @@ read_not_reliable:
+ return 0;
+
+ fail:
+- priv->state = XC2028_NO_FIRMWARE;
++ free_firmware(priv);
+
+- memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
+ if (retry_count < 8) {
+ msleep(50);
+ retry_count++;
+@@ -1332,11 +1336,8 @@ static int xc2028_dvb_release(struct dvb
+ mutex_lock(&xc2028_list_mutex);
+
+ /* only perform final cleanup if this is the last instance */
+- if (hybrid_tuner_report_instance_count(priv) == 1) {
++ if (hybrid_tuner_report_instance_count(priv) == 1)
+ free_firmware(priv);
+- kfree(priv->ctrl.fname);
+- priv->ctrl.fname = NULL;
+- }
+
+ if (priv)
+ hybrid_tuner_release_state(priv);
+@@ -1399,19 +1400,8 @@ static int xc2028_set_config(struct dvb_
+
+ /*
+ * Copy the config data.
+- * For the firmware name, keep a local copy of the string,
+- * in order to avoid troubles during device release.
+ */
+- kfree(priv->ctrl.fname);
+- priv->ctrl.fname = NULL;
+ memcpy(&priv->ctrl, p, sizeof(priv->ctrl));
+- if (p->fname) {
+- priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL);
+- if (priv->ctrl.fname == NULL) {
+- rc = -ENOMEM;
+- goto unlock;
+- }
+- }
+
+ /*
+ * If firmware name changed, frees firmware. As free_firmware will
+@@ -1426,10 +1416,15 @@ static int xc2028_set_config(struct dvb_
+
+ if (priv->state == XC2028_NO_FIRMWARE) {
+ if (!firmware_name[0])
+- priv->fname = priv->ctrl.fname;
++ priv->fname = kstrdup(p->fname, GFP_KERNEL);
+ else
+ priv->fname = firmware_name;
+
++ if (!priv->fname) {
++ rc = -ENOMEM;
++ goto unlock;
++ }
++
+ rc = request_firmware_nowait(THIS_MODULE, 1,
+ priv->fname,
+ priv->i2c_props.adap->dev.parent,