1639 lines
52 KiB
Diff
1639 lines
52 KiB
Diff
diff --git a/Makefile b/Makefile
|
|
index a07a010095bc9..6f3b4e1e9a144 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -1,6 +1,6 @@
|
|
VERSION = 4
|
|
PATCHLEVEL = 9
|
|
-SUBLEVEL = 293
|
|
+SUBLEVEL = 294
|
|
EXTRAVERSION =
|
|
NAME = Roaring Lionus
|
|
|
|
diff --git a/arch/arm/mm/copypage-fa.c b/arch/arm/mm/copypage-fa.c
|
|
index d130a5ece5d55..bf24690ec83af 100644
|
|
--- a/arch/arm/mm/copypage-fa.c
|
|
+++ b/arch/arm/mm/copypage-fa.c
|
|
@@ -17,26 +17,25 @@
|
|
/*
|
|
* Faraday optimised copy_user_page
|
|
*/
|
|
-static void __naked
|
|
-fa_copy_user_page(void *kto, const void *kfrom)
|
|
+static void fa_copy_user_page(void *kto, const void *kfrom)
|
|
{
|
|
- asm("\
|
|
- stmfd sp!, {r4, lr} @ 2\n\
|
|
- mov r2, %0 @ 1\n\
|
|
-1: ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
|
- stmia r0, {r3, r4, ip, lr} @ 4\n\
|
|
- mcr p15, 0, r0, c7, c14, 1 @ 1 clean and invalidate D line\n\
|
|
- add r0, r0, #16 @ 1\n\
|
|
- ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
|
- stmia r0, {r3, r4, ip, lr} @ 4\n\
|
|
- mcr p15, 0, r0, c7, c14, 1 @ 1 clean and invalidate D line\n\
|
|
- add r0, r0, #16 @ 1\n\
|
|
- subs r2, r2, #1 @ 1\n\
|
|
+ int tmp;
|
|
+
|
|
+ asm volatile ("\
|
|
+1: ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
|
+ stmia %0, {r3, r4, ip, lr} @ 4\n\
|
|
+ mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\
|
|
+ add %0, %0, #16 @ 1\n\
|
|
+ ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
|
+ stmia %0, {r3, r4, ip, lr} @ 4\n\
|
|
+ mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\
|
|
+ add %0, %0, #16 @ 1\n\
|
|
+ subs %2, %2, #1 @ 1\n\
|
|
bne 1b @ 1\n\
|
|
- mcr p15, 0, r2, c7, c10, 4 @ 1 drain WB\n\
|
|
- ldmfd sp!, {r4, pc} @ 3"
|
|
- :
|
|
- : "I" (PAGE_SIZE / 32));
|
|
+ mcr p15, 0, %2, c7, c10, 4 @ 1 drain WB"
|
|
+ : "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
|
|
+ : "2" (PAGE_SIZE / 32)
|
|
+ : "r3", "r4", "ip", "lr");
|
|
}
|
|
|
|
void fa_copy_user_highpage(struct page *to, struct page *from,
|
|
diff --git a/arch/arm/mm/copypage-feroceon.c b/arch/arm/mm/copypage-feroceon.c
|
|
index 49ee0c1a72097..cc819732d9b82 100644
|
|
--- a/arch/arm/mm/copypage-feroceon.c
|
|
+++ b/arch/arm/mm/copypage-feroceon.c
|
|
@@ -13,58 +13,56 @@
|
|
#include <linux/init.h>
|
|
#include <linux/highmem.h>
|
|
|
|
-static void __naked
|
|
-feroceon_copy_user_page(void *kto, const void *kfrom)
|
|
+static void feroceon_copy_user_page(void *kto, const void *kfrom)
|
|
{
|
|
- asm("\
|
|
- stmfd sp!, {r4-r9, lr} \n\
|
|
- mov ip, %2 \n\
|
|
-1: mov lr, r1 \n\
|
|
- ldmia r1!, {r2 - r9} \n\
|
|
- pld [lr, #32] \n\
|
|
- pld [lr, #64] \n\
|
|
- pld [lr, #96] \n\
|
|
- pld [lr, #128] \n\
|
|
- pld [lr, #160] \n\
|
|
- pld [lr, #192] \n\
|
|
- pld [lr, #224] \n\
|
|
- stmia r0, {r2 - r9} \n\
|
|
- ldmia r1!, {r2 - r9} \n\
|
|
- mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
|
- add r0, r0, #32 \n\
|
|
- stmia r0, {r2 - r9} \n\
|
|
- ldmia r1!, {r2 - r9} \n\
|
|
- mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
|
- add r0, r0, #32 \n\
|
|
- stmia r0, {r2 - r9} \n\
|
|
- ldmia r1!, {r2 - r9} \n\
|
|
- mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
|
- add r0, r0, #32 \n\
|
|
- stmia r0, {r2 - r9} \n\
|
|
- ldmia r1!, {r2 - r9} \n\
|
|
- mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
|
- add r0, r0, #32 \n\
|
|
- stmia r0, {r2 - r9} \n\
|
|
- ldmia r1!, {r2 - r9} \n\
|
|
- mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
|
- add r0, r0, #32 \n\
|
|
- stmia r0, {r2 - r9} \n\
|
|
- ldmia r1!, {r2 - r9} \n\
|
|
- mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
|
- add r0, r0, #32 \n\
|
|
- stmia r0, {r2 - r9} \n\
|
|
- ldmia r1!, {r2 - r9} \n\
|
|
- mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
|
- add r0, r0, #32 \n\
|
|
- stmia r0, {r2 - r9} \n\
|
|
- subs ip, ip, #(32 * 8) \n\
|
|
- mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
|
- add r0, r0, #32 \n\
|
|
+ int tmp;
|
|
+
|
|
+ asm volatile ("\
|
|
+1: ldmia %1!, {r2 - r7, ip, lr} \n\
|
|
+ pld [%1, #0] \n\
|
|
+ pld [%1, #32] \n\
|
|
+ pld [%1, #64] \n\
|
|
+ pld [%1, #96] \n\
|
|
+ pld [%1, #128] \n\
|
|
+ pld [%1, #160] \n\
|
|
+ pld [%1, #192] \n\
|
|
+ stmia %0, {r2 - r7, ip, lr} \n\
|
|
+ ldmia %1!, {r2 - r7, ip, lr} \n\
|
|
+ mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
|
+ add %0, %0, #32 \n\
|
|
+ stmia %0, {r2 - r7, ip, lr} \n\
|
|
+ ldmia %1!, {r2 - r7, ip, lr} \n\
|
|
+ mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
|
+ add %0, %0, #32 \n\
|
|
+ stmia %0, {r2 - r7, ip, lr} \n\
|
|
+ ldmia %1!, {r2 - r7, ip, lr} \n\
|
|
+ mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
|
+ add %0, %0, #32 \n\
|
|
+ stmia %0, {r2 - r7, ip, lr} \n\
|
|
+ ldmia %1!, {r2 - r7, ip, lr} \n\
|
|
+ mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
|
+ add %0, %0, #32 \n\
|
|
+ stmia %0, {r2 - r7, ip, lr} \n\
|
|
+ ldmia %1!, {r2 - r7, ip, lr} \n\
|
|
+ mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
|
+ add %0, %0, #32 \n\
|
|
+ stmia %0, {r2 - r7, ip, lr} \n\
|
|
+ ldmia %1!, {r2 - r7, ip, lr} \n\
|
|
+ mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
|
+ add %0, %0, #32 \n\
|
|
+ stmia %0, {r2 - r7, ip, lr} \n\
|
|
+ ldmia %1!, {r2 - r7, ip, lr} \n\
|
|
+ mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
|
+ add %0, %0, #32 \n\
|
|
+ stmia %0, {r2 - r7, ip, lr} \n\
|
|
+ subs %2, %2, #(32 * 8) \n\
|
|
+ mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
|
+ add %0, %0, #32 \n\
|
|
bne 1b \n\
|
|
- mcr p15, 0, ip, c7, c10, 4 @ drain WB\n\
|
|
- ldmfd sp!, {r4-r9, pc}"
|
|
- :
|
|
- : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE));
|
|
+ mcr p15, 0, %2, c7, c10, 4 @ drain WB"
|
|
+ : "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
|
|
+ : "2" (PAGE_SIZE)
|
|
+ : "r2", "r3", "r4", "r5", "r6", "r7", "ip", "lr");
|
|
}
|
|
|
|
void feroceon_copy_user_highpage(struct page *to, struct page *from,
|
|
diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c
|
|
index 1267e64133b92..db624170854a0 100644
|
|
--- a/arch/arm/mm/copypage-v4mc.c
|
|
+++ b/arch/arm/mm/copypage-v4mc.c
|
|
@@ -40,12 +40,11 @@ static DEFINE_RAW_SPINLOCK(minicache_lock);
|
|
* instruction. If your processor does not supply this, you have to write your
|
|
* own copy_user_highpage that does the right thing.
|
|
*/
|
|
-static void __naked
|
|
-mc_copy_user_page(void *from, void *to)
|
|
+static void mc_copy_user_page(void *from, void *to)
|
|
{
|
|
- asm volatile(
|
|
- "stmfd sp!, {r4, lr} @ 2\n\
|
|
- mov r4, %2 @ 1\n\
|
|
+ int tmp;
|
|
+
|
|
+ asm volatile ("\
|
|
ldmia %0!, {r2, r3, ip, lr} @ 4\n\
|
|
1: mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\
|
|
stmia %1!, {r2, r3, ip, lr} @ 4\n\
|
|
@@ -55,13 +54,13 @@ mc_copy_user_page(void *from, void *to)
|
|
mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\
|
|
stmia %1!, {r2, r3, ip, lr} @ 4\n\
|
|
ldmia %0!, {r2, r3, ip, lr} @ 4\n\
|
|
- subs r4, r4, #1 @ 1\n\
|
|
+ subs %2, %2, #1 @ 1\n\
|
|
stmia %1!, {r2, r3, ip, lr} @ 4\n\
|
|
ldmneia %0!, {r2, r3, ip, lr} @ 4\n\
|
|
- bne 1b @ 1\n\
|
|
- ldmfd sp!, {r4, pc} @ 3"
|
|
- :
|
|
- : "r" (from), "r" (to), "I" (PAGE_SIZE / 64));
|
|
+ bne 1b @ "
|
|
+ : "+&r" (from), "+&r" (to), "=&r" (tmp)
|
|
+ : "2" (PAGE_SIZE / 64)
|
|
+ : "r2", "r3", "ip", "lr");
|
|
}
|
|
|
|
void v4_mc_copy_user_highpage(struct page *to, struct page *from,
|
|
diff --git a/arch/arm/mm/copypage-v4wb.c b/arch/arm/mm/copypage-v4wb.c
|
|
index 067d0fdd630c1..cd3e165afeede 100644
|
|
--- a/arch/arm/mm/copypage-v4wb.c
|
|
+++ b/arch/arm/mm/copypage-v4wb.c
|
|
@@ -22,29 +22,28 @@
|
|
* instruction. If your processor does not supply this, you have to write your
|
|
* own copy_user_highpage that does the right thing.
|
|
*/
|
|
-static void __naked
|
|
-v4wb_copy_user_page(void *kto, const void *kfrom)
|
|
+static void v4wb_copy_user_page(void *kto, const void *kfrom)
|
|
{
|
|
- asm("\
|
|
- stmfd sp!, {r4, lr} @ 2\n\
|
|
- mov r2, %2 @ 1\n\
|
|
- ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
|
-1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\
|
|
- stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
|
- ldmia r1!, {r3, r4, ip, lr} @ 4+1\n\
|
|
- stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
|
- ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
|
- mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\
|
|
- stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
|
- ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
|
- subs r2, r2, #1 @ 1\n\
|
|
- stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
|
- ldmneia r1!, {r3, r4, ip, lr} @ 4\n\
|
|
+ int tmp;
|
|
+
|
|
+ asm volatile ("\
|
|
+ ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
|
+1: mcr p15, 0, %0, c7, c6, 1 @ 1 invalidate D line\n\
|
|
+ stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
|
+ ldmia %1!, {r3, r4, ip, lr} @ 4+1\n\
|
|
+ stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
|
+ ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
|
+ mcr p15, 0, %0, c7, c6, 1 @ 1 invalidate D line\n\
|
|
+ stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
|
+ ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
|
+ subs %2, %2, #1 @ 1\n\
|
|
+ stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
|
+ ldmneia %1!, {r3, r4, ip, lr} @ 4\n\
|
|
bne 1b @ 1\n\
|
|
- mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB\n\
|
|
- ldmfd sp!, {r4, pc} @ 3"
|
|
- :
|
|
- : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64));
|
|
+ mcr p15, 0, %1, c7, c10, 4 @ 1 drain WB"
|
|
+ : "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
|
|
+ : "2" (PAGE_SIZE / 64)
|
|
+ : "r3", "r4", "ip", "lr");
|
|
}
|
|
|
|
void v4wb_copy_user_highpage(struct page *to, struct page *from,
|
|
diff --git a/arch/arm/mm/copypage-v4wt.c b/arch/arm/mm/copypage-v4wt.c
|
|
index b85c5da2e510e..8614572e1296b 100644
|
|
--- a/arch/arm/mm/copypage-v4wt.c
|
|
+++ b/arch/arm/mm/copypage-v4wt.c
|
|
@@ -20,27 +20,26 @@
|
|
* dirty data in the cache. However, we do have to ensure that
|
|
* subsequent reads are up to date.
|
|
*/
|
|
-static void __naked
|
|
-v4wt_copy_user_page(void *kto, const void *kfrom)
|
|
+static void v4wt_copy_user_page(void *kto, const void *kfrom)
|
|
{
|
|
- asm("\
|
|
- stmfd sp!, {r4, lr} @ 2\n\
|
|
- mov r2, %2 @ 1\n\
|
|
- ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
|
-1: stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
|
- ldmia r1!, {r3, r4, ip, lr} @ 4+1\n\
|
|
- stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
|
- ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
|
- stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
|
- ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
|
- subs r2, r2, #1 @ 1\n\
|
|
- stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
|
- ldmneia r1!, {r3, r4, ip, lr} @ 4\n\
|
|
+ int tmp;
|
|
+
|
|
+ asm volatile ("\
|
|
+ ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
|
+1: stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
|
+ ldmia %1!, {r3, r4, ip, lr} @ 4+1\n\
|
|
+ stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
|
+ ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
|
+ stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
|
+ ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
|
+ subs %2, %2, #1 @ 1\n\
|
|
+ stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
|
+ ldmneia %1!, {r3, r4, ip, lr} @ 4\n\
|
|
bne 1b @ 1\n\
|
|
- mcr p15, 0, r2, c7, c7, 0 @ flush ID cache\n\
|
|
- ldmfd sp!, {r4, pc} @ 3"
|
|
- :
|
|
- : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64));
|
|
+ mcr p15, 0, %2, c7, c7, 0 @ flush ID cache"
|
|
+ : "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
|
|
+ : "2" (PAGE_SIZE / 64)
|
|
+ : "r3", "r4", "ip", "lr");
|
|
}
|
|
|
|
void v4wt_copy_user_highpage(struct page *to, struct page *from,
|
|
diff --git a/arch/arm/mm/copypage-xsc3.c b/arch/arm/mm/copypage-xsc3.c
|
|
index 03a2042aced5f..55cbc3a89d858 100644
|
|
--- a/arch/arm/mm/copypage-xsc3.c
|
|
+++ b/arch/arm/mm/copypage-xsc3.c
|
|
@@ -21,53 +21,46 @@
|
|
|
|
/*
|
|
* XSC3 optimised copy_user_highpage
|
|
- * r0 = destination
|
|
- * r1 = source
|
|
*
|
|
* The source page may have some clean entries in the cache already, but we
|
|
* can safely ignore them - break_cow() will flush them out of the cache
|
|
* if we eventually end up using our copied page.
|
|
*
|
|
*/
|
|
-static void __naked
|
|
-xsc3_mc_copy_user_page(void *kto, const void *kfrom)
|
|
+static void xsc3_mc_copy_user_page(void *kto, const void *kfrom)
|
|
{
|
|
- asm("\
|
|
- stmfd sp!, {r4, r5, lr} \n\
|
|
- mov lr, %2 \n\
|
|
- \n\
|
|
- pld [r1, #0] \n\
|
|
- pld [r1, #32] \n\
|
|
-1: pld [r1, #64] \n\
|
|
- pld [r1, #96] \n\
|
|
+ int tmp;
|
|
+
|
|
+ asm volatile ("\
|
|
+ pld [%1, #0] \n\
|
|
+ pld [%1, #32] \n\
|
|
+1: pld [%1, #64] \n\
|
|
+ pld [%1, #96] \n\
|
|
\n\
|
|
-2: ldrd r2, [r1], #8 \n\
|
|
- mov ip, r0 \n\
|
|
- ldrd r4, [r1], #8 \n\
|
|
- mcr p15, 0, ip, c7, c6, 1 @ invalidate\n\
|
|
- strd r2, [r0], #8 \n\
|
|
- ldrd r2, [r1], #8 \n\
|
|
- strd r4, [r0], #8 \n\
|
|
- ldrd r4, [r1], #8 \n\
|
|
- strd r2, [r0], #8 \n\
|
|
- strd r4, [r0], #8 \n\
|
|
- ldrd r2, [r1], #8 \n\
|
|
- mov ip, r0 \n\
|
|
- ldrd r4, [r1], #8 \n\
|
|
- mcr p15, 0, ip, c7, c6, 1 @ invalidate\n\
|
|
- strd r2, [r0], #8 \n\
|
|
- ldrd r2, [r1], #8 \n\
|
|
- subs lr, lr, #1 \n\
|
|
- strd r4, [r0], #8 \n\
|
|
- ldrd r4, [r1], #8 \n\
|
|
- strd r2, [r0], #8 \n\
|
|
- strd r4, [r0], #8 \n\
|
|
+2: ldrd r2, [%1], #8 \n\
|
|
+ ldrd r4, [%1], #8 \n\
|
|
+ mcr p15, 0, %0, c7, c6, 1 @ invalidate\n\
|
|
+ strd r2, [%0], #8 \n\
|
|
+ ldrd r2, [%1], #8 \n\
|
|
+ strd r4, [%0], #8 \n\
|
|
+ ldrd r4, [%1], #8 \n\
|
|
+ strd r2, [%0], #8 \n\
|
|
+ strd r4, [%0], #8 \n\
|
|
+ ldrd r2, [%1], #8 \n\
|
|
+ ldrd r4, [%1], #8 \n\
|
|
+ mcr p15, 0, %0, c7, c6, 1 @ invalidate\n\
|
|
+ strd r2, [%0], #8 \n\
|
|
+ ldrd r2, [%1], #8 \n\
|
|
+ subs %2, %2, #1 \n\
|
|
+ strd r4, [%0], #8 \n\
|
|
+ ldrd r4, [%1], #8 \n\
|
|
+ strd r2, [%0], #8 \n\
|
|
+ strd r4, [%0], #8 \n\
|
|
bgt 1b \n\
|
|
- beq 2b \n\
|
|
- \n\
|
|
- ldmfd sp!, {r4, r5, pc}"
|
|
- :
|
|
- : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64 - 1));
|
|
+ beq 2b "
|
|
+ : "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
|
|
+ : "2" (PAGE_SIZE / 64 - 1)
|
|
+ : "r2", "r3", "r4", "r5");
|
|
}
|
|
|
|
void xsc3_mc_copy_user_highpage(struct page *to, struct page *from,
|
|
@@ -85,8 +78,6 @@ void xsc3_mc_copy_user_highpage(struct page *to, struct page *from,
|
|
|
|
/*
|
|
* XScale optimised clear_user_page
|
|
- * r0 = destination
|
|
- * r1 = virtual user address of ultimate destination page
|
|
*/
|
|
void xsc3_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
|
|
{
|
|
diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c
|
|
index 0fb85025344d9..c775d4b7adb08 100644
|
|
--- a/arch/arm/mm/copypage-xscale.c
|
|
+++ b/arch/arm/mm/copypage-xscale.c
|
|
@@ -36,52 +36,51 @@ static DEFINE_RAW_SPINLOCK(minicache_lock);
|
|
* Dcache aliasing issue. The writes will be forwarded to the write buffer,
|
|
* and merged as appropriate.
|
|
*/
|
|
-static void __naked
|
|
-mc_copy_user_page(void *from, void *to)
|
|
+static void mc_copy_user_page(void *from, void *to)
|
|
{
|
|
+ int tmp;
|
|
+
|
|
/*
|
|
* Strangely enough, best performance is achieved
|
|
* when prefetching destination as well. (NP)
|
|
*/
|
|
- asm volatile(
|
|
- "stmfd sp!, {r4, r5, lr} \n\
|
|
- mov lr, %2 \n\
|
|
- pld [r0, #0] \n\
|
|
- pld [r0, #32] \n\
|
|
- pld [r1, #0] \n\
|
|
- pld [r1, #32] \n\
|
|
-1: pld [r0, #64] \n\
|
|
- pld [r0, #96] \n\
|
|
- pld [r1, #64] \n\
|
|
- pld [r1, #96] \n\
|
|
-2: ldrd r2, [r0], #8 \n\
|
|
- ldrd r4, [r0], #8 \n\
|
|
- mov ip, r1 \n\
|
|
- strd r2, [r1], #8 \n\
|
|
- ldrd r2, [r0], #8 \n\
|
|
- strd r4, [r1], #8 \n\
|
|
- ldrd r4, [r0], #8 \n\
|
|
- strd r2, [r1], #8 \n\
|
|
- strd r4, [r1], #8 \n\
|
|
+ asm volatile ("\
|
|
+ pld [%0, #0] \n\
|
|
+ pld [%0, #32] \n\
|
|
+ pld [%1, #0] \n\
|
|
+ pld [%1, #32] \n\
|
|
+1: pld [%0, #64] \n\
|
|
+ pld [%0, #96] \n\
|
|
+ pld [%1, #64] \n\
|
|
+ pld [%1, #96] \n\
|
|
+2: ldrd r2, [%0], #8 \n\
|
|
+ ldrd r4, [%0], #8 \n\
|
|
+ mov ip, %1 \n\
|
|
+ strd r2, [%1], #8 \n\
|
|
+ ldrd r2, [%0], #8 \n\
|
|
+ strd r4, [%1], #8 \n\
|
|
+ ldrd r4, [%0], #8 \n\
|
|
+ strd r2, [%1], #8 \n\
|
|
+ strd r4, [%1], #8 \n\
|
|
mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
|
|
- ldrd r2, [r0], #8 \n\
|
|
+ ldrd r2, [%0], #8 \n\
|
|
mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
|
|
- ldrd r4, [r0], #8 \n\
|
|
- mov ip, r1 \n\
|
|
- strd r2, [r1], #8 \n\
|
|
- ldrd r2, [r0], #8 \n\
|
|
- strd r4, [r1], #8 \n\
|
|
- ldrd r4, [r0], #8 \n\
|
|
- strd r2, [r1], #8 \n\
|
|
- strd r4, [r1], #8 \n\
|
|
+ ldrd r4, [%0], #8 \n\
|
|
+ mov ip, %1 \n\
|
|
+ strd r2, [%1], #8 \n\
|
|
+ ldrd r2, [%0], #8 \n\
|
|
+ strd r4, [%1], #8 \n\
|
|
+ ldrd r4, [%0], #8 \n\
|
|
+ strd r2, [%1], #8 \n\
|
|
+ strd r4, [%1], #8 \n\
|
|
mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
|
|
- subs lr, lr, #1 \n\
|
|
+ subs %2, %2, #1 \n\
|
|
mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
|
|
bgt 1b \n\
|
|
- beq 2b \n\
|
|
- ldmfd sp!, {r4, r5, pc} "
|
|
- :
|
|
- : "r" (from), "r" (to), "I" (PAGE_SIZE / 64 - 1));
|
|
+ beq 2b "
|
|
+ : "+&r" (from), "+&r" (to), "=&r" (tmp)
|
|
+ : "2" (PAGE_SIZE / 64 - 1)
|
|
+ : "r2", "r3", "r4", "r5", "ip");
|
|
}
|
|
|
|
void xscale_mc_copy_user_highpage(struct page *to, struct page *from,
|
|
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
|
|
index df58e7d793f52..d420597b0d2b4 100644
|
|
--- a/drivers/block/xen-blkfront.c
|
|
+++ b/drivers/block/xen-blkfront.c
|
|
@@ -1555,9 +1555,12 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
|
struct blkfront_ring_info *rinfo = (struct blkfront_ring_info *)dev_id;
|
|
struct blkfront_info *info = rinfo->dev_info;
|
|
int error;
|
|
+ unsigned int eoiflag = XEN_EOI_FLAG_SPURIOUS;
|
|
|
|
- if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
|
|
+ if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) {
|
|
+ xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS);
|
|
return IRQ_HANDLED;
|
|
+ }
|
|
|
|
spin_lock_irqsave(&rinfo->ring_lock, flags);
|
|
again:
|
|
@@ -1573,6 +1576,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
|
unsigned long id;
|
|
unsigned int op;
|
|
|
|
+ eoiflag = 0;
|
|
+
|
|
RING_COPY_RESPONSE(&rinfo->ring, i, &bret);
|
|
id = bret.id;
|
|
|
|
@@ -1684,6 +1689,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
|
|
|
spin_unlock_irqrestore(&rinfo->ring_lock, flags);
|
|
|
|
+ xen_irq_lateeoi(irq, eoiflag);
|
|
+
|
|
return IRQ_HANDLED;
|
|
|
|
err:
|
|
@@ -1691,6 +1698,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
|
|
|
spin_unlock_irqrestore(&rinfo->ring_lock, flags);
|
|
|
|
+ /* No EOI in order to avoid further interrupts. */
|
|
+
|
|
pr_alert("%s disabled for further use\n", info->gd->disk_name);
|
|
return IRQ_HANDLED;
|
|
}
|
|
@@ -1730,8 +1739,8 @@ static int setup_blkring(struct xenbus_device *dev,
|
|
if (err)
|
|
goto fail;
|
|
|
|
- err = bind_evtchn_to_irqhandler(rinfo->evtchn, blkif_interrupt, 0,
|
|
- "blkif", rinfo);
|
|
+ err = bind_evtchn_to_irqhandler_lateeoi(rinfo->evtchn, blkif_interrupt,
|
|
+ 0, "blkif", rinfo);
|
|
if (err <= 0) {
|
|
xenbus_dev_fatal(dev, err,
|
|
"bind_evtchn_to_irqhandler failed");
|
|
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
|
|
index 15f2e7025b78e..1d5510cb6db4e 100644
|
|
--- a/drivers/char/agp/parisc-agp.c
|
|
+++ b/drivers/char/agp/parisc-agp.c
|
|
@@ -285,7 +285,7 @@ agp_ioc_init(void __iomem *ioc_regs)
|
|
return 0;
|
|
}
|
|
|
|
-static int
|
|
+static int __init
|
|
lba_find_capability(int cap)
|
|
{
|
|
struct _parisc_agp_info *info = &parisc_agp_info;
|
|
@@ -370,7 +370,7 @@ fail:
|
|
return error;
|
|
}
|
|
|
|
-static int
|
|
+static int __init
|
|
find_quicksilver(struct device *dev, void *data)
|
|
{
|
|
struct parisc_device **lba = data;
|
|
@@ -382,7 +382,7 @@ find_quicksilver(struct device *dev, void *data)
|
|
return 0;
|
|
}
|
|
|
|
-static int
|
|
+static int __init
|
|
parisc_agp_init(void)
|
|
{
|
|
extern struct sba_device *sba_list;
|
|
diff --git a/drivers/firmware/scpi_pm_domain.c b/drivers/firmware/scpi_pm_domain.c
|
|
index f395dec271131..a6e62a793fbe6 100644
|
|
--- a/drivers/firmware/scpi_pm_domain.c
|
|
+++ b/drivers/firmware/scpi_pm_domain.c
|
|
@@ -27,7 +27,6 @@ struct scpi_pm_domain {
|
|
struct generic_pm_domain genpd;
|
|
struct scpi_ops *ops;
|
|
u32 domain;
|
|
- char name[30];
|
|
};
|
|
|
|
/*
|
|
@@ -121,8 +120,13 @@ static int scpi_pm_domain_probe(struct platform_device *pdev)
|
|
|
|
scpi_pd->domain = i;
|
|
scpi_pd->ops = scpi_ops;
|
|
- sprintf(scpi_pd->name, "%s.%d", np->name, i);
|
|
- scpi_pd->genpd.name = scpi_pd->name;
|
|
+ scpi_pd->genpd.name = devm_kasprintf(dev, GFP_KERNEL,
|
|
+ "%s.%d", np->name, i);
|
|
+ if (!scpi_pd->genpd.name) {
|
|
+ dev_err(dev, "Failed to allocate genpd name:%s.%d\n",
|
|
+ np->name, i);
|
|
+ continue;
|
|
+ }
|
|
scpi_pd->genpd.power_off = scpi_pd_power_off;
|
|
scpi_pd->genpd.power_on = scpi_pd_power_on;
|
|
|
|
diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c
|
|
index 34704b0451b49..d19ad92eede95 100644
|
|
--- a/drivers/hwmon/dell-smm-hwmon.c
|
|
+++ b/drivers/hwmon/dell-smm-hwmon.c
|
|
@@ -578,15 +578,18 @@ static const struct file_operations i8k_fops = {
|
|
.unlocked_ioctl = i8k_ioctl,
|
|
};
|
|
|
|
+static struct proc_dir_entry *entry;
|
|
+
|
|
static void __init i8k_init_procfs(void)
|
|
{
|
|
/* Register the proc entry */
|
|
- proc_create("i8k", 0, NULL, &i8k_fops);
|
|
+ entry = proc_create("i8k", 0, NULL, &i8k_fops);
|
|
}
|
|
|
|
static void __exit i8k_exit_procfs(void)
|
|
{
|
|
- remove_proc_entry("i8k", NULL);
|
|
+ if (entry)
|
|
+ remove_proc_entry("i8k", NULL);
|
|
}
|
|
|
|
#else
|
|
diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c
|
|
index df220666d6274..b4f8cd7dc8b74 100644
|
|
--- a/drivers/i2c/busses/i2c-rk3x.c
|
|
+++ b/drivers/i2c/busses/i2c-rk3x.c
|
|
@@ -424,8 +424,8 @@ static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd)
|
|
if (!(ipd & REG_INT_MBRF))
|
|
return;
|
|
|
|
- /* ack interrupt */
|
|
- i2c_writel(i2c, REG_INT_MBRF, REG_IPD);
|
|
+ /* ack interrupt (read also produces a spurious START flag, clear it too) */
|
|
+ i2c_writel(i2c, REG_INT_MBRF | REG_INT_START, REG_IPD);
|
|
|
|
/* Can only handle a maximum of 32 bytes at a time */
|
|
if (len > 32)
|
|
diff --git a/drivers/input/touchscreen/of_touchscreen.c b/drivers/input/touchscreen/of_touchscreen.c
|
|
index 8d7f9c8f2771c..db499ef6ccff4 100644
|
|
--- a/drivers/input/touchscreen/of_touchscreen.c
|
|
+++ b/drivers/input/touchscreen/of_touchscreen.c
|
|
@@ -79,8 +79,8 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch,
|
|
data_present = touchscreen_get_prop_u32(dev, "touchscreen-size-x",
|
|
input_abs_get_max(input,
|
|
axis) + 1,
|
|
- &maximum) |
|
|
- touchscreen_get_prop_u32(dev, "touchscreen-fuzz-x",
|
|
+ &maximum);
|
|
+ data_present |= touchscreen_get_prop_u32(dev, "touchscreen-fuzz-x",
|
|
input_abs_get_fuzz(input, axis),
|
|
&fuzz);
|
|
if (data_present)
|
|
@@ -90,8 +90,8 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch,
|
|
data_present = touchscreen_get_prop_u32(dev, "touchscreen-size-y",
|
|
input_abs_get_max(input,
|
|
axis) + 1,
|
|
- &maximum) |
|
|
- touchscreen_get_prop_u32(dev, "touchscreen-fuzz-y",
|
|
+ &maximum);
|
|
+ data_present |= touchscreen_get_prop_u32(dev, "touchscreen-fuzz-y",
|
|
input_abs_get_fuzz(input, axis),
|
|
&fuzz);
|
|
if (data_present)
|
|
@@ -101,11 +101,11 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch,
|
|
data_present = touchscreen_get_prop_u32(dev,
|
|
"touchscreen-max-pressure",
|
|
input_abs_get_max(input, axis),
|
|
- &maximum) |
|
|
- touchscreen_get_prop_u32(dev,
|
|
- "touchscreen-fuzz-pressure",
|
|
- input_abs_get_fuzz(input, axis),
|
|
- &fuzz);
|
|
+ &maximum);
|
|
+ data_present |= touchscreen_get_prop_u32(dev,
|
|
+ "touchscreen-fuzz-pressure",
|
|
+ input_abs_get_fuzz(input, axis),
|
|
+ &fuzz);
|
|
if (data_present)
|
|
touchscreen_set_params(input, axis, maximum, fuzz);
|
|
|
|
diff --git a/drivers/md/persistent-data/dm-btree-remove.c b/drivers/md/persistent-data/dm-btree-remove.c
|
|
index 9e4d1212f4c16..63f2baed3c8a6 100644
|
|
--- a/drivers/md/persistent-data/dm-btree-remove.c
|
|
+++ b/drivers/md/persistent-data/dm-btree-remove.c
|
|
@@ -423,9 +423,9 @@ static int rebalance_children(struct shadow_spine *s,
|
|
|
|
memcpy(n, dm_block_data(child),
|
|
dm_bm_block_size(dm_tm_get_bm(info->tm)));
|
|
- dm_tm_unlock(info->tm, child);
|
|
|
|
dm_tm_dec(info->tm, dm_block_location(child));
|
|
+ dm_tm_unlock(info->tm, child);
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
|
|
index 5d67dbdd943dc..98392a069f2b2 100644
|
|
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
|
|
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
|
|
@@ -90,9 +90,13 @@ static inline void tdma_port_write_desc_addr(struct bcm_sysport_priv *priv,
|
|
struct dma_desc *desc,
|
|
unsigned int port)
|
|
{
|
|
+ unsigned long desc_flags;
|
|
+
|
|
/* Ports are latched, so write upper address first */
|
|
+ spin_lock_irqsave(&priv->desc_lock, desc_flags);
|
|
tdma_writel(priv, desc->addr_status_len, TDMA_WRITE_PORT_HI(port));
|
|
tdma_writel(priv, desc->addr_lo, TDMA_WRITE_PORT_LO(port));
|
|
+ spin_unlock_irqrestore(&priv->desc_lock, desc_flags);
|
|
}
|
|
|
|
/* Ethtool operations */
|
|
@@ -1587,6 +1591,7 @@ static int bcm_sysport_open(struct net_device *dev)
|
|
}
|
|
|
|
/* Initialize both hardware and software ring */
|
|
+ spin_lock_init(&priv->desc_lock);
|
|
for (i = 0; i < dev->num_tx_queues; i++) {
|
|
ret = bcm_sysport_init_tx_ring(priv, i);
|
|
if (ret) {
|
|
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.h b/drivers/net/ethernet/broadcom/bcmsysport.h
|
|
index 0d3444f1d78a0..1cf5af2b11e1f 100644
|
|
--- a/drivers/net/ethernet/broadcom/bcmsysport.h
|
|
+++ b/drivers/net/ethernet/broadcom/bcmsysport.h
|
|
@@ -660,6 +660,7 @@ struct bcm_sysport_priv {
|
|
int wol_irq;
|
|
|
|
/* Transmit rings */
|
|
+ spinlock_t desc_lock;
|
|
struct bcm_sysport_tx_ring tx_rings[TDMA_NUM_RINGS];
|
|
|
|
/* Receive queue */
|
|
diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c
|
|
index 5428e39fa4e5c..7587a8f98619a 100644
|
|
--- a/drivers/net/ethernet/intel/igbvf/netdev.c
|
|
+++ b/drivers/net/ethernet/intel/igbvf/netdev.c
|
|
@@ -2846,6 +2846,7 @@ static int igbvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
return 0;
|
|
|
|
err_hw_init:
|
|
+ netif_napi_del(&adapter->rx_ring->napi);
|
|
kfree(adapter->tx_ring);
|
|
kfree(adapter->rx_ring);
|
|
err_sw_init:
|
|
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
|
|
index 8466f3874a285..5029db8835d7d 100644
|
|
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
|
|
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
|
|
@@ -2597,6 +2597,9 @@ static s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw)
|
|
/* flush pending Tx transactions */
|
|
ixgbe_clear_tx_pending(hw);
|
|
|
|
+ /* set MDIO speed before talking to the PHY in case it's the 1st time */
|
|
+ ixgbe_set_mdio_speed(hw);
|
|
+
|
|
/* PHY ops must be identified and initialized prior to reset */
|
|
|
|
/* Identify PHY and related function pointers */
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
|
|
index 410a36c982419..1569300844f0c 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
|
|
@@ -620,7 +620,7 @@ void __init mlx4_en_init_ptys2ethtool_map(void)
|
|
MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_T, SPEED_1000,
|
|
ETHTOOL_LINK_MODE_1000baseT_Full_BIT);
|
|
MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_CX_SGMII, SPEED_1000,
|
|
- ETHTOOL_LINK_MODE_1000baseKX_Full_BIT);
|
|
+ ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
|
|
MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_KX, SPEED_1000,
|
|
ETHTOOL_LINK_MODE_1000baseKX_Full_BIT);
|
|
MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_T, SPEED_10000,
|
|
@@ -632,9 +632,9 @@ void __init mlx4_en_init_ptys2ethtool_map(void)
|
|
MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_KR, SPEED_10000,
|
|
ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
|
|
MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_CR, SPEED_10000,
|
|
- ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
|
|
+ ETHTOOL_LINK_MODE_10000baseCR_Full_BIT);
|
|
MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_SR, SPEED_10000,
|
|
- ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
|
|
+ ETHTOOL_LINK_MODE_10000baseSR_Full_BIT);
|
|
MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_20GBASE_KR2, SPEED_20000,
|
|
ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT,
|
|
ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT);
|
|
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
|
|
index bce898ad6e96f..7752cc09a1da5 100644
|
|
--- a/drivers/net/usb/lan78xx.c
|
|
+++ b/drivers/net/usb/lan78xx.c
|
|
@@ -865,11 +865,9 @@ static int lan78xx_read_otp(struct lan78xx_net *dev, u32 offset,
|
|
ret = lan78xx_read_raw_otp(dev, 0, 1, &sig);
|
|
|
|
if (ret == 0) {
|
|
- if (sig == OTP_INDICATOR_1)
|
|
- offset = offset;
|
|
- else if (sig == OTP_INDICATOR_2)
|
|
+ if (sig == OTP_INDICATOR_2)
|
|
offset += 0x100;
|
|
- else
|
|
+ else if (sig != OTP_INDICATOR_1)
|
|
ret = -EINVAL;
|
|
if (!ret)
|
|
ret = lan78xx_read_raw_otp(dev, offset, length, data);
|
|
diff --git a/drivers/net/wireless/marvell/mwifiex/cmdevt.c b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
|
|
index 53477280f39c2..7c848852aa094 100644
|
|
--- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c
|
|
+++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
|
|
@@ -321,9 +321,9 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
|
|
|
|
adapter->seq_num++;
|
|
sleep_cfm_buf->seq_num =
|
|
- cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO
|
|
+ cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO
|
|
(adapter->seq_num, priv->bss_num,
|
|
- priv->bss_type)));
|
|
+ priv->bss_type));
|
|
|
|
mwifiex_dbg(adapter, CMD,
|
|
"cmd: DNLD_CMD: %#x, act %#x, len %d, seqno %#x\n",
|
|
diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
|
|
index 341f6ed5b3556..fccce1b4afcd1 100644
|
|
--- a/drivers/net/wireless/marvell/mwifiex/fw.h
|
|
+++ b/drivers/net/wireless/marvell/mwifiex/fw.h
|
|
@@ -482,10 +482,10 @@ enum mwifiex_channel_flags {
|
|
|
|
#define RF_ANTENNA_AUTO 0xFFFF
|
|
|
|
-#define HostCmd_SET_SEQ_NO_BSS_INFO(seq, num, type) { \
|
|
- (((seq) & 0x00ff) | \
|
|
- (((num) & 0x000f) << 8)) | \
|
|
- (((type) & 0x000f) << 12); }
|
|
+#define HostCmd_SET_SEQ_NO_BSS_INFO(seq, num, type) \
|
|
+ ((((seq) & 0x00ff) | \
|
|
+ (((num) & 0x000f) << 8)) | \
|
|
+ (((type) & 0x000f) << 12))
|
|
|
|
#define HostCmd_GET_SEQ_NO(seq) \
|
|
((seq) & HostCmd_SEQ_NUM_MASK)
|
|
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
|
|
index 347c796afd4ed..bfa3c6aaebe6b 100644
|
|
--- a/drivers/net/xen-netback/common.h
|
|
+++ b/drivers/net/xen-netback/common.h
|
|
@@ -203,6 +203,7 @@ struct xenvif_queue { /* Per-queue data for xenvif */
|
|
unsigned int rx_queue_max;
|
|
unsigned int rx_queue_len;
|
|
unsigned long last_rx_time;
|
|
+ unsigned int rx_slots_needed;
|
|
bool stalled;
|
|
|
|
struct xenvif_copy_state rx_copy;
|
|
diff --git a/drivers/net/xen-netback/rx.c b/drivers/net/xen-netback/rx.c
|
|
index ddfb1cfa2dd94..29c7645f57805 100644
|
|
--- a/drivers/net/xen-netback/rx.c
|
|
+++ b/drivers/net/xen-netback/rx.c
|
|
@@ -33,28 +33,36 @@
|
|
#include <xen/xen.h>
|
|
#include <xen/events.h>
|
|
|
|
-static bool xenvif_rx_ring_slots_available(struct xenvif_queue *queue)
|
|
+/*
|
|
+ * Update the needed ring page slots for the first SKB queued.
|
|
+ * Note that any call sequence outside the RX thread calling this function
|
|
+ * needs to wake up the RX thread via a call of xenvif_kick_thread()
|
|
+ * afterwards in order to avoid a race with putting the thread to sleep.
|
|
+ */
|
|
+static void xenvif_update_needed_slots(struct xenvif_queue *queue,
|
|
+ const struct sk_buff *skb)
|
|
{
|
|
- RING_IDX prod, cons;
|
|
- struct sk_buff *skb;
|
|
- int needed;
|
|
- unsigned long flags;
|
|
-
|
|
- spin_lock_irqsave(&queue->rx_queue.lock, flags);
|
|
+ unsigned int needed = 0;
|
|
|
|
- skb = skb_peek(&queue->rx_queue);
|
|
- if (!skb) {
|
|
- spin_unlock_irqrestore(&queue->rx_queue.lock, flags);
|
|
- return false;
|
|
+ if (skb) {
|
|
+ needed = DIV_ROUND_UP(skb->len, XEN_PAGE_SIZE);
|
|
+ if (skb_is_gso(skb))
|
|
+ needed++;
|
|
+ if (skb->sw_hash)
|
|
+ needed++;
|
|
}
|
|
|
|
- needed = DIV_ROUND_UP(skb->len, XEN_PAGE_SIZE);
|
|
- if (skb_is_gso(skb))
|
|
- needed++;
|
|
- if (skb->sw_hash)
|
|
- needed++;
|
|
+ WRITE_ONCE(queue->rx_slots_needed, needed);
|
|
+}
|
|
|
|
- spin_unlock_irqrestore(&queue->rx_queue.lock, flags);
|
|
+static bool xenvif_rx_ring_slots_available(struct xenvif_queue *queue)
|
|
+{
|
|
+ RING_IDX prod, cons;
|
|
+ unsigned int needed;
|
|
+
|
|
+ needed = READ_ONCE(queue->rx_slots_needed);
|
|
+ if (!needed)
|
|
+ return false;
|
|
|
|
do {
|
|
prod = queue->rx.sring->req_prod;
|
|
@@ -80,13 +88,19 @@ void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb)
|
|
|
|
spin_lock_irqsave(&queue->rx_queue.lock, flags);
|
|
|
|
- __skb_queue_tail(&queue->rx_queue, skb);
|
|
-
|
|
- queue->rx_queue_len += skb->len;
|
|
- if (queue->rx_queue_len > queue->rx_queue_max) {
|
|
+ if (queue->rx_queue_len >= queue->rx_queue_max) {
|
|
struct net_device *dev = queue->vif->dev;
|
|
|
|
netif_tx_stop_queue(netdev_get_tx_queue(dev, queue->id));
|
|
+ kfree_skb(skb);
|
|
+ queue->vif->dev->stats.rx_dropped++;
|
|
+ } else {
|
|
+ if (skb_queue_empty(&queue->rx_queue))
|
|
+ xenvif_update_needed_slots(queue, skb);
|
|
+
|
|
+ __skb_queue_tail(&queue->rx_queue, skb);
|
|
+
|
|
+ queue->rx_queue_len += skb->len;
|
|
}
|
|
|
|
spin_unlock_irqrestore(&queue->rx_queue.lock, flags);
|
|
@@ -100,6 +114,8 @@ static struct sk_buff *xenvif_rx_dequeue(struct xenvif_queue *queue)
|
|
|
|
skb = __skb_dequeue(&queue->rx_queue);
|
|
if (skb) {
|
|
+ xenvif_update_needed_slots(queue, skb_peek(&queue->rx_queue));
|
|
+
|
|
queue->rx_queue_len -= skb->len;
|
|
if (queue->rx_queue_len < queue->rx_queue_max) {
|
|
struct netdev_queue *txq;
|
|
@@ -134,6 +150,7 @@ static void xenvif_rx_queue_drop_expired(struct xenvif_queue *queue)
|
|
break;
|
|
xenvif_rx_dequeue(queue);
|
|
kfree_skb(skb);
|
|
+ queue->vif->dev->stats.rx_dropped++;
|
|
}
|
|
}
|
|
|
|
@@ -474,27 +491,31 @@ void xenvif_rx_action(struct xenvif_queue *queue)
|
|
xenvif_rx_copy_flush(queue);
|
|
}
|
|
|
|
-static bool xenvif_rx_queue_stalled(struct xenvif_queue *queue)
|
|
+static RING_IDX xenvif_rx_queue_slots(const struct xenvif_queue *queue)
|
|
{
|
|
RING_IDX prod, cons;
|
|
|
|
prod = queue->rx.sring->req_prod;
|
|
cons = queue->rx.req_cons;
|
|
|
|
+ return prod - cons;
|
|
+}
|
|
+
|
|
+static bool xenvif_rx_queue_stalled(const struct xenvif_queue *queue)
|
|
+{
|
|
+ unsigned int needed = READ_ONCE(queue->rx_slots_needed);
|
|
+
|
|
return !queue->stalled &&
|
|
- prod - cons < 1 &&
|
|
+ xenvif_rx_queue_slots(queue) < needed &&
|
|
time_after(jiffies,
|
|
queue->last_rx_time + queue->vif->stall_timeout);
|
|
}
|
|
|
|
static bool xenvif_rx_queue_ready(struct xenvif_queue *queue)
|
|
{
|
|
- RING_IDX prod, cons;
|
|
-
|
|
- prod = queue->rx.sring->req_prod;
|
|
- cons = queue->rx.req_cons;
|
|
+ unsigned int needed = READ_ONCE(queue->rx_slots_needed);
|
|
|
|
- return queue->stalled && prod - cons >= 1;
|
|
+ return queue->stalled && xenvif_rx_queue_slots(queue) >= needed;
|
|
}
|
|
|
|
bool xenvif_have_rx_work(struct xenvif_queue *queue, bool test_kthread)
|
|
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
|
|
index 0d2df76902384..65a50bc5661d2 100644
|
|
--- a/drivers/net/xen-netfront.c
|
|
+++ b/drivers/net/xen-netfront.c
|
|
@@ -141,6 +141,9 @@ struct netfront_queue {
|
|
struct sk_buff *rx_skbs[NET_RX_RING_SIZE];
|
|
grant_ref_t gref_rx_head;
|
|
grant_ref_t grant_rx_ref[NET_RX_RING_SIZE];
|
|
+
|
|
+ unsigned int rx_rsp_unconsumed;
|
|
+ spinlock_t rx_cons_lock;
|
|
};
|
|
|
|
struct netfront_info {
|
|
@@ -365,12 +368,13 @@ static int xennet_open(struct net_device *dev)
|
|
return 0;
|
|
}
|
|
|
|
-static void xennet_tx_buf_gc(struct netfront_queue *queue)
|
|
+static bool xennet_tx_buf_gc(struct netfront_queue *queue)
|
|
{
|
|
RING_IDX cons, prod;
|
|
unsigned short id;
|
|
struct sk_buff *skb;
|
|
bool more_to_do;
|
|
+ bool work_done = false;
|
|
const struct device *dev = &queue->info->netdev->dev;
|
|
|
|
BUG_ON(!netif_carrier_ok(queue->info->netdev));
|
|
@@ -387,6 +391,8 @@ static void xennet_tx_buf_gc(struct netfront_queue *queue)
|
|
for (cons = queue->tx.rsp_cons; cons != prod; cons++) {
|
|
struct xen_netif_tx_response txrsp;
|
|
|
|
+ work_done = true;
|
|
+
|
|
RING_COPY_RESPONSE(&queue->tx, cons, &txrsp);
|
|
if (txrsp.status == XEN_NETIF_RSP_NULL)
|
|
continue;
|
|
@@ -430,11 +436,13 @@ static void xennet_tx_buf_gc(struct netfront_queue *queue)
|
|
|
|
xennet_maybe_wake_tx(queue);
|
|
|
|
- return;
|
|
+ return work_done;
|
|
|
|
err:
|
|
queue->info->broken = true;
|
|
dev_alert(dev, "Disabled for further use\n");
|
|
+
|
|
+ return work_done;
|
|
}
|
|
|
|
struct xennet_gnttab_make_txreq {
|
|
@@ -754,6 +762,16 @@ static int xennet_close(struct net_device *dev)
|
|
return 0;
|
|
}
|
|
|
|
+static void xennet_set_rx_rsp_cons(struct netfront_queue *queue, RING_IDX val)
|
|
+{
|
|
+ unsigned long flags;
|
|
+
|
|
+ spin_lock_irqsave(&queue->rx_cons_lock, flags);
|
|
+ queue->rx.rsp_cons = val;
|
|
+ queue->rx_rsp_unconsumed = RING_HAS_UNCONSUMED_RESPONSES(&queue->rx);
|
|
+ spin_unlock_irqrestore(&queue->rx_cons_lock, flags);
|
|
+}
|
|
+
|
|
static void xennet_move_rx_slot(struct netfront_queue *queue, struct sk_buff *skb,
|
|
grant_ref_t ref)
|
|
{
|
|
@@ -805,7 +823,7 @@ static int xennet_get_extras(struct netfront_queue *queue,
|
|
xennet_move_rx_slot(queue, skb, ref);
|
|
} while (extra.flags & XEN_NETIF_EXTRA_FLAG_MORE);
|
|
|
|
- queue->rx.rsp_cons = cons;
|
|
+ xennet_set_rx_rsp_cons(queue, cons);
|
|
return err;
|
|
}
|
|
|
|
@@ -885,7 +903,7 @@ next:
|
|
}
|
|
|
|
if (unlikely(err))
|
|
- queue->rx.rsp_cons = cons + slots;
|
|
+ xennet_set_rx_rsp_cons(queue, cons + slots);
|
|
|
|
return err;
|
|
}
|
|
@@ -939,7 +957,8 @@ static int xennet_fill_frags(struct netfront_queue *queue,
|
|
__pskb_pull_tail(skb, pull_to - skb_headlen(skb));
|
|
}
|
|
if (unlikely(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS)) {
|
|
- queue->rx.rsp_cons = ++cons + skb_queue_len(list);
|
|
+ xennet_set_rx_rsp_cons(queue,
|
|
+ ++cons + skb_queue_len(list));
|
|
kfree_skb(nskb);
|
|
return -ENOENT;
|
|
}
|
|
@@ -952,7 +971,7 @@ static int xennet_fill_frags(struct netfront_queue *queue,
|
|
kfree_skb(nskb);
|
|
}
|
|
|
|
- queue->rx.rsp_cons = cons;
|
|
+ xennet_set_rx_rsp_cons(queue, cons);
|
|
|
|
return 0;
|
|
}
|
|
@@ -1073,7 +1092,9 @@ err:
|
|
|
|
if (unlikely(xennet_set_skb_gso(skb, gso))) {
|
|
__skb_queue_head(&tmpq, skb);
|
|
- queue->rx.rsp_cons += skb_queue_len(&tmpq);
|
|
+ xennet_set_rx_rsp_cons(queue,
|
|
+ queue->rx.rsp_cons +
|
|
+ skb_queue_len(&tmpq));
|
|
goto err;
|
|
}
|
|
}
|
|
@@ -1097,7 +1118,8 @@ err:
|
|
|
|
__skb_queue_tail(&rxq, skb);
|
|
|
|
- i = ++queue->rx.rsp_cons;
|
|
+ i = queue->rx.rsp_cons + 1;
|
|
+ xennet_set_rx_rsp_cons(queue, i);
|
|
work_done++;
|
|
}
|
|
|
|
@@ -1281,40 +1303,79 @@ static int xennet_set_features(struct net_device *dev,
|
|
return 0;
|
|
}
|
|
|
|
-static irqreturn_t xennet_tx_interrupt(int irq, void *dev_id)
|
|
+static bool xennet_handle_tx(struct netfront_queue *queue, unsigned int *eoi)
|
|
{
|
|
- struct netfront_queue *queue = dev_id;
|
|
unsigned long flags;
|
|
|
|
- if (queue->info->broken)
|
|
- return IRQ_HANDLED;
|
|
+ if (unlikely(queue->info->broken))
|
|
+ return false;
|
|
|
|
spin_lock_irqsave(&queue->tx_lock, flags);
|
|
- xennet_tx_buf_gc(queue);
|
|
+ if (xennet_tx_buf_gc(queue))
|
|
+ *eoi = 0;
|
|
spin_unlock_irqrestore(&queue->tx_lock, flags);
|
|
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static irqreturn_t xennet_tx_interrupt(int irq, void *dev_id)
|
|
+{
|
|
+ unsigned int eoiflag = XEN_EOI_FLAG_SPURIOUS;
|
|
+
|
|
+ if (likely(xennet_handle_tx(dev_id, &eoiflag)))
|
|
+ xen_irq_lateeoi(irq, eoiflag);
|
|
+
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
-static irqreturn_t xennet_rx_interrupt(int irq, void *dev_id)
|
|
+static bool xennet_handle_rx(struct netfront_queue *queue, unsigned int *eoi)
|
|
{
|
|
- struct netfront_queue *queue = dev_id;
|
|
- struct net_device *dev = queue->info->netdev;
|
|
+ unsigned int work_queued;
|
|
+ unsigned long flags;
|
|
|
|
- if (queue->info->broken)
|
|
- return IRQ_HANDLED;
|
|
+ if (unlikely(queue->info->broken))
|
|
+ return false;
|
|
+
|
|
+ spin_lock_irqsave(&queue->rx_cons_lock, flags);
|
|
+ work_queued = RING_HAS_UNCONSUMED_RESPONSES(&queue->rx);
|
|
+ if (work_queued > queue->rx_rsp_unconsumed) {
|
|
+ queue->rx_rsp_unconsumed = work_queued;
|
|
+ *eoi = 0;
|
|
+ } else if (unlikely(work_queued < queue->rx_rsp_unconsumed)) {
|
|
+ const struct device *dev = &queue->info->netdev->dev;
|
|
+
|
|
+ spin_unlock_irqrestore(&queue->rx_cons_lock, flags);
|
|
+ dev_alert(dev, "RX producer index going backwards\n");
|
|
+ dev_alert(dev, "Disabled for further use\n");
|
|
+ queue->info->broken = true;
|
|
+ return false;
|
|
+ }
|
|
+ spin_unlock_irqrestore(&queue->rx_cons_lock, flags);
|
|
|
|
- if (likely(netif_carrier_ok(dev) &&
|
|
- RING_HAS_UNCONSUMED_RESPONSES(&queue->rx)))
|
|
+ if (likely(netif_carrier_ok(queue->info->netdev) && work_queued))
|
|
napi_schedule(&queue->napi);
|
|
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static irqreturn_t xennet_rx_interrupt(int irq, void *dev_id)
|
|
+{
|
|
+ unsigned int eoiflag = XEN_EOI_FLAG_SPURIOUS;
|
|
+
|
|
+ if (likely(xennet_handle_rx(dev_id, &eoiflag)))
|
|
+ xen_irq_lateeoi(irq, eoiflag);
|
|
+
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
static irqreturn_t xennet_interrupt(int irq, void *dev_id)
|
|
{
|
|
- xennet_tx_interrupt(irq, dev_id);
|
|
- xennet_rx_interrupt(irq, dev_id);
|
|
+ unsigned int eoiflag = XEN_EOI_FLAG_SPURIOUS;
|
|
+
|
|
+ if (xennet_handle_tx(dev_id, &eoiflag) &&
|
|
+ xennet_handle_rx(dev_id, &eoiflag))
|
|
+ xen_irq_lateeoi(irq, eoiflag);
|
|
+
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
@@ -1546,9 +1607,10 @@ static int setup_netfront_single(struct netfront_queue *queue)
|
|
if (err < 0)
|
|
goto fail;
|
|
|
|
- err = bind_evtchn_to_irqhandler(queue->tx_evtchn,
|
|
- xennet_interrupt,
|
|
- 0, queue->info->netdev->name, queue);
|
|
+ err = bind_evtchn_to_irqhandler_lateeoi(queue->tx_evtchn,
|
|
+ xennet_interrupt, 0,
|
|
+ queue->info->netdev->name,
|
|
+ queue);
|
|
if (err < 0)
|
|
goto bind_fail;
|
|
queue->rx_evtchn = queue->tx_evtchn;
|
|
@@ -1576,18 +1638,18 @@ static int setup_netfront_split(struct netfront_queue *queue)
|
|
|
|
snprintf(queue->tx_irq_name, sizeof(queue->tx_irq_name),
|
|
"%s-tx", queue->name);
|
|
- err = bind_evtchn_to_irqhandler(queue->tx_evtchn,
|
|
- xennet_tx_interrupt,
|
|
- 0, queue->tx_irq_name, queue);
|
|
+ err = bind_evtchn_to_irqhandler_lateeoi(queue->tx_evtchn,
|
|
+ xennet_tx_interrupt, 0,
|
|
+ queue->tx_irq_name, queue);
|
|
if (err < 0)
|
|
goto bind_tx_fail;
|
|
queue->tx_irq = err;
|
|
|
|
snprintf(queue->rx_irq_name, sizeof(queue->rx_irq_name),
|
|
"%s-rx", queue->name);
|
|
- err = bind_evtchn_to_irqhandler(queue->rx_evtchn,
|
|
- xennet_rx_interrupt,
|
|
- 0, queue->rx_irq_name, queue);
|
|
+ err = bind_evtchn_to_irqhandler_lateeoi(queue->rx_evtchn,
|
|
+ xennet_rx_interrupt, 0,
|
|
+ queue->rx_irq_name, queue);
|
|
if (err < 0)
|
|
goto bind_rx_fail;
|
|
queue->rx_irq = err;
|
|
@@ -1689,6 +1751,7 @@ static int xennet_init_queue(struct netfront_queue *queue)
|
|
|
|
spin_lock_init(&queue->tx_lock);
|
|
spin_lock_init(&queue->rx_lock);
|
|
+ spin_lock_init(&queue->rx_cons_lock);
|
|
|
|
setup_timer(&queue->rx_refill_timer, rx_refill_timeout,
|
|
(unsigned long)queue);
|
|
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
|
|
index be2f1402c84c2..161de28dc1626 100644
|
|
--- a/drivers/pci/msi.c
|
|
+++ b/drivers/pci/msi.c
|
|
@@ -871,7 +871,7 @@ out_free:
|
|
free_msi_irqs(dev);
|
|
|
|
out_disable:
|
|
- pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0);
|
|
+ pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE, 0);
|
|
|
|
return ret;
|
|
}
|
|
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
|
|
index 99bfb003be3fc..4358eb158c48c 100644
|
|
--- a/drivers/scsi/scsi_debug.c
|
|
+++ b/drivers/scsi/scsi_debug.c
|
|
@@ -2175,11 +2175,11 @@ static int resp_mode_select(struct scsi_cmnd *scp,
|
|
__func__, param_len, res);
|
|
md_len = mselect6 ? (arr[0] + 1) : (get_unaligned_be16(arr + 0) + 2);
|
|
bd_len = mselect6 ? arr[3] : get_unaligned_be16(arr + 6);
|
|
- if (md_len > 2) {
|
|
+ off = bd_len + (mselect6 ? 4 : 8);
|
|
+ if (md_len > 2 || off >= res) {
|
|
mk_sense_invalid_fld(scp, SDEB_IN_DATA, 0, -1);
|
|
return check_condition_result;
|
|
}
|
|
- off = bd_len + (mselect6 ? 4 : 8);
|
|
mpage = arr[off] & 0x3f;
|
|
ps = !!(arr[off] & 0x80);
|
|
if (ps) {
|
|
diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c
|
|
index c4f5e5bbb8dce..9397e8ba26469 100644
|
|
--- a/drivers/soc/tegra/fuse/fuse-tegra.c
|
|
+++ b/drivers/soc/tegra/fuse/fuse-tegra.c
|
|
@@ -176,7 +176,7 @@ static struct platform_driver tegra_fuse_driver = {
|
|
};
|
|
module_platform_driver(tegra_fuse_driver);
|
|
|
|
-bool __init tegra_fuse_read_spare(unsigned int spare)
|
|
+u32 __init tegra_fuse_read_spare(unsigned int spare)
|
|
{
|
|
unsigned int offset = fuse->soc->info->spare + spare * 4;
|
|
|
|
diff --git a/drivers/soc/tegra/fuse/fuse.h b/drivers/soc/tegra/fuse/fuse.h
|
|
index 10c2076d5089a..f368bd5373088 100644
|
|
--- a/drivers/soc/tegra/fuse/fuse.h
|
|
+++ b/drivers/soc/tegra/fuse/fuse.h
|
|
@@ -62,7 +62,7 @@ struct tegra_fuse {
|
|
void tegra_init_revision(void);
|
|
void tegra_init_apbmisc(void);
|
|
|
|
-bool __init tegra_fuse_read_spare(unsigned int spare);
|
|
+u32 __init tegra_fuse_read_spare(unsigned int spare);
|
|
u32 __init tegra_fuse_read_early(unsigned int offset);
|
|
|
|
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
|
|
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c
|
|
index 858c7b4b197cb..2af089b2a343d 100644
|
|
--- a/drivers/tty/hvc/hvc_xen.c
|
|
+++ b/drivers/tty/hvc/hvc_xen.c
|
|
@@ -50,6 +50,8 @@ struct xencons_info {
|
|
struct xenbus_device *xbdev;
|
|
struct xencons_interface *intf;
|
|
unsigned int evtchn;
|
|
+ XENCONS_RING_IDX out_cons;
|
|
+ unsigned int out_cons_same;
|
|
struct hvc_struct *hvc;
|
|
int irq;
|
|
int vtermno;
|
|
@@ -151,6 +153,8 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len)
|
|
XENCONS_RING_IDX cons, prod;
|
|
int recv = 0;
|
|
struct xencons_info *xencons = vtermno_to_xencons(vtermno);
|
|
+ unsigned int eoiflag = 0;
|
|
+
|
|
if (xencons == NULL)
|
|
return -EINVAL;
|
|
intf = xencons->intf;
|
|
@@ -170,7 +174,27 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len)
|
|
mb(); /* read ring before consuming */
|
|
intf->in_cons = cons;
|
|
|
|
- notify_daemon(xencons);
|
|
+ /*
|
|
+ * When to mark interrupt having been spurious:
|
|
+ * - there was no new data to be read, and
|
|
+ * - the backend did not consume some output bytes, and
|
|
+ * - the previous round with no read data didn't see consumed bytes
|
|
+ * (we might have a race with an interrupt being in flight while
|
|
+ * updating xencons->out_cons, so account for that by allowing one
|
|
+ * round without any visible reason)
|
|
+ */
|
|
+ if (intf->out_cons != xencons->out_cons) {
|
|
+ xencons->out_cons = intf->out_cons;
|
|
+ xencons->out_cons_same = 0;
|
|
+ }
|
|
+ if (recv) {
|
|
+ notify_daemon(xencons);
|
|
+ } else if (xencons->out_cons_same++ > 1) {
|
|
+ eoiflag = XEN_EOI_FLAG_SPURIOUS;
|
|
+ }
|
|
+
|
|
+ xen_irq_lateeoi(xencons->irq, eoiflag);
|
|
+
|
|
return recv;
|
|
}
|
|
|
|
@@ -399,7 +423,7 @@ static int xencons_connect_backend(struct xenbus_device *dev,
|
|
if (ret)
|
|
return ret;
|
|
info->evtchn = evtchn;
|
|
- irq = bind_evtchn_to_irq(evtchn);
|
|
+ irq = bind_interdomain_evtchn_to_irq_lateeoi(dev->otherend_id, evtchn);
|
|
if (irq < 0)
|
|
return irq;
|
|
info->irq = irq;
|
|
@@ -563,7 +587,7 @@ static int __init xen_hvc_init(void)
|
|
return r;
|
|
|
|
info = vtermno_to_xencons(HVC_COOKIE);
|
|
- info->irq = bind_evtchn_to_irq(info->evtchn);
|
|
+ info->irq = bind_evtchn_to_irq_lateeoi(info->evtchn);
|
|
}
|
|
if (info->irq < 0)
|
|
info->irq = 0; /* NO_IRQ */
|
|
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
|
|
index 3d14a316830a6..a7c44a3cb2d25 100644
|
|
--- a/drivers/usb/gadget/composite.c
|
|
+++ b/drivers/usb/gadget/composite.c
|
|
@@ -1632,14 +1632,14 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
|
u8 endp;
|
|
|
|
if (w_length > USB_COMP_EP0_BUFSIZ) {
|
|
- if (ctrl->bRequestType == USB_DIR_OUT) {
|
|
- goto done;
|
|
- } else {
|
|
+ if (ctrl->bRequestType & USB_DIR_IN) {
|
|
/* Cast away the const, we are going to overwrite on purpose. */
|
|
__le16 *temp = (__le16 *)&ctrl->wLength;
|
|
|
|
*temp = cpu_to_le16(USB_COMP_EP0_BUFSIZ);
|
|
w_length = USB_COMP_EP0_BUFSIZ;
|
|
+ } else {
|
|
+ goto done;
|
|
}
|
|
}
|
|
|
|
diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c
|
|
index f1c5a22704b28..e8818ad973e4b 100644
|
|
--- a/drivers/usb/gadget/legacy/dbgp.c
|
|
+++ b/drivers/usb/gadget/legacy/dbgp.c
|
|
@@ -345,14 +345,14 @@ static int dbgp_setup(struct usb_gadget *gadget,
|
|
u16 len = 0;
|
|
|
|
if (length > DBGP_REQ_LEN) {
|
|
- if (ctrl->bRequestType == USB_DIR_OUT) {
|
|
- return err;
|
|
- } else {
|
|
+ if (ctrl->bRequestType & USB_DIR_IN) {
|
|
/* Cast away the const, we are going to overwrite on purpose. */
|
|
__le16 *temp = (__le16 *)&ctrl->wLength;
|
|
|
|
*temp = cpu_to_le16(DBGP_REQ_LEN);
|
|
length = DBGP_REQ_LEN;
|
|
+ } else {
|
|
+ return err;
|
|
}
|
|
}
|
|
|
|
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c
|
|
index d39bd1a1ab8fc..19eb954a7afa3 100644
|
|
--- a/drivers/usb/gadget/legacy/inode.c
|
|
+++ b/drivers/usb/gadget/legacy/inode.c
|
|
@@ -1339,14 +1339,14 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
|
u16 w_length = le16_to_cpu(ctrl->wLength);
|
|
|
|
if (w_length > RBUF_SIZE) {
|
|
- if (ctrl->bRequestType == USB_DIR_OUT) {
|
|
- return value;
|
|
- } else {
|
|
+ if (ctrl->bRequestType & USB_DIR_IN) {
|
|
/* Cast away the const, we are going to overwrite on purpose. */
|
|
__le16 *temp = (__le16 *)&ctrl->wLength;
|
|
|
|
*temp = cpu_to_le16(RBUF_SIZE);
|
|
w_length = RBUF_SIZE;
|
|
+ } else {
|
|
+ return value;
|
|
}
|
|
}
|
|
|
|
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
|
|
index 502931f658a8e..9479abb9eaaaf 100644
|
|
--- a/drivers/usb/serial/option.c
|
|
+++ b/drivers/usb/serial/option.c
|
|
@@ -1195,6 +1195,14 @@ static const struct usb_device_id option_ids[] = {
|
|
.driver_info = NCTRL(2) | RSVD(3) },
|
|
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1063, 0xff), /* Telit LN920 (ECM) */
|
|
.driver_info = NCTRL(0) | RSVD(1) },
|
|
+ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1070, 0xff), /* Telit FN990 (rmnet) */
|
|
+ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
|
|
+ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1071, 0xff), /* Telit FN990 (MBIM) */
|
|
+ .driver_info = NCTRL(0) | RSVD(1) },
|
|
+ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1072, 0xff), /* Telit FN990 (RNDIS) */
|
|
+ .driver_info = NCTRL(2) | RSVD(3) },
|
|
+ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990 (ECM) */
|
|
+ .driver_info = NCTRL(0) | RSVD(1) },
|
|
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
|
|
.driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
|
|
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
|
|
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
|
|
index 9af23f4365586..b41cc537eb311 100644
|
|
--- a/fs/fuse/dir.c
|
|
+++ b/fs/fuse/dir.c
|
|
@@ -973,7 +973,7 @@ int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
|
|
if (!parent)
|
|
return -ENOENT;
|
|
|
|
- inode_lock(parent);
|
|
+ inode_lock_nested(parent, I_MUTEX_PARENT);
|
|
if (!S_ISDIR(parent->i_mode))
|
|
goto unlock;
|
|
|
|
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
|
|
index 5c9231d5e14a0..524d98e3bcf5b 100644
|
|
--- a/fs/nfsd/nfs4state.c
|
|
+++ b/fs/nfsd/nfs4state.c
|
|
@@ -955,6 +955,11 @@ hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp)
|
|
return 0;
|
|
}
|
|
|
|
+static bool delegation_hashed(struct nfs4_delegation *dp)
|
|
+{
|
|
+ return !(list_empty(&dp->dl_perfile));
|
|
+}
|
|
+
|
|
static bool
|
|
unhash_delegation_locked(struct nfs4_delegation *dp)
|
|
{
|
|
@@ -962,7 +967,7 @@ unhash_delegation_locked(struct nfs4_delegation *dp)
|
|
|
|
lockdep_assert_held(&state_lock);
|
|
|
|
- if (list_empty(&dp->dl_perfile))
|
|
+ if (!delegation_hashed(dp))
|
|
return false;
|
|
|
|
dp->dl_stid.sc_type = NFS4_CLOSED_DELEG_STID;
|
|
@@ -3882,7 +3887,7 @@ static void nfsd4_cb_recall_prepare(struct nfsd4_callback *cb)
|
|
* queued for a lease break. Don't queue it again.
|
|
*/
|
|
spin_lock(&state_lock);
|
|
- if (dp->dl_time == 0) {
|
|
+ if (delegation_hashed(dp) && dp->dl_time == 0) {
|
|
dp->dl_time = get_seconds();
|
|
list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru);
|
|
}
|
|
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
|
|
index e21b4d8b72405..bcba817f7af20 100644
|
|
--- a/kernel/time/timekeeping.c
|
|
+++ b/kernel/time/timekeeping.c
|
|
@@ -1198,8 +1198,7 @@ int do_settimeofday64(const struct timespec64 *ts)
|
|
timekeeping_forward_now(tk);
|
|
|
|
xt = tk_xtime(tk);
|
|
- ts_delta.tv_sec = ts->tv_sec - xt.tv_sec;
|
|
- ts_delta.tv_nsec = ts->tv_nsec - xt.tv_nsec;
|
|
+ ts_delta = timespec64_sub(*ts, xt);
|
|
|
|
if (timespec64_compare(&tk->wall_to_monotonic, &ts_delta) > 0) {
|
|
ret = -EINVAL;
|
|
diff --git a/kernel/trace/tracing_map.c b/kernel/trace/tracing_map.c
|
|
index 379db35838b64..572c0854d631c 100644
|
|
--- a/kernel/trace/tracing_map.c
|
|
+++ b/kernel/trace/tracing_map.c
|
|
@@ -24,6 +24,7 @@
|
|
#include <linux/jhash.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/sort.h>
|
|
+#include <linux/kmemleak.h>
|
|
|
|
#include "tracing_map.h"
|
|
#include "trace.h"
|
|
@@ -227,6 +228,7 @@ void tracing_map_array_free(struct tracing_map_array *a)
|
|
for (i = 0; i < a->n_pages; i++) {
|
|
if (!a->pages[i])
|
|
break;
|
|
+ kmemleak_free(a->pages[i]);
|
|
free_page((unsigned long)a->pages[i]);
|
|
}
|
|
|
|
@@ -262,6 +264,7 @@ struct tracing_map_array *tracing_map_array_alloc(unsigned int n_elts,
|
|
a->pages[i] = (void *)get_zeroed_page(GFP_KERNEL);
|
|
if (!a->pages[i])
|
|
goto free;
|
|
+ kmemleak_alloc(a->pages[i], PAGE_SIZE, 1, GFP_KERNEL);
|
|
}
|
|
out:
|
|
return a;
|
|
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
|
|
index 80c45567ee3ad..030d85790584d 100644
|
|
--- a/net/mac80211/agg-tx.c
|
|
+++ b/net/mac80211/agg-tx.c
|
|
@@ -109,7 +109,7 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
|
|
mgmt->u.action.u.addba_req.start_seq_num =
|
|
cpu_to_le16(start_seq_num << 4);
|
|
|
|
- ieee80211_tx_skb(sdata, skb);
|
|
+ ieee80211_tx_skb_tid(sdata, skb, tid);
|
|
}
|
|
|
|
void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn)
|
|
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
|
|
index 1b70de5898c42..13d69cbd14c20 100644
|
|
--- a/net/netlink/af_netlink.c
|
|
+++ b/net/netlink/af_netlink.c
|
|
@@ -1804,6 +1804,11 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
|
|
if (msg->msg_flags&MSG_OOB)
|
|
return -EOPNOTSUPP;
|
|
|
|
+ if (len == 0) {
|
|
+ pr_warn_once("Zero length message leads to an empty skb\n");
|
|
+ return -ENODATA;
|
|
+ }
|
|
+
|
|
err = scm_send(sock, msg, &scm, true);
|
|
if (err < 0)
|
|
return err;
|
|
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
|
|
index 27ad73861a33f..6e771022d43e1 100644
|
|
--- a/net/nfc/netlink.c
|
|
+++ b/net/nfc/netlink.c
|
|
@@ -669,8 +669,10 @@ static int nfc_genl_dump_devices_done(struct netlink_callback *cb)
|
|
{
|
|
struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
|
|
|
|
- nfc_device_iter_exit(iter);
|
|
- kfree(iter);
|
|
+ if (iter) {
|
|
+ nfc_device_iter_exit(iter);
|
|
+ kfree(iter);
|
|
+ }
|
|
|
|
return 0;
|
|
}
|
|
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
|
|
index 113c7a0718108..21da2831e05b4 100755
|
|
--- a/scripts/recordmcount.pl
|
|
+++ b/scripts/recordmcount.pl
|
|
@@ -250,7 +250,7 @@ if ($arch eq "x86_64") {
|
|
|
|
} elsif ($arch eq "s390" && $bits == 64) {
|
|
if ($cc =~ /-DCC_USING_HOTPATCH/) {
|
|
- $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*c0 04 00 00 00 00\\s*brcl\\s*0,[0-9a-f]+ <([^\+]*)>\$";
|
|
+ $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*c0 04 00 00 00 00\\s*(bcrl\\s*0,|jgnop\\s*)[0-9a-f]+ <([^\+]*)>\$";
|
|
$mcount_adjust = 0;
|
|
} else {
|
|
$mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_390_(PC|PLT)32DBL\\s+_mcount\\+0x2\$";
|