mirror of
https://github.com/Fishwaldo/build.git
synced 2025-03-27 09:11:49 +00:00
4356 lines
136 KiB
Diff
4356 lines
136 KiB
Diff
diff --git a/Makefile b/Makefile
|
|
index a9de3c45a7ef..436d49582d3b 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -1,7 +1,7 @@
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
VERSION = 4
|
|
PATCHLEVEL = 14
|
|
-SUBLEVEL = 119
|
|
+SUBLEVEL = 120
|
|
EXTRAVERSION =
|
|
NAME = Petit Gorille
|
|
|
|
diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
|
|
index 30d48ecf46e0..27d2bd85d1ae 100644
|
|
--- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
|
|
+++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
|
|
@@ -65,6 +65,23 @@
|
|
method = "smc";
|
|
};
|
|
|
|
+ reserved-memory {
|
|
+ #address-cells = <2>;
|
|
+ #size-cells = <2>;
|
|
+ ranges;
|
|
+
|
|
+ /*
|
|
+ * This area matches the mapping done with a
|
|
+ * mainline U-Boot, and should be updated by the
|
|
+ * bootloader.
|
|
+ */
|
|
+
|
|
+ psci-area@4000000 {
|
|
+ reg = <0x0 0x4000000 0x0 0x200000>;
|
|
+ no-map;
|
|
+ };
|
|
+ };
|
|
+
|
|
ap806 {
|
|
#address-cells = <2>;
|
|
#size-cells = <2>;
|
|
diff --git a/arch/arm64/kvm/hyp/tlb.c b/arch/arm64/kvm/hyp/tlb.c
|
|
index 73464a96c365..db23c6e5c885 100644
|
|
--- a/arch/arm64/kvm/hyp/tlb.c
|
|
+++ b/arch/arm64/kvm/hyp/tlb.c
|
|
@@ -15,13 +15,18 @@
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
+#include <linux/irqflags.h>
|
|
+
|
|
#include <asm/kvm_hyp.h>
|
|
#include <asm/tlbflush.h>
|
|
|
|
-static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm)
|
|
+static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm,
|
|
+ unsigned long *flags)
|
|
{
|
|
u64 val;
|
|
|
|
+ local_irq_save(*flags);
|
|
+
|
|
/*
|
|
* With VHE enabled, we have HCR_EL2.{E2H,TGE} = {1,1}, and
|
|
* most TLB operations target EL2/EL0. In order to affect the
|
|
@@ -36,7 +41,8 @@ static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm)
|
|
isb();
|
|
}
|
|
|
|
-static void __hyp_text __tlb_switch_to_guest_nvhe(struct kvm *kvm)
|
|
+static void __hyp_text __tlb_switch_to_guest_nvhe(struct kvm *kvm,
|
|
+ unsigned long *flags)
|
|
{
|
|
write_sysreg(kvm->arch.vttbr, vttbr_el2);
|
|
isb();
|
|
@@ -47,7 +53,8 @@ static hyp_alternate_select(__tlb_switch_to_guest,
|
|
__tlb_switch_to_guest_vhe,
|
|
ARM64_HAS_VIRT_HOST_EXTN);
|
|
|
|
-static void __hyp_text __tlb_switch_to_host_vhe(struct kvm *kvm)
|
|
+static void __hyp_text __tlb_switch_to_host_vhe(struct kvm *kvm,
|
|
+ unsigned long flags)
|
|
{
|
|
/*
|
|
* We're done with the TLB operation, let's restore the host's
|
|
@@ -55,9 +62,12 @@ static void __hyp_text __tlb_switch_to_host_vhe(struct kvm *kvm)
|
|
*/
|
|
write_sysreg(0, vttbr_el2);
|
|
write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2);
|
|
+ isb();
|
|
+ local_irq_restore(flags);
|
|
}
|
|
|
|
-static void __hyp_text __tlb_switch_to_host_nvhe(struct kvm *kvm)
|
|
+static void __hyp_text __tlb_switch_to_host_nvhe(struct kvm *kvm,
|
|
+ unsigned long flags)
|
|
{
|
|
write_sysreg(0, vttbr_el2);
|
|
}
|
|
@@ -69,11 +79,13 @@ static hyp_alternate_select(__tlb_switch_to_host,
|
|
|
|
void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
|
|
{
|
|
+ unsigned long flags;
|
|
+
|
|
dsb(ishst);
|
|
|
|
/* Switch to requested VMID */
|
|
kvm = kern_hyp_va(kvm);
|
|
- __tlb_switch_to_guest()(kvm);
|
|
+ __tlb_switch_to_guest()(kvm, &flags);
|
|
|
|
/*
|
|
* We could do so much better if we had the VA as well.
|
|
@@ -116,36 +128,39 @@ void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
|
|
if (!has_vhe() && icache_is_vpipt())
|
|
__flush_icache_all();
|
|
|
|
- __tlb_switch_to_host()(kvm);
|
|
+ __tlb_switch_to_host()(kvm, flags);
|
|
}
|
|
|
|
void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
|
|
{
|
|
+ unsigned long flags;
|
|
+
|
|
dsb(ishst);
|
|
|
|
/* Switch to requested VMID */
|
|
kvm = kern_hyp_va(kvm);
|
|
- __tlb_switch_to_guest()(kvm);
|
|
+ __tlb_switch_to_guest()(kvm, &flags);
|
|
|
|
__tlbi(vmalls12e1is);
|
|
dsb(ish);
|
|
isb();
|
|
|
|
- __tlb_switch_to_host()(kvm);
|
|
+ __tlb_switch_to_host()(kvm, flags);
|
|
}
|
|
|
|
void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu)
|
|
{
|
|
struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm);
|
|
+ unsigned long flags;
|
|
|
|
/* Switch to requested VMID */
|
|
- __tlb_switch_to_guest()(kvm);
|
|
+ __tlb_switch_to_guest()(kvm, &flags);
|
|
|
|
__tlbi(vmalle1);
|
|
dsb(nsh);
|
|
isb();
|
|
|
|
- __tlb_switch_to_host()(kvm);
|
|
+ __tlb_switch_to_host()(kvm, flags);
|
|
}
|
|
|
|
void __hyp_text __kvm_flush_vm_context(void)
|
|
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
|
|
index 26a058d58d37..c7c31e214813 100644
|
|
--- a/arch/mips/ath79/setup.c
|
|
+++ b/arch/mips/ath79/setup.c
|
|
@@ -183,12 +183,6 @@ const char *get_system_type(void)
|
|
return ath79_sys_type;
|
|
}
|
|
|
|
-int get_c0_perfcount_int(void)
|
|
-{
|
|
- return ATH79_MISC_IRQ(5);
|
|
-}
|
|
-EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
|
|
-
|
|
unsigned int get_c0_compare_int(void)
|
|
{
|
|
return CP0_LEGACY_COMPARE_IRQ;
|
|
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
|
|
index 8bbbab611a3f..0b86a01de956 100644
|
|
--- a/arch/mips/include/asm/processor.h
|
|
+++ b/arch/mips/include/asm/processor.h
|
|
@@ -81,7 +81,7 @@ extern unsigned int vced_count, vcei_count;
|
|
|
|
#endif
|
|
|
|
-#define VDSO_RANDOMIZE_SIZE (TASK_IS_32BIT_ADDR ? SZ_1M : SZ_256M)
|
|
+#define VDSO_RANDOMIZE_SIZE (TASK_IS_32BIT_ADDR ? SZ_1M : SZ_64M)
|
|
|
|
extern unsigned long mips_stack_top(void);
|
|
#define STACK_TOP mips_stack_top()
|
|
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
|
|
index 7452e50f4d1f..0f04c878113e 100644
|
|
--- a/arch/powerpc/Makefile
|
|
+++ b/arch/powerpc/Makefile
|
|
@@ -396,36 +396,9 @@ archprepare: checkbin
|
|
# to stdout and these checks are run even on install targets.
|
|
TOUT := .tmp_gas_check
|
|
|
|
-# Check gcc and binutils versions:
|
|
-# - gcc-3.4 and binutils-2.14 are a fatal combination
|
|
-# - Require gcc 4.0 or above on 64-bit
|
|
-# - gcc-4.2.0 has issues compiling modules on 64-bit
|
|
+# Check toolchain versions:
|
|
+# - gcc-4.6 is the minimum kernel-wide version so nothing required.
|
|
checkbin:
|
|
- @if test "$(cc-name)" != "clang" \
|
|
- && test "$(cc-version)" = "0304" ; then \
|
|
- if ! /bin/echo mftb 5 | $(AS) -v -mppc -many -o $(TOUT) >/dev/null 2>&1 ; then \
|
|
- echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build '; \
|
|
- echo 'correctly with gcc-3.4 and your version of binutils.'; \
|
|
- echo '*** Please upgrade your binutils or downgrade your gcc'; \
|
|
- false; \
|
|
- fi ; \
|
|
- fi
|
|
- @if test "$(cc-name)" != "clang" \
|
|
- && test "$(cc-version)" -lt "0400" \
|
|
- && test "x${CONFIG_PPC64}" = "xy" ; then \
|
|
- echo -n "Sorry, GCC v4.0 or above is required to build " ; \
|
|
- echo "the 64-bit powerpc kernel." ; \
|
|
- false ; \
|
|
- fi
|
|
- @if test "$(cc-name)" != "clang" \
|
|
- && test "$(cc-fullversion)" = "040200" \
|
|
- && test "x${CONFIG_MODULES}${CONFIG_PPC64}" = "xyy" ; then \
|
|
- echo -n '*** GCC-4.2.0 cannot compile the 64-bit powerpc ' ; \
|
|
- echo 'kernel with modules enabled.' ; \
|
|
- echo -n '*** Please use a different GCC version or ' ; \
|
|
- echo 'disable kernel modules' ; \
|
|
- false ; \
|
|
- fi
|
|
@if test "x${CONFIG_CPU_LITTLE_ENDIAN}" = "xy" \
|
|
&& $(LD) --version | head -1 | grep ' 2\.24$$' >/dev/null ; then \
|
|
echo -n '*** binutils 2.24 miscompiles weak symbols ' ; \
|
|
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
|
|
index eb2a33d5df26..e382bd6ede84 100644
|
|
--- a/arch/powerpc/include/asm/reg_booke.h
|
|
+++ b/arch/powerpc/include/asm/reg_booke.h
|
|
@@ -41,7 +41,7 @@
|
|
#if defined(CONFIG_PPC_BOOK3E_64)
|
|
#define MSR_64BIT MSR_CM
|
|
|
|
-#define MSR_ (MSR_ME | MSR_CE)
|
|
+#define MSR_ (MSR_ME | MSR_RI | MSR_CE)
|
|
#define MSR_KERNEL (MSR_ | MSR_64BIT)
|
|
#define MSR_USER32 (MSR_ | MSR_PR | MSR_EE)
|
|
#define MSR_USER64 (MSR_USER32 | MSR_64BIT)
|
|
diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S
|
|
index 4efbde0984b2..74fc20431082 100644
|
|
--- a/arch/powerpc/kernel/idle_book3s.S
|
|
+++ b/arch/powerpc/kernel/idle_book3s.S
|
|
@@ -163,6 +163,9 @@ core_idle_lock_held:
|
|
bne- core_idle_lock_held
|
|
blr
|
|
|
|
+/* Reuse an unused pt_regs slot for IAMR */
|
|
+#define PNV_POWERSAVE_IAMR _DAR
|
|
+
|
|
/*
|
|
* Pass requested state in r3:
|
|
* r3 - PNV_THREAD_NAP/SLEEP/WINKLE in POWER8
|
|
@@ -193,6 +196,12 @@ pnv_powersave_common:
|
|
/* Continue saving state */
|
|
SAVE_GPR(2, r1)
|
|
SAVE_NVGPRS(r1)
|
|
+
|
|
+BEGIN_FTR_SECTION
|
|
+ mfspr r5, SPRN_IAMR
|
|
+ std r5, PNV_POWERSAVE_IAMR(r1)
|
|
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
|
|
+
|
|
mfcr r5
|
|
std r5,_CCR(r1)
|
|
std r1,PACAR1(r13)
|
|
@@ -940,6 +949,17 @@ BEGIN_FTR_SECTION
|
|
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
|
|
REST_NVGPRS(r1)
|
|
REST_GPR(2, r1)
|
|
+
|
|
+BEGIN_FTR_SECTION
|
|
+ /* IAMR was saved in pnv_powersave_common() */
|
|
+ ld r5, PNV_POWERSAVE_IAMR(r1)
|
|
+ mtspr SPRN_IAMR, r5
|
|
+ /*
|
|
+ * We don't need an isync here because the upcoming mtmsrd is
|
|
+ * execution synchronizing.
|
|
+ */
|
|
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
|
|
+
|
|
ld r4,PACAKMSR(r13)
|
|
ld r5,_LINK(r1)
|
|
ld r6,_CCR(r1)
|
|
diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c
|
|
index e9af5d9badf2..68d4ec373cfc 100644
|
|
--- a/arch/powerpc/kernel/security.c
|
|
+++ b/arch/powerpc/kernel/security.c
|
|
@@ -4,6 +4,7 @@
|
|
//
|
|
// Copyright 2018, Michael Ellerman, IBM Corporation.
|
|
|
|
+#include <linux/cpu.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/device.h>
|
|
#include <linux/seq_buf.h>
|
|
diff --git a/arch/s390/kernel/nospec-branch.c b/arch/s390/kernel/nospec-branch.c
|
|
index 83e597688562..6956902bba12 100644
|
|
--- a/arch/s390/kernel/nospec-branch.c
|
|
+++ b/arch/s390/kernel/nospec-branch.c
|
|
@@ -66,6 +66,7 @@ void __init nospec_auto_detect(void)
|
|
if (IS_ENABLED(CC_USING_EXPOLINE))
|
|
nospec_disable = 1;
|
|
__clear_facility(82, S390_lowcore.alt_stfle_fac_list);
|
|
+ }
|
|
if (IS_ENABLED(CC_USING_EXPOLINE)) {
|
|
/*
|
|
* The kernel has been compiled with expolines.
|
|
diff --git a/arch/sparc/include/asm/switch_to_64.h b/arch/sparc/include/asm/switch_to_64.h
|
|
index 4ff29b1406a9..b1d4e2e3210f 100644
|
|
--- a/arch/sparc/include/asm/switch_to_64.h
|
|
+++ b/arch/sparc/include/asm/switch_to_64.h
|
|
@@ -67,6 +67,7 @@ do { save_and_clear_fpu(); \
|
|
} while(0)
|
|
|
|
void synchronize_user_stack(void);
|
|
-void fault_in_user_windows(void);
|
|
+struct pt_regs;
|
|
+void fault_in_user_windows(struct pt_regs *);
|
|
|
|
#endif /* __SPARC64_SWITCH_TO_64_H */
|
|
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
|
|
index 318efd784a0b..5640131e2abf 100644
|
|
--- a/arch/sparc/kernel/process_64.c
|
|
+++ b/arch/sparc/kernel/process_64.c
|
|
@@ -36,6 +36,7 @@
|
|
#include <linux/sysrq.h>
|
|
#include <linux/nmi.h>
|
|
#include <linux/context_tracking.h>
|
|
+#include <linux/signal.h>
|
|
|
|
#include <linux/uaccess.h>
|
|
#include <asm/page.h>
|
|
@@ -528,7 +529,12 @@ static void stack_unaligned(unsigned long sp)
|
|
force_sig_info(SIGBUS, &info, current);
|
|
}
|
|
|
|
-void fault_in_user_windows(void)
|
|
+static const char uwfault32[] = KERN_INFO \
|
|
+ "%s[%d]: bad register window fault: SP %08lx (orig_sp %08lx) TPC %08lx O7 %08lx\n";
|
|
+static const char uwfault64[] = KERN_INFO \
|
|
+ "%s[%d]: bad register window fault: SP %016lx (orig_sp %016lx) TPC %08lx O7 %016lx\n";
|
|
+
|
|
+void fault_in_user_windows(struct pt_regs *regs)
|
|
{
|
|
struct thread_info *t = current_thread_info();
|
|
unsigned long window;
|
|
@@ -541,9 +547,9 @@ void fault_in_user_windows(void)
|
|
do {
|
|
struct reg_window *rwin = &t->reg_window[window];
|
|
int winsize = sizeof(struct reg_window);
|
|
- unsigned long sp;
|
|
+ unsigned long sp, orig_sp;
|
|
|
|
- sp = t->rwbuf_stkptrs[window];
|
|
+ orig_sp = sp = t->rwbuf_stkptrs[window];
|
|
|
|
if (test_thread_64bit_stack(sp))
|
|
sp += STACK_BIAS;
|
|
@@ -554,8 +560,16 @@ void fault_in_user_windows(void)
|
|
stack_unaligned(sp);
|
|
|
|
if (unlikely(copy_to_user((char __user *)sp,
|
|
- rwin, winsize)))
|
|
+ rwin, winsize))) {
|
|
+ if (show_unhandled_signals)
|
|
+ printk_ratelimited(is_compat_task() ?
|
|
+ uwfault32 : uwfault64,
|
|
+ current->comm, current->pid,
|
|
+ sp, orig_sp,
|
|
+ regs->tpc,
|
|
+ regs->u_regs[UREG_I7]);
|
|
goto barf;
|
|
+ }
|
|
} while (window--);
|
|
}
|
|
set_thread_wsaved(0);
|
|
@@ -563,8 +577,7 @@ void fault_in_user_windows(void)
|
|
|
|
barf:
|
|
set_thread_wsaved(window + 1);
|
|
- user_exit();
|
|
- do_exit(SIGILL);
|
|
+ force_sig(SIGSEGV, current);
|
|
}
|
|
|
|
asmlinkage long sparc_do_fork(unsigned long clone_flags,
|
|
diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S
|
|
index 0b21042ab181..ad88d60bb740 100644
|
|
--- a/arch/sparc/kernel/rtrap_64.S
|
|
+++ b/arch/sparc/kernel/rtrap_64.S
|
|
@@ -30,6 +30,7 @@ __handle_preemption:
|
|
wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
|
|
|
|
__handle_user_windows:
|
|
+ add %sp, PTREGS_OFF, %o0
|
|
call fault_in_user_windows
|
|
wrpr %g0, RTRAP_PSTATE, %pstate
|
|
ba,pt %xcc, __handle_preemption_continue
|
|
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
|
|
index 5c572de64c74..879f8d86bc21 100644
|
|
--- a/arch/sparc/kernel/signal32.c
|
|
+++ b/arch/sparc/kernel/signal32.c
|
|
@@ -442,7 +442,11 @@ static int setup_frame32(struct ksignal *ksig, struct pt_regs *regs,
|
|
get_sigframe(ksig, regs, sigframe_size);
|
|
|
|
if (invalid_frame_pointer(sf, sigframe_size)) {
|
|
- do_exit(SIGILL);
|
|
+ if (show_unhandled_signals)
|
|
+ pr_info("%s[%d] bad frame in setup_frame32: %08lx TPC %08lx O7 %08lx\n",
|
|
+ current->comm, current->pid, (unsigned long)sf,
|
|
+ regs->tpc, regs->u_regs[UREG_I7]);
|
|
+ force_sigsegv(ksig->sig, current);
|
|
return -EINVAL;
|
|
}
|
|
|
|
@@ -573,7 +577,11 @@ static int setup_rt_frame32(struct ksignal *ksig, struct pt_regs *regs,
|
|
get_sigframe(ksig, regs, sigframe_size);
|
|
|
|
if (invalid_frame_pointer(sf, sigframe_size)) {
|
|
- do_exit(SIGILL);
|
|
+ if (show_unhandled_signals)
|
|
+ pr_info("%s[%d] bad frame in setup_rt_frame32: %08lx TPC %08lx O7 %08lx\n",
|
|
+ current->comm, current->pid, (unsigned long)sf,
|
|
+ regs->tpc, regs->u_regs[UREG_I7]);
|
|
+ force_sigsegv(ksig->sig, current);
|
|
return -EINVAL;
|
|
}
|
|
|
|
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
|
|
index 20426a1c28f2..2d0a50bde3f9 100644
|
|
--- a/arch/sparc/kernel/signal_64.c
|
|
+++ b/arch/sparc/kernel/signal_64.c
|
|
@@ -373,7 +373,11 @@ setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs)
|
|
get_sigframe(ksig, regs, sf_size);
|
|
|
|
if (invalid_frame_pointer (sf)) {
|
|
- do_exit(SIGILL); /* won't return, actually */
|
|
+ if (show_unhandled_signals)
|
|
+ pr_info("%s[%d] bad frame in setup_rt_frame: %016lx TPC %016lx O7 %016lx\n",
|
|
+ current->comm, current->pid, (unsigned long)sf,
|
|
+ regs->tpc, regs->u_regs[UREG_I7]);
|
|
+ force_sigsegv(ksig->sig, current);
|
|
return -EINVAL;
|
|
}
|
|
|
|
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
|
|
index 984e9d65ea0d..76977296dc9c 100644
|
|
--- a/arch/sparc/mm/init_64.c
|
|
+++ b/arch/sparc/mm/init_64.c
|
|
@@ -1383,6 +1383,7 @@ int __node_distance(int from, int to)
|
|
}
|
|
return numa_latency[from][to];
|
|
}
|
|
+EXPORT_SYMBOL(__node_distance);
|
|
|
|
static int __init find_best_numa_node_for_mlgroup(struct mdesc_mlgroup *grp)
|
|
{
|
|
diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile
|
|
index 839015f1b0de..ab7f730cf7f2 100644
|
|
--- a/arch/x86/entry/vdso/Makefile
|
|
+++ b/arch/x86/entry/vdso/Makefile
|
|
@@ -182,7 +182,8 @@ quiet_cmd_vdso = VDSO $@
|
|
sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
|
|
|
|
VDSO_LDFLAGS = -shared $(call ld-option, --hash-style=both) \
|
|
- $(call ld-option, --build-id) -Bsymbolic
|
|
+ $(call ld-option, --build-id) $(call ld-option, --eh-frame-hdr) \
|
|
+ -Bsymbolic
|
|
GCOV_PROFILE := n
|
|
|
|
#
|
|
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
|
|
index a399c1ebf6f0..96fd0251f8f5 100644
|
|
--- a/arch/x86/include/asm/efi.h
|
|
+++ b/arch/x86/include/asm/efi.h
|
|
@@ -82,8 +82,7 @@ struct efi_scratch {
|
|
#define arch_efi_call_virt_setup() \
|
|
({ \
|
|
efi_sync_low_kernel_mappings(); \
|
|
- preempt_disable(); \
|
|
- __kernel_fpu_begin(); \
|
|
+ kernel_fpu_begin(); \
|
|
firmware_restrict_branch_speculation_start(); \
|
|
\
|
|
if (efi_scratch.use_pgd) { \
|
|
@@ -104,8 +103,7 @@ struct efi_scratch {
|
|
} \
|
|
\
|
|
firmware_restrict_branch_speculation_end(); \
|
|
- __kernel_fpu_end(); \
|
|
- preempt_enable(); \
|
|
+ kernel_fpu_end(); \
|
|
})
|
|
|
|
extern void __iomem *__init efi_ioremap(unsigned long addr, unsigned long size,
|
|
diff --git a/arch/x86/include/asm/fpu/api.h b/arch/x86/include/asm/fpu/api.h
|
|
index a9caac9d4a72..b56d504af654 100644
|
|
--- a/arch/x86/include/asm/fpu/api.h
|
|
+++ b/arch/x86/include/asm/fpu/api.h
|
|
@@ -12,17 +12,12 @@
|
|
#define _ASM_X86_FPU_API_H
|
|
|
|
/*
|
|
- * Careful: __kernel_fpu_begin/end() must be called with preempt disabled
|
|
- * and they don't touch the preempt state on their own.
|
|
- * If you enable preemption after __kernel_fpu_begin(), preempt notifier
|
|
- * should call the __kernel_fpu_end() to prevent the kernel/user FPU
|
|
- * state from getting corrupted. KVM for example uses this model.
|
|
- *
|
|
- * All other cases use kernel_fpu_begin/end() which disable preemption
|
|
- * during kernel FPU usage.
|
|
+ * Use kernel_fpu_begin/end() if you intend to use FPU in kernel context. It
|
|
+ * disables preemption so be careful if you intend to use it for long periods
|
|
+ * of time.
|
|
+ * If you intend to use the FPU in softirq you need to check first with
|
|
+ * irq_fpu_usable() if it is possible.
|
|
*/
|
|
-extern void __kernel_fpu_begin(void);
|
|
-extern void __kernel_fpu_end(void);
|
|
extern void kernel_fpu_begin(void);
|
|
extern void kernel_fpu_end(void);
|
|
extern bool irq_fpu_usable(void);
|
|
diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
|
|
index 2ea85b32421a..2e5003fef51a 100644
|
|
--- a/arch/x86/kernel/fpu/core.c
|
|
+++ b/arch/x86/kernel/fpu/core.c
|
|
@@ -93,7 +93,7 @@ bool irq_fpu_usable(void)
|
|
}
|
|
EXPORT_SYMBOL(irq_fpu_usable);
|
|
|
|
-void __kernel_fpu_begin(void)
|
|
+static void __kernel_fpu_begin(void)
|
|
{
|
|
struct fpu *fpu = ¤t->thread.fpu;
|
|
|
|
@@ -111,9 +111,8 @@ void __kernel_fpu_begin(void)
|
|
__cpu_invalidate_fpregs_state();
|
|
}
|
|
}
|
|
-EXPORT_SYMBOL(__kernel_fpu_begin);
|
|
|
|
-void __kernel_fpu_end(void)
|
|
+static void __kernel_fpu_end(void)
|
|
{
|
|
struct fpu *fpu = ¤t->thread.fpu;
|
|
|
|
@@ -122,7 +121,6 @@ void __kernel_fpu_end(void)
|
|
|
|
kernel_fpu_enable();
|
|
}
|
|
-EXPORT_SYMBOL(__kernel_fpu_end);
|
|
|
|
void kernel_fpu_begin(void)
|
|
{
|
|
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
|
|
index 56cf6c263254..9d7bb8de2917 100644
|
|
--- a/arch/x86/kernel/kprobes/core.c
|
|
+++ b/arch/x86/kernel/kprobes/core.c
|
|
@@ -744,11 +744,16 @@ asm(
|
|
NOKPROBE_SYMBOL(kretprobe_trampoline);
|
|
STACK_FRAME_NON_STANDARD(kretprobe_trampoline);
|
|
|
|
+static struct kprobe kretprobe_kprobe = {
|
|
+ .addr = (void *)kretprobe_trampoline,
|
|
+};
|
|
+
|
|
/*
|
|
* Called from kretprobe_trampoline
|
|
*/
|
|
__visible __used void *trampoline_handler(struct pt_regs *regs)
|
|
{
|
|
+ struct kprobe_ctlblk *kcb;
|
|
struct kretprobe_instance *ri = NULL;
|
|
struct hlist_head *head, empty_rp;
|
|
struct hlist_node *tmp;
|
|
@@ -758,6 +763,17 @@ __visible __used void *trampoline_handler(struct pt_regs *regs)
|
|
void *frame_pointer;
|
|
bool skipped = false;
|
|
|
|
+ preempt_disable();
|
|
+
|
|
+ /*
|
|
+ * Set a dummy kprobe for avoiding kretprobe recursion.
|
|
+ * Since kretprobe never run in kprobe handler, kprobe must not
|
|
+ * be running at this point.
|
|
+ */
|
|
+ kcb = get_kprobe_ctlblk();
|
|
+ __this_cpu_write(current_kprobe, &kretprobe_kprobe);
|
|
+ kcb->kprobe_status = KPROBE_HIT_ACTIVE;
|
|
+
|
|
INIT_HLIST_HEAD(&empty_rp);
|
|
kretprobe_hash_lock(current, &head, &flags);
|
|
/* fixup registers */
|
|
@@ -833,10 +849,9 @@ __visible __used void *trampoline_handler(struct pt_regs *regs)
|
|
orig_ret_address = (unsigned long)ri->ret_addr;
|
|
if (ri->rp && ri->rp->handler) {
|
|
__this_cpu_write(current_kprobe, &ri->rp->kp);
|
|
- get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
|
|
ri->ret_addr = correct_ret_addr;
|
|
ri->rp->handler(ri, regs);
|
|
- __this_cpu_write(current_kprobe, NULL);
|
|
+ __this_cpu_write(current_kprobe, &kretprobe_kprobe);
|
|
}
|
|
|
|
recycle_rp_inst(ri, &empty_rp);
|
|
@@ -852,6 +867,9 @@ __visible __used void *trampoline_handler(struct pt_regs *regs)
|
|
|
|
kretprobe_hash_unlock(current, &flags);
|
|
|
|
+ __this_cpu_write(current_kprobe, NULL);
|
|
+ preempt_enable();
|
|
+
|
|
hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
|
|
hlist_del(&ri->hlist);
|
|
kfree(ri);
|
|
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
|
|
index 2126b9d27c34..c663d5fcff2e 100644
|
|
--- a/arch/x86/kernel/reboot.c
|
|
+++ b/arch/x86/kernel/reboot.c
|
|
@@ -81,6 +81,19 @@ static int __init set_bios_reboot(const struct dmi_system_id *d)
|
|
return 0;
|
|
}
|
|
|
|
+/*
|
|
+ * Some machines don't handle the default ACPI reboot method and
|
|
+ * require the EFI reboot method:
|
|
+ */
|
|
+static int __init set_efi_reboot(const struct dmi_system_id *d)
|
|
+{
|
|
+ if (reboot_type != BOOT_EFI && !efi_runtime_disabled()) {
|
|
+ reboot_type = BOOT_EFI;
|
|
+ pr_info("%s series board detected. Selecting EFI-method for reboot.\n", d->ident);
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
void __noreturn machine_real_restart(unsigned int type)
|
|
{
|
|
local_irq_disable();
|
|
@@ -166,6 +179,14 @@ static const struct dmi_system_id reboot_dmi_table[] __initconst = {
|
|
DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
|
|
},
|
|
},
|
|
+ { /* Handle reboot issue on Acer TravelMate X514-51T */
|
|
+ .callback = set_efi_reboot,
|
|
+ .ident = "Acer TravelMate X514-51T",
|
|
+ .matches = {
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
|
|
+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate X514-51T"),
|
|
+ },
|
|
+ },
|
|
|
|
/* Apple */
|
|
{ /* Handle problems with rebooting on Apple MacBook5 */
|
|
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
|
|
index f7c34184342a..053e4937af0c 100644
|
|
--- a/arch/x86/kvm/lapic.c
|
|
+++ b/arch/x86/kvm/lapic.c
|
|
@@ -133,6 +133,7 @@ static inline bool kvm_apic_map_get_logical_dest(struct kvm_apic_map *map,
|
|
if (offset <= max_apic_id) {
|
|
u8 cluster_size = min(max_apic_id - offset + 1, 16U);
|
|
|
|
+ offset = array_index_nospec(offset, map->max_apic_id + 1);
|
|
*cluster = &map->phys_map[offset];
|
|
*mask = dest_id & (0xffff >> (16 - cluster_size));
|
|
} else {
|
|
@@ -829,7 +830,8 @@ static inline bool kvm_apic_map_get_dest_lapic(struct kvm *kvm,
|
|
if (irq->dest_id > map->max_apic_id) {
|
|
*bitmap = 0;
|
|
} else {
|
|
- *dst = &map->phys_map[irq->dest_id];
|
|
+ u32 dest_id = array_index_nospec(irq->dest_id, map->max_apic_id + 1);
|
|
+ *dst = &map->phys_map[dest_id];
|
|
*bitmap = 1;
|
|
}
|
|
return true;
|
|
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
|
|
index 9807c314c478..3bf41413ab15 100644
|
|
--- a/arch/x86/kvm/trace.h
|
|
+++ b/arch/x86/kvm/trace.h
|
|
@@ -438,13 +438,13 @@ TRACE_EVENT(kvm_apic_ipi,
|
|
);
|
|
|
|
TRACE_EVENT(kvm_apic_accept_irq,
|
|
- TP_PROTO(__u32 apicid, __u16 dm, __u8 tm, __u8 vec),
|
|
+ TP_PROTO(__u32 apicid, __u16 dm, __u16 tm, __u8 vec),
|
|
TP_ARGS(apicid, dm, tm, vec),
|
|
|
|
TP_STRUCT__entry(
|
|
__field( __u32, apicid )
|
|
__field( __u16, dm )
|
|
- __field( __u8, tm )
|
|
+ __field( __u16, tm )
|
|
__field( __u8, vec )
|
|
),
|
|
|
|
diff --git a/arch/xtensa/boot/dts/xtfpga.dtsi b/arch/xtensa/boot/dts/xtfpga.dtsi
|
|
index 1090528825ec..e46ae07bab05 100644
|
|
--- a/arch/xtensa/boot/dts/xtfpga.dtsi
|
|
+++ b/arch/xtensa/boot/dts/xtfpga.dtsi
|
|
@@ -103,7 +103,7 @@
|
|
};
|
|
};
|
|
|
|
- spi0: spi-master@0d0a0000 {
|
|
+ spi0: spi@0d0a0000 {
|
|
compatible = "cdns,xtfpga-spi";
|
|
#address-cells = <1>;
|
|
#size-cells = <0>;
|
|
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c
|
|
index 0336df7ac47d..e8070f6ca835 100644
|
|
--- a/drivers/acpi/acpica/dsopcode.c
|
|
+++ b/drivers/acpi/acpica/dsopcode.c
|
|
@@ -451,6 +451,10 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
|
|
ACPI_FORMAT_UINT64(obj_desc->region.address),
|
|
obj_desc->region.length));
|
|
|
|
+ status = acpi_ut_add_address_range(obj_desc->region.space_id,
|
|
+ obj_desc->region.address,
|
|
+ obj_desc->region.length, node);
|
|
+
|
|
/* Now the address and length are valid for this opregion */
|
|
|
|
obj_desc->region.flags |= AOPOBJ_DATA_VALID;
|
|
diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c
|
|
index 707b2aa501e1..099be6424255 100644
|
|
--- a/drivers/acpi/acpica/nsobject.c
|
|
+++ b/drivers/acpi/acpica/nsobject.c
|
|
@@ -222,6 +222,10 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node)
|
|
}
|
|
}
|
|
|
|
+ if (obj_desc->common.type == ACPI_TYPE_REGION) {
|
|
+ acpi_ut_remove_address_range(obj_desc->region.space_id, node);
|
|
+ }
|
|
+
|
|
/* Clear the Node entry in all cases */
|
|
|
|
node->object = NULL;
|
|
diff --git a/drivers/base/devres.c b/drivers/base/devres.c
|
|
index 71d577025285..e43a04a495a3 100644
|
|
--- a/drivers/base/devres.c
|
|
+++ b/drivers/base/devres.c
|
|
@@ -25,8 +25,14 @@ struct devres_node {
|
|
|
|
struct devres {
|
|
struct devres_node node;
|
|
- /* -- 3 pointers */
|
|
- unsigned long long data[]; /* guarantee ull alignment */
|
|
+ /*
|
|
+ * Some archs want to perform DMA into kmalloc caches
|
|
+ * and need a guaranteed alignment larger than
|
|
+ * the alignment of a 64-bit integer.
|
|
+ * Thus we use ARCH_KMALLOC_MINALIGN here and get exactly the same
|
|
+ * buffer alignment as if it was allocated by plain kmalloc().
|
|
+ */
|
|
+ u8 __aligned(ARCH_KMALLOC_MINALIGN) data[];
|
|
};
|
|
|
|
struct devres_group {
|
|
diff --git a/drivers/clocksource/timer-oxnas-rps.c b/drivers/clocksource/timer-oxnas-rps.c
|
|
index eed6feff8b5f..30c6f4ce672b 100644
|
|
--- a/drivers/clocksource/timer-oxnas-rps.c
|
|
+++ b/drivers/clocksource/timer-oxnas-rps.c
|
|
@@ -296,4 +296,4 @@ err_alloc:
|
|
TIMER_OF_DECLARE(ox810se_rps,
|
|
"oxsemi,ox810se-rps-timer", oxnas_rps_timer_init);
|
|
TIMER_OF_DECLARE(ox820_rps,
|
|
- "oxsemi,ox820se-rps-timer", oxnas_rps_timer_init);
|
|
+ "oxsemi,ox820-rps-timer", oxnas_rps_timer_init);
|
|
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
|
|
index 87cccb5f8c5d..cb377b003321 100644
|
|
--- a/drivers/gpu/drm/i915/intel_pm.c
|
|
+++ b/drivers/gpu/drm/i915/intel_pm.c
|
|
@@ -2471,6 +2471,9 @@ static uint32_t ilk_compute_pri_wm(const struct intel_crtc_state *cstate,
|
|
uint32_t method1, method2;
|
|
int cpp;
|
|
|
|
+ if (mem_value == 0)
|
|
+ return U32_MAX;
|
|
+
|
|
if (!intel_wm_plane_visible(cstate, pstate))
|
|
return 0;
|
|
|
|
@@ -2500,6 +2503,9 @@ static uint32_t ilk_compute_spr_wm(const struct intel_crtc_state *cstate,
|
|
uint32_t method1, method2;
|
|
int cpp;
|
|
|
|
+ if (mem_value == 0)
|
|
+ return U32_MAX;
|
|
+
|
|
if (!intel_wm_plane_visible(cstate, pstate))
|
|
return 0;
|
|
|
|
@@ -2523,6 +2529,9 @@ static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate,
|
|
{
|
|
int cpp;
|
|
|
|
+ if (mem_value == 0)
|
|
+ return U32_MAX;
|
|
+
|
|
if (!intel_wm_plane_visible(cstate, pstate))
|
|
return 0;
|
|
|
|
@@ -2925,8 +2934,8 @@ static void intel_print_wm_latency(struct drm_i915_private *dev_priv,
|
|
unsigned int latency = wm[level];
|
|
|
|
if (latency == 0) {
|
|
- DRM_ERROR("%s WM%d latency not provided\n",
|
|
- name, level);
|
|
+ DRM_DEBUG_KMS("%s WM%d latency not provided\n",
|
|
+ name, level);
|
|
continue;
|
|
}
|
|
|
|
@@ -2981,6 +2990,34 @@ static void snb_wm_latency_quirk(struct drm_i915_private *dev_priv)
|
|
intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency);
|
|
}
|
|
|
|
+static void snb_wm_lp3_irq_quirk(struct drm_i915_private *dev_priv)
|
|
+{
|
|
+ /*
|
|
+ * On some SNB machines (Thinkpad X220 Tablet at least)
|
|
+ * LP3 usage can cause vblank interrupts to be lost.
|
|
+ * The DEIIR bit will go high but it looks like the CPU
|
|
+ * never gets interrupted.
|
|
+ *
|
|
+ * It's not clear whether other interrupt source could
|
|
+ * be affected or if this is somehow limited to vblank
|
|
+ * interrupts only. To play it safe we disable LP3
|
|
+ * watermarks entirely.
|
|
+ */
|
|
+ if (dev_priv->wm.pri_latency[3] == 0 &&
|
|
+ dev_priv->wm.spr_latency[3] == 0 &&
|
|
+ dev_priv->wm.cur_latency[3] == 0)
|
|
+ return;
|
|
+
|
|
+ dev_priv->wm.pri_latency[3] = 0;
|
|
+ dev_priv->wm.spr_latency[3] = 0;
|
|
+ dev_priv->wm.cur_latency[3] = 0;
|
|
+
|
|
+ DRM_DEBUG_KMS("LP3 watermarks disabled due to potential for lost interrupts\n");
|
|
+ intel_print_wm_latency(dev_priv, "Primary", dev_priv->wm.pri_latency);
|
|
+ intel_print_wm_latency(dev_priv, "Sprite", dev_priv->wm.spr_latency);
|
|
+ intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency);
|
|
+}
|
|
+
|
|
static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv)
|
|
{
|
|
intel_read_wm_latency(dev_priv, dev_priv->wm.pri_latency);
|
|
@@ -2997,8 +3034,10 @@ static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv)
|
|
intel_print_wm_latency(dev_priv, "Sprite", dev_priv->wm.spr_latency);
|
|
intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency);
|
|
|
|
- if (IS_GEN6(dev_priv))
|
|
+ if (IS_GEN6(dev_priv)) {
|
|
snb_wm_latency_quirk(dev_priv);
|
|
+ snb_wm_lp3_irq_quirk(dev_priv);
|
|
+ }
|
|
}
|
|
|
|
static void skl_setup_wm_latency(struct drm_i915_private *dev_priv)
|
|
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
|
|
index d976391dfa31..957fbf8c55eb 100644
|
|
--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
|
|
+++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
|
|
@@ -79,7 +79,7 @@ static void ipu_crtc_disable_planes(struct ipu_crtc *ipu_crtc,
|
|
if (disable_partial)
|
|
ipu_plane_disable(ipu_crtc->plane[1], true);
|
|
if (disable_full)
|
|
- ipu_plane_disable(ipu_crtc->plane[0], false);
|
|
+ ipu_plane_disable(ipu_crtc->plane[0], true);
|
|
}
|
|
|
|
static void ipu_crtc_atomic_disable(struct drm_crtc *crtc,
|
|
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
|
|
index 0ed7e91471f6..4df201d21f27 100644
|
|
--- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c
|
|
+++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
|
|
@@ -113,7 +113,7 @@ static int cdp_dp_mailbox_write(struct cdn_dp_device *dp, u8 val)
|
|
|
|
static int cdn_dp_mailbox_validate_receive(struct cdn_dp_device *dp,
|
|
u8 module_id, u8 opcode,
|
|
- u8 req_size)
|
|
+ u16 req_size)
|
|
{
|
|
u32 mbox_size, i;
|
|
u8 header[4];
|
|
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
|
|
index a553e182ff53..32e7dba2bf5e 100644
|
|
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
|
|
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
|
|
@@ -221,13 +221,15 @@ EXPORT_SYMBOL(rockchip_drm_psr_flush_all);
|
|
int rockchip_drm_psr_register(struct drm_encoder *encoder,
|
|
void (*psr_set)(struct drm_encoder *, bool enable))
|
|
{
|
|
- struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;
|
|
+ struct rockchip_drm_private *drm_drv;
|
|
struct psr_drv *psr;
|
|
unsigned long flags;
|
|
|
|
if (!encoder || !psr_set)
|
|
return -EINVAL;
|
|
|
|
+ drm_drv = encoder->dev->dev_private;
|
|
+
|
|
psr = kzalloc(sizeof(struct psr_drv), GFP_KERNEL);
|
|
if (!psr)
|
|
return -ENOMEM;
|
|
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
|
|
index 8d3c8070ed86..e09161cf312f 100644
|
|
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
|
|
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
|
|
@@ -96,6 +96,8 @@ static int sun4i_drv_bind(struct device *dev)
|
|
ret = -ENOMEM;
|
|
goto free_drm;
|
|
}
|
|
+
|
|
+ dev_set_drvdata(dev, drm);
|
|
drm->dev_private = drv;
|
|
INIT_LIST_HEAD(&drv->engine_list);
|
|
INIT_LIST_HEAD(&drv->tcon_list);
|
|
diff --git a/drivers/gpu/ipu-v3/ipu-dp.c b/drivers/gpu/ipu-v3/ipu-dp.c
|
|
index 9b2b3fa479c4..5e44ff1f2085 100644
|
|
--- a/drivers/gpu/ipu-v3/ipu-dp.c
|
|
+++ b/drivers/gpu/ipu-v3/ipu-dp.c
|
|
@@ -195,7 +195,8 @@ int ipu_dp_setup_channel(struct ipu_dp *dp,
|
|
ipu_dp_csc_init(flow, flow->foreground.in_cs, flow->out_cs,
|
|
DP_COM_CONF_CSC_DEF_BOTH);
|
|
} else {
|
|
- if (flow->foreground.in_cs == flow->out_cs)
|
|
+ if (flow->foreground.in_cs == IPUV3_COLORSPACE_UNKNOWN ||
|
|
+ flow->foreground.in_cs == flow->out_cs)
|
|
/*
|
|
* foreground identical to output, apply color
|
|
* conversion on background
|
|
@@ -261,6 +262,8 @@ void ipu_dp_disable_channel(struct ipu_dp *dp, bool sync)
|
|
struct ipu_dp_priv *priv = flow->priv;
|
|
u32 reg, csc;
|
|
|
|
+ dp->in_cs = IPUV3_COLORSPACE_UNKNOWN;
|
|
+
|
|
if (!dp->foreground)
|
|
return;
|
|
|
|
@@ -268,8 +271,9 @@ void ipu_dp_disable_channel(struct ipu_dp *dp, bool sync)
|
|
|
|
reg = readl(flow->base + DP_COM_CONF);
|
|
csc = reg & DP_COM_CONF_CSC_DEF_MASK;
|
|
- if (csc == DP_COM_CONF_CSC_DEF_FG)
|
|
- reg &= ~DP_COM_CONF_CSC_DEF_MASK;
|
|
+ reg &= ~DP_COM_CONF_CSC_DEF_MASK;
|
|
+ if (csc == DP_COM_CONF_CSC_DEF_BOTH || csc == DP_COM_CONF_CSC_DEF_BG)
|
|
+ reg |= DP_COM_CONF_CSC_DEF_BG;
|
|
|
|
reg &= ~DP_COM_CONF_FG_EN;
|
|
writel(reg, flow->base + DP_COM_CONF);
|
|
@@ -347,6 +351,8 @@ int ipu_dp_init(struct ipu_soc *ipu, struct device *dev, unsigned long base)
|
|
mutex_init(&priv->mutex);
|
|
|
|
for (i = 0; i < IPUV3_NUM_FLOWS; i++) {
|
|
+ priv->flow[i].background.in_cs = IPUV3_COLORSPACE_UNKNOWN;
|
|
+ priv->flow[i].foreground.in_cs = IPUV3_COLORSPACE_UNKNOWN;
|
|
priv->flow[i].foreground.foreground = true;
|
|
priv->flow[i].base = priv->base + ipu_dp_flow_base[i];
|
|
priv->flow[i].priv = priv;
|
|
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
|
|
index 1aa7d268686b..d723185de3ba 100644
|
|
--- a/drivers/hid/hid-input.c
|
|
+++ b/drivers/hid/hid-input.c
|
|
@@ -677,6 +677,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
|
break;
|
|
}
|
|
|
|
+ if ((usage->hid & 0xf0) == 0xb0) { /* SC - Display */
|
|
+ switch (usage->hid & 0xf) {
|
|
+ case 0x05: map_key_clear(KEY_SWITCHVIDEOMODE); break;
|
|
+ default: goto ignore;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+
|
|
/*
|
|
* Some lazy vendors declare 255 usages for System Control,
|
|
* leading to the creation of ABS_X|Y axis and too many others.
|
|
@@ -886,6 +894,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
|
case 0x074: map_key_clear(KEY_BRIGHTNESS_MAX); break;
|
|
case 0x075: map_key_clear(KEY_BRIGHTNESS_AUTO); break;
|
|
|
|
+ case 0x079: map_key_clear(KEY_KBDILLUMUP); break;
|
|
+ case 0x07a: map_key_clear(KEY_KBDILLUMDOWN); break;
|
|
+ case 0x07c: map_key_clear(KEY_KBDILLUMTOGGLE); break;
|
|
+
|
|
case 0x082: map_key_clear(KEY_VIDEO_NEXT); break;
|
|
case 0x083: map_key_clear(KEY_LAST); break;
|
|
case 0x084: map_key_clear(KEY_ENTER); break;
|
|
@@ -1017,6 +1029,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
|
case 0x2cb: map_key_clear(KEY_KBDINPUTASSIST_ACCEPT); break;
|
|
case 0x2cc: map_key_clear(KEY_KBDINPUTASSIST_CANCEL); break;
|
|
|
|
+ case 0x29f: map_key_clear(KEY_SCALE); break;
|
|
+
|
|
default: map_key_clear(KEY_UNKNOWN);
|
|
}
|
|
break;
|
|
diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c
|
|
index ca250e7ac511..6d30bec04f2d 100644
|
|
--- a/drivers/hwmon/pwm-fan.c
|
|
+++ b/drivers/hwmon/pwm-fan.c
|
|
@@ -250,7 +250,7 @@ static int pwm_fan_probe(struct platform_device *pdev)
|
|
|
|
ret = pwm_fan_of_get_cooling_data(&pdev->dev, ctx);
|
|
if (ret)
|
|
- return ret;
|
|
+ goto err_pwm_disable;
|
|
|
|
ctx->pwm_fan_state = ctx->pwm_fan_max_state;
|
|
if (IS_ENABLED(CONFIG_THERMAL)) {
|
|
diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c
|
|
index 4a60497a1f19..e89711b30ae8 100644
|
|
--- a/drivers/iio/adc/xilinx-xadc-core.c
|
|
+++ b/drivers/iio/adc/xilinx-xadc-core.c
|
|
@@ -1302,7 +1302,7 @@ static int xadc_remove(struct platform_device *pdev)
|
|
}
|
|
free_irq(irq, indio_dev);
|
|
clk_disable_unprepare(xadc->clk);
|
|
- cancel_delayed_work(&xadc->zynq_unmask_work);
|
|
+ cancel_delayed_work_sync(&xadc->zynq_unmask_work);
|
|
kfree(xadc->data);
|
|
kfree(indio_dev->channels);
|
|
|
|
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h b/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h
|
|
index 984aa3484928..4463e1c1a764 100644
|
|
--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h
|
|
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h
|
|
@@ -407,7 +407,40 @@ static inline enum ib_qp_state pvrdma_qp_state_to_ib(enum pvrdma_qp_state state)
|
|
|
|
static inline enum pvrdma_wr_opcode ib_wr_opcode_to_pvrdma(enum ib_wr_opcode op)
|
|
{
|
|
- return (enum pvrdma_wr_opcode)op;
|
|
+ switch (op) {
|
|
+ case IB_WR_RDMA_WRITE:
|
|
+ return PVRDMA_WR_RDMA_WRITE;
|
|
+ case IB_WR_RDMA_WRITE_WITH_IMM:
|
|
+ return PVRDMA_WR_RDMA_WRITE_WITH_IMM;
|
|
+ case IB_WR_SEND:
|
|
+ return PVRDMA_WR_SEND;
|
|
+ case IB_WR_SEND_WITH_IMM:
|
|
+ return PVRDMA_WR_SEND_WITH_IMM;
|
|
+ case IB_WR_RDMA_READ:
|
|
+ return PVRDMA_WR_RDMA_READ;
|
|
+ case IB_WR_ATOMIC_CMP_AND_SWP:
|
|
+ return PVRDMA_WR_ATOMIC_CMP_AND_SWP;
|
|
+ case IB_WR_ATOMIC_FETCH_AND_ADD:
|
|
+ return PVRDMA_WR_ATOMIC_FETCH_AND_ADD;
|
|
+ case IB_WR_LSO:
|
|
+ return PVRDMA_WR_LSO;
|
|
+ case IB_WR_SEND_WITH_INV:
|
|
+ return PVRDMA_WR_SEND_WITH_INV;
|
|
+ case IB_WR_RDMA_READ_WITH_INV:
|
|
+ return PVRDMA_WR_RDMA_READ_WITH_INV;
|
|
+ case IB_WR_LOCAL_INV:
|
|
+ return PVRDMA_WR_LOCAL_INV;
|
|
+ case IB_WR_REG_MR:
|
|
+ return PVRDMA_WR_FAST_REG_MR;
|
|
+ case IB_WR_MASKED_ATOMIC_CMP_AND_SWP:
|
|
+ return PVRDMA_WR_MASKED_ATOMIC_CMP_AND_SWP;
|
|
+ case IB_WR_MASKED_ATOMIC_FETCH_AND_ADD:
|
|
+ return PVRDMA_WR_MASKED_ATOMIC_FETCH_AND_ADD;
|
|
+ case IB_WR_REG_SIG_MR:
|
|
+ return PVRDMA_WR_REG_SIG_MR;
|
|
+ default:
|
|
+ return PVRDMA_WR_ERROR;
|
|
+ }
|
|
}
|
|
|
|
static inline enum ib_wc_status pvrdma_wc_status_to_ib(
|
|
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c
|
|
index d7162f2b7979..4d9c99dd366b 100644
|
|
--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c
|
|
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c
|
|
@@ -695,6 +695,12 @@ int pvrdma_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
|
|
wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM)
|
|
wqe_hdr->ex.imm_data = wr->ex.imm_data;
|
|
|
|
+ if (unlikely(wqe_hdr->opcode == PVRDMA_WR_ERROR)) {
|
|
+ *bad_wr = wr;
|
|
+ ret = -EINVAL;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
switch (qp->ibqp.qp_type) {
|
|
case IB_QPT_GSI:
|
|
case IB_QPT_UD:
|
|
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
|
|
index 2ce805d31ed1..ad89ba143a0e 100644
|
|
--- a/drivers/input/mouse/elan_i2c_core.c
|
|
+++ b/drivers/input/mouse/elan_i2c_core.c
|
|
@@ -1254,22 +1254,47 @@ static const struct acpi_device_id elan_acpi_id[] = {
|
|
{ "ELAN0600", 0 },
|
|
{ "ELAN0601", 0 },
|
|
{ "ELAN0602", 0 },
|
|
+ { "ELAN0603", 0 },
|
|
+ { "ELAN0604", 0 },
|
|
{ "ELAN0605", 0 },
|
|
+ { "ELAN0606", 0 },
|
|
+ { "ELAN0607", 0 },
|
|
{ "ELAN0608", 0 },
|
|
{ "ELAN0605", 0 },
|
|
{ "ELAN0609", 0 },
|
|
{ "ELAN060B", 0 },
|
|
{ "ELAN060C", 0 },
|
|
+ { "ELAN060F", 0 },
|
|
+ { "ELAN0610", 0 },
|
|
{ "ELAN0611", 0 },
|
|
{ "ELAN0612", 0 },
|
|
+ { "ELAN0615", 0 },
|
|
+ { "ELAN0616", 0 },
|
|
{ "ELAN0617", 0 },
|
|
{ "ELAN0618", 0 },
|
|
+ { "ELAN0619", 0 },
|
|
+ { "ELAN061A", 0 },
|
|
+ { "ELAN061B", 0 },
|
|
{ "ELAN061C", 0 },
|
|
{ "ELAN061D", 0 },
|
|
{ "ELAN061E", 0 },
|
|
+ { "ELAN061F", 0 },
|
|
{ "ELAN0620", 0 },
|
|
{ "ELAN0621", 0 },
|
|
{ "ELAN0622", 0 },
|
|
+ { "ELAN0623", 0 },
|
|
+ { "ELAN0624", 0 },
|
|
+ { "ELAN0625", 0 },
|
|
+ { "ELAN0626", 0 },
|
|
+ { "ELAN0627", 0 },
|
|
+ { "ELAN0628", 0 },
|
|
+ { "ELAN0629", 0 },
|
|
+ { "ELAN062A", 0 },
|
|
+ { "ELAN062B", 0 },
|
|
+ { "ELAN062C", 0 },
|
|
+ { "ELAN062D", 0 },
|
|
+ { "ELAN0631", 0 },
|
|
+ { "ELAN0632", 0 },
|
|
{ "ELAN1000", 0 },
|
|
{ }
|
|
};
|
|
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
|
|
index f5954981e9ee..997ccae7ee05 100644
|
|
--- a/drivers/input/rmi4/rmi_driver.c
|
|
+++ b/drivers/input/rmi4/rmi_driver.c
|
|
@@ -883,7 +883,7 @@ static int rmi_create_function(struct rmi_device *rmi_dev,
|
|
|
|
error = rmi_register_function(fn);
|
|
if (error)
|
|
- goto err_put_fn;
|
|
+ return error;
|
|
|
|
if (pdt->function_number == 0x01)
|
|
data->f01_container = fn;
|
|
@@ -893,10 +893,6 @@ static int rmi_create_function(struct rmi_device *rmi_dev,
|
|
list_add_tail(&fn->node, &data->function_list);
|
|
|
|
return RMI_SCAN_CONTINUE;
|
|
-
|
|
-err_put_fn:
|
|
- put_device(&fn->dev);
|
|
- return error;
|
|
}
|
|
|
|
void rmi_enable_irq(struct rmi_device *rmi_dev, bool clear_wake)
|
|
diff --git a/drivers/irqchip/irq-ath79-misc.c b/drivers/irqchip/irq-ath79-misc.c
|
|
index aa7290784636..0390603170b4 100644
|
|
--- a/drivers/irqchip/irq-ath79-misc.c
|
|
+++ b/drivers/irqchip/irq-ath79-misc.c
|
|
@@ -22,6 +22,15 @@
|
|
#define AR71XX_RESET_REG_MISC_INT_ENABLE 4
|
|
|
|
#define ATH79_MISC_IRQ_COUNT 32
|
|
+#define ATH79_MISC_PERF_IRQ 5
|
|
+
|
|
+static int ath79_perfcount_irq;
|
|
+
|
|
+int get_c0_perfcount_int(void)
|
|
+{
|
|
+ return ath79_perfcount_irq;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
|
|
|
|
static void ath79_misc_irq_handler(struct irq_desc *desc)
|
|
{
|
|
@@ -113,6 +122,8 @@ static void __init ath79_misc_intc_domain_init(
|
|
{
|
|
void __iomem *base = domain->host_data;
|
|
|
|
+ ath79_perfcount_irq = irq_create_mapping(domain, ATH79_MISC_PERF_IRQ);
|
|
+
|
|
/* Disable and clear all interrupts */
|
|
__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
|
|
__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
|
|
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
|
|
index c5603d1a07d6..65cb4aac8dce 100644
|
|
--- a/drivers/isdn/mISDN/socket.c
|
|
+++ b/drivers/isdn/mISDN/socket.c
|
|
@@ -712,10 +712,10 @@ base_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
|
|
struct sock *sk = sock->sk;
|
|
int err = 0;
|
|
|
|
- if (!maddr || maddr->family != AF_ISDN)
|
|
+ if (addr_len < sizeof(struct sockaddr_mISDN))
|
|
return -EINVAL;
|
|
|
|
- if (addr_len < sizeof(struct sockaddr_mISDN))
|
|
+ if (!maddr || maddr->family != AF_ISDN)
|
|
return -EINVAL;
|
|
|
|
lock_sock(sk);
|
|
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
|
|
index 8d456dc6c5bf..83f9bbe57e02 100644
|
|
--- a/drivers/leds/leds-pwm.c
|
|
+++ b/drivers/leds/leds-pwm.c
|
|
@@ -101,8 +101,9 @@ static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,
|
|
led_data->pwm = devm_pwm_get(dev, led->name);
|
|
if (IS_ERR(led_data->pwm)) {
|
|
ret = PTR_ERR(led_data->pwm);
|
|
- dev_err(dev, "unable to request PWM for %s: %d\n",
|
|
- led->name, ret);
|
|
+ if (ret != -EPROBE_DEFER)
|
|
+ dev_err(dev, "unable to request PWM for %s: %d\n",
|
|
+ led->name, ret);
|
|
return ret;
|
|
}
|
|
|
|
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
|
|
index fe6e4c319b7c..9e875aba41b9 100644
|
|
--- a/drivers/md/bcache/super.c
|
|
+++ b/drivers/md/bcache/super.c
|
|
@@ -1045,12 +1045,13 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c,
|
|
}
|
|
|
|
if (BDEV_STATE(&dc->sb) == BDEV_STATE_DIRTY) {
|
|
- bch_sectors_dirty_init(&dc->disk);
|
|
atomic_set(&dc->has_dirty, 1);
|
|
atomic_inc(&dc->count);
|
|
bch_writeback_queue(dc);
|
|
}
|
|
|
|
+ bch_sectors_dirty_init(&dc->disk);
|
|
+
|
|
bch_cached_dev_run(dc);
|
|
bcache_device_link(&dc->disk, c, "bdev");
|
|
|
|
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
|
|
index 77a482c6eeda..b8f887bfa06a 100644
|
|
--- a/drivers/md/raid5.c
|
|
+++ b/drivers/md/raid5.c
|
|
@@ -4218,26 +4218,15 @@ static void handle_parity_checks6(struct r5conf *conf, struct stripe_head *sh,
|
|
case check_state_check_result:
|
|
sh->check_state = check_state_idle;
|
|
|
|
+ if (s->failed > 1)
|
|
+ break;
|
|
/* handle a successful check operation, if parity is correct
|
|
* we are done. Otherwise update the mismatch count and repair
|
|
* parity if !MD_RECOVERY_CHECK
|
|
*/
|
|
if (sh->ops.zero_sum_result == 0) {
|
|
- /* both parities are correct */
|
|
- if (!s->failed)
|
|
- set_bit(STRIPE_INSYNC, &sh->state);
|
|
- else {
|
|
- /* in contrast to the raid5 case we can validate
|
|
- * parity, but still have a failure to write
|
|
- * back
|
|
- */
|
|
- sh->check_state = check_state_compute_result;
|
|
- /* Returning at this point means that we may go
|
|
- * off and bring p and/or q uptodate again so
|
|
- * we make sure to check zero_sum_result again
|
|
- * to verify if p or q need writeback
|
|
- */
|
|
- }
|
|
+ /* Any parity checked was correct */
|
|
+ set_bit(STRIPE_INSYNC, &sh->state);
|
|
} else {
|
|
atomic64_add(STRIPE_SECTORS, &conf->mddev->resync_mismatches);
|
|
if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery)) {
|
|
diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c
|
|
index a079f7fe018c..21a5f45e0259 100644
|
|
--- a/drivers/media/cec/cec-api.c
|
|
+++ b/drivers/media/cec/cec-api.c
|
|
@@ -113,6 +113,23 @@ static long cec_adap_g_phys_addr(struct cec_adapter *adap,
|
|
return 0;
|
|
}
|
|
|
|
+static int cec_validate_phys_addr(u16 phys_addr)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ if (phys_addr == CEC_PHYS_ADDR_INVALID)
|
|
+ return 0;
|
|
+ for (i = 0; i < 16; i += 4)
|
|
+ if (phys_addr & (0xf << i))
|
|
+ break;
|
|
+ if (i == 16)
|
|
+ return 0;
|
|
+ for (i += 4; i < 16; i += 4)
|
|
+ if ((phys_addr & (0xf << i)) == 0)
|
|
+ return -EINVAL;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static long cec_adap_s_phys_addr(struct cec_adapter *adap, struct cec_fh *fh,
|
|
bool block, __u16 __user *parg)
|
|
{
|
|
@@ -124,7 +141,7 @@ static long cec_adap_s_phys_addr(struct cec_adapter *adap, struct cec_fh *fh,
|
|
if (copy_from_user(&phys_addr, parg, sizeof(phys_addr)))
|
|
return -EFAULT;
|
|
|
|
- err = cec_phys_addr_validate(phys_addr, NULL, NULL);
|
|
+ err = cec_validate_phys_addr(phys_addr);
|
|
if (err)
|
|
return err;
|
|
mutex_lock(&adap->lock);
|
|
diff --git a/drivers/media/cec/cec-edid.c b/drivers/media/cec/cec-edid.c
|
|
index 38e3fec6152b..19a31d4c8603 100644
|
|
--- a/drivers/media/cec/cec-edid.c
|
|
+++ b/drivers/media/cec/cec-edid.c
|
|
@@ -22,66 +22,6 @@
|
|
#include <linux/types.h>
|
|
#include <media/cec.h>
|
|
|
|
-/*
|
|
- * This EDID is expected to be a CEA-861 compliant, which means that there are
|
|
- * at least two blocks and one or more of the extensions blocks are CEA-861
|
|
- * blocks.
|
|
- *
|
|
- * The returned location is guaranteed to be < size - 1.
|
|
- */
|
|
-static unsigned int cec_get_edid_spa_location(const u8 *edid, unsigned int size)
|
|
-{
|
|
- unsigned int blocks = size / 128;
|
|
- unsigned int block;
|
|
- u8 d;
|
|
-
|
|
- /* Sanity check: at least 2 blocks and a multiple of the block size */
|
|
- if (blocks < 2 || size % 128)
|
|
- return 0;
|
|
-
|
|
- /*
|
|
- * If there are fewer extension blocks than the size, then update
|
|
- * 'blocks'. It is allowed to have more extension blocks than the size,
|
|
- * since some hardware can only read e.g. 256 bytes of the EDID, even
|
|
- * though more blocks are present. The first CEA-861 extension block
|
|
- * should normally be in block 1 anyway.
|
|
- */
|
|
- if (edid[0x7e] + 1 < blocks)
|
|
- blocks = edid[0x7e] + 1;
|
|
-
|
|
- for (block = 1; block < blocks; block++) {
|
|
- unsigned int offset = block * 128;
|
|
-
|
|
- /* Skip any non-CEA-861 extension blocks */
|
|
- if (edid[offset] != 0x02 || edid[offset + 1] != 0x03)
|
|
- continue;
|
|
-
|
|
- /* search Vendor Specific Data Block (tag 3) */
|
|
- d = edid[offset + 2] & 0x7f;
|
|
- /* Check if there are Data Blocks */
|
|
- if (d <= 4)
|
|
- continue;
|
|
- if (d > 4) {
|
|
- unsigned int i = offset + 4;
|
|
- unsigned int end = offset + d;
|
|
-
|
|
- /* Note: 'end' is always < 'size' */
|
|
- do {
|
|
- u8 tag = edid[i] >> 5;
|
|
- u8 len = edid[i] & 0x1f;
|
|
-
|
|
- if (tag == 3 && len >= 5 && i + len <= end &&
|
|
- edid[i + 1] == 0x03 &&
|
|
- edid[i + 2] == 0x0c &&
|
|
- edid[i + 3] == 0x00)
|
|
- return i + 4;
|
|
- i += len + 1;
|
|
- } while (i < end);
|
|
- }
|
|
- }
|
|
- return 0;
|
|
-}
|
|
-
|
|
u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
|
|
unsigned int *offset)
|
|
{
|
|
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
|
|
index d2108aad3c65..26c3ec573a56 100644
|
|
--- a/drivers/media/i2c/adv7604.c
|
|
+++ b/drivers/media/i2c/adv7604.c
|
|
@@ -2295,8 +2295,10 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
|
|
state->aspect_ratio.numerator = 16;
|
|
state->aspect_ratio.denominator = 9;
|
|
|
|
- if (!state->edid.present)
|
|
+ if (!state->edid.present) {
|
|
state->edid.blocks = 0;
|
|
+ cec_phys_addr_invalidate(state->cec_adap);
|
|
+ }
|
|
|
|
v4l2_dbg(2, debug, sd, "%s: clear EDID pad %d, edid.present = 0x%x\n",
|
|
__func__, edid->pad, state->edid.present);
|
|
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
|
|
index f9c23173c9fa..dcce8d030e5d 100644
|
|
--- a/drivers/media/i2c/adv7842.c
|
|
+++ b/drivers/media/i2c/adv7842.c
|
|
@@ -799,8 +799,10 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port)
|
|
/* Disable I2C access to internal EDID ram from HDMI DDC ports */
|
|
rep_write_and_or(sd, 0x77, 0xf3, 0x00);
|
|
|
|
- if (!state->hdmi_edid.present)
|
|
+ if (!state->hdmi_edid.present) {
|
|
+ cec_phys_addr_invalidate(state->cec_adap);
|
|
return 0;
|
|
+ }
|
|
|
|
pa = cec_get_edid_phys_addr(edid, 256, &spa_loc);
|
|
err = cec_phys_addr_validate(pa, &pa, NULL);
|
|
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
|
|
index 39a2269c0bee..acf5c8a55bbd 100644
|
|
--- a/drivers/media/i2c/ov5640.c
|
|
+++ b/drivers/media/i2c/ov5640.c
|
|
@@ -1216,7 +1216,7 @@ static int ov5640_set_ae_target(struct ov5640_dev *sensor, int target)
|
|
return ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL1F, fast_low);
|
|
}
|
|
|
|
-static int ov5640_binning_on(struct ov5640_dev *sensor)
|
|
+static int ov5640_get_binning(struct ov5640_dev *sensor)
|
|
{
|
|
u8 temp;
|
|
int ret;
|
|
@@ -1224,8 +1224,8 @@ static int ov5640_binning_on(struct ov5640_dev *sensor)
|
|
ret = ov5640_read_reg(sensor, OV5640_REG_TIMING_TC_REG21, &temp);
|
|
if (ret)
|
|
return ret;
|
|
- temp &= 0xfe;
|
|
- return temp ? 1 : 0;
|
|
+
|
|
+ return temp & BIT(0);
|
|
}
|
|
|
|
static int ov5640_set_virtual_channel(struct ov5640_dev *sensor)
|
|
@@ -1293,7 +1293,7 @@ static int ov5640_set_mode_exposure_calc(
|
|
if (ret < 0)
|
|
return ret;
|
|
prev_shutter = ret;
|
|
- ret = ov5640_binning_on(sensor);
|
|
+ ret = ov5640_get_binning(sensor);
|
|
if (ret < 0)
|
|
return ret;
|
|
if (ret && mode->id != OV5640_MODE_720P_1280_720 &&
|
|
@@ -1900,16 +1900,12 @@ static int ov5640_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
|
|
|
|
switch (ctrl->id) {
|
|
case V4L2_CID_AUTOGAIN:
|
|
- if (!ctrl->val)
|
|
- return 0;
|
|
val = ov5640_get_gain(sensor);
|
|
if (val < 0)
|
|
return val;
|
|
sensor->ctrls.gain->val = val;
|
|
break;
|
|
case V4L2_CID_EXPOSURE_AUTO:
|
|
- if (ctrl->val == V4L2_EXPOSURE_MANUAL)
|
|
- return 0;
|
|
val = ov5640_get_exposure(sensor);
|
|
if (val < 0)
|
|
return val;
|
|
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
|
|
index aba0d652095b..f3357091e9d1 100644
|
|
--- a/drivers/net/Kconfig
|
|
+++ b/drivers/net/Kconfig
|
|
@@ -212,8 +212,8 @@ config GENEVE
|
|
|
|
config GTP
|
|
tristate "GPRS Tunneling Protocol datapath (GTP-U)"
|
|
- depends on INET && NET_UDP_TUNNEL
|
|
- select NET_IP_TUNNEL
|
|
+ depends on INET
|
|
+ select NET_UDP_TUNNEL
|
|
---help---
|
|
This allows one to create gtp virtual interfaces that provide
|
|
the GPRS Tunneling Protocol datapath (GTP-U). This tunneling protocol
|
|
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
|
|
index 3d154eb63dcf..f24df859f0a7 100644
|
|
--- a/drivers/net/bonding/bond_options.c
|
|
+++ b/drivers/net/bonding/bond_options.c
|
|
@@ -1098,13 +1098,6 @@ static int bond_option_arp_validate_set(struct bonding *bond,
|
|
{
|
|
netdev_dbg(bond->dev, "Setting arp_validate to %s (%llu)\n",
|
|
newval->string, newval->value);
|
|
-
|
|
- if (bond->dev->flags & IFF_UP) {
|
|
- if (!newval->value)
|
|
- bond->recv_probe = NULL;
|
|
- else if (bond->params.arp_interval)
|
|
- bond->recv_probe = bond_arp_rcv;
|
|
- }
|
|
bond->params.arp_validate = newval->value;
|
|
|
|
return 0;
|
|
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
|
|
index a202c50d6fc7..d5f8bf87519a 100644
|
|
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
|
|
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
|
|
@@ -1639,7 +1639,7 @@ static struct sk_buff *dpaa_cleanup_tx_fd(const struct dpaa_priv *priv,
|
|
qm_sg_entry_get_len(&sgt[0]), dma_dir);
|
|
|
|
/* remaining pages were mapped with skb_frag_dma_map() */
|
|
- for (i = 1; i < nr_frags; i++) {
|
|
+ for (i = 1; i <= nr_frags; i++) {
|
|
WARN_ON(qm_sg_entry_is_ext(&sgt[i]));
|
|
|
|
dma_unmap_page(dev, qm_sg_addr(&sgt[i]),
|
|
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
|
|
index ce55c8f7f33a..ad3aabc39cc2 100644
|
|
--- a/drivers/net/ethernet/freescale/fec_main.c
|
|
+++ b/drivers/net/ethernet/freescale/fec_main.c
|
|
@@ -1851,13 +1851,9 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
|
|
int ret;
|
|
|
|
if (enable) {
|
|
- ret = clk_prepare_enable(fep->clk_ahb);
|
|
- if (ret)
|
|
- return ret;
|
|
-
|
|
ret = clk_prepare_enable(fep->clk_enet_out);
|
|
if (ret)
|
|
- goto failed_clk_enet_out;
|
|
+ return ret;
|
|
|
|
if (fep->clk_ptp) {
|
|
mutex_lock(&fep->ptp_clk_mutex);
|
|
@@ -1875,7 +1871,6 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
|
|
if (ret)
|
|
goto failed_clk_ref;
|
|
} else {
|
|
- clk_disable_unprepare(fep->clk_ahb);
|
|
clk_disable_unprepare(fep->clk_enet_out);
|
|
if (fep->clk_ptp) {
|
|
mutex_lock(&fep->ptp_clk_mutex);
|
|
@@ -1894,8 +1889,6 @@ failed_clk_ref:
|
|
failed_clk_ptp:
|
|
if (fep->clk_enet_out)
|
|
clk_disable_unprepare(fep->clk_enet_out);
|
|
-failed_clk_enet_out:
|
|
- clk_disable_unprepare(fep->clk_ahb);
|
|
|
|
return ret;
|
|
}
|
|
@@ -3455,6 +3448,9 @@ fec_probe(struct platform_device *pdev)
|
|
ret = clk_prepare_enable(fep->clk_ipg);
|
|
if (ret)
|
|
goto failed_clk_ipg;
|
|
+ ret = clk_prepare_enable(fep->clk_ahb);
|
|
+ if (ret)
|
|
+ goto failed_clk_ahb;
|
|
|
|
fep->reg_phy = devm_regulator_get(&pdev->dev, "phy");
|
|
if (!IS_ERR(fep->reg_phy)) {
|
|
@@ -3546,6 +3542,9 @@ failed_reset:
|
|
pm_runtime_put(&pdev->dev);
|
|
pm_runtime_disable(&pdev->dev);
|
|
failed_regulator:
|
|
+ clk_disable_unprepare(fep->clk_ahb);
|
|
+failed_clk_ahb:
|
|
+ clk_disable_unprepare(fep->clk_ipg);
|
|
failed_clk_ipg:
|
|
fec_enet_clk_enable(ndev, false);
|
|
failed_clk:
|
|
@@ -3669,6 +3668,7 @@ static int __maybe_unused fec_runtime_suspend(struct device *dev)
|
|
struct net_device *ndev = dev_get_drvdata(dev);
|
|
struct fec_enet_private *fep = netdev_priv(ndev);
|
|
|
|
+ clk_disable_unprepare(fep->clk_ahb);
|
|
clk_disable_unprepare(fep->clk_ipg);
|
|
|
|
return 0;
|
|
@@ -3678,8 +3678,20 @@ static int __maybe_unused fec_runtime_resume(struct device *dev)
|
|
{
|
|
struct net_device *ndev = dev_get_drvdata(dev);
|
|
struct fec_enet_private *fep = netdev_priv(ndev);
|
|
+ int ret;
|
|
|
|
- return clk_prepare_enable(fep->clk_ipg);
|
|
+ ret = clk_prepare_enable(fep->clk_ahb);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ ret = clk_prepare_enable(fep->clk_ipg);
|
|
+ if (ret)
|
|
+ goto failed_clk_ipg;
|
|
+
|
|
+ return 0;
|
|
+
|
|
+failed_clk_ipg:
|
|
+ clk_disable_unprepare(fep->clk_ahb);
|
|
+ return ret;
|
|
}
|
|
|
|
static const struct dev_pm_ops fec_pm_ops = {
|
|
diff --git a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
|
|
index 4df282ed22c7..9b4bd74665e0 100644
|
|
--- a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
|
|
+++ b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
|
|
@@ -252,14 +252,12 @@ uec_set_ringparam(struct net_device *netdev,
|
|
return -EINVAL;
|
|
}
|
|
|
|
+ if (netif_running(netdev))
|
|
+ return -EBUSY;
|
|
+
|
|
ug_info->bdRingLenRx[queue] = ring->rx_pending;
|
|
ug_info->bdRingLenTx[queue] = ring->tx_pending;
|
|
|
|
- if (netif_running(netdev)) {
|
|
- /* FIXME: restart automatically */
|
|
- netdev_info(netdev, "Please re-open the interface\n");
|
|
- }
|
|
-
|
|
return ret;
|
|
}
|
|
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
|
|
index 8fd040817804..b681c07b33fb 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
|
|
@@ -1267,6 +1267,12 @@ int hns_nic_init_phy(struct net_device *ndev, struct hnae_handle *h)
|
|
if (!h->phy_dev)
|
|
return 0;
|
|
|
|
+ phy_dev->supported &= h->if_support;
|
|
+ phy_dev->advertising = phy_dev->supported;
|
|
+
|
|
+ if (h->phy_if == PHY_INTERFACE_MODE_XGMII)
|
|
+ phy_dev->autoneg = false;
|
|
+
|
|
if (h->phy_if != PHY_INTERFACE_MODE_XGMII) {
|
|
phy_dev->dev_flags = 0;
|
|
|
|
@@ -1278,15 +1284,6 @@ int hns_nic_init_phy(struct net_device *ndev, struct hnae_handle *h)
|
|
if (unlikely(ret))
|
|
return -ENODEV;
|
|
|
|
- phy_dev->supported &= h->if_support;
|
|
- phy_dev->advertising = phy_dev->supported;
|
|
-
|
|
- if (h->phy_if == PHY_INTERFACE_MODE_XGMII)
|
|
- phy_dev->autoneg = false;
|
|
-
|
|
- if (h->phy_if == PHY_INTERFACE_MODE_SGMII)
|
|
- phy_stop(phy_dev);
|
|
-
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
|
|
index cced009da869..fad26046e159 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
|
|
@@ -600,7 +600,7 @@ static int mlxsw_emad_init(struct mlxsw_core *mlxsw_core)
|
|
if (!(mlxsw_core->bus->features & MLXSW_BUS_F_TXRX))
|
|
return 0;
|
|
|
|
- emad_wq = alloc_workqueue("mlxsw_core_emad", WQ_MEM_RECLAIM, 0);
|
|
+ emad_wq = alloc_workqueue("mlxsw_core_emad", 0, 0);
|
|
if (!emad_wq)
|
|
return -ENOMEM;
|
|
mlxsw_core->emad_wq = emad_wq;
|
|
@@ -1812,10 +1812,10 @@ static int __init mlxsw_core_module_init(void)
|
|
{
|
|
int err;
|
|
|
|
- mlxsw_wq = alloc_workqueue(mlxsw_core_driver_name, WQ_MEM_RECLAIM, 0);
|
|
+ mlxsw_wq = alloc_workqueue(mlxsw_core_driver_name, 0, 0);
|
|
if (!mlxsw_wq)
|
|
return -ENOMEM;
|
|
- mlxsw_owq = alloc_ordered_workqueue("%s_ordered", WQ_MEM_RECLAIM,
|
|
+ mlxsw_owq = alloc_ordered_workqueue("%s_ordered", 0,
|
|
mlxsw_core_driver_name);
|
|
if (!mlxsw_owq) {
|
|
err = -ENOMEM;
|
|
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
|
|
index 3ba9f2c079b2..8a1788108f52 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
|
|
@@ -1320,7 +1320,7 @@ static int mlxsw_sp_port_mdb_add(struct mlxsw_sp_port *mlxsw_sp_port,
|
|
u16 fid_index;
|
|
int err = 0;
|
|
|
|
- if (switchdev_trans_ph_prepare(trans))
|
|
+ if (switchdev_trans_ph_commit(trans))
|
|
return 0;
|
|
|
|
bridge_port = mlxsw_sp_bridge_port_find(mlxsw_sp->bridge, orig_dev);
|
|
diff --git a/drivers/net/ethernet/seeq/sgiseeq.c b/drivers/net/ethernet/seeq/sgiseeq.c
|
|
index 573691bc3b71..84a42ed97601 100644
|
|
--- a/drivers/net/ethernet/seeq/sgiseeq.c
|
|
+++ b/drivers/net/ethernet/seeq/sgiseeq.c
|
|
@@ -734,6 +734,7 @@ static int sgiseeq_probe(struct platform_device *pdev)
|
|
}
|
|
|
|
platform_set_drvdata(pdev, dev);
|
|
+ SET_NETDEV_DEV(dev, &pdev->dev);
|
|
sp = netdev_priv(dev);
|
|
|
|
/* Make private data page aligned */
|
|
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
|
|
index 14866331eced..a62128a444a6 100644
|
|
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
|
|
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
|
|
@@ -858,6 +858,8 @@ static struct mac_device_info *sun8i_dwmac_setup(void *ppriv)
|
|
mac->mac = &sun8i_dwmac_ops;
|
|
mac->dma = &sun8i_dwmac_dma_ops;
|
|
|
|
+ priv->dev->priv_flags |= IFF_UNICAST_FLT;
|
|
+
|
|
/* The loopback bit seems to be re-set when link change
|
|
* Simply mask it each time
|
|
* Speed 10/100/1000 are set in BIT(2)/BIT(3)
|
|
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
|
index 0f85e540001f..f4df9ab0aed5 100644
|
|
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
|
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
|
@@ -2530,12 +2530,6 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
|
|
netdev_warn(priv->dev, "PTP init failed\n");
|
|
}
|
|
|
|
-#ifdef CONFIG_DEBUG_FS
|
|
- ret = stmmac_init_fs(dev);
|
|
- if (ret < 0)
|
|
- netdev_warn(priv->dev, "%s: failed debugFS registration\n",
|
|
- __func__);
|
|
-#endif
|
|
priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS;
|
|
|
|
if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) {
|
|
@@ -2729,10 +2723,6 @@ static int stmmac_release(struct net_device *dev)
|
|
|
|
netif_carrier_off(dev);
|
|
|
|
-#ifdef CONFIG_DEBUG_FS
|
|
- stmmac_exit_fs(dev);
|
|
-#endif
|
|
-
|
|
stmmac_release_ptp(priv);
|
|
|
|
return 0;
|
|
@@ -3839,6 +3829,9 @@ static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v)
|
|
u32 tx_count = priv->plat->tx_queues_to_use;
|
|
u32 queue;
|
|
|
|
+ if ((dev->flags & IFF_UP) == 0)
|
|
+ return 0;
|
|
+
|
|
for (queue = 0; queue < rx_count; queue++) {
|
|
struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
|
|
|
|
@@ -4310,6 +4303,13 @@ int stmmac_dvr_probe(struct device *device,
|
|
goto error_netdev_register;
|
|
}
|
|
|
|
+#ifdef CONFIG_DEBUG_FS
|
|
+ ret = stmmac_init_fs(ndev);
|
|
+ if (ret < 0)
|
|
+ netdev_warn(priv->dev, "%s: failed debugFS registration\n",
|
|
+ __func__);
|
|
+#endif
|
|
+
|
|
return ret;
|
|
|
|
error_netdev_register:
|
|
@@ -4343,6 +4343,9 @@ int stmmac_dvr_remove(struct device *dev)
|
|
|
|
netdev_info(priv->dev, "%s: removing driver", __func__);
|
|
|
|
+#ifdef CONFIG_DEBUG_FS
|
|
+ stmmac_exit_fs(ndev);
|
|
+#endif
|
|
stmmac_stop_all_dma(priv);
|
|
|
|
priv->hw->mac->set_mac(priv->ioaddr, false);
|
|
diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/phy/spi_ks8995.c
|
|
index 1e2d4f1179da..45df03673e01 100644
|
|
--- a/drivers/net/phy/spi_ks8995.c
|
|
+++ b/drivers/net/phy/spi_ks8995.c
|
|
@@ -162,6 +162,14 @@ static const struct spi_device_id ks8995_id[] = {
|
|
};
|
|
MODULE_DEVICE_TABLE(spi, ks8995_id);
|
|
|
|
+static const struct of_device_id ks8895_spi_of_match[] = {
|
|
+ { .compatible = "micrel,ks8995" },
|
|
+ { .compatible = "micrel,ksz8864" },
|
|
+ { .compatible = "micrel,ksz8795" },
|
|
+ { },
|
|
+ };
|
|
+MODULE_DEVICE_TABLE(of, ks8895_spi_of_match);
|
|
+
|
|
static inline u8 get_chip_id(u8 val)
|
|
{
|
|
return (val >> ID1_CHIPID_S) & ID1_CHIPID_M;
|
|
@@ -529,6 +537,7 @@ static int ks8995_remove(struct spi_device *spi)
|
|
static struct spi_driver ks8995_driver = {
|
|
.driver = {
|
|
.name = "spi-ks8995",
|
|
+ .of_match_table = of_match_ptr(ks8895_spi_of_match),
|
|
},
|
|
.probe = ks8995_probe,
|
|
.remove = ks8995_remove,
|
|
diff --git a/drivers/net/wireless/marvell/mwl8k.c b/drivers/net/wireless/marvell/mwl8k.c
|
|
index e813b2ca740c..a87ccf9ceb67 100644
|
|
--- a/drivers/net/wireless/marvell/mwl8k.c
|
|
+++ b/drivers/net/wireless/marvell/mwl8k.c
|
|
@@ -436,6 +436,9 @@ static const struct ieee80211_rate mwl8k_rates_50[] = {
|
|
#define MWL8K_CMD_UPDATE_STADB 0x1123
|
|
#define MWL8K_CMD_BASTREAM 0x1125
|
|
|
|
+#define MWL8K_LEGACY_5G_RATE_OFFSET \
|
|
+ (ARRAY_SIZE(mwl8k_rates_24) - ARRAY_SIZE(mwl8k_rates_50))
|
|
+
|
|
static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize)
|
|
{
|
|
u16 command = le16_to_cpu(cmd);
|
|
@@ -1011,8 +1014,9 @@ mwl8k_rxd_ap_process(void *_rxd, struct ieee80211_rx_status *status,
|
|
|
|
if (rxd->channel > 14) {
|
|
status->band = NL80211_BAND_5GHZ;
|
|
- if (!(status->encoding == RX_ENC_HT))
|
|
- status->rate_idx -= 5;
|
|
+ if (!(status->encoding == RX_ENC_HT) &&
|
|
+ status->rate_idx >= MWL8K_LEGACY_5G_RATE_OFFSET)
|
|
+ status->rate_idx -= MWL8K_LEGACY_5G_RATE_OFFSET;
|
|
} else {
|
|
status->band = NL80211_BAND_2GHZ;
|
|
}
|
|
@@ -1119,8 +1123,9 @@ mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status,
|
|
|
|
if (rxd->channel > 14) {
|
|
status->band = NL80211_BAND_5GHZ;
|
|
- if (!(status->encoding == RX_ENC_HT))
|
|
- status->rate_idx -= 5;
|
|
+ if (!(status->encoding == RX_ENC_HT) &&
|
|
+ status->rate_idx >= MWL8K_LEGACY_5G_RATE_OFFSET)
|
|
+ status->rate_idx -= MWL8K_LEGACY_5G_RATE_OFFSET;
|
|
} else {
|
|
status->band = NL80211_BAND_2GHZ;
|
|
}
|
|
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c
|
|
index 5ac7b815648a..7604a0bdaf2d 100644
|
|
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c
|
|
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c
|
|
@@ -1699,6 +1699,7 @@ static void _rtl8723e_read_adapter_info(struct ieee80211_hw *hw,
|
|
rtlhal->oem_id = RT_CID_819X_LENOVO;
|
|
break;
|
|
}
|
|
+ break;
|
|
case 0x1025:
|
|
rtlhal->oem_id = RT_CID_819X_ACER;
|
|
break;
|
|
diff --git a/drivers/net/wireless/st/cw1200/scan.c b/drivers/net/wireless/st/cw1200/scan.c
|
|
index f22c8ae15ad8..446d973cba81 100644
|
|
--- a/drivers/net/wireless/st/cw1200/scan.c
|
|
+++ b/drivers/net/wireless/st/cw1200/scan.c
|
|
@@ -84,8 +84,11 @@ int cw1200_hw_scan(struct ieee80211_hw *hw,
|
|
|
|
frame.skb = ieee80211_probereq_get(hw, priv->vif->addr, NULL, 0,
|
|
req->ie_len);
|
|
- if (!frame.skb)
|
|
+ if (!frame.skb) {
|
|
+ mutex_unlock(&priv->conf_mutex);
|
|
+ up(&priv->scan.lock);
|
|
return -ENOMEM;
|
|
+ }
|
|
|
|
if (req->ie_len)
|
|
skb_put_data(frame.skb, req->ie, req->ie_len);
|
|
diff --git a/drivers/nfc/st95hf/core.c b/drivers/nfc/st95hf/core.c
|
|
index 2b26f762fbc3..01acb6e53365 100644
|
|
--- a/drivers/nfc/st95hf/core.c
|
|
+++ b/drivers/nfc/st95hf/core.c
|
|
@@ -1074,6 +1074,12 @@ static const struct spi_device_id st95hf_id[] = {
|
|
};
|
|
MODULE_DEVICE_TABLE(spi, st95hf_id);
|
|
|
|
+static const struct of_device_id st95hf_spi_of_match[] = {
|
|
+ { .compatible = "st,st95hf" },
|
|
+ { },
|
|
+};
|
|
+MODULE_DEVICE_TABLE(of, st95hf_spi_of_match);
|
|
+
|
|
static int st95hf_probe(struct spi_device *nfc_spi_dev)
|
|
{
|
|
int ret;
|
|
@@ -1260,6 +1266,7 @@ static struct spi_driver st95hf_driver = {
|
|
.driver = {
|
|
.name = "st95hf",
|
|
.owner = THIS_MODULE,
|
|
+ .of_match_table = of_match_ptr(st95hf_spi_of_match),
|
|
},
|
|
.id_table = st95hf_id,
|
|
.probe = st95hf_probe,
|
|
diff --git a/drivers/nvdimm/btt_devs.c b/drivers/nvdimm/btt_devs.c
|
|
index d58925295aa7..e610dd890263 100644
|
|
--- a/drivers/nvdimm/btt_devs.c
|
|
+++ b/drivers/nvdimm/btt_devs.c
|
|
@@ -190,14 +190,15 @@ static struct device *__nd_btt_create(struct nd_region *nd_region,
|
|
return NULL;
|
|
|
|
nd_btt->id = ida_simple_get(&nd_region->btt_ida, 0, 0, GFP_KERNEL);
|
|
- if (nd_btt->id < 0) {
|
|
- kfree(nd_btt);
|
|
- return NULL;
|
|
- }
|
|
+ if (nd_btt->id < 0)
|
|
+ goto out_nd_btt;
|
|
|
|
nd_btt->lbasize = lbasize;
|
|
- if (uuid)
|
|
+ if (uuid) {
|
|
uuid = kmemdup(uuid, 16, GFP_KERNEL);
|
|
+ if (!uuid)
|
|
+ goto out_put_id;
|
|
+ }
|
|
nd_btt->uuid = uuid;
|
|
dev = &nd_btt->dev;
|
|
dev_set_name(dev, "btt%d.%d", nd_region->id, nd_btt->id);
|
|
@@ -212,6 +213,13 @@ static struct device *__nd_btt_create(struct nd_region *nd_region,
|
|
return NULL;
|
|
}
|
|
return dev;
|
|
+
|
|
+out_put_id:
|
|
+ ida_simple_remove(&nd_region->btt_ida, nd_btt->id);
|
|
+
|
|
+out_nd_btt:
|
|
+ kfree(nd_btt);
|
|
+ return NULL;
|
|
}
|
|
|
|
struct device *nd_btt_create(struct nd_region *nd_region)
|
|
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
|
|
index 50b01d3eadd9..e3f228af59d1 100644
|
|
--- a/drivers/nvdimm/namespace_devs.c
|
|
+++ b/drivers/nvdimm/namespace_devs.c
|
|
@@ -2234,9 +2234,12 @@ struct device *create_namespace_blk(struct nd_region *nd_region,
|
|
if (!nsblk->uuid)
|
|
goto blk_err;
|
|
memcpy(name, nd_label->name, NSLABEL_NAME_LEN);
|
|
- if (name[0])
|
|
+ if (name[0]) {
|
|
nsblk->alt_name = kmemdup(name, NSLABEL_NAME_LEN,
|
|
GFP_KERNEL);
|
|
+ if (!nsblk->alt_name)
|
|
+ goto blk_err;
|
|
+ }
|
|
res = nsblk_add_resource(nd_region, ndd, nsblk,
|
|
__le64_to_cpu(nd_label->dpa));
|
|
if (!res)
|
|
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
|
|
index a16cea2be9c3..8fcbe2a62273 100644
|
|
--- a/drivers/platform/x86/sony-laptop.c
|
|
+++ b/drivers/platform/x86/sony-laptop.c
|
|
@@ -4422,14 +4422,16 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
|
|
}
|
|
return AE_OK;
|
|
}
|
|
+
|
|
+ case ACPI_RESOURCE_TYPE_END_TAG:
|
|
+ return AE_OK;
|
|
+
|
|
default:
|
|
dprintk("Resource %d isn't an IRQ nor an IO port\n",
|
|
resource->type);
|
|
+ return AE_CTRL_TERMINATE;
|
|
|
|
- case ACPI_RESOURCE_TYPE_END_TAG:
|
|
- return AE_OK;
|
|
}
|
|
- return AE_CTRL_TERMINATE;
|
|
}
|
|
|
|
static int sony_pic_possible_resources(struct acpi_device *device)
|
|
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
|
|
index c407d52ef7cf..c3fb9d66b768 100644
|
|
--- a/drivers/platform/x86/thinkpad_acpi.c
|
|
+++ b/drivers/platform/x86/thinkpad_acpi.c
|
|
@@ -77,7 +77,7 @@
|
|
#include <linux/jiffies.h>
|
|
#include <linux/workqueue.h>
|
|
#include <linux/acpi.h>
|
|
-#include <linux/pci_ids.h>
|
|
+#include <linux/pci.h>
|
|
#include <linux/thinkpad_acpi.h>
|
|
#include <sound/core.h>
|
|
#include <sound/control.h>
|
|
@@ -4366,6 +4366,74 @@ static void bluetooth_exit(void)
|
|
bluetooth_shutdown();
|
|
}
|
|
|
|
+static const struct dmi_system_id bt_fwbug_list[] __initconst = {
|
|
+ {
|
|
+ .ident = "ThinkPad E485",
|
|
+ .matches = {
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "20KU"),
|
|
+ },
|
|
+ },
|
|
+ {
|
|
+ .ident = "ThinkPad E585",
|
|
+ .matches = {
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "20KV"),
|
|
+ },
|
|
+ },
|
|
+ {
|
|
+ .ident = "ThinkPad A285 - 20MW",
|
|
+ .matches = {
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "20MW"),
|
|
+ },
|
|
+ },
|
|
+ {
|
|
+ .ident = "ThinkPad A285 - 20MX",
|
|
+ .matches = {
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "20MX"),
|
|
+ },
|
|
+ },
|
|
+ {
|
|
+ .ident = "ThinkPad A485 - 20MU",
|
|
+ .matches = {
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "20MU"),
|
|
+ },
|
|
+ },
|
|
+ {
|
|
+ .ident = "ThinkPad A485 - 20MV",
|
|
+ .matches = {
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "20MV"),
|
|
+ },
|
|
+ },
|
|
+ {}
|
|
+};
|
|
+
|
|
+static const struct pci_device_id fwbug_cards_ids[] __initconst = {
|
|
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x24F3) },
|
|
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x24FD) },
|
|
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2526) },
|
|
+ {}
|
|
+};
|
|
+
|
|
+
|
|
+static int __init have_bt_fwbug(void)
|
|
+{
|
|
+ /*
|
|
+ * Some AMD based ThinkPads have a firmware bug that calling
|
|
+ * "GBDC" will cause bluetooth on Intel wireless cards blocked
|
|
+ */
|
|
+ if (dmi_check_system(bt_fwbug_list) && pci_dev_present(fwbug_cards_ids)) {
|
|
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
|
|
+ FW_BUG "disable bluetooth subdriver for Intel cards\n");
|
|
+ return 1;
|
|
+ } else
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int __init bluetooth_init(struct ibm_init_struct *iibm)
|
|
{
|
|
int res;
|
|
@@ -4378,7 +4446,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
|
|
|
|
/* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
|
|
G4x, R30, R31, R40e, R50e, T20-22, X20-21 */
|
|
- tp_features.bluetooth = hkey_handle &&
|
|
+ tp_features.bluetooth = !have_bt_fwbug() && hkey_handle &&
|
|
acpi_evalf(hkey_handle, &status, "GBDC", "qd");
|
|
|
|
vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
|
|
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
|
|
index 0a1e7f9b5239..0d5e2d92e05b 100644
|
|
--- a/drivers/s390/block/dasd_eckd.c
|
|
+++ b/drivers/s390/block/dasd_eckd.c
|
|
@@ -2001,14 +2001,14 @@ static int dasd_eckd_end_analysis(struct dasd_block *block)
|
|
blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
|
|
|
|
raw:
|
|
- block->blocks = (private->real_cyl *
|
|
+ block->blocks = ((unsigned long) private->real_cyl *
|
|
private->rdc_data.trk_per_cyl *
|
|
blk_per_trk);
|
|
|
|
dev_info(&device->cdev->dev,
|
|
- "DASD with %d KB/block, %d KB total size, %d KB/track, "
|
|
+ "DASD with %u KB/block, %lu KB total size, %u KB/track, "
|
|
"%s\n", (block->bp_block >> 10),
|
|
- ((private->real_cyl *
|
|
+ (((unsigned long) private->real_cyl *
|
|
private->rdc_data.trk_per_cyl *
|
|
blk_per_trk * (block->bp_block >> 9)) >> 1),
|
|
((blk_per_trk * block->bp_block) >> 10),
|
|
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
|
|
index be3e3c1206c2..1868ff803f43 100644
|
|
--- a/drivers/s390/char/con3270.c
|
|
+++ b/drivers/s390/char/con3270.c
|
|
@@ -629,7 +629,7 @@ con3270_init(void)
|
|
(void (*)(unsigned long)) con3270_read_tasklet,
|
|
(unsigned long) condev->read);
|
|
|
|
- raw3270_add_view(&condev->view, &con3270_fn, 1);
|
|
+ raw3270_add_view(&condev->view, &con3270_fn, 1, RAW3270_VIEW_LOCK_IRQ);
|
|
|
|
INIT_LIST_HEAD(&condev->freemem);
|
|
for (i = 0; i < CON3270_STRING_PAGES; i++) {
|
|
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
|
|
index c4518168fd02..4f73a38c7cbd 100644
|
|
--- a/drivers/s390/char/fs3270.c
|
|
+++ b/drivers/s390/char/fs3270.c
|
|
@@ -463,7 +463,8 @@ fs3270_open(struct inode *inode, struct file *filp)
|
|
|
|
init_waitqueue_head(&fp->wait);
|
|
fp->fs_pid = get_pid(task_pid(current));
|
|
- rc = raw3270_add_view(&fp->view, &fs3270_fn, minor);
|
|
+ rc = raw3270_add_view(&fp->view, &fs3270_fn, minor,
|
|
+ RAW3270_VIEW_LOCK_BH);
|
|
if (rc) {
|
|
fs3270_free_view(&fp->view);
|
|
goto out;
|
|
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
|
|
index 5d4f053d7c38..0f47fec35acc 100644
|
|
--- a/drivers/s390/char/raw3270.c
|
|
+++ b/drivers/s390/char/raw3270.c
|
|
@@ -919,7 +919,7 @@ raw3270_deactivate_view(struct raw3270_view *view)
|
|
* Add view to device with minor "minor".
|
|
*/
|
|
int
|
|
-raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor)
|
|
+raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor, int subclass)
|
|
{
|
|
unsigned long flags;
|
|
struct raw3270 *rp;
|
|
@@ -941,6 +941,7 @@ raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor)
|
|
view->cols = rp->cols;
|
|
view->ascebc = rp->ascebc;
|
|
spin_lock_init(&view->lock);
|
|
+ lockdep_set_subclass(&view->lock, subclass);
|
|
list_add(&view->list, &rp->view_list);
|
|
rc = 0;
|
|
spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
|
|
diff --git a/drivers/s390/char/raw3270.h b/drivers/s390/char/raw3270.h
|
|
index 114ca7cbf889..3afaa35f7351 100644
|
|
--- a/drivers/s390/char/raw3270.h
|
|
+++ b/drivers/s390/char/raw3270.h
|
|
@@ -150,6 +150,8 @@ struct raw3270_fn {
|
|
struct raw3270_view {
|
|
struct list_head list;
|
|
spinlock_t lock;
|
|
+#define RAW3270_VIEW_LOCK_IRQ 0
|
|
+#define RAW3270_VIEW_LOCK_BH 1
|
|
atomic_t ref_count;
|
|
struct raw3270 *dev;
|
|
struct raw3270_fn *fn;
|
|
@@ -158,7 +160,7 @@ struct raw3270_view {
|
|
unsigned char *ascebc; /* ascii -> ebcdic table */
|
|
};
|
|
|
|
-int raw3270_add_view(struct raw3270_view *, struct raw3270_fn *, int);
|
|
+int raw3270_add_view(struct raw3270_view *, struct raw3270_fn *, int, int);
|
|
int raw3270_activate_view(struct raw3270_view *);
|
|
void raw3270_del_view(struct raw3270_view *);
|
|
void raw3270_deactivate_view(struct raw3270_view *);
|
|
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
|
|
index e5ebe2fbee23..401688bf8fd3 100644
|
|
--- a/drivers/s390/char/tty3270.c
|
|
+++ b/drivers/s390/char/tty3270.c
|
|
@@ -978,7 +978,8 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty)
|
|
return PTR_ERR(tp);
|
|
|
|
rc = raw3270_add_view(&tp->view, &tty3270_fn,
|
|
- tty->index + RAW3270_FIRSTMINOR);
|
|
+ tty->index + RAW3270_FIRSTMINOR,
|
|
+ RAW3270_VIEW_LOCK_BH);
|
|
if (rc) {
|
|
tty3270_free_view(tp);
|
|
return rc;
|
|
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
|
|
index f61fa47135a6..bd0376dc7e1e 100644
|
|
--- a/drivers/s390/crypto/pkey_api.c
|
|
+++ b/drivers/s390/crypto/pkey_api.c
|
|
@@ -49,7 +49,8 @@ static debug_info_t *debug_info;
|
|
|
|
static void __init pkey_debug_init(void)
|
|
{
|
|
- debug_info = debug_register("pkey", 1, 1, 4 * sizeof(long));
|
|
+ /* 5 arguments per dbf entry (including the format string ptr) */
|
|
+ debug_info = debug_register("pkey", 1, 1, 5 * sizeof(long));
|
|
debug_register_view(debug_info, &debug_sprintf_view);
|
|
debug_set_level(debug_info, 3);
|
|
}
|
|
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
|
|
index 26363e0816fe..fbe35c2ac898 100644
|
|
--- a/drivers/s390/net/ctcm_main.c
|
|
+++ b/drivers/s390/net/ctcm_main.c
|
|
@@ -1594,6 +1594,7 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev)
|
|
if (priv->channel[direction] == NULL) {
|
|
if (direction == CTCM_WRITE)
|
|
channel_free(priv->channel[CTCM_READ]);
|
|
+ result = -ENODEV;
|
|
goto out_dev;
|
|
}
|
|
priv->channel[direction]->netdev = dev;
|
|
diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c
|
|
index 2c146b44d95f..cddd78893b46 100644
|
|
--- a/drivers/scsi/raid_class.c
|
|
+++ b/drivers/scsi/raid_class.c
|
|
@@ -63,8 +63,7 @@ static int raid_match(struct attribute_container *cont, struct device *dev)
|
|
* emulated RAID devices, so start with SCSI */
|
|
struct raid_internal *i = ac_to_raid_internal(cont);
|
|
|
|
-#if defined(CONFIG_SCSI) || defined(CONFIG_SCSI_MODULE)
|
|
- if (scsi_is_sdev_device(dev)) {
|
|
+ if (IS_ENABLED(CONFIG_SCSI) && scsi_is_sdev_device(dev)) {
|
|
struct scsi_device *sdev = to_scsi_device(dev);
|
|
|
|
if (i->f->cookie != sdev->host->hostt)
|
|
@@ -72,7 +71,6 @@ static int raid_match(struct attribute_container *cont, struct device *dev)
|
|
|
|
return i->f->is_raid(dev);
|
|
}
|
|
-#endif
|
|
/* FIXME: look at other subsystems too */
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/staging/olpc_dcon/Kconfig b/drivers/staging/olpc_dcon/Kconfig
|
|
index d277f048789e..8c6cc61d634b 100644
|
|
--- a/drivers/staging/olpc_dcon/Kconfig
|
|
+++ b/drivers/staging/olpc_dcon/Kconfig
|
|
@@ -2,6 +2,7 @@ config FB_OLPC_DCON
|
|
tristate "One Laptop Per Child Display CONtroller support"
|
|
depends on OLPC && FB
|
|
depends on I2C
|
|
+ depends on BACKLIGHT_LCD_SUPPORT
|
|
depends on (GPIO_CS5535 || GPIO_CS5535=n)
|
|
select BACKLIGHT_CLASS_DEVICE
|
|
---help---
|
|
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
|
|
index 1fb5e7f409c4..6ff921cf9a9e 100644
|
|
--- a/drivers/tty/vt/vt.c
|
|
+++ b/drivers/tty/vt/vt.c
|
|
@@ -2435,8 +2435,8 @@ rescan_last_byte:
|
|
}
|
|
con_flush(vc, draw_from, draw_to, &draw_x);
|
|
console_conditional_schedule();
|
|
- console_unlock();
|
|
notify_update(vc);
|
|
+ console_unlock();
|
|
return n;
|
|
}
|
|
|
|
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
|
|
index 35cb8c0e584f..efd7ce92878b 100644
|
|
--- a/drivers/usb/serial/generic.c
|
|
+++ b/drivers/usb/serial/generic.c
|
|
@@ -379,6 +379,7 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)
|
|
struct usb_serial_port *port = urb->context;
|
|
unsigned char *data = urb->transfer_buffer;
|
|
unsigned long flags;
|
|
+ bool stopped = false;
|
|
int status = urb->status;
|
|
int i;
|
|
|
|
@@ -386,33 +387,51 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)
|
|
if (urb == port->read_urbs[i])
|
|
break;
|
|
}
|
|
- set_bit(i, &port->read_urbs_free);
|
|
|
|
dev_dbg(&port->dev, "%s - urb %d, len %d\n", __func__, i,
|
|
urb->actual_length);
|
|
switch (status) {
|
|
case 0:
|
|
+ usb_serial_debug_data(&port->dev, __func__, urb->actual_length,
|
|
+ data);
|
|
+ port->serial->type->process_read_urb(urb);
|
|
break;
|
|
case -ENOENT:
|
|
case -ECONNRESET:
|
|
case -ESHUTDOWN:
|
|
dev_dbg(&port->dev, "%s - urb stopped: %d\n",
|
|
__func__, status);
|
|
- return;
|
|
+ stopped = true;
|
|
+ break;
|
|
case -EPIPE:
|
|
dev_err(&port->dev, "%s - urb stopped: %d\n",
|
|
__func__, status);
|
|
- return;
|
|
+ stopped = true;
|
|
+ break;
|
|
default:
|
|
dev_dbg(&port->dev, "%s - nonzero urb status: %d\n",
|
|
__func__, status);
|
|
- goto resubmit;
|
|
+ break;
|
|
}
|
|
|
|
- usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
|
|
- port->serial->type->process_read_urb(urb);
|
|
+ /*
|
|
+ * Make sure URB processing is done before marking as free to avoid
|
|
+ * racing with unthrottle() on another CPU. Matches the barriers
|
|
+ * implied by the test_and_clear_bit() in
|
|
+ * usb_serial_generic_submit_read_urb().
|
|
+ */
|
|
+ smp_mb__before_atomic();
|
|
+ set_bit(i, &port->read_urbs_free);
|
|
+ /*
|
|
+ * Make sure URB is marked as free before checking the throttled flag
|
|
+ * to avoid racing with unthrottle() on another CPU. Matches the
|
|
+ * smp_mb() in unthrottle().
|
|
+ */
|
|
+ smp_mb__after_atomic();
|
|
+
|
|
+ if (stopped)
|
|
+ return;
|
|
|
|
-resubmit:
|
|
/* Throttle the device if requested by tty */
|
|
spin_lock_irqsave(&port->lock, flags);
|
|
port->throttled = port->throttle_req;
|
|
@@ -487,6 +506,12 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty)
|
|
port->throttled = port->throttle_req = 0;
|
|
spin_unlock_irq(&port->lock);
|
|
|
|
+ /*
|
|
+ * Matches the smp_mb__after_atomic() in
|
|
+ * usb_serial_generic_read_bulk_callback().
|
|
+ */
|
|
+ smp_mb();
|
|
+
|
|
if (was_throttled)
|
|
usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);
|
|
}
|
|
diff --git a/drivers/virt/fsl_hypervisor.c b/drivers/virt/fsl_hypervisor.c
|
|
index d993df5586c0..2e1678d22f6f 100644
|
|
--- a/drivers/virt/fsl_hypervisor.c
|
|
+++ b/drivers/virt/fsl_hypervisor.c
|
|
@@ -215,6 +215,9 @@ static long ioctl_memcpy(struct fsl_hv_ioctl_memcpy __user *p)
|
|
* hypervisor.
|
|
*/
|
|
lb_offset = param.local_vaddr & (PAGE_SIZE - 1);
|
|
+ if (param.count == 0 ||
|
|
+ param.count > U64_MAX - lb_offset - PAGE_SIZE + 1)
|
|
+ return -EINVAL;
|
|
num_pages = (param.count + lb_offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
|
|
|
/* Allocate the buffers we need */
|
|
@@ -331,8 +334,8 @@ static long ioctl_dtprop(struct fsl_hv_ioctl_prop __user *p, int set)
|
|
struct fsl_hv_ioctl_prop param;
|
|
char __user *upath, *upropname;
|
|
void __user *upropval;
|
|
- char *path = NULL, *propname = NULL;
|
|
- void *propval = NULL;
|
|
+ char *path, *propname;
|
|
+ void *propval;
|
|
int ret = 0;
|
|
|
|
/* Get the parameters from the user. */
|
|
@@ -344,32 +347,30 @@ static long ioctl_dtprop(struct fsl_hv_ioctl_prop __user *p, int set)
|
|
upropval = (void __user *)(uintptr_t)param.propval;
|
|
|
|
path = strndup_user(upath, FH_DTPROP_MAX_PATHLEN);
|
|
- if (IS_ERR(path)) {
|
|
- ret = PTR_ERR(path);
|
|
- goto out;
|
|
- }
|
|
+ if (IS_ERR(path))
|
|
+ return PTR_ERR(path);
|
|
|
|
propname = strndup_user(upropname, FH_DTPROP_MAX_PATHLEN);
|
|
if (IS_ERR(propname)) {
|
|
ret = PTR_ERR(propname);
|
|
- goto out;
|
|
+ goto err_free_path;
|
|
}
|
|
|
|
if (param.proplen > FH_DTPROP_MAX_PROPLEN) {
|
|
ret = -EINVAL;
|
|
- goto out;
|
|
+ goto err_free_propname;
|
|
}
|
|
|
|
propval = kmalloc(param.proplen, GFP_KERNEL);
|
|
if (!propval) {
|
|
ret = -ENOMEM;
|
|
- goto out;
|
|
+ goto err_free_propname;
|
|
}
|
|
|
|
if (set) {
|
|
if (copy_from_user(propval, upropval, param.proplen)) {
|
|
ret = -EFAULT;
|
|
- goto out;
|
|
+ goto err_free_propval;
|
|
}
|
|
|
|
param.ret = fh_partition_set_dtprop(param.handle,
|
|
@@ -388,7 +389,7 @@ static long ioctl_dtprop(struct fsl_hv_ioctl_prop __user *p, int set)
|
|
if (copy_to_user(upropval, propval, param.proplen) ||
|
|
put_user(param.proplen, &p->proplen)) {
|
|
ret = -EFAULT;
|
|
- goto out;
|
|
+ goto err_free_propval;
|
|
}
|
|
}
|
|
}
|
|
@@ -396,10 +397,12 @@ static long ioctl_dtprop(struct fsl_hv_ioctl_prop __user *p, int set)
|
|
if (put_user(param.ret, &p->ret))
|
|
ret = -EFAULT;
|
|
|
|
-out:
|
|
- kfree(path);
|
|
+err_free_propval:
|
|
kfree(propval);
|
|
+err_free_propname:
|
|
kfree(propname);
|
|
+err_free_path:
|
|
+ kfree(path);
|
|
|
|
return ret;
|
|
}
|
|
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
|
|
index e0bdc0c902e4..813834552aa1 100644
|
|
--- a/fs/btrfs/disk-io.c
|
|
+++ b/fs/btrfs/disk-io.c
|
|
@@ -1688,9 +1688,8 @@ static int cleaner_kthread(void *arg)
|
|
struct btrfs_root *root = arg;
|
|
struct btrfs_fs_info *fs_info = root->fs_info;
|
|
int again;
|
|
- struct btrfs_trans_handle *trans;
|
|
|
|
- do {
|
|
+ while (1) {
|
|
again = 0;
|
|
|
|
/* Make the cleaner go to sleep early. */
|
|
@@ -1739,42 +1738,16 @@ static int cleaner_kthread(void *arg)
|
|
*/
|
|
btrfs_delete_unused_bgs(fs_info);
|
|
sleep:
|
|
+ if (kthread_should_park())
|
|
+ kthread_parkme();
|
|
+ if (kthread_should_stop())
|
|
+ return 0;
|
|
if (!again) {
|
|
set_current_state(TASK_INTERRUPTIBLE);
|
|
- if (!kthread_should_stop())
|
|
- schedule();
|
|
+ schedule();
|
|
__set_current_state(TASK_RUNNING);
|
|
}
|
|
- } while (!kthread_should_stop());
|
|
-
|
|
- /*
|
|
- * Transaction kthread is stopped before us and wakes us up.
|
|
- * However we might have started a new transaction and COWed some
|
|
- * tree blocks when deleting unused block groups for example. So
|
|
- * make sure we commit the transaction we started to have a clean
|
|
- * shutdown when evicting the btree inode - if it has dirty pages
|
|
- * when we do the final iput() on it, eviction will trigger a
|
|
- * writeback for it which will fail with null pointer dereferences
|
|
- * since work queues and other resources were already released and
|
|
- * destroyed by the time the iput/eviction/writeback is made.
|
|
- */
|
|
- trans = btrfs_attach_transaction(root);
|
|
- if (IS_ERR(trans)) {
|
|
- if (PTR_ERR(trans) != -ENOENT)
|
|
- btrfs_err(fs_info,
|
|
- "cleaner transaction attach returned %ld",
|
|
- PTR_ERR(trans));
|
|
- } else {
|
|
- int ret;
|
|
-
|
|
- ret = btrfs_commit_transaction(trans);
|
|
- if (ret)
|
|
- btrfs_err(fs_info,
|
|
- "cleaner open transaction commit returned %d",
|
|
- ret);
|
|
}
|
|
-
|
|
- return 0;
|
|
}
|
|
|
|
static int transaction_kthread(void *arg)
|
|
@@ -3713,6 +3686,13 @@ void close_ctree(struct btrfs_fs_info *fs_info)
|
|
int ret;
|
|
|
|
set_bit(BTRFS_FS_CLOSING_START, &fs_info->flags);
|
|
+ /*
|
|
+ * We don't want the cleaner to start new transactions, add more delayed
|
|
+ * iputs, etc. while we're closing. We can't use kthread_stop() yet
|
|
+ * because that frees the task_struct, and the transaction kthread might
|
|
+ * still try to wake up the cleaner.
|
|
+ */
|
|
+ kthread_park(fs_info->cleaner_kthread);
|
|
|
|
/* wait for the qgroup rescan worker to stop */
|
|
btrfs_qgroup_wait_for_completion(fs_info, false);
|
|
@@ -3740,9 +3720,8 @@ void close_ctree(struct btrfs_fs_info *fs_info)
|
|
|
|
if (!sb_rdonly(fs_info->sb)) {
|
|
/*
|
|
- * If the cleaner thread is stopped and there are
|
|
- * block groups queued for removal, the deletion will be
|
|
- * skipped when we quit the cleaner thread.
|
|
+ * The cleaner kthread is stopped, so do one final pass over
|
|
+ * unused block groups.
|
|
*/
|
|
btrfs_delete_unused_bgs(fs_info);
|
|
|
|
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
|
|
index fd2d199dd413..7936eac5a38a 100644
|
|
--- a/fs/cifs/smb2pdu.c
|
|
+++ b/fs/cifs/smb2pdu.c
|
|
@@ -2699,6 +2699,7 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
|
|
cifs_dbg(VFS, "Send error in read = %d\n", rc);
|
|
}
|
|
free_rsp_buf(resp_buftype, rsp_iov.iov_base);
|
|
+ cifs_small_buf_release(req);
|
|
return rc == -ENODATA ? 0 : rc;
|
|
}
|
|
|
|
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
|
|
index 770733106d6d..c934fab44452 100644
|
|
--- a/fs/fuse/dev.c
|
|
+++ b/fs/fuse/dev.c
|
|
@@ -133,9 +133,13 @@ static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background)
|
|
|
|
static void fuse_drop_waiting(struct fuse_conn *fc)
|
|
{
|
|
- if (fc->connected) {
|
|
- atomic_dec(&fc->num_waiting);
|
|
- } else if (atomic_dec_and_test(&fc->num_waiting)) {
|
|
+ /*
|
|
+ * lockess check of fc->connected is okay, because atomic_dec_and_test()
|
|
+ * provides a memory barrier mached with the one in fuse_wait_aborted()
|
|
+ * to ensure no wake-up is missed.
|
|
+ */
|
|
+ if (atomic_dec_and_test(&fc->num_waiting) &&
|
|
+ !READ_ONCE(fc->connected)) {
|
|
/* wake up aborters */
|
|
wake_up_all(&fc->blocked_waitq);
|
|
}
|
|
@@ -2170,6 +2174,8 @@ EXPORT_SYMBOL_GPL(fuse_abort_conn);
|
|
|
|
void fuse_wait_aborted(struct fuse_conn *fc)
|
|
{
|
|
+ /* matches implicit memory barrier in fuse_drop_waiting() */
|
|
+ smp_mb();
|
|
wait_event(fc->blocked_waitq, atomic_read(&fc->num_waiting) == 0);
|
|
}
|
|
|
|
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
|
|
index 89d1dc19340b..9e9117533fd7 100644
|
|
--- a/fs/kernfs/dir.c
|
|
+++ b/fs/kernfs/dir.c
|
|
@@ -649,11 +649,10 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
|
|
kn->id.generation = gen;
|
|
|
|
/*
|
|
- * set ino first. This barrier is paired with atomic_inc_not_zero in
|
|
+ * set ino first. This RELEASE is paired with atomic_inc_not_zero in
|
|
* kernfs_find_and_get_node_by_ino
|
|
*/
|
|
- smp_mb__before_atomic();
|
|
- atomic_set(&kn->count, 1);
|
|
+ atomic_set_release(&kn->count, 1);
|
|
atomic_set(&kn->active, KN_DEACTIVATED_BIAS);
|
|
RB_CLEAR_NODE(&kn->rb);
|
|
|
|
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
|
|
index f00421dfacbd..0c21014a38f2 100644
|
|
--- a/include/asm-generic/pgtable.h
|
|
+++ b/include/asm-generic/pgtable.h
|
|
@@ -1081,4 +1081,20 @@ static inline bool arch_has_pfn_modify_check(void)
|
|
#endif
|
|
#endif
|
|
|
|
+/*
|
|
+ * On some architectures it depends on the mm if the p4d/pud or pmd
|
|
+ * layer of the page table hierarchy is folded or not.
|
|
+ */
|
|
+#ifndef mm_p4d_folded
|
|
+#define mm_p4d_folded(mm) __is_defined(__PAGETABLE_P4D_FOLDED)
|
|
+#endif
|
|
+
|
|
+#ifndef mm_pud_folded
|
|
+#define mm_pud_folded(mm) __is_defined(__PAGETABLE_PUD_FOLDED)
|
|
+#endif
|
|
+
|
|
+#ifndef mm_pmd_folded
|
|
+#define mm_pmd_folded(mm) __is_defined(__PAGETABLE_PMD_FOLDED)
|
|
+#endif
|
|
+
|
|
#endif /* _ASM_GENERIC_PGTABLE_H */
|
|
diff --git a/include/linux/efi.h b/include/linux/efi.h
|
|
index b68b7d199fee..2dab158b74c4 100644
|
|
--- a/include/linux/efi.h
|
|
+++ b/include/linux/efi.h
|
|
@@ -1518,7 +1518,12 @@ efi_status_t efi_setup_gop(efi_system_table_t *sys_table_arg,
|
|
struct screen_info *si, efi_guid_t *proto,
|
|
unsigned long size);
|
|
|
|
-bool efi_runtime_disabled(void);
|
|
+#ifdef CONFIG_EFI
|
|
+extern bool efi_runtime_disabled(void);
|
|
+#else
|
|
+static inline bool efi_runtime_disabled(void) { return true; }
|
|
+#endif
|
|
+
|
|
extern void efi_call_virt_check_flags(unsigned long flags, const char *call);
|
|
|
|
enum efi_secureboot_mode {
|
|
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
|
|
index 753c16633bac..026615e242d8 100644
|
|
--- a/include/linux/kvm_host.h
|
|
+++ b/include/linux/kvm_host.h
|
|
@@ -27,6 +27,7 @@
|
|
#include <linux/irqbypass.h>
|
|
#include <linux/swait.h>
|
|
#include <linux/refcount.h>
|
|
+#include <linux/nospec.h>
|
|
#include <asm/signal.h>
|
|
|
|
#include <linux/kvm.h>
|
|
@@ -483,10 +484,10 @@ static inline struct kvm_io_bus *kvm_get_bus(struct kvm *kvm, enum kvm_bus idx)
|
|
|
|
static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i)
|
|
{
|
|
- /* Pairs with smp_wmb() in kvm_vm_ioctl_create_vcpu, in case
|
|
- * the caller has read kvm->online_vcpus before (as is the case
|
|
- * for kvm_for_each_vcpu, for example).
|
|
- */
|
|
+ int num_vcpus = atomic_read(&kvm->online_vcpus);
|
|
+ i = array_index_nospec(i, num_vcpus);
|
|
+
|
|
+ /* Pairs with smp_wmb() in kvm_vm_ioctl_create_vcpu. */
|
|
smp_rmb();
|
|
return kvm->vcpus[i];
|
|
}
|
|
@@ -570,6 +571,7 @@ void kvm_put_kvm(struct kvm *kvm);
|
|
|
|
static inline struct kvm_memslots *__kvm_memslots(struct kvm *kvm, int as_id)
|
|
{
|
|
+ as_id = array_index_nospec(as_id, KVM_ADDRESS_SPACE_NUM);
|
|
return srcu_dereference_check(kvm->memslots[as_id], &kvm->srcu,
|
|
lockdep_is_held(&kvm->slots_lock) ||
|
|
!refcount_read(&kvm->users_count));
|
|
diff --git a/include/media/cec.h b/include/media/cec.h
|
|
index df6b3bd31284..b7339cc6fd3d 100644
|
|
--- a/include/media/cec.h
|
|
+++ b/include/media/cec.h
|
|
@@ -435,4 +435,74 @@ static inline void cec_phys_addr_invalidate(struct cec_adapter *adap)
|
|
cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false);
|
|
}
|
|
|
|
+/**
|
|
+ * cec_get_edid_spa_location() - find location of the Source Physical Address
|
|
+ *
|
|
+ * @edid: the EDID
|
|
+ * @size: the size of the EDID
|
|
+ *
|
|
+ * This EDID is expected to be a CEA-861 compliant, which means that there are
|
|
+ * at least two blocks and one or more of the extensions blocks are CEA-861
|
|
+ * blocks.
|
|
+ *
|
|
+ * The returned location is guaranteed to be <= size-2.
|
|
+ *
|
|
+ * This is an inline function since it is used by both CEC and V4L2.
|
|
+ * Ideally this would go in a module shared by both, but it is overkill to do
|
|
+ * that for just a single function.
|
|
+ */
|
|
+static inline unsigned int cec_get_edid_spa_location(const u8 *edid,
|
|
+ unsigned int size)
|
|
+{
|
|
+ unsigned int blocks = size / 128;
|
|
+ unsigned int block;
|
|
+ u8 d;
|
|
+
|
|
+ /* Sanity check: at least 2 blocks and a multiple of the block size */
|
|
+ if (blocks < 2 || size % 128)
|
|
+ return 0;
|
|
+
|
|
+ /*
|
|
+ * If there are fewer extension blocks than the size, then update
|
|
+ * 'blocks'. It is allowed to have more extension blocks than the size,
|
|
+ * since some hardware can only read e.g. 256 bytes of the EDID, even
|
|
+ * though more blocks are present. The first CEA-861 extension block
|
|
+ * should normally be in block 1 anyway.
|
|
+ */
|
|
+ if (edid[0x7e] + 1 < blocks)
|
|
+ blocks = edid[0x7e] + 1;
|
|
+
|
|
+ for (block = 1; block < blocks; block++) {
|
|
+ unsigned int offset = block * 128;
|
|
+
|
|
+ /* Skip any non-CEA-861 extension blocks */
|
|
+ if (edid[offset] != 0x02 || edid[offset + 1] != 0x03)
|
|
+ continue;
|
|
+
|
|
+ /* search Vendor Specific Data Block (tag 3) */
|
|
+ d = edid[offset + 2] & 0x7f;
|
|
+ /* Check if there are Data Blocks */
|
|
+ if (d <= 4)
|
|
+ continue;
|
|
+ if (d > 4) {
|
|
+ unsigned int i = offset + 4;
|
|
+ unsigned int end = offset + d;
|
|
+
|
|
+ /* Note: 'end' is always < 'size' */
|
|
+ do {
|
|
+ u8 tag = edid[i] >> 5;
|
|
+ u8 len = edid[i] & 0x1f;
|
|
+
|
|
+ if (tag == 3 && len >= 5 && i + len <= end &&
|
|
+ edid[i + 1] == 0x03 &&
|
|
+ edid[i + 2] == 0x0c &&
|
|
+ edid[i + 3] == 0x00)
|
|
+ return i + 4;
|
|
+ i += len + 1;
|
|
+ } while (i < end);
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
#endif /* _MEDIA_CEC_H */
|
|
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
|
|
index 792c3f6d30ce..93bbae8f9641 100644
|
|
--- a/include/net/netfilter/nf_conntrack.h
|
|
+++ b/include/net/netfilter/nf_conntrack.h
|
|
@@ -315,6 +315,8 @@ struct nf_conn *nf_ct_tmpl_alloc(struct net *net,
|
|
gfp_t flags);
|
|
void nf_ct_tmpl_free(struct nf_conn *tmpl);
|
|
|
|
+u32 nf_ct_get_id(const struct nf_conn *ct);
|
|
+
|
|
static inline void
|
|
nf_ct_set(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info info)
|
|
{
|
|
diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h
|
|
index 87499b6b35d6..df5c69db68af 100644
|
|
--- a/include/net/nfc/nci_core.h
|
|
+++ b/include/net/nfc/nci_core.h
|
|
@@ -166,7 +166,7 @@ struct nci_conn_info {
|
|
* According to specification 102 622 chapter 4.4 Pipes,
|
|
* the pipe identifier is 7 bits long.
|
|
*/
|
|
-#define NCI_HCI_MAX_PIPES 127
|
|
+#define NCI_HCI_MAX_PIPES 128
|
|
|
|
struct nci_hci_gate {
|
|
u8 gate;
|
|
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
|
|
index 5a24b4c700e5..9e76b2410d03 100644
|
|
--- a/include/rdma/ib_verbs.h
|
|
+++ b/include/rdma/ib_verbs.h
|
|
@@ -1251,21 +1251,27 @@ struct ib_qp_attr {
|
|
};
|
|
|
|
enum ib_wr_opcode {
|
|
- IB_WR_RDMA_WRITE,
|
|
- IB_WR_RDMA_WRITE_WITH_IMM,
|
|
- IB_WR_SEND,
|
|
- IB_WR_SEND_WITH_IMM,
|
|
- IB_WR_RDMA_READ,
|
|
- IB_WR_ATOMIC_CMP_AND_SWP,
|
|
- IB_WR_ATOMIC_FETCH_AND_ADD,
|
|
- IB_WR_LSO,
|
|
- IB_WR_SEND_WITH_INV,
|
|
- IB_WR_RDMA_READ_WITH_INV,
|
|
- IB_WR_LOCAL_INV,
|
|
- IB_WR_REG_MR,
|
|
- IB_WR_MASKED_ATOMIC_CMP_AND_SWP,
|
|
- IB_WR_MASKED_ATOMIC_FETCH_AND_ADD,
|
|
+ /* These are shared with userspace */
|
|
+ IB_WR_RDMA_WRITE = IB_UVERBS_WR_RDMA_WRITE,
|
|
+ IB_WR_RDMA_WRITE_WITH_IMM = IB_UVERBS_WR_RDMA_WRITE_WITH_IMM,
|
|
+ IB_WR_SEND = IB_UVERBS_WR_SEND,
|
|
+ IB_WR_SEND_WITH_IMM = IB_UVERBS_WR_SEND_WITH_IMM,
|
|
+ IB_WR_RDMA_READ = IB_UVERBS_WR_RDMA_READ,
|
|
+ IB_WR_ATOMIC_CMP_AND_SWP = IB_UVERBS_WR_ATOMIC_CMP_AND_SWP,
|
|
+ IB_WR_ATOMIC_FETCH_AND_ADD = IB_UVERBS_WR_ATOMIC_FETCH_AND_ADD,
|
|
+ IB_WR_LSO = IB_UVERBS_WR_TSO,
|
|
+ IB_WR_SEND_WITH_INV = IB_UVERBS_WR_SEND_WITH_INV,
|
|
+ IB_WR_RDMA_READ_WITH_INV = IB_UVERBS_WR_RDMA_READ_WITH_INV,
|
|
+ IB_WR_LOCAL_INV = IB_UVERBS_WR_LOCAL_INV,
|
|
+ IB_WR_MASKED_ATOMIC_CMP_AND_SWP =
|
|
+ IB_UVERBS_WR_MASKED_ATOMIC_CMP_AND_SWP,
|
|
+ IB_WR_MASKED_ATOMIC_FETCH_AND_ADD =
|
|
+ IB_UVERBS_WR_MASKED_ATOMIC_FETCH_AND_ADD,
|
|
+
|
|
+ /* These are kernel only and can not be issued by userspace */
|
|
+ IB_WR_REG_MR = 0x20,
|
|
IB_WR_REG_SIG_MR,
|
|
+
|
|
/* reserve values for low level drivers' internal use.
|
|
* These values will not be used at all in the ib core layer.
|
|
*/
|
|
diff --git a/include/uapi/rdma/ib_user_verbs.h b/include/uapi/rdma/ib_user_verbs.h
|
|
index e0e83a105953..e11b4def8630 100644
|
|
--- a/include/uapi/rdma/ib_user_verbs.h
|
|
+++ b/include/uapi/rdma/ib_user_verbs.h
|
|
@@ -751,10 +751,28 @@ struct ib_uverbs_sge {
|
|
__u32 lkey;
|
|
};
|
|
|
|
+enum ib_uverbs_wr_opcode {
|
|
+ IB_UVERBS_WR_RDMA_WRITE = 0,
|
|
+ IB_UVERBS_WR_RDMA_WRITE_WITH_IMM = 1,
|
|
+ IB_UVERBS_WR_SEND = 2,
|
|
+ IB_UVERBS_WR_SEND_WITH_IMM = 3,
|
|
+ IB_UVERBS_WR_RDMA_READ = 4,
|
|
+ IB_UVERBS_WR_ATOMIC_CMP_AND_SWP = 5,
|
|
+ IB_UVERBS_WR_ATOMIC_FETCH_AND_ADD = 6,
|
|
+ IB_UVERBS_WR_LOCAL_INV = 7,
|
|
+ IB_UVERBS_WR_BIND_MW = 8,
|
|
+ IB_UVERBS_WR_SEND_WITH_INV = 9,
|
|
+ IB_UVERBS_WR_TSO = 10,
|
|
+ IB_UVERBS_WR_RDMA_READ_WITH_INV = 11,
|
|
+ IB_UVERBS_WR_MASKED_ATOMIC_CMP_AND_SWP = 12,
|
|
+ IB_UVERBS_WR_MASKED_ATOMIC_FETCH_AND_ADD = 13,
|
|
+ /* Review enum ib_wr_opcode before modifying this */
|
|
+};
|
|
+
|
|
struct ib_uverbs_send_wr {
|
|
__u64 wr_id;
|
|
__u32 num_sge;
|
|
- __u32 opcode;
|
|
+ __u32 opcode; /* see enum ib_uverbs_wr_opcode */
|
|
__u32 send_flags;
|
|
union {
|
|
__u32 imm_data;
|
|
diff --git a/include/uapi/rdma/vmw_pvrdma-abi.h b/include/uapi/rdma/vmw_pvrdma-abi.h
|
|
index 912ea1556a0b..fd801c7be120 100644
|
|
--- a/include/uapi/rdma/vmw_pvrdma-abi.h
|
|
+++ b/include/uapi/rdma/vmw_pvrdma-abi.h
|
|
@@ -76,6 +76,7 @@ enum pvrdma_wr_opcode {
|
|
PVRDMA_WR_MASKED_ATOMIC_FETCH_AND_ADD,
|
|
PVRDMA_WR_BIND_MW,
|
|
PVRDMA_WR_REG_SIG_MR,
|
|
+ PVRDMA_WR_ERROR,
|
|
};
|
|
|
|
enum pvrdma_wc_status {
|
|
diff --git a/init/main.c b/init/main.c
|
|
index 3d3d79c5a232..51067e2db509 100644
|
|
--- a/init/main.c
|
|
+++ b/init/main.c
|
|
@@ -550,6 +550,8 @@ asmlinkage __visible void __init start_kernel(void)
|
|
page_alloc_init();
|
|
|
|
pr_notice("Kernel command line: %s\n", boot_command_line);
|
|
+ /* parameters may set static keys */
|
|
+ jump_label_init();
|
|
parse_early_param();
|
|
after_dashes = parse_args("Booting kernel",
|
|
static_command_line, __start___param,
|
|
@@ -559,8 +561,6 @@ asmlinkage __visible void __init start_kernel(void)
|
|
parse_args("Setting init args", after_dashes, NULL, 0, -1, -1,
|
|
NULL, set_init_arg);
|
|
|
|
- jump_label_init();
|
|
-
|
|
/*
|
|
* These use large bootmem allocations and must precede
|
|
* kmem_cache_init()
|
|
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
|
|
index 851cd1605085..a51e32de7c5f 100644
|
|
--- a/kernel/trace/trace.h
|
|
+++ b/kernel/trace/trace.h
|
|
@@ -504,12 +504,44 @@ enum {
|
|
* can only be modified by current, we can reuse trace_recursion.
|
|
*/
|
|
TRACE_IRQ_BIT,
|
|
+
|
|
+ /* Set if the function is in the set_graph_function file */
|
|
+ TRACE_GRAPH_BIT,
|
|
+
|
|
+ /*
|
|
+ * In the very unlikely case that an interrupt came in
|
|
+ * at a start of graph tracing, and we want to trace
|
|
+ * the function in that interrupt, the depth can be greater
|
|
+ * than zero, because of the preempted start of a previous
|
|
+ * trace. In an even more unlikely case, depth could be 2
|
|
+ * if a softirq interrupted the start of graph tracing,
|
|
+ * followed by an interrupt preempting a start of graph
|
|
+ * tracing in the softirq, and depth can even be 3
|
|
+ * if an NMI came in at the start of an interrupt function
|
|
+ * that preempted a softirq start of a function that
|
|
+ * preempted normal context!!!! Luckily, it can't be
|
|
+ * greater than 3, so the next two bits are a mask
|
|
+ * of what the depth is when we set TRACE_GRAPH_BIT
|
|
+ */
|
|
+
|
|
+ TRACE_GRAPH_DEPTH_START_BIT,
|
|
+ TRACE_GRAPH_DEPTH_END_BIT,
|
|
};
|
|
|
|
#define trace_recursion_set(bit) do { (current)->trace_recursion |= (1<<(bit)); } while (0)
|
|
#define trace_recursion_clear(bit) do { (current)->trace_recursion &= ~(1<<(bit)); } while (0)
|
|
#define trace_recursion_test(bit) ((current)->trace_recursion & (1<<(bit)))
|
|
|
|
+#define trace_recursion_depth() \
|
|
+ (((current)->trace_recursion >> TRACE_GRAPH_DEPTH_START_BIT) & 3)
|
|
+#define trace_recursion_set_depth(depth) \
|
|
+ do { \
|
|
+ current->trace_recursion &= \
|
|
+ ~(3 << TRACE_GRAPH_DEPTH_START_BIT); \
|
|
+ current->trace_recursion |= \
|
|
+ ((depth) & 3) << TRACE_GRAPH_DEPTH_START_BIT; \
|
|
+ } while (0)
|
|
+
|
|
#define TRACE_CONTEXT_BITS 4
|
|
|
|
#define TRACE_FTRACE_START TRACE_FTRACE_BIT
|
|
@@ -839,8 +871,9 @@ extern void __trace_graph_return(struct trace_array *tr,
|
|
extern struct ftrace_hash *ftrace_graph_hash;
|
|
extern struct ftrace_hash *ftrace_graph_notrace_hash;
|
|
|
|
-static inline int ftrace_graph_addr(unsigned long addr)
|
|
+static inline int ftrace_graph_addr(struct ftrace_graph_ent *trace)
|
|
{
|
|
+ unsigned long addr = trace->func;
|
|
int ret = 0;
|
|
|
|
preempt_disable_notrace();
|
|
@@ -851,6 +884,14 @@ static inline int ftrace_graph_addr(unsigned long addr)
|
|
}
|
|
|
|
if (ftrace_lookup_ip(ftrace_graph_hash, addr)) {
|
|
+
|
|
+ /*
|
|
+ * This needs to be cleared on the return functions
|
|
+ * when the depth is zero.
|
|
+ */
|
|
+ trace_recursion_set(TRACE_GRAPH_BIT);
|
|
+ trace_recursion_set_depth(trace->depth);
|
|
+
|
|
/*
|
|
* If no irqs are to be traced, but a set_graph_function
|
|
* is set, and called by an interrupt handler, we still
|
|
@@ -868,6 +909,13 @@ out:
|
|
return ret;
|
|
}
|
|
|
|
+static inline void ftrace_graph_addr_finish(struct ftrace_graph_ret *trace)
|
|
+{
|
|
+ if (trace_recursion_test(TRACE_GRAPH_BIT) &&
|
|
+ trace->depth == trace_recursion_depth())
|
|
+ trace_recursion_clear(TRACE_GRAPH_BIT);
|
|
+}
|
|
+
|
|
static inline int ftrace_graph_notrace_addr(unsigned long addr)
|
|
{
|
|
int ret = 0;
|
|
@@ -881,7 +929,7 @@ static inline int ftrace_graph_notrace_addr(unsigned long addr)
|
|
return ret;
|
|
}
|
|
#else
|
|
-static inline int ftrace_graph_addr(unsigned long addr)
|
|
+static inline int ftrace_graph_addr(struct ftrace_graph_ent *trace)
|
|
{
|
|
return 1;
|
|
}
|
|
@@ -890,6 +938,8 @@ static inline int ftrace_graph_notrace_addr(unsigned long addr)
|
|
{
|
|
return 0;
|
|
}
|
|
+static inline void ftrace_graph_addr_finish(struct ftrace_graph_ret *trace)
|
|
+{ }
|
|
#endif /* CONFIG_DYNAMIC_FTRACE */
|
|
|
|
extern unsigned int fgraph_max_depth;
|
|
@@ -897,7 +947,8 @@ extern unsigned int fgraph_max_depth;
|
|
static inline bool ftrace_graph_ignore_func(struct ftrace_graph_ent *trace)
|
|
{
|
|
/* trace it when it is-nested-in or is a function enabled. */
|
|
- return !(trace->depth || ftrace_graph_addr(trace->func)) ||
|
|
+ return !(trace_recursion_test(TRACE_GRAPH_BIT) ||
|
|
+ ftrace_graph_addr(trace)) ||
|
|
(trace->depth < 0) ||
|
|
(fgraph_max_depth && trace->depth >= fgraph_max_depth);
|
|
}
|
|
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
|
|
index 169b3c44ee97..72d0d477f5c1 100644
|
|
--- a/kernel/trace/trace_functions_graph.c
|
|
+++ b/kernel/trace/trace_functions_graph.c
|
|
@@ -482,6 +482,8 @@ void trace_graph_return(struct ftrace_graph_ret *trace)
|
|
int cpu;
|
|
int pc;
|
|
|
|
+ ftrace_graph_addr_finish(trace);
|
|
+
|
|
local_irq_save(flags);
|
|
cpu = raw_smp_processor_id();
|
|
data = per_cpu_ptr(tr->trace_buffer.data, cpu);
|
|
@@ -505,6 +507,8 @@ void set_graph_array(struct trace_array *tr)
|
|
|
|
static void trace_graph_thresh_return(struct ftrace_graph_ret *trace)
|
|
{
|
|
+ ftrace_graph_addr_finish(trace);
|
|
+
|
|
if (tracing_thresh &&
|
|
(trace->rettime - trace->calltime < tracing_thresh))
|
|
return;
|
|
diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c
|
|
index 7758bc0617cb..2d9e12380dc3 100644
|
|
--- a/kernel/trace/trace_irqsoff.c
|
|
+++ b/kernel/trace/trace_irqsoff.c
|
|
@@ -204,6 +204,8 @@ static void irqsoff_graph_return(struct ftrace_graph_ret *trace)
|
|
unsigned long flags;
|
|
int pc;
|
|
|
|
+ ftrace_graph_addr_finish(trace);
|
|
+
|
|
if (!func_prolog_dec(tr, &data, &flags))
|
|
return;
|
|
|
|
diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c
|
|
index 7d461dcd4831..0fa9dadf3f4f 100644
|
|
--- a/kernel/trace/trace_sched_wakeup.c
|
|
+++ b/kernel/trace/trace_sched_wakeup.c
|
|
@@ -270,6 +270,8 @@ static void wakeup_graph_return(struct ftrace_graph_ret *trace)
|
|
unsigned long flags;
|
|
int pc;
|
|
|
|
+ ftrace_graph_addr_finish(trace);
|
|
+
|
|
if (!func_prolog_preempt_disable(tr, &data, &pc))
|
|
return;
|
|
|
|
diff --git a/mm/memory.c b/mm/memory.c
|
|
index f99b64ca1303..e9bce27bc18c 100644
|
|
--- a/mm/memory.c
|
|
+++ b/mm/memory.c
|
|
@@ -1813,10 +1813,12 @@ static int insert_pfn(struct vm_area_struct *vma, unsigned long addr,
|
|
WARN_ON_ONCE(!is_zero_pfn(pte_pfn(*pte)));
|
|
goto out_unlock;
|
|
}
|
|
- entry = *pte;
|
|
- goto out_mkwrite;
|
|
- } else
|
|
- goto out_unlock;
|
|
+ entry = pte_mkyoung(*pte);
|
|
+ entry = maybe_mkwrite(pte_mkdirty(entry), vma);
|
|
+ if (ptep_set_access_flags(vma, addr, pte, entry, 1))
|
|
+ update_mmu_cache(vma, addr, pte);
|
|
+ }
|
|
+ goto out_unlock;
|
|
}
|
|
|
|
/* Ok, finally just insert the thing.. */
|
|
@@ -1825,7 +1827,6 @@ static int insert_pfn(struct vm_area_struct *vma, unsigned long addr,
|
|
else
|
|
entry = pte_mkspecial(pfn_t_pte(pfn, prot));
|
|
|
|
-out_mkwrite:
|
|
if (mkwrite) {
|
|
entry = pte_mkyoung(entry);
|
|
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
|
|
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
|
index 99837e931f53..7b140c967bca 100644
|
|
--- a/mm/vmscan.c
|
|
+++ b/mm/vmscan.c
|
|
@@ -2120,7 +2120,6 @@ static void shrink_active_list(unsigned long nr_to_scan,
|
|
* 10TB 320 32GB
|
|
*/
|
|
static bool inactive_list_is_low(struct lruvec *lruvec, bool file,
|
|
- struct mem_cgroup *memcg,
|
|
struct scan_control *sc, bool actual_reclaim)
|
|
{
|
|
enum lru_list active_lru = file * LRU_FILE + LRU_ACTIVE;
|
|
@@ -2141,16 +2140,12 @@ static bool inactive_list_is_low(struct lruvec *lruvec, bool file,
|
|
inactive = lruvec_lru_size(lruvec, inactive_lru, sc->reclaim_idx);
|
|
active = lruvec_lru_size(lruvec, active_lru, sc->reclaim_idx);
|
|
|
|
- if (memcg)
|
|
- refaults = memcg_page_state(memcg, WORKINGSET_ACTIVATE);
|
|
- else
|
|
- refaults = node_page_state(pgdat, WORKINGSET_ACTIVATE);
|
|
-
|
|
/*
|
|
* When refaults are being observed, it means a new workingset
|
|
* is being established. Disable active list protection to get
|
|
* rid of the stale workingset quickly.
|
|
*/
|
|
+ refaults = lruvec_page_state(lruvec, WORKINGSET_ACTIVATE);
|
|
if (file && actual_reclaim && lruvec->refaults != refaults) {
|
|
inactive_ratio = 0;
|
|
} else {
|
|
@@ -2171,12 +2166,10 @@ static bool inactive_list_is_low(struct lruvec *lruvec, bool file,
|
|
}
|
|
|
|
static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan,
|
|
- struct lruvec *lruvec, struct mem_cgroup *memcg,
|
|
- struct scan_control *sc)
|
|
+ struct lruvec *lruvec, struct scan_control *sc)
|
|
{
|
|
if (is_active_lru(lru)) {
|
|
- if (inactive_list_is_low(lruvec, is_file_lru(lru),
|
|
- memcg, sc, true))
|
|
+ if (inactive_list_is_low(lruvec, is_file_lru(lru), sc, true))
|
|
shrink_active_list(nr_to_scan, lruvec, sc, lru);
|
|
return 0;
|
|
}
|
|
@@ -2276,7 +2269,7 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg,
|
|
* anonymous pages on the LRU in eligible zones.
|
|
* Otherwise, the small LRU gets thrashed.
|
|
*/
|
|
- if (!inactive_list_is_low(lruvec, false, memcg, sc, false) &&
|
|
+ if (!inactive_list_is_low(lruvec, false, sc, false) &&
|
|
lruvec_lru_size(lruvec, LRU_INACTIVE_ANON, sc->reclaim_idx)
|
|
>> sc->priority) {
|
|
scan_balance = SCAN_ANON;
|
|
@@ -2294,7 +2287,7 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg,
|
|
* lruvec even if it has plenty of old anonymous pages unless the
|
|
* system is under heavy pressure.
|
|
*/
|
|
- if (!inactive_list_is_low(lruvec, true, memcg, sc, false) &&
|
|
+ if (!inactive_list_is_low(lruvec, true, sc, false) &&
|
|
lruvec_lru_size(lruvec, LRU_INACTIVE_FILE, sc->reclaim_idx) >> sc->priority) {
|
|
scan_balance = SCAN_FILE;
|
|
goto out;
|
|
@@ -2447,7 +2440,7 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc
|
|
nr[lru] -= nr_to_scan;
|
|
|
|
nr_reclaimed += shrink_list(lru, nr_to_scan,
|
|
- lruvec, memcg, sc);
|
|
+ lruvec, sc);
|
|
}
|
|
}
|
|
|
|
@@ -2514,7 +2507,7 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc
|
|
* Even if we did not try to evict anon pages at all, we want to
|
|
* rebalance the anon lru active/inactive ratio.
|
|
*/
|
|
- if (inactive_list_is_low(lruvec, false, memcg, sc, true))
|
|
+ if (inactive_list_is_low(lruvec, false, sc, true))
|
|
shrink_active_list(SWAP_CLUSTER_MAX, lruvec,
|
|
sc, LRU_ACTIVE_ANON);
|
|
}
|
|
@@ -2839,12 +2832,8 @@ static void snapshot_refaults(struct mem_cgroup *root_memcg, pg_data_t *pgdat)
|
|
unsigned long refaults;
|
|
struct lruvec *lruvec;
|
|
|
|
- if (memcg)
|
|
- refaults = memcg_page_state(memcg, WORKINGSET_ACTIVATE);
|
|
- else
|
|
- refaults = node_page_state(pgdat, WORKINGSET_ACTIVATE);
|
|
-
|
|
lruvec = mem_cgroup_lruvec(pgdat, memcg);
|
|
+ refaults = lruvec_page_state(lruvec, WORKINGSET_ACTIVATE);
|
|
lruvec->refaults = refaults;
|
|
} while ((memcg = mem_cgroup_iter(root_memcg, memcg, NULL)));
|
|
}
|
|
@@ -3192,7 +3181,7 @@ static void age_active_anon(struct pglist_data *pgdat,
|
|
do {
|
|
struct lruvec *lruvec = mem_cgroup_lruvec(pgdat, memcg);
|
|
|
|
- if (inactive_list_is_low(lruvec, false, memcg, sc, true))
|
|
+ if (inactive_list_is_low(lruvec, false, sc, true))
|
|
shrink_active_list(SWAP_CLUSTER_MAX, lruvec,
|
|
sc, LRU_ACTIVE_ANON);
|
|
|
|
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
|
|
index 236452ebbd9e..ac4c93c999b0 100644
|
|
--- a/net/8021q/vlan_dev.c
|
|
+++ b/net/8021q/vlan_dev.c
|
|
@@ -366,10 +366,12 @@ static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
|
ifrr.ifr_ifru = ifr->ifr_ifru;
|
|
|
|
switch (cmd) {
|
|
+ case SIOCSHWTSTAMP:
|
|
+ if (!net_eq(dev_net(dev), &init_net))
|
|
+ break;
|
|
case SIOCGMIIPHY:
|
|
case SIOCGMIIREG:
|
|
case SIOCSMIIREG:
|
|
- case SIOCSHWTSTAMP:
|
|
case SIOCGHWTSTAMP:
|
|
if (netif_device_present(real_dev) && ops->ndo_do_ioctl)
|
|
err = ops->ndo_do_ioctl(real_dev, &ifrr, cmd);
|
|
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
|
|
index 55a73ef388bf..d9156eabddb8 100644
|
|
--- a/net/bridge/br_if.c
|
|
+++ b/net/bridge/br_if.c
|
|
@@ -518,13 +518,15 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
|
|
call_netdevice_notifiers(NETDEV_JOIN, dev);
|
|
|
|
err = dev_set_allmulti(dev, 1);
|
|
- if (err)
|
|
- goto put_back;
|
|
+ if (err) {
|
|
+ kfree(p); /* kobject not yet init'd, manually free */
|
|
+ goto err1;
|
|
+ }
|
|
|
|
err = kobject_init_and_add(&p->kobj, &brport_ktype, &(dev->dev.kobj),
|
|
SYSFS_BRIDGE_PORT_ATTR);
|
|
if (err)
|
|
- goto err1;
|
|
+ goto err2;
|
|
|
|
err = br_sysfs_addif(p);
|
|
if (err)
|
|
@@ -607,12 +609,9 @@ err3:
|
|
sysfs_remove_link(br->ifobj, p->dev->name);
|
|
err2:
|
|
kobject_put(&p->kobj);
|
|
- p = NULL; /* kobject_put frees */
|
|
-err1:
|
|
dev_set_allmulti(dev, -1);
|
|
-put_back:
|
|
+err1:
|
|
dev_put(dev);
|
|
- kfree(p);
|
|
return err;
|
|
}
|
|
|
|
diff --git a/net/core/dev.c b/net/core/dev.c
|
|
index 93a1b07990b8..90ec30d5b851 100644
|
|
--- a/net/core/dev.c
|
|
+++ b/net/core/dev.c
|
|
@@ -5308,11 +5308,14 @@ bool napi_complete_done(struct napi_struct *n, int work_done)
|
|
if (work_done)
|
|
timeout = n->dev->gro_flush_timeout;
|
|
|
|
+ /* When the NAPI instance uses a timeout and keeps postponing
|
|
+ * it, we need to bound somehow the time packets are kept in
|
|
+ * the GRO layer
|
|
+ */
|
|
+ napi_gro_flush(n, !!timeout);
|
|
if (timeout)
|
|
hrtimer_start(&n->timer, ns_to_ktime(timeout),
|
|
HRTIMER_MODE_REL_PINNED);
|
|
- else
|
|
- napi_gro_flush(n, false);
|
|
}
|
|
if (unlikely(!list_empty(&n->poll_list))) {
|
|
/* If n->poll_list is not empty, we need to mask irqs */
|
|
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
|
|
index 9a6d97c1d810..5229d1cf51fd 100644
|
|
--- a/net/core/fib_rules.c
|
|
+++ b/net/core/fib_rules.c
|
|
@@ -563,9 +563,9 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|
rule->uid_range = fib_kuid_range_unset;
|
|
}
|
|
|
|
- if ((nlh->nlmsg_flags & NLM_F_EXCL) &&
|
|
- rule_exists(ops, frh, tb, rule)) {
|
|
- err = -EEXIST;
|
|
+ if (rule_exists(ops, frh, tb, rule)) {
|
|
+ if (nlh->nlmsg_flags & NLM_F_EXCL)
|
|
+ err = -EEXIST;
|
|
goto errout_free;
|
|
}
|
|
|
|
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
|
|
index 03c58b0eb082..8c8f756f3cc8 100644
|
|
--- a/net/dsa/dsa.c
|
|
+++ b/net/dsa/dsa.c
|
|
@@ -300,15 +300,22 @@ static int __init dsa_init_module(void)
|
|
|
|
rc = dsa_slave_register_notifier();
|
|
if (rc)
|
|
- return rc;
|
|
+ goto register_notifier_fail;
|
|
|
|
rc = dsa_legacy_register();
|
|
if (rc)
|
|
- return rc;
|
|
+ goto legacy_register_fail;
|
|
|
|
dev_add_pack(&dsa_pack_type);
|
|
|
|
return 0;
|
|
+
|
|
+legacy_register_fail:
|
|
+ dsa_slave_unregister_notifier();
|
|
+register_notifier_fail:
|
|
+ destroy_workqueue(dsa_owq);
|
|
+
|
|
+ return rc;
|
|
}
|
|
module_init(dsa_init_module);
|
|
|
|
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
|
|
index 125c1eab3eaa..115d9fd413e2 100644
|
|
--- a/net/ipv4/raw.c
|
|
+++ b/net/ipv4/raw.c
|
|
@@ -174,6 +174,7 @@ static int icmp_filter(const struct sock *sk, const struct sk_buff *skb)
|
|
static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
|
|
{
|
|
int sdif = inet_sdif(skb);
|
|
+ int dif = inet_iif(skb);
|
|
struct sock *sk;
|
|
struct hlist_head *head;
|
|
int delivered = 0;
|
|
@@ -186,8 +187,7 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
|
|
|
|
net = dev_net(skb->dev);
|
|
sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol,
|
|
- iph->saddr, iph->daddr,
|
|
- skb->dev->ifindex, sdif);
|
|
+ iph->saddr, iph->daddr, dif, sdif);
|
|
|
|
while (sk) {
|
|
delivered = 1;
|
|
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
|
|
index f7d080d1cf8e..d2529c38e7e4 100644
|
|
--- a/net/ipv6/sit.c
|
|
+++ b/net/ipv6/sit.c
|
|
@@ -1070,7 +1070,7 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev)
|
|
if (!tdev && tunnel->parms.link)
|
|
tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link);
|
|
|
|
- if (tdev) {
|
|
+ if (tdev && !netif_is_l3_master(tdev)) {
|
|
int t_hlen = tunnel->hlen + sizeof(struct iphdr);
|
|
|
|
dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
|
|
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
|
|
index 1ce068865629..130022091205 100644
|
|
--- a/net/mac80211/mesh_pathtbl.c
|
|
+++ b/net/mac80211/mesh_pathtbl.c
|
|
@@ -23,7 +23,7 @@ static void mesh_path_free_rcu(struct mesh_table *tbl, struct mesh_path *mpath);
|
|
static u32 mesh_table_hash(const void *addr, u32 len, u32 seed)
|
|
{
|
|
/* Use last four bytes of hw addr as hash index */
|
|
- return jhash_1word(*(u32 *)(addr+2), seed);
|
|
+ return jhash_1word(__get_unaligned_cpu32((u8 *)addr + 2), seed);
|
|
}
|
|
|
|
static const struct rhashtable_params mesh_rht_params = {
|
|
diff --git a/net/mac80211/trace_msg.h b/net/mac80211/trace_msg.h
|
|
index 366b9e6f043e..40141df09f25 100644
|
|
--- a/net/mac80211/trace_msg.h
|
|
+++ b/net/mac80211/trace_msg.h
|
|
@@ -1,4 +1,9 @@
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
|
+/*
|
|
+ * Portions of this file
|
|
+ * Copyright (C) 2019 Intel Corporation
|
|
+ */
|
|
+
|
|
#ifdef CONFIG_MAC80211_MESSAGE_TRACING
|
|
|
|
#if !defined(__MAC80211_MSG_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ)
|
|
@@ -11,7 +16,7 @@
|
|
#undef TRACE_SYSTEM
|
|
#define TRACE_SYSTEM mac80211_msg
|
|
|
|
-#define MAX_MSG_LEN 100
|
|
+#define MAX_MSG_LEN 120
|
|
|
|
DECLARE_EVENT_CLASS(mac80211_msg_event,
|
|
TP_PROTO(struct va_format *vaf),
|
|
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
|
|
index 305a4655f23e..09c7aa519ca8 100644
|
|
--- a/net/mac80211/tx.c
|
|
+++ b/net/mac80211/tx.c
|
|
@@ -3125,6 +3125,7 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata,
|
|
u8 max_subframes = sta->sta.max_amsdu_subframes;
|
|
int max_frags = local->hw.max_tx_fragments;
|
|
int max_amsdu_len = sta->sta.max_amsdu_len;
|
|
+ int orig_truesize;
|
|
__be16 len;
|
|
void *data;
|
|
bool ret = false;
|
|
@@ -3158,6 +3159,7 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata,
|
|
if (!head)
|
|
goto out;
|
|
|
|
+ orig_truesize = head->truesize;
|
|
orig_len = head->len;
|
|
|
|
if (skb->len + head->len > max_amsdu_len)
|
|
@@ -3212,6 +3214,7 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata,
|
|
*frag_tail = skb;
|
|
|
|
out_recalc:
|
|
+ fq->memory_usage += head->truesize - orig_truesize;
|
|
if (head->len != orig_len) {
|
|
flow->backlog += head->len - orig_len;
|
|
tin->backlog_bytes += head->len - orig_len;
|
|
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
|
|
index 4278f5c947ab..d1c0378144f3 100644
|
|
--- a/net/netfilter/ipvs/ip_vs_core.c
|
|
+++ b/net/netfilter/ipvs/ip_vs_core.c
|
|
@@ -1635,7 +1635,7 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,
|
|
if (!cp) {
|
|
int v;
|
|
|
|
- if (!sysctl_schedule_icmp(ipvs))
|
|
+ if (ipip || !sysctl_schedule_icmp(ipvs))
|
|
return NF_ACCEPT;
|
|
|
|
if (!ip_vs_try_to_schedule(ipvs, AF_INET, skb, pd, &v, &cp, &ciph))
|
|
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
|
|
index 06520bf30f29..fa49a627b681 100644
|
|
--- a/net/netfilter/nf_conntrack_core.c
|
|
+++ b/net/netfilter/nf_conntrack_core.c
|
|
@@ -25,6 +25,7 @@
|
|
#include <linux/slab.h>
|
|
#include <linux/random.h>
|
|
#include <linux/jhash.h>
|
|
+#include <linux/siphash.h>
|
|
#include <linux/err.h>
|
|
#include <linux/percpu.h>
|
|
#include <linux/moduleparam.h>
|
|
@@ -300,6 +301,40 @@ nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
|
|
}
|
|
EXPORT_SYMBOL_GPL(nf_ct_invert_tuple);
|
|
|
|
+/* Generate a almost-unique pseudo-id for a given conntrack.
|
|
+ *
|
|
+ * intentionally doesn't re-use any of the seeds used for hash
|
|
+ * table location, we assume id gets exposed to userspace.
|
|
+ *
|
|
+ * Following nf_conn items do not change throughout lifetime
|
|
+ * of the nf_conn after it has been committed to main hash table:
|
|
+ *
|
|
+ * 1. nf_conn address
|
|
+ * 2. nf_conn->ext address
|
|
+ * 3. nf_conn->master address (normally NULL)
|
|
+ * 4. tuple
|
|
+ * 5. the associated net namespace
|
|
+ */
|
|
+u32 nf_ct_get_id(const struct nf_conn *ct)
|
|
+{
|
|
+ static __read_mostly siphash_key_t ct_id_seed;
|
|
+ unsigned long a, b, c, d;
|
|
+
|
|
+ net_get_random_once(&ct_id_seed, sizeof(ct_id_seed));
|
|
+
|
|
+ a = (unsigned long)ct;
|
|
+ b = (unsigned long)ct->master ^ net_hash_mix(nf_ct_net(ct));
|
|
+ c = (unsigned long)ct->ext;
|
|
+ d = (unsigned long)siphash(&ct->tuplehash, sizeof(ct->tuplehash),
|
|
+ &ct_id_seed);
|
|
+#ifdef CONFIG_64BIT
|
|
+ return siphash_4u64((u64)a, (u64)b, (u64)c, (u64)d, &ct_id_seed);
|
|
+#else
|
|
+ return siphash_4u32((u32)a, (u32)b, (u32)c, (u32)d, &ct_id_seed);
|
|
+#endif
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(nf_ct_get_id);
|
|
+
|
|
static void
|
|
clean_from_lists(struct nf_conn *ct)
|
|
{
|
|
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
|
|
index 48dab1403b2c..c781c9a1a697 100644
|
|
--- a/net/netfilter/nf_conntrack_netlink.c
|
|
+++ b/net/netfilter/nf_conntrack_netlink.c
|
|
@@ -29,6 +29,7 @@
|
|
#include <linux/spinlock.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/slab.h>
|
|
+#include <linux/siphash.h>
|
|
|
|
#include <linux/netfilter.h>
|
|
#include <net/netlink.h>
|
|
@@ -445,7 +446,9 @@ err:
|
|
|
|
static int ctnetlink_dump_id(struct sk_buff *skb, const struct nf_conn *ct)
|
|
{
|
|
- if (nla_put_be32(skb, CTA_ID, htonl((unsigned long)ct)))
|
|
+ __be32 id = (__force __be32)nf_ct_get_id(ct);
|
|
+
|
|
+ if (nla_put_be32(skb, CTA_ID, id))
|
|
goto nla_put_failure;
|
|
return 0;
|
|
|
|
@@ -1179,8 +1182,9 @@ static int ctnetlink_del_conntrack(struct net *net, struct sock *ctnl,
|
|
ct = nf_ct_tuplehash_to_ctrack(h);
|
|
|
|
if (cda[CTA_ID]) {
|
|
- u_int32_t id = ntohl(nla_get_be32(cda[CTA_ID]));
|
|
- if (id != (u32)(unsigned long)ct) {
|
|
+ __be32 id = nla_get_be32(cda[CTA_ID]);
|
|
+
|
|
+ if (id != (__force __be32)nf_ct_get_id(ct)) {
|
|
nf_ct_put(ct);
|
|
return -ENOENT;
|
|
}
|
|
@@ -2521,6 +2525,25 @@ nla_put_failure:
|
|
|
|
static const union nf_inet_addr any_addr;
|
|
|
|
+static __be32 nf_expect_get_id(const struct nf_conntrack_expect *exp)
|
|
+{
|
|
+ static __read_mostly siphash_key_t exp_id_seed;
|
|
+ unsigned long a, b, c, d;
|
|
+
|
|
+ net_get_random_once(&exp_id_seed, sizeof(exp_id_seed));
|
|
+
|
|
+ a = (unsigned long)exp;
|
|
+ b = (unsigned long)exp->helper;
|
|
+ c = (unsigned long)exp->master;
|
|
+ d = (unsigned long)siphash(&exp->tuple, sizeof(exp->tuple), &exp_id_seed);
|
|
+
|
|
+#ifdef CONFIG_64BIT
|
|
+ return (__force __be32)siphash_4u64((u64)a, (u64)b, (u64)c, (u64)d, &exp_id_seed);
|
|
+#else
|
|
+ return (__force __be32)siphash_4u32((u32)a, (u32)b, (u32)c, (u32)d, &exp_id_seed);
|
|
+#endif
|
|
+}
|
|
+
|
|
static int
|
|
ctnetlink_exp_dump_expect(struct sk_buff *skb,
|
|
const struct nf_conntrack_expect *exp)
|
|
@@ -2568,7 +2591,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
|
|
}
|
|
#endif
|
|
if (nla_put_be32(skb, CTA_EXPECT_TIMEOUT, htonl(timeout)) ||
|
|
- nla_put_be32(skb, CTA_EXPECT_ID, htonl((unsigned long)exp)) ||
|
|
+ nla_put_be32(skb, CTA_EXPECT_ID, nf_expect_get_id(exp)) ||
|
|
nla_put_be32(skb, CTA_EXPECT_FLAGS, htonl(exp->flags)) ||
|
|
nla_put_be32(skb, CTA_EXPECT_CLASS, htonl(exp->class)))
|
|
goto nla_put_failure;
|
|
@@ -2873,7 +2896,8 @@ static int ctnetlink_get_expect(struct net *net, struct sock *ctnl,
|
|
|
|
if (cda[CTA_EXPECT_ID]) {
|
|
__be32 id = nla_get_be32(cda[CTA_EXPECT_ID]);
|
|
- if (ntohl(id) != (u32)(unsigned long)exp) {
|
|
+
|
|
+ if (id != nf_expect_get_id(exp)) {
|
|
nf_ct_expect_put(exp);
|
|
return -ENOENT;
|
|
}
|
|
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
|
|
index c445d57e3a5b..b149a7219084 100644
|
|
--- a/net/netfilter/nf_tables_api.c
|
|
+++ b/net/netfilter/nf_tables_api.c
|
|
@@ -220,6 +220,18 @@ static int nft_delchain(struct nft_ctx *ctx)
|
|
return err;
|
|
}
|
|
|
|
+/* either expr ops provide both activate/deactivate, or neither */
|
|
+static bool nft_expr_check_ops(const struct nft_expr_ops *ops)
|
|
+{
|
|
+ if (!ops)
|
|
+ return true;
|
|
+
|
|
+ if (WARN_ON_ONCE((!ops->activate ^ !ops->deactivate)))
|
|
+ return false;
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
static void nft_rule_expr_activate(const struct nft_ctx *ctx,
|
|
struct nft_rule *rule)
|
|
{
|
|
@@ -1724,6 +1736,9 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk,
|
|
*/
|
|
int nft_register_expr(struct nft_expr_type *type)
|
|
{
|
|
+ if (!nft_expr_check_ops(type->ops))
|
|
+ return -EINVAL;
|
|
+
|
|
nfnl_lock(NFNL_SUBSYS_NFTABLES);
|
|
if (type->family == NFPROTO_UNSPEC)
|
|
list_add_tail_rcu(&type->list, &nf_tables_expressions);
|
|
@@ -1873,6 +1888,10 @@ static int nf_tables_expr_parse(const struct nft_ctx *ctx,
|
|
err = PTR_ERR(ops);
|
|
goto err1;
|
|
}
|
|
+ if (!nft_expr_check_ops(ops)) {
|
|
+ err = -EINVAL;
|
|
+ goto err1;
|
|
+ }
|
|
} else
|
|
ops = type->ops;
|
|
|
|
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
|
|
index 8e054c63b54e..d42211a0b5e3 100644
|
|
--- a/net/netfilter/x_tables.c
|
|
+++ b/net/netfilter/x_tables.c
|
|
@@ -1798,7 +1798,7 @@ static int __init xt_init(void)
|
|
seqcount_init(&per_cpu(xt_recseq, i));
|
|
}
|
|
|
|
- xt = kmalloc(sizeof(struct xt_af) * NFPROTO_NUMPROTO, GFP_KERNEL);
|
|
+ xt = kcalloc(NFPROTO_NUMPROTO, sizeof(struct xt_af), GFP_KERNEL);
|
|
if (!xt)
|
|
return -ENOMEM;
|
|
|
|
diff --git a/net/nfc/nci/hci.c b/net/nfc/nci/hci.c
|
|
index ddfc52ac1f9b..c0d323b58e73 100644
|
|
--- a/net/nfc/nci/hci.c
|
|
+++ b/net/nfc/nci/hci.c
|
|
@@ -312,6 +312,10 @@ static void nci_hci_cmd_received(struct nci_dev *ndev, u8 pipe,
|
|
create_info = (struct nci_hci_create_pipe_resp *)skb->data;
|
|
dest_gate = create_info->dest_gate;
|
|
new_pipe = create_info->pipe;
|
|
+ if (new_pipe >= NCI_HCI_MAX_PIPES) {
|
|
+ status = NCI_HCI_ANY_E_NOK;
|
|
+ goto exit;
|
|
+ }
|
|
|
|
/* Save the new created pipe and bind with local gate,
|
|
* the description for skb->data[3] is destination gate id
|
|
@@ -336,6 +340,10 @@ static void nci_hci_cmd_received(struct nci_dev *ndev, u8 pipe,
|
|
goto exit;
|
|
}
|
|
delete_info = (struct nci_hci_delete_pipe_noti *)skb->data;
|
|
+ if (delete_info->pipe >= NCI_HCI_MAX_PIPES) {
|
|
+ status = NCI_HCI_ANY_E_NOK;
|
|
+ goto exit;
|
|
+ }
|
|
|
|
ndev->hci_dev->pipes[delete_info->pipe].gate =
|
|
NCI_HCI_INVALID_GATE;
|
|
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
|
|
index e522316a80c7..a968e81d4c81 100644
|
|
--- a/net/packet/af_packet.c
|
|
+++ b/net/packet/af_packet.c
|
|
@@ -4629,14 +4629,29 @@ static void __exit packet_exit(void)
|
|
|
|
static int __init packet_init(void)
|
|
{
|
|
- int rc = proto_register(&packet_proto, 0);
|
|
+ int rc;
|
|
|
|
- if (rc != 0)
|
|
+ rc = proto_register(&packet_proto, 0);
|
|
+ if (rc)
|
|
goto out;
|
|
+ rc = sock_register(&packet_family_ops);
|
|
+ if (rc)
|
|
+ goto out_proto;
|
|
+ rc = register_pernet_subsys(&packet_net_ops);
|
|
+ if (rc)
|
|
+ goto out_sock;
|
|
+ rc = register_netdevice_notifier(&packet_netdev_notifier);
|
|
+ if (rc)
|
|
+ goto out_pernet;
|
|
|
|
- sock_register(&packet_family_ops);
|
|
- register_pernet_subsys(&packet_net_ops);
|
|
- register_netdevice_notifier(&packet_netdev_notifier);
|
|
+ return 0;
|
|
+
|
|
+out_pernet:
|
|
+ unregister_pernet_subsys(&packet_net_ops);
|
|
+out_sock:
|
|
+ sock_unregister(PF_PACKET);
|
|
+out_proto:
|
|
+ proto_unregister(&packet_proto);
|
|
out:
|
|
return rc;
|
|
}
|
|
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
|
|
index 52829fdc280b..75c7c7cc7499 100644
|
|
--- a/net/sched/cls_tcindex.c
|
|
+++ b/net/sched/cls_tcindex.c
|
|
@@ -322,9 +322,9 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
|
|
struct nlattr *est, bool ovr)
|
|
{
|
|
struct tcindex_filter_result new_filter_result, *old_r = r;
|
|
- struct tcindex_filter_result cr;
|
|
struct tcindex_data *cp = NULL, *oldp;
|
|
struct tcindex_filter *f = NULL; /* make gcc behave */
|
|
+ struct tcf_result cr = {};
|
|
int err, balloc = 0;
|
|
struct tcf_exts e;
|
|
|
|
@@ -363,13 +363,10 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
|
|
cp->h = p->h;
|
|
|
|
err = tcindex_filter_result_init(&new_filter_result);
|
|
- if (err < 0)
|
|
- goto errout1;
|
|
- err = tcindex_filter_result_init(&cr);
|
|
if (err < 0)
|
|
goto errout1;
|
|
if (old_r)
|
|
- cr.res = r->res;
|
|
+ cr = r->res;
|
|
|
|
if (tb[TCA_TCINDEX_HASH])
|
|
cp->hash = nla_get_u32(tb[TCA_TCINDEX_HASH]);
|
|
@@ -460,8 +457,8 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
|
|
}
|
|
|
|
if (tb[TCA_TCINDEX_CLASSID]) {
|
|
- cr.res.classid = nla_get_u32(tb[TCA_TCINDEX_CLASSID]);
|
|
- tcf_bind_filter(tp, &cr.res, base);
|
|
+ cr.classid = nla_get_u32(tb[TCA_TCINDEX_CLASSID]);
|
|
+ tcf_bind_filter(tp, &cr, base);
|
|
}
|
|
|
|
if (old_r && old_r != r) {
|
|
@@ -473,7 +470,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
|
|
}
|
|
|
|
oldp = p;
|
|
- r->res = cr.res;
|
|
+ r->res = cr;
|
|
tcf_exts_change(&r->exts, &e);
|
|
|
|
rcu_assign_pointer(tp->root, cp);
|
|
@@ -492,6 +489,8 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
|
|
; /* nothing */
|
|
|
|
rcu_assign_pointer(*fp, f);
|
|
+ } else {
|
|
+ tcf_exts_destroy(&new_filter_result.exts);
|
|
}
|
|
|
|
if (oldp)
|
|
@@ -504,7 +503,6 @@ errout_alloc:
|
|
else if (balloc == 2)
|
|
kfree(cp->h);
|
|
errout1:
|
|
- tcf_exts_destroy(&cr.exts);
|
|
tcf_exts_destroy(&new_filter_result.exts);
|
|
errout:
|
|
kfree(cp);
|
|
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
|
|
index 75681845679e..f13fb607c563 100644
|
|
--- a/net/tipc/socket.c
|
|
+++ b/net/tipc/socket.c
|
|
@@ -709,11 +709,11 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
|
|
|
|
switch (sk->sk_state) {
|
|
case TIPC_ESTABLISHED:
|
|
- case TIPC_CONNECTING:
|
|
if (!tsk->cong_link_cnt && !tsk_conn_cong(tsk))
|
|
mask |= POLLOUT;
|
|
/* fall thru' */
|
|
case TIPC_LISTEN:
|
|
+ case TIPC_CONNECTING:
|
|
if (!skb_queue_empty(&sk->sk_receive_queue))
|
|
mask |= (POLLIN | POLLRDNORM);
|
|
break;
|
|
@@ -1588,7 +1588,7 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
|
|
return true;
|
|
|
|
/* If empty 'ACK-' message, wake up sleeping connect() */
|
|
- sk->sk_data_ready(sk);
|
|
+ sk->sk_state_change(sk);
|
|
|
|
/* 'ACK-' message is neither accepted nor rejected: */
|
|
msg_set_dest_droppable(hdr, 1);
|
|
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
|
|
index 46e9812d13c0..c1a2ad050e61 100644
|
|
--- a/net/wireless/nl80211.c
|
|
+++ b/net/wireless/nl80211.c
|
|
@@ -12761,7 +12761,8 @@ static const struct genl_ops nl80211_ops[] = {
|
|
.policy = nl80211_policy,
|
|
.flags = GENL_UNS_ADMIN_PERM,
|
|
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
|
|
- NL80211_FLAG_NEED_RTNL,
|
|
+ NL80211_FLAG_NEED_RTNL |
|
|
+ NL80211_FLAG_CLEAR_SKB,
|
|
},
|
|
{
|
|
.cmd = NL80211_CMD_DEAUTHENTICATE,
|
|
@@ -12812,7 +12813,8 @@ static const struct genl_ops nl80211_ops[] = {
|
|
.policy = nl80211_policy,
|
|
.flags = GENL_UNS_ADMIN_PERM,
|
|
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
|
|
- NL80211_FLAG_NEED_RTNL,
|
|
+ NL80211_FLAG_NEED_RTNL |
|
|
+ NL80211_FLAG_CLEAR_SKB,
|
|
},
|
|
{
|
|
.cmd = NL80211_CMD_UPDATE_CONNECT_PARAMS,
|
|
@@ -12820,7 +12822,8 @@ static const struct genl_ops nl80211_ops[] = {
|
|
.policy = nl80211_policy,
|
|
.flags = GENL_ADMIN_PERM,
|
|
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
|
|
- NL80211_FLAG_NEED_RTNL,
|
|
+ NL80211_FLAG_NEED_RTNL |
|
|
+ NL80211_FLAG_CLEAR_SKB,
|
|
},
|
|
{
|
|
.cmd = NL80211_CMD_DISCONNECT,
|
|
@@ -12849,7 +12852,8 @@ static const struct genl_ops nl80211_ops[] = {
|
|
.policy = nl80211_policy,
|
|
.flags = GENL_UNS_ADMIN_PERM,
|
|
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
|
|
- NL80211_FLAG_NEED_RTNL,
|
|
+ NL80211_FLAG_NEED_RTNL |
|
|
+ NL80211_FLAG_CLEAR_SKB,
|
|
},
|
|
{
|
|
.cmd = NL80211_CMD_DEL_PMKSA,
|
|
@@ -13201,7 +13205,8 @@ static const struct genl_ops nl80211_ops[] = {
|
|
.policy = nl80211_policy,
|
|
.flags = GENL_UNS_ADMIN_PERM,
|
|
.internal_flags = NL80211_FLAG_NEED_WIPHY |
|
|
- NL80211_FLAG_NEED_RTNL,
|
|
+ NL80211_FLAG_NEED_RTNL |
|
|
+ NL80211_FLAG_CLEAR_SKB,
|
|
},
|
|
{
|
|
.cmd = NL80211_CMD_SET_QOS_MAP,
|
|
@@ -13256,7 +13261,8 @@ static const struct genl_ops nl80211_ops[] = {
|
|
.doit = nl80211_set_pmk,
|
|
.policy = nl80211_policy,
|
|
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
|
|
- NL80211_FLAG_NEED_RTNL,
|
|
+ NL80211_FLAG_NEED_RTNL |
|
|
+ NL80211_FLAG_CLEAR_SKB,
|
|
},
|
|
{
|
|
.cmd = NL80211_CMD_DEL_PMK,
|
|
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
|
|
index cb041af9eddb..af680b5b678a 100644
|
|
--- a/security/integrity/ima/ima_crypto.c
|
|
+++ b/security/integrity/ima/ima_crypto.c
|
|
@@ -232,7 +232,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
|
|
{
|
|
loff_t i_size, offset;
|
|
char *rbuf[2] = { NULL, };
|
|
- int rc, read = 0, rbuf_len, active = 0, ahash_rc = 0;
|
|
+ int rc, rbuf_len, active = 0, ahash_rc = 0;
|
|
struct ahash_request *req;
|
|
struct scatterlist sg[1];
|
|
struct ahash_completion res;
|
|
@@ -279,11 +279,6 @@ static int ima_calc_file_hash_atfm(struct file *file,
|
|
&rbuf_size[1], 0);
|
|
}
|
|
|
|
- if (!(file->f_mode & FMODE_READ)) {
|
|
- file->f_mode |= FMODE_READ;
|
|
- read = 1;
|
|
- }
|
|
-
|
|
for (offset = 0; offset < i_size; offset += rbuf_len) {
|
|
if (!rbuf[1] && offset) {
|
|
/* Not using two buffers, and it is not the first
|
|
@@ -322,8 +317,6 @@ static int ima_calc_file_hash_atfm(struct file *file,
|
|
/* wait for the last update request to complete */
|
|
rc = ahash_wait(ahash_rc, &res);
|
|
out3:
|
|
- if (read)
|
|
- file->f_mode &= ~FMODE_READ;
|
|
ima_free_pages(rbuf[0], rbuf_size[0]);
|
|
ima_free_pages(rbuf[1], rbuf_size[1]);
|
|
out2:
|
|
@@ -358,7 +351,7 @@ static int ima_calc_file_hash_tfm(struct file *file,
|
|
{
|
|
loff_t i_size, offset = 0;
|
|
char *rbuf;
|
|
- int rc, read = 0;
|
|
+ int rc;
|
|
SHASH_DESC_ON_STACK(shash, tfm);
|
|
|
|
shash->tfm = tfm;
|
|
@@ -379,11 +372,6 @@ static int ima_calc_file_hash_tfm(struct file *file,
|
|
if (!rbuf)
|
|
return -ENOMEM;
|
|
|
|
- if (!(file->f_mode & FMODE_READ)) {
|
|
- file->f_mode |= FMODE_READ;
|
|
- read = 1;
|
|
- }
|
|
-
|
|
while (offset < i_size) {
|
|
int rbuf_len;
|
|
|
|
@@ -400,8 +388,6 @@ static int ima_calc_file_hash_tfm(struct file *file,
|
|
if (rc)
|
|
break;
|
|
}
|
|
- if (read)
|
|
- file->f_mode &= ~FMODE_READ;
|
|
kfree(rbuf);
|
|
out:
|
|
if (!rc)
|
|
@@ -442,6 +428,8 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
|
|
{
|
|
loff_t i_size;
|
|
int rc;
|
|
+ struct file *f = file;
|
|
+ bool new_file_instance = false, modified_flags = false;
|
|
|
|
/*
|
|
* For consistency, fail file's opened with the O_DIRECT flag on
|
|
@@ -453,15 +441,41 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
|
|
return -EINVAL;
|
|
}
|
|
|
|
- i_size = i_size_read(file_inode(file));
|
|
+ /* Open a new file instance in O_RDONLY if we cannot read */
|
|
+ if (!(file->f_mode & FMODE_READ)) {
|
|
+ int flags = file->f_flags & ~(O_WRONLY | O_APPEND |
|
|
+ O_TRUNC | O_CREAT | O_NOCTTY | O_EXCL);
|
|
+ flags |= O_RDONLY;
|
|
+ f = dentry_open(&file->f_path, flags, file->f_cred);
|
|
+ if (IS_ERR(f)) {
|
|
+ /*
|
|
+ * Cannot open the file again, lets modify f_flags
|
|
+ * of original and continue
|
|
+ */
|
|
+ pr_info_ratelimited("Unable to reopen file for reading.\n");
|
|
+ f = file;
|
|
+ f->f_flags |= FMODE_READ;
|
|
+ modified_flags = true;
|
|
+ } else {
|
|
+ new_file_instance = true;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ i_size = i_size_read(file_inode(f));
|
|
|
|
if (ima_ahash_minsize && i_size >= ima_ahash_minsize) {
|
|
- rc = ima_calc_file_ahash(file, hash);
|
|
+ rc = ima_calc_file_ahash(f, hash);
|
|
if (!rc)
|
|
- return 0;
|
|
+ goto out;
|
|
}
|
|
|
|
- return ima_calc_file_shash(file, hash);
|
|
+ rc = ima_calc_file_shash(f, hash);
|
|
+out:
|
|
+ if (new_file_instance)
|
|
+ fput(f);
|
|
+ else if (modified_flags)
|
|
+ f->f_flags &= ~FMODE_READ;
|
|
+ return rc;
|
|
}
|
|
|
|
/*
|
|
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
|
|
index 3955ba9e6fcb..7989dd6289e7 100644
|
|
--- a/tools/lib/traceevent/event-parse.c
|
|
+++ b/tools/lib/traceevent/event-parse.c
|
|
@@ -2206,7 +2206,7 @@ eval_type_str(unsigned long long val, const char *type, int pointer)
|
|
return val & 0xffffffff;
|
|
|
|
if (strcmp(type, "u64") == 0 ||
|
|
- strcmp(type, "s64"))
|
|
+ strcmp(type, "s64") == 0)
|
|
return val;
|
|
|
|
if (strcmp(type, "s8") == 0)
|
|
diff --git a/tools/testing/selftests/net/run_netsocktests b/tools/testing/selftests/net/run_netsocktests
|
|
index b093f39c298c..14e41faf2c57 100755
|
|
--- a/tools/testing/selftests/net/run_netsocktests
|
|
+++ b/tools/testing/selftests/net/run_netsocktests
|
|
@@ -7,7 +7,7 @@ echo "--------------------"
|
|
./socket
|
|
if [ $? -ne 0 ]; then
|
|
echo "[FAIL]"
|
|
+ exit 1
|
|
else
|
|
echo "[PASS]"
|
|
fi
|
|
-
|
|
diff --git a/tools/testing/selftests/netfilter/Makefile b/tools/testing/selftests/netfilter/Makefile
|
|
index c9ff2b47bd1c..a37cb1192c6a 100644
|
|
--- a/tools/testing/selftests/netfilter/Makefile
|
|
+++ b/tools/testing/selftests/netfilter/Makefile
|
|
@@ -1,6 +1,6 @@
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
# Makefile for netfilter selftests
|
|
|
|
-TEST_PROGS := nft_trans_stress.sh nft_nat.sh
|
|
+TEST_PROGS := nft_trans_stress.sh nft_nat.sh conntrack_icmp_related.sh
|
|
|
|
include ../lib.mk
|
|
diff --git a/tools/testing/selftests/netfilter/conntrack_icmp_related.sh b/tools/testing/selftests/netfilter/conntrack_icmp_related.sh
|
|
new file mode 100755
|
|
index 000000000000..b48e1833bc89
|
|
--- /dev/null
|
|
+++ b/tools/testing/selftests/netfilter/conntrack_icmp_related.sh
|
|
@@ -0,0 +1,283 @@
|
|
+#!/bin/bash
|
|
+#
|
|
+# check that ICMP df-needed/pkttoobig icmp are set are set as related
|
|
+# state
|
|
+#
|
|
+# Setup is:
|
|
+#
|
|
+# nsclient1 -> nsrouter1 -> nsrouter2 -> nsclient2
|
|
+# MTU 1500, except for nsrouter2 <-> nsclient2 link (1280).
|
|
+# ping nsclient2 from nsclient1, checking that conntrack did set RELATED
|
|
+# 'fragmentation needed' icmp packet.
|
|
+#
|
|
+# In addition, nsrouter1 will perform IP masquerading, i.e. also
|
|
+# check the icmp errors are propagated to the correct host as per
|
|
+# nat of "established" icmp-echo "connection".
|
|
+
|
|
+# Kselftest framework requirement - SKIP code is 4.
|
|
+ksft_skip=4
|
|
+ret=0
|
|
+
|
|
+nft --version > /dev/null 2>&1
|
|
+if [ $? -ne 0 ];then
|
|
+ echo "SKIP: Could not run test without nft tool"
|
|
+ exit $ksft_skip
|
|
+fi
|
|
+
|
|
+ip -Version > /dev/null 2>&1
|
|
+if [ $? -ne 0 ];then
|
|
+ echo "SKIP: Could not run test without ip tool"
|
|
+ exit $ksft_skip
|
|
+fi
|
|
+
|
|
+cleanup() {
|
|
+ for i in 1 2;do ip netns del nsclient$i;done
|
|
+ for i in 1 2;do ip netns del nsrouter$i;done
|
|
+}
|
|
+
|
|
+ipv4() {
|
|
+ echo -n 192.168.$1.2
|
|
+}
|
|
+
|
|
+ipv6 () {
|
|
+ echo -n dead:$1::2
|
|
+}
|
|
+
|
|
+check_counter()
|
|
+{
|
|
+ ns=$1
|
|
+ name=$2
|
|
+ expect=$3
|
|
+ local lret=0
|
|
+
|
|
+ cnt=$(ip netns exec $ns nft list counter inet filter "$name" | grep -q "$expect")
|
|
+ if [ $? -ne 0 ]; then
|
|
+ echo "ERROR: counter $name in $ns has unexpected value (expected $expect)" 1>&2
|
|
+ ip netns exec $ns nft list counter inet filter "$name" 1>&2
|
|
+ lret=1
|
|
+ fi
|
|
+
|
|
+ return $lret
|
|
+}
|
|
+
|
|
+check_unknown()
|
|
+{
|
|
+ expect="packets 0 bytes 0"
|
|
+ for n in nsclient1 nsclient2 nsrouter1 nsrouter2; do
|
|
+ check_counter $n "unknown" "$expect"
|
|
+ if [ $? -ne 0 ] ;then
|
|
+ return 1
|
|
+ fi
|
|
+ done
|
|
+
|
|
+ return 0
|
|
+}
|
|
+
|
|
+for n in nsclient1 nsclient2 nsrouter1 nsrouter2; do
|
|
+ ip netns add $n
|
|
+ ip -net $n link set lo up
|
|
+done
|
|
+
|
|
+DEV=veth0
|
|
+ip link add $DEV netns nsclient1 type veth peer name eth1 netns nsrouter1
|
|
+DEV=veth0
|
|
+ip link add $DEV netns nsclient2 type veth peer name eth1 netns nsrouter2
|
|
+
|
|
+DEV=veth0
|
|
+ip link add $DEV netns nsrouter1 type veth peer name eth2 netns nsrouter2
|
|
+
|
|
+DEV=veth0
|
|
+for i in 1 2; do
|
|
+ ip -net nsclient$i link set $DEV up
|
|
+ ip -net nsclient$i addr add $(ipv4 $i)/24 dev $DEV
|
|
+ ip -net nsclient$i addr add $(ipv6 $i)/64 dev $DEV
|
|
+done
|
|
+
|
|
+ip -net nsrouter1 link set eth1 up
|
|
+ip -net nsrouter1 link set veth0 up
|
|
+
|
|
+ip -net nsrouter2 link set eth1 up
|
|
+ip -net nsrouter2 link set eth2 up
|
|
+
|
|
+ip -net nsclient1 route add default via 192.168.1.1
|
|
+ip -net nsclient1 -6 route add default via dead:1::1
|
|
+
|
|
+ip -net nsclient2 route add default via 192.168.2.1
|
|
+ip -net nsclient2 route add default via dead:2::1
|
|
+
|
|
+i=3
|
|
+ip -net nsrouter1 addr add 192.168.1.1/24 dev eth1
|
|
+ip -net nsrouter1 addr add 192.168.3.1/24 dev veth0
|
|
+ip -net nsrouter1 addr add dead:1::1/64 dev eth1
|
|
+ip -net nsrouter1 addr add dead:3::1/64 dev veth0
|
|
+ip -net nsrouter1 route add default via 192.168.3.10
|
|
+ip -net nsrouter1 -6 route add default via dead:3::10
|
|
+
|
|
+ip -net nsrouter2 addr add 192.168.2.1/24 dev eth1
|
|
+ip -net nsrouter2 addr add 192.168.3.10/24 dev eth2
|
|
+ip -net nsrouter2 addr add dead:2::1/64 dev eth1
|
|
+ip -net nsrouter2 addr add dead:3::10/64 dev eth2
|
|
+ip -net nsrouter2 route add default via 192.168.3.1
|
|
+ip -net nsrouter2 route add default via dead:3::1
|
|
+
|
|
+sleep 2
|
|
+for i in 4 6; do
|
|
+ ip netns exec nsrouter1 sysctl -q net.ipv$i.conf.all.forwarding=1
|
|
+ ip netns exec nsrouter2 sysctl -q net.ipv$i.conf.all.forwarding=1
|
|
+done
|
|
+
|
|
+for netns in nsrouter1 nsrouter2; do
|
|
+ip netns exec $netns nft -f - <<EOF
|
|
+table inet filter {
|
|
+ counter unknown { }
|
|
+ counter related { }
|
|
+ chain forward {
|
|
+ type filter hook forward priority 0; policy accept;
|
|
+ meta l4proto icmpv6 icmpv6 type "packet-too-big" ct state "related" counter name "related" accept
|
|
+ meta l4proto icmp icmp type "destination-unreachable" ct state "related" counter name "related" accept
|
|
+ meta l4proto { icmp, icmpv6 } ct state new,established accept
|
|
+ counter name "unknown" drop
|
|
+ }
|
|
+}
|
|
+EOF
|
|
+done
|
|
+
|
|
+ip netns exec nsclient1 nft -f - <<EOF
|
|
+table inet filter {
|
|
+ counter unknown { }
|
|
+ counter related { }
|
|
+ chain input {
|
|
+ type filter hook input priority 0; policy accept;
|
|
+ meta l4proto { icmp, icmpv6 } ct state established,untracked accept
|
|
+
|
|
+ meta l4proto { icmp, icmpv6 } ct state "related" counter name "related" accept
|
|
+ counter name "unknown" drop
|
|
+ }
|
|
+}
|
|
+EOF
|
|
+
|
|
+ip netns exec nsclient2 nft -f - <<EOF
|
|
+table inet filter {
|
|
+ counter unknown { }
|
|
+ counter new { }
|
|
+ counter established { }
|
|
+
|
|
+ chain input {
|
|
+ type filter hook input priority 0; policy accept;
|
|
+ meta l4proto { icmp, icmpv6 } ct state established,untracked accept
|
|
+
|
|
+ meta l4proto { icmp, icmpv6 } ct state "new" counter name "new" accept
|
|
+ meta l4proto { icmp, icmpv6 } ct state "established" counter name "established" accept
|
|
+ counter name "unknown" drop
|
|
+ }
|
|
+ chain output {
|
|
+ type filter hook output priority 0; policy accept;
|
|
+ meta l4proto { icmp, icmpv6 } ct state established,untracked accept
|
|
+
|
|
+ meta l4proto { icmp, icmpv6 } ct state "new" counter name "new"
|
|
+ meta l4proto { icmp, icmpv6 } ct state "established" counter name "established"
|
|
+ counter name "unknown" drop
|
|
+ }
|
|
+}
|
|
+EOF
|
|
+
|
|
+
|
|
+# make sure NAT core rewrites adress of icmp error if nat is used according to
|
|
+# conntrack nat information (icmp error will be directed at nsrouter1 address,
|
|
+# but it needs to be routed to nsclient1 address).
|
|
+ip netns exec nsrouter1 nft -f - <<EOF
|
|
+table ip nat {
|
|
+ chain postrouting {
|
|
+ type nat hook postrouting priority 0; policy accept;
|
|
+ ip protocol icmp oifname "veth0" counter masquerade
|
|
+ }
|
|
+}
|
|
+table ip6 nat {
|
|
+ chain postrouting {
|
|
+ type nat hook postrouting priority 0; policy accept;
|
|
+ ip6 nexthdr icmpv6 oifname "veth0" counter masquerade
|
|
+ }
|
|
+}
|
|
+EOF
|
|
+
|
|
+ip netns exec nsrouter2 ip link set eth1 mtu 1280
|
|
+ip netns exec nsclient2 ip link set veth0 mtu 1280
|
|
+sleep 1
|
|
+
|
|
+ip netns exec nsclient1 ping -c 1 -s 1000 -q -M do 192.168.2.2 >/dev/null
|
|
+if [ $? -ne 0 ]; then
|
|
+ echo "ERROR: netns ip routing/connectivity broken" 1>&2
|
|
+ cleanup
|
|
+ exit 1
|
|
+fi
|
|
+ip netns exec nsclient1 ping6 -q -c 1 -s 1000 dead:2::2 >/dev/null
|
|
+if [ $? -ne 0 ]; then
|
|
+ echo "ERROR: netns ipv6 routing/connectivity broken" 1>&2
|
|
+ cleanup
|
|
+ exit 1
|
|
+fi
|
|
+
|
|
+check_unknown
|
|
+if [ $? -ne 0 ]; then
|
|
+ ret=1
|
|
+fi
|
|
+
|
|
+expect="packets 0 bytes 0"
|
|
+for netns in nsrouter1 nsrouter2 nsclient1;do
|
|
+ check_counter "$netns" "related" "$expect"
|
|
+ if [ $? -ne 0 ]; then
|
|
+ ret=1
|
|
+ fi
|
|
+done
|
|
+
|
|
+expect="packets 2 bytes 2076"
|
|
+check_counter nsclient2 "new" "$expect"
|
|
+if [ $? -ne 0 ]; then
|
|
+ ret=1
|
|
+fi
|
|
+
|
|
+ip netns exec nsclient1 ping -q -c 1 -s 1300 -M do 192.168.2.2 > /dev/null
|
|
+if [ $? -eq 0 ]; then
|
|
+ echo "ERROR: ping should have failed with PMTU too big error" 1>&2
|
|
+ ret=1
|
|
+fi
|
|
+
|
|
+# nsrouter2 should have generated the icmp error, so
|
|
+# related counter should be 0 (its in forward).
|
|
+expect="packets 0 bytes 0"
|
|
+check_counter "nsrouter2" "related" "$expect"
|
|
+if [ $? -ne 0 ]; then
|
|
+ ret=1
|
|
+fi
|
|
+
|
|
+# but nsrouter1 should have seen it, same for nsclient1.
|
|
+expect="packets 1 bytes 576"
|
|
+for netns in nsrouter1 nsclient1;do
|
|
+ check_counter "$netns" "related" "$expect"
|
|
+ if [ $? -ne 0 ]; then
|
|
+ ret=1
|
|
+ fi
|
|
+done
|
|
+
|
|
+ip netns exec nsclient1 ping6 -c 1 -s 1300 dead:2::2 > /dev/null
|
|
+if [ $? -eq 0 ]; then
|
|
+ echo "ERROR: ping6 should have failed with PMTU too big error" 1>&2
|
|
+ ret=1
|
|
+fi
|
|
+
|
|
+expect="packets 2 bytes 1856"
|
|
+for netns in nsrouter1 nsclient1;do
|
|
+ check_counter "$netns" "related" "$expect"
|
|
+ if [ $? -ne 0 ]; then
|
|
+ ret=1
|
|
+ fi
|
|
+done
|
|
+
|
|
+if [ $ret -eq 0 ];then
|
|
+ echo "PASS: icmp mtu error had RELATED state"
|
|
+else
|
|
+ echo "ERROR: icmp error RELATED state test has failed"
|
|
+fi
|
|
+
|
|
+cleanup
|
|
+exit $ret
|
|
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
|
|
index 225dc671ae31..1f4cac53b923 100644
|
|
--- a/virt/kvm/arm/mmu.c
|
|
+++ b/virt/kvm/arm/mmu.c
|
|
@@ -1068,8 +1068,14 @@ static bool transparent_hugepage_adjust(kvm_pfn_t *pfnp, phys_addr_t *ipap)
|
|
{
|
|
kvm_pfn_t pfn = *pfnp;
|
|
gfn_t gfn = *ipap >> PAGE_SHIFT;
|
|
+ struct page *page = pfn_to_page(pfn);
|
|
|
|
- if (PageTransCompoundMap(pfn_to_page(pfn))) {
|
|
+ /*
|
|
+ * PageTransCompoungMap() returns true for THP and
|
|
+ * hugetlbfs. Make sure the adjustment is done only for THP
|
|
+ * pages.
|
|
+ */
|
|
+ if (!PageHuge(page) && PageTransCompoundMap(page)) {
|
|
unsigned long mask;
|
|
/*
|
|
* The address we faulted on is backed by a transparent huge
|
|
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
|
|
index b1286c4e0712..0bd0683640bd 100644
|
|
--- a/virt/kvm/irqchip.c
|
|
+++ b/virt/kvm/irqchip.c
|
|
@@ -144,18 +144,19 @@ static int setup_routing_entry(struct kvm *kvm,
|
|
{
|
|
struct kvm_kernel_irq_routing_entry *ei;
|
|
int r;
|
|
+ u32 gsi = array_index_nospec(ue->gsi, KVM_MAX_IRQ_ROUTES);
|
|
|
|
/*
|
|
* Do not allow GSI to be mapped to the same irqchip more than once.
|
|
* Allow only one to one mapping between GSI and non-irqchip routing.
|
|
*/
|
|
- hlist_for_each_entry(ei, &rt->map[ue->gsi], link)
|
|
+ hlist_for_each_entry(ei, &rt->map[gsi], link)
|
|
if (ei->type != KVM_IRQ_ROUTING_IRQCHIP ||
|
|
ue->type != KVM_IRQ_ROUTING_IRQCHIP ||
|
|
ue->u.irqchip.irqchip == ei->irqchip.irqchip)
|
|
return -EINVAL;
|
|
|
|
- e->gsi = ue->gsi;
|
|
+ e->gsi = gsi;
|
|
e->type = ue->type;
|
|
r = kvm_set_routing_entry(kvm, e, ue);
|
|
if (r)
|
|
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
|
|
index a373c60ef1c0..b91716b1b428 100644
|
|
--- a/virt/kvm/kvm_main.c
|
|
+++ b/virt/kvm/kvm_main.c
|
|
@@ -2886,12 +2886,14 @@ static int kvm_ioctl_create_device(struct kvm *kvm,
|
|
struct kvm_device_ops *ops = NULL;
|
|
struct kvm_device *dev;
|
|
bool test = cd->flags & KVM_CREATE_DEVICE_TEST;
|
|
+ int type;
|
|
int ret;
|
|
|
|
if (cd->type >= ARRAY_SIZE(kvm_device_ops_table))
|
|
return -ENODEV;
|
|
|
|
- ops = kvm_device_ops_table[cd->type];
|
|
+ type = array_index_nospec(cd->type, ARRAY_SIZE(kvm_device_ops_table));
|
|
+ ops = kvm_device_ops_table[type];
|
|
if (ops == NULL)
|
|
return -ENODEV;
|
|
|
|
@@ -2906,7 +2908,7 @@ static int kvm_ioctl_create_device(struct kvm *kvm,
|
|
dev->kvm = kvm;
|
|
|
|
mutex_lock(&kvm->lock);
|
|
- ret = ops->create(dev, cd->type);
|
|
+ ret = ops->create(dev, type);
|
|
if (ret < 0) {
|
|
mutex_unlock(&kvm->lock);
|
|
kfree(dev);
|