mirror of
https://github.com/Fishwaldo/build.git
synced 2025-03-25 16:21:32 +00:00
5333 lines
172 KiB
Diff
5333 lines
172 KiB
Diff
diff --git a/Makefile b/Makefile
|
|
index 58c0390573c1..575459bb47eb 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -1,6 +1,6 @@
|
|
VERSION = 4
|
|
PATCHLEVEL = 4
|
|
-SUBLEVEL = 127
|
|
+SUBLEVEL = 128
|
|
EXTRAVERSION =
|
|
NAME = Blurry Fish Butt
|
|
|
|
diff --git a/arch/arm/boot/dts/imx53-qsrb.dts b/arch/arm/boot/dts/imx53-qsrb.dts
|
|
index 96d7eede412e..036c9bd9bf75 100644
|
|
--- a/arch/arm/boot/dts/imx53-qsrb.dts
|
|
+++ b/arch/arm/boot/dts/imx53-qsrb.dts
|
|
@@ -23,7 +23,7 @@
|
|
imx53-qsrb {
|
|
pinctrl_pmic: pmicgrp {
|
|
fsl,pins = <
|
|
- MX53_PAD_CSI0_DAT5__GPIO5_23 0x1e4 /* IRQ */
|
|
+ MX53_PAD_CSI0_DAT5__GPIO5_23 0x1c4 /* IRQ */
|
|
>;
|
|
};
|
|
};
|
|
diff --git a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi
|
|
index 9e096d811bed..7a032dd84bb2 100644
|
|
--- a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi
|
|
+++ b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi
|
|
@@ -88,6 +88,7 @@
|
|
clocks = <&clks 201>;
|
|
VDDA-supply = <®_2p5v>;
|
|
VDDIO-supply = <®_3p3v>;
|
|
+ lrclk-strength = <3>;
|
|
};
|
|
};
|
|
|
|
diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
|
|
index 9430a9928199..00de37fe5f8a 100644
|
|
--- a/arch/arm/boot/dts/ls1021a.dtsi
|
|
+++ b/arch/arm/boot/dts/ls1021a.dtsi
|
|
@@ -132,7 +132,7 @@
|
|
};
|
|
|
|
esdhc: esdhc@1560000 {
|
|
- compatible = "fsl,esdhc";
|
|
+ compatible = "fsl,ls1021a-esdhc", "fsl,esdhc";
|
|
reg = <0x0 0x1560000 0x0 0x10000>;
|
|
interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
|
|
clock-frequency = <0>;
|
|
diff --git a/arch/arm/include/asm/xen/events.h b/arch/arm/include/asm/xen/events.h
|
|
index 71e473d05fcc..620dc75362e5 100644
|
|
--- a/arch/arm/include/asm/xen/events.h
|
|
+++ b/arch/arm/include/asm/xen/events.h
|
|
@@ -16,7 +16,7 @@ static inline int xen_irqs_disabled(struct pt_regs *regs)
|
|
return raw_irqs_disabled_flags(regs->ARM_cpsr);
|
|
}
|
|
|
|
-#define xchg_xen_ulong(ptr, val) atomic64_xchg(container_of((ptr), \
|
|
+#define xchg_xen_ulong(ptr, val) atomic64_xchg(container_of((long long*)(ptr),\
|
|
atomic64_t, \
|
|
counter), (val))
|
|
|
|
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
|
|
index 28c90bc372bd..78d325f3245a 100644
|
|
--- a/arch/arm/mach-davinci/devices-da8xx.c
|
|
+++ b/arch/arm/mach-davinci/devices-da8xx.c
|
|
@@ -795,6 +795,8 @@ static struct platform_device da8xx_dsp = {
|
|
.resource = da8xx_rproc_resources,
|
|
};
|
|
|
|
+static bool rproc_mem_inited __initdata;
|
|
+
|
|
#if IS_ENABLED(CONFIG_DA8XX_REMOTEPROC)
|
|
|
|
static phys_addr_t rproc_base __initdata;
|
|
@@ -833,6 +835,8 @@ void __init da8xx_rproc_reserve_cma(void)
|
|
ret = dma_declare_contiguous(&da8xx_dsp.dev, rproc_size, rproc_base, 0);
|
|
if (ret)
|
|
pr_err("%s: dma_declare_contiguous failed %d\n", __func__, ret);
|
|
+ else
|
|
+ rproc_mem_inited = true;
|
|
}
|
|
|
|
#else
|
|
@@ -847,6 +851,12 @@ int __init da8xx_register_rproc(void)
|
|
{
|
|
int ret;
|
|
|
|
+ if (!rproc_mem_inited) {
|
|
+ pr_warn("%s: memory not reserved for DSP, not registering DSP device\n",
|
|
+ __func__);
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+
|
|
ret = platform_device_register(&da8xx_dsp);
|
|
if (ret)
|
|
pr_err("%s: can't register DSP device: %d\n", __func__, ret);
|
|
diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c
|
|
index 5b0f752d5507..24be631e487d 100644
|
|
--- a/arch/arm/mach-imx/cpu.c
|
|
+++ b/arch/arm/mach-imx/cpu.c
|
|
@@ -133,6 +133,9 @@ struct device * __init imx_soc_device_init(void)
|
|
case MXC_CPU_IMX6UL:
|
|
soc_id = "i.MX6UL";
|
|
break;
|
|
+ case MXC_CPU_IMX6ULL:
|
|
+ soc_id = "i.MX6ULL";
|
|
+ break;
|
|
case MXC_CPU_IMX7D:
|
|
soc_id = "i.MX7D";
|
|
break;
|
|
diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h
|
|
index a5b1af6d7441..478cd91d0885 100644
|
|
--- a/arch/arm/mach-imx/mxc.h
|
|
+++ b/arch/arm/mach-imx/mxc.h
|
|
@@ -39,6 +39,7 @@
|
|
#define MXC_CPU_IMX6SX 0x62
|
|
#define MXC_CPU_IMX6Q 0x63
|
|
#define MXC_CPU_IMX6UL 0x64
|
|
+#define MXC_CPU_IMX6ULL 0x65
|
|
#define MXC_CPU_IMX7D 0x72
|
|
|
|
#define IMX_DDR_TYPE_LPDDR2 1
|
|
@@ -171,6 +172,11 @@ static inline bool cpu_is_imx6ul(void)
|
|
return __mxc_cpu_type == MXC_CPU_IMX6UL;
|
|
}
|
|
|
|
+static inline bool cpu_is_imx6ull(void)
|
|
+{
|
|
+ return __mxc_cpu_type == MXC_CPU_IMX6ULL;
|
|
+}
|
|
+
|
|
static inline bool cpu_is_imx6q(void)
|
|
{
|
|
return __mxc_cpu_type == MXC_CPU_IMX6Q;
|
|
diff --git a/arch/mips/include/asm/kprobes.h b/arch/mips/include/asm/kprobes.h
|
|
index daba1f9a4f79..174aedce3167 100644
|
|
--- a/arch/mips/include/asm/kprobes.h
|
|
+++ b/arch/mips/include/asm/kprobes.h
|
|
@@ -40,7 +40,8 @@ typedef union mips_instruction kprobe_opcode_t;
|
|
|
|
#define flush_insn_slot(p) \
|
|
do { \
|
|
- flush_icache_range((unsigned long)p->addr, \
|
|
+ if (p->addr) \
|
|
+ flush_icache_range((unsigned long)p->addr, \
|
|
(unsigned long)p->addr + \
|
|
(MAX_INSN_SIZE * sizeof(kprobe_opcode_t))); \
|
|
} while (0)
|
|
diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h
|
|
index 832e2167d00f..ef7c02af7522 100644
|
|
--- a/arch/mips/include/asm/pgtable-32.h
|
|
+++ b/arch/mips/include/asm/pgtable-32.h
|
|
@@ -18,6 +18,10 @@
|
|
|
|
#include <asm-generic/pgtable-nopmd.h>
|
|
|
|
+#ifdef CONFIG_HIGHMEM
|
|
+#include <asm/highmem.h>
|
|
+#endif
|
|
+
|
|
extern int temp_tlb_entry;
|
|
|
|
/*
|
|
@@ -61,7 +65,8 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
|
|
|
|
#define VMALLOC_START MAP_BASE
|
|
|
|
-#define PKMAP_BASE (0xfe000000UL)
|
|
+#define PKMAP_END ((FIXADDR_START) & ~((LAST_PKMAP << PAGE_SHIFT)-1))
|
|
+#define PKMAP_BASE (PKMAP_END - PAGE_SIZE * LAST_PKMAP)
|
|
|
|
#ifdef CONFIG_HIGHMEM
|
|
# define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
|
|
diff --git a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c
|
|
index adc6911ba748..b19a3c506b1e 100644
|
|
--- a/arch/mips/mm/pgtable-32.c
|
|
+++ b/arch/mips/mm/pgtable-32.c
|
|
@@ -51,15 +51,15 @@ void __init pagetable_init(void)
|
|
/*
|
|
* Fixed mappings:
|
|
*/
|
|
- vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
|
|
- fixrange_init(vaddr, vaddr + FIXADDR_SIZE, pgd_base);
|
|
+ vaddr = __fix_to_virt(__end_of_fixed_addresses - 1);
|
|
+ fixrange_init(vaddr & PMD_MASK, vaddr + FIXADDR_SIZE, pgd_base);
|
|
|
|
#ifdef CONFIG_HIGHMEM
|
|
/*
|
|
* Permanent kmaps:
|
|
*/
|
|
vaddr = PKMAP_BASE;
|
|
- fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
|
|
+ fixrange_init(vaddr & PMD_MASK, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
|
|
|
|
pgd = swapper_pg_dir + __pgd_offset(vaddr);
|
|
pud = pud_offset(pgd, vaddr);
|
|
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
|
|
index 3140c19c448c..70b379ee6b7e 100644
|
|
--- a/arch/powerpc/include/asm/page.h
|
|
+++ b/arch/powerpc/include/asm/page.h
|
|
@@ -132,7 +132,19 @@ extern long long virt_phys_offset;
|
|
#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT)
|
|
#define virt_to_page(kaddr) pfn_to_page(virt_to_pfn(kaddr))
|
|
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
|
|
+
|
|
+#ifdef CONFIG_PPC_BOOK3S_64
|
|
+/*
|
|
+ * On hash the vmalloc and other regions alias to the kernel region when passed
|
|
+ * through __pa(), which virt_to_pfn() uses. That means virt_addr_valid() can
|
|
+ * return true for some vmalloc addresses, which is incorrect. So explicitly
|
|
+ * check that the address is in the kernel region.
|
|
+ */
|
|
+#define virt_addr_valid(kaddr) (REGION_ID(kaddr) == KERNEL_REGION_ID && \
|
|
+ pfn_valid(virt_to_pfn(kaddr)))
|
|
+#else
|
|
#define virt_addr_valid(kaddr) pfn_valid(virt_to_pfn(kaddr))
|
|
+#endif
|
|
|
|
/*
|
|
* On Book-E parts we need __va to parse the device tree and we can't
|
|
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
|
|
index 1be1092c7204..9baba9576e99 100644
|
|
--- a/arch/powerpc/kernel/time.c
|
|
+++ b/arch/powerpc/kernel/time.c
|
|
@@ -686,12 +686,20 @@ static int __init get_freq(char *name, int cells, unsigned long *val)
|
|
static void start_cpu_decrementer(void)
|
|
{
|
|
#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
|
|
+ unsigned int tcr;
|
|
+
|
|
/* Clear any pending timer interrupts */
|
|
mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
|
|
|
|
- /* Enable decrementer interrupt */
|
|
- mtspr(SPRN_TCR, TCR_DIE);
|
|
-#endif /* defined(CONFIG_BOOKE) || defined(CONFIG_40x) */
|
|
+ tcr = mfspr(SPRN_TCR);
|
|
+ /*
|
|
+ * The watchdog may have already been enabled by u-boot. So leave
|
|
+ * TRC[WP] (Watchdog Period) alone.
|
|
+ */
|
|
+ tcr &= TCR_WP_MASK; /* Clear all bits except for TCR[WP] */
|
|
+ tcr |= TCR_DIE; /* Enable decrementer */
|
|
+ mtspr(SPRN_TCR, tcr);
|
|
+#endif
|
|
}
|
|
|
|
void __init generic_calibrate_decr(void)
|
|
diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c
|
|
index f2c75a1e0536..0d91baf63fed 100644
|
|
--- a/arch/powerpc/kvm/book3s_pr_papr.c
|
|
+++ b/arch/powerpc/kvm/book3s_pr_papr.c
|
|
@@ -50,7 +50,9 @@ static int kvmppc_h_pr_enter(struct kvm_vcpu *vcpu)
|
|
pteg_addr = get_pteg_addr(vcpu, pte_index);
|
|
|
|
mutex_lock(&vcpu->kvm->arch.hpt_mutex);
|
|
- copy_from_user(pteg, (void __user *)pteg_addr, sizeof(pteg));
|
|
+ ret = H_FUNCTION;
|
|
+ if (copy_from_user(pteg, (void __user *)pteg_addr, sizeof(pteg)))
|
|
+ goto done;
|
|
hpte = pteg;
|
|
|
|
ret = H_PTEG_FULL;
|
|
@@ -71,7 +73,9 @@ static int kvmppc_h_pr_enter(struct kvm_vcpu *vcpu)
|
|
hpte[0] = cpu_to_be64(kvmppc_get_gpr(vcpu, 6));
|
|
hpte[1] = cpu_to_be64(kvmppc_get_gpr(vcpu, 7));
|
|
pteg_addr += i * HPTE_SIZE;
|
|
- copy_to_user((void __user *)pteg_addr, hpte, HPTE_SIZE);
|
|
+ ret = H_FUNCTION;
|
|
+ if (copy_to_user((void __user *)pteg_addr, hpte, HPTE_SIZE))
|
|
+ goto done;
|
|
kvmppc_set_gpr(vcpu, 4, pte_index | i);
|
|
ret = H_SUCCESS;
|
|
|
|
@@ -93,7 +97,9 @@ static int kvmppc_h_pr_remove(struct kvm_vcpu *vcpu)
|
|
|
|
pteg = get_pteg_addr(vcpu, pte_index);
|
|
mutex_lock(&vcpu->kvm->arch.hpt_mutex);
|
|
- copy_from_user(pte, (void __user *)pteg, sizeof(pte));
|
|
+ ret = H_FUNCTION;
|
|
+ if (copy_from_user(pte, (void __user *)pteg, sizeof(pte)))
|
|
+ goto done;
|
|
pte[0] = be64_to_cpu((__force __be64)pte[0]);
|
|
pte[1] = be64_to_cpu((__force __be64)pte[1]);
|
|
|
|
@@ -103,7 +109,9 @@ static int kvmppc_h_pr_remove(struct kvm_vcpu *vcpu)
|
|
((flags & H_ANDCOND) && (pte[0] & avpn) != 0))
|
|
goto done;
|
|
|
|
- copy_to_user((void __user *)pteg, &v, sizeof(v));
|
|
+ ret = H_FUNCTION;
|
|
+ if (copy_to_user((void __user *)pteg, &v, sizeof(v)))
|
|
+ goto done;
|
|
|
|
rb = compute_tlbie_rb(pte[0], pte[1], pte_index);
|
|
vcpu->arch.mmu.tlbie(vcpu, rb, rb & 1 ? true : false);
|
|
@@ -171,7 +179,10 @@ static int kvmppc_h_pr_bulk_remove(struct kvm_vcpu *vcpu)
|
|
}
|
|
|
|
pteg = get_pteg_addr(vcpu, tsh & H_BULK_REMOVE_PTEX);
|
|
- copy_from_user(pte, (void __user *)pteg, sizeof(pte));
|
|
+ if (copy_from_user(pte, (void __user *)pteg, sizeof(pte))) {
|
|
+ ret = H_FUNCTION;
|
|
+ break;
|
|
+ }
|
|
pte[0] = be64_to_cpu((__force __be64)pte[0]);
|
|
pte[1] = be64_to_cpu((__force __be64)pte[1]);
|
|
|
|
@@ -184,7 +195,10 @@ static int kvmppc_h_pr_bulk_remove(struct kvm_vcpu *vcpu)
|
|
tsh |= H_BULK_REMOVE_NOT_FOUND;
|
|
} else {
|
|
/* Splat the pteg in (userland) hpt */
|
|
- copy_to_user((void __user *)pteg, &v, sizeof(v));
|
|
+ if (copy_to_user((void __user *)pteg, &v, sizeof(v))) {
|
|
+ ret = H_FUNCTION;
|
|
+ break;
|
|
+ }
|
|
|
|
rb = compute_tlbie_rb(pte[0], pte[1],
|
|
tsh & H_BULK_REMOVE_PTEX);
|
|
@@ -211,7 +225,9 @@ static int kvmppc_h_pr_protect(struct kvm_vcpu *vcpu)
|
|
|
|
pteg = get_pteg_addr(vcpu, pte_index);
|
|
mutex_lock(&vcpu->kvm->arch.hpt_mutex);
|
|
- copy_from_user(pte, (void __user *)pteg, sizeof(pte));
|
|
+ ret = H_FUNCTION;
|
|
+ if (copy_from_user(pte, (void __user *)pteg, sizeof(pte)))
|
|
+ goto done;
|
|
pte[0] = be64_to_cpu((__force __be64)pte[0]);
|
|
pte[1] = be64_to_cpu((__force __be64)pte[1]);
|
|
|
|
@@ -234,7 +250,9 @@ static int kvmppc_h_pr_protect(struct kvm_vcpu *vcpu)
|
|
vcpu->arch.mmu.tlbie(vcpu, rb, rb & 1 ? true : false);
|
|
pte[0] = (__force u64)cpu_to_be64(pte[0]);
|
|
pte[1] = (__force u64)cpu_to_be64(pte[1]);
|
|
- copy_to_user((void __user *)pteg, pte, sizeof(pte));
|
|
+ ret = H_FUNCTION;
|
|
+ if (copy_to_user((void __user *)pteg, pte, sizeof(pte)))
|
|
+ goto done;
|
|
ret = H_SUCCESS;
|
|
|
|
done:
|
|
diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
|
|
index be6212ddbf06..7e42e3ec2142 100644
|
|
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
|
|
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
|
|
@@ -174,6 +174,8 @@ static int spufs_arch_write_note(struct spu_context *ctx, int i,
|
|
if (!dump_skip(cprm,
|
|
roundup(cprm->written - total + sz, 4) - cprm->written))
|
|
goto Eio;
|
|
+
|
|
+ rc = 0;
|
|
out:
|
|
free_page((unsigned long)buf);
|
|
return rc;
|
|
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
|
|
index 445657fe658c..6c553f6e791a 100644
|
|
--- a/arch/s390/kernel/vmlinux.lds.S
|
|
+++ b/arch/s390/kernel/vmlinux.lds.S
|
|
@@ -21,8 +21,14 @@ SECTIONS
|
|
{
|
|
. = 0x00000000;
|
|
.text : {
|
|
- _text = .; /* Text and read-only data */
|
|
+ /* Text and read-only data */
|
|
HEAD_TEXT
|
|
+ /*
|
|
+ * E.g. perf doesn't like symbols starting at address zero,
|
|
+ * therefore skip the initial PSW and channel program located
|
|
+ * at address zero and let _text start at 0x200.
|
|
+ */
|
|
+ _text = 0x200;
|
|
TEXT_TEXT
|
|
SCHED_TEXT
|
|
LOCK_TEXT
|
|
diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c
|
|
index 59d503866431..9cc600b2d68c 100644
|
|
--- a/arch/sparc/kernel/ldc.c
|
|
+++ b/arch/sparc/kernel/ldc.c
|
|
@@ -1733,9 +1733,14 @@ static int read_nonraw(struct ldc_channel *lp, void *buf, unsigned int size)
|
|
|
|
lp->rcv_nxt = p->seqid;
|
|
|
|
+ /*
|
|
+ * If this is a control-only packet, there is nothing
|
|
+ * else to do but advance the rx queue since the packet
|
|
+ * was already processed above.
|
|
+ */
|
|
if (!(p->type & LDC_DATA)) {
|
|
new = rx_advance(lp, new);
|
|
- goto no_data;
|
|
+ break;
|
|
}
|
|
if (p->stype & (LDC_ACK | LDC_NACK)) {
|
|
err = data_ack_nack(lp, p);
|
|
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
|
|
index c7c4d9c51e99..eb02087650d2 100644
|
|
--- a/arch/x86/kernel/tsc.c
|
|
+++ b/arch/x86/kernel/tsc.c
|
|
@@ -365,6 +365,8 @@ static int __init tsc_setup(char *str)
|
|
tsc_clocksource_reliable = 1;
|
|
if (!strncmp(str, "noirqtime", 9))
|
|
no_sched_irq_time = 1;
|
|
+ if (!strcmp(str, "unstable"))
|
|
+ mark_tsc_unstable("boot parameter");
|
|
return 1;
|
|
}
|
|
|
|
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
|
|
index 2038e5bacce6..42654375b73f 100644
|
|
--- a/arch/x86/kvm/svm.c
|
|
+++ b/arch/x86/kvm/svm.c
|
|
@@ -1386,6 +1386,7 @@ static void svm_get_segment(struct kvm_vcpu *vcpu,
|
|
*/
|
|
if (var->unusable)
|
|
var->db = 0;
|
|
+ /* This is symmetric with svm_set_segment() */
|
|
var->dpl = to_svm(vcpu)->vmcb->save.cpl;
|
|
break;
|
|
}
|
|
@@ -1531,18 +1532,14 @@ static void svm_set_segment(struct kvm_vcpu *vcpu,
|
|
s->base = var->base;
|
|
s->limit = var->limit;
|
|
s->selector = var->selector;
|
|
- if (var->unusable)
|
|
- s->attrib = 0;
|
|
- else {
|
|
- s->attrib = (var->type & SVM_SELECTOR_TYPE_MASK);
|
|
- s->attrib |= (var->s & 1) << SVM_SELECTOR_S_SHIFT;
|
|
- s->attrib |= (var->dpl & 3) << SVM_SELECTOR_DPL_SHIFT;
|
|
- s->attrib |= (var->present & 1) << SVM_SELECTOR_P_SHIFT;
|
|
- s->attrib |= (var->avl & 1) << SVM_SELECTOR_AVL_SHIFT;
|
|
- s->attrib |= (var->l & 1) << SVM_SELECTOR_L_SHIFT;
|
|
- s->attrib |= (var->db & 1) << SVM_SELECTOR_DB_SHIFT;
|
|
- s->attrib |= (var->g & 1) << SVM_SELECTOR_G_SHIFT;
|
|
- }
|
|
+ s->attrib = (var->type & SVM_SELECTOR_TYPE_MASK);
|
|
+ s->attrib |= (var->s & 1) << SVM_SELECTOR_S_SHIFT;
|
|
+ s->attrib |= (var->dpl & 3) << SVM_SELECTOR_DPL_SHIFT;
|
|
+ s->attrib |= ((var->present & 1) && !var->unusable) << SVM_SELECTOR_P_SHIFT;
|
|
+ s->attrib |= (var->avl & 1) << SVM_SELECTOR_AVL_SHIFT;
|
|
+ s->attrib |= (var->l & 1) << SVM_SELECTOR_L_SHIFT;
|
|
+ s->attrib |= (var->db & 1) << SVM_SELECTOR_DB_SHIFT;
|
|
+ s->attrib |= (var->g & 1) << SVM_SELECTOR_G_SHIFT;
|
|
|
|
/*
|
|
* This is always accurate, except if SYSRET returned to a segment
|
|
@@ -1551,7 +1548,8 @@ static void svm_set_segment(struct kvm_vcpu *vcpu,
|
|
* would entail passing the CPL to userspace and back.
|
|
*/
|
|
if (seg == VCPU_SREG_SS)
|
|
- svm->vmcb->save.cpl = (s->attrib >> SVM_SELECTOR_DPL_SHIFT) & 3;
|
|
+ /* This is symmetric with svm_get_segment() */
|
|
+ svm->vmcb->save.cpl = (var->dpl & 3);
|
|
|
|
mark_dirty(svm->vmcb, VMCB_SEG);
|
|
}
|
|
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
|
|
index 46bbc69844bd..528b4352fa99 100644
|
|
--- a/arch/x86/kvm/vmx.c
|
|
+++ b/arch/x86/kvm/vmx.c
|
|
@@ -7657,11 +7657,13 @@ static bool nested_vmx_exit_handled_cr(struct kvm_vcpu *vcpu,
|
|
{
|
|
unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
|
|
int cr = exit_qualification & 15;
|
|
- int reg = (exit_qualification >> 8) & 15;
|
|
- unsigned long val = kvm_register_readl(vcpu, reg);
|
|
+ int reg;
|
|
+ unsigned long val;
|
|
|
|
switch ((exit_qualification >> 4) & 3) {
|
|
case 0: /* mov to cr */
|
|
+ reg = (exit_qualification >> 8) & 15;
|
|
+ val = kvm_register_readl(vcpu, reg);
|
|
switch (cr) {
|
|
case 0:
|
|
if (vmcs12->cr0_guest_host_mask &
|
|
@@ -7716,6 +7718,7 @@ static bool nested_vmx_exit_handled_cr(struct kvm_vcpu *vcpu,
|
|
* lmsw can change bits 1..3 of cr0, and only set bit 0 of
|
|
* cr0. Other attempted changes are ignored, with no exit.
|
|
*/
|
|
+ val = (exit_qualification >> LMSW_SOURCE_DATA_SHIFT) & 0x0f;
|
|
if (vmcs12->cr0_guest_host_mask & 0xe &
|
|
(val ^ vmcs12->cr0_read_shadow))
|
|
return true;
|
|
diff --git a/arch/x86/lib/csum-copy_64.S b/arch/x86/lib/csum-copy_64.S
|
|
index 7e48807b2fa1..45a53dfe1859 100644
|
|
--- a/arch/x86/lib/csum-copy_64.S
|
|
+++ b/arch/x86/lib/csum-copy_64.S
|
|
@@ -55,7 +55,7 @@ ENTRY(csum_partial_copy_generic)
|
|
movq %r12, 3*8(%rsp)
|
|
movq %r14, 4*8(%rsp)
|
|
movq %r13, 5*8(%rsp)
|
|
- movq %rbp, 6*8(%rsp)
|
|
+ movq %r15, 6*8(%rsp)
|
|
|
|
movq %r8, (%rsp)
|
|
movq %r9, 1*8(%rsp)
|
|
@@ -74,7 +74,7 @@ ENTRY(csum_partial_copy_generic)
|
|
/* main loop. clear in 64 byte blocks */
|
|
/* r9: zero, r8: temp2, rbx: temp1, rax: sum, rcx: saved length */
|
|
/* r11: temp3, rdx: temp4, r12 loopcnt */
|
|
- /* r10: temp5, rbp: temp6, r14 temp7, r13 temp8 */
|
|
+ /* r10: temp5, r15: temp6, r14 temp7, r13 temp8 */
|
|
.p2align 4
|
|
.Lloop:
|
|
source
|
|
@@ -89,7 +89,7 @@ ENTRY(csum_partial_copy_generic)
|
|
source
|
|
movq 32(%rdi), %r10
|
|
source
|
|
- movq 40(%rdi), %rbp
|
|
+ movq 40(%rdi), %r15
|
|
source
|
|
movq 48(%rdi), %r14
|
|
source
|
|
@@ -103,7 +103,7 @@ ENTRY(csum_partial_copy_generic)
|
|
adcq %r11, %rax
|
|
adcq %rdx, %rax
|
|
adcq %r10, %rax
|
|
- adcq %rbp, %rax
|
|
+ adcq %r15, %rax
|
|
adcq %r14, %rax
|
|
adcq %r13, %rax
|
|
|
|
@@ -121,7 +121,7 @@ ENTRY(csum_partial_copy_generic)
|
|
dest
|
|
movq %r10, 32(%rsi)
|
|
dest
|
|
- movq %rbp, 40(%rsi)
|
|
+ movq %r15, 40(%rsi)
|
|
dest
|
|
movq %r14, 48(%rsi)
|
|
dest
|
|
@@ -203,7 +203,7 @@ ENTRY(csum_partial_copy_generic)
|
|
movq 3*8(%rsp), %r12
|
|
movq 4*8(%rsp), %r14
|
|
movq 5*8(%rsp), %r13
|
|
- movq 6*8(%rsp), %rbp
|
|
+ movq 6*8(%rsp), %r15
|
|
addq $7*8, %rsp
|
|
ret
|
|
|
|
diff --git a/block/bio-integrity.c b/block/bio-integrity.c
|
|
index f6325d573c10..6e091ccadcd4 100644
|
|
--- a/block/bio-integrity.c
|
|
+++ b/block/bio-integrity.c
|
|
@@ -175,6 +175,9 @@ bool bio_integrity_enabled(struct bio *bio)
|
|
if (!bio_is_rw(bio))
|
|
return false;
|
|
|
|
+ if (!bio_sectors(bio))
|
|
+ return false;
|
|
+
|
|
/* Already protected? */
|
|
if (bio_integrity(bio))
|
|
return false;
|
|
diff --git a/block/blk-mq.c b/block/blk-mq.c
|
|
index 0d1af3e44efb..8649dbf06ce4 100644
|
|
--- a/block/blk-mq.c
|
|
+++ b/block/blk-mq.c
|
|
@@ -1252,13 +1252,13 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
|
|
|
|
blk_queue_bounce(q, &bio);
|
|
|
|
+ blk_queue_split(q, &bio, q->bio_split);
|
|
+
|
|
if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
|
|
bio_io_error(bio);
|
|
return BLK_QC_T_NONE;
|
|
}
|
|
|
|
- blk_queue_split(q, &bio, q->bio_split);
|
|
-
|
|
if (!is_flush_fua && !blk_queue_nomerges(q) &&
|
|
blk_attempt_plug_merge(q, bio, &request_count, &same_queue_rq))
|
|
return BLK_QC_T_NONE;
|
|
@@ -1634,7 +1634,8 @@ static void blk_mq_exit_hctx(struct request_queue *q,
|
|
{
|
|
unsigned flush_start_tag = set->queue_depth;
|
|
|
|
- blk_mq_tag_idle(hctx);
|
|
+ if (blk_mq_hw_queue_mapped(hctx))
|
|
+ blk_mq_tag_idle(hctx);
|
|
|
|
if (set->ops->exit_request)
|
|
set->ops->exit_request(set->driver_data,
|
|
diff --git a/block/partition-generic.c b/block/partition-generic.c
|
|
index 3c062699f28b..29521753fb23 100644
|
|
--- a/block/partition-generic.c
|
|
+++ b/block/partition-generic.c
|
|
@@ -309,8 +309,10 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
|
|
|
|
if (info) {
|
|
struct partition_meta_info *pinfo = alloc_part_info(disk);
|
|
- if (!pinfo)
|
|
+ if (!pinfo) {
|
|
+ err = -ENOMEM;
|
|
goto out_free_stats;
|
|
+ }
|
|
memcpy(pinfo, info, sizeof(*info));
|
|
p->info = pinfo;
|
|
}
|
|
diff --git a/crypto/async_tx/async_pq.c b/crypto/async_tx/async_pq.c
|
|
index 84f8d4d8b6bc..09f706b7b06e 100644
|
|
--- a/crypto/async_tx/async_pq.c
|
|
+++ b/crypto/async_tx/async_pq.c
|
|
@@ -62,9 +62,6 @@ do_async_gen_syndrome(struct dma_chan *chan,
|
|
dma_addr_t dma_dest[2];
|
|
int src_off = 0;
|
|
|
|
- if (submit->flags & ASYNC_TX_FENCE)
|
|
- dma_flags |= DMA_PREP_FENCE;
|
|
-
|
|
while (src_cnt > 0) {
|
|
submit->flags = flags_orig;
|
|
pq_src_cnt = min(src_cnt, dma_maxpq(dma, dma_flags));
|
|
@@ -83,6 +80,8 @@ do_async_gen_syndrome(struct dma_chan *chan,
|
|
if (cb_fn_orig)
|
|
dma_flags |= DMA_PREP_INTERRUPT;
|
|
}
|
|
+ if (submit->flags & ASYNC_TX_FENCE)
|
|
+ dma_flags |= DMA_PREP_FENCE;
|
|
|
|
/* Drivers force forward progress in case they can not provide
|
|
* a descriptor
|
|
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
|
|
index 10ce48e16ebf..d830705f8a18 100644
|
|
--- a/drivers/acpi/acpica/evxfevnt.c
|
|
+++ b/drivers/acpi/acpica/evxfevnt.c
|
|
@@ -180,6 +180,12 @@ acpi_status acpi_enable_event(u32 event, u32 flags)
|
|
|
|
ACPI_FUNCTION_TRACE(acpi_enable_event);
|
|
|
|
+ /* If Hardware Reduced flag is set, there are no fixed events */
|
|
+
|
|
+ if (acpi_gbl_reduced_hardware) {
|
|
+ return_ACPI_STATUS(AE_OK);
|
|
+ }
|
|
+
|
|
/* Decode the Fixed Event */
|
|
|
|
if (event > ACPI_EVENT_MAX) {
|
|
@@ -237,6 +243,12 @@ acpi_status acpi_disable_event(u32 event, u32 flags)
|
|
|
|
ACPI_FUNCTION_TRACE(acpi_disable_event);
|
|
|
|
+ /* If Hardware Reduced flag is set, there are no fixed events */
|
|
+
|
|
+ if (acpi_gbl_reduced_hardware) {
|
|
+ return_ACPI_STATUS(AE_OK);
|
|
+ }
|
|
+
|
|
/* Decode the Fixed Event */
|
|
|
|
if (event > ACPI_EVENT_MAX) {
|
|
@@ -290,6 +302,12 @@ acpi_status acpi_clear_event(u32 event)
|
|
|
|
ACPI_FUNCTION_TRACE(acpi_clear_event);
|
|
|
|
+ /* If Hardware Reduced flag is set, there are no fixed events */
|
|
+
|
|
+ if (acpi_gbl_reduced_hardware) {
|
|
+ return_ACPI_STATUS(AE_OK);
|
|
+ }
|
|
+
|
|
/* Decode the Fixed Event */
|
|
|
|
if (event > ACPI_EVENT_MAX) {
|
|
diff --git a/drivers/acpi/acpica/psobject.c b/drivers/acpi/acpica/psobject.c
|
|
index e54bc2aa7a88..a05b3b79b987 100644
|
|
--- a/drivers/acpi/acpica/psobject.c
|
|
+++ b/drivers/acpi/acpica/psobject.c
|
|
@@ -121,6 +121,9 @@ static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
|
|
(u32)(aml_offset +
|
|
sizeof(struct acpi_table_header)));
|
|
|
|
+ ACPI_ERROR((AE_INFO,
|
|
+ "Aborting disassembly, AML byte code is corrupt"));
|
|
+
|
|
/* Dump the context surrounding the invalid opcode */
|
|
|
|
acpi_ut_dump_buffer(((u8 *)walk_state->parser_state.
|
|
@@ -129,6 +132,14 @@ static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
|
|
sizeof(struct acpi_table_header) -
|
|
16));
|
|
acpi_os_printf(" */\n");
|
|
+
|
|
+ /*
|
|
+ * Just abort the disassembly, cannot continue because the
|
|
+ * parser is essentially lost. The disassembler can then
|
|
+ * randomly fail because an ill-constructed parse tree
|
|
+ * can result.
|
|
+ */
|
|
+ return_ACPI_STATUS(AE_AML_BAD_OPCODE);
|
|
#endif
|
|
}
|
|
|
|
@@ -293,6 +304,9 @@ acpi_ps_create_op(struct acpi_walk_state *walk_state,
|
|
if (status == AE_CTRL_PARSE_CONTINUE) {
|
|
return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
|
|
}
|
|
+ if (ACPI_FAILURE(status)) {
|
|
+ return_ACPI_STATUS(status);
|
|
+ }
|
|
|
|
/* Create Op structure and append to parent's argument list */
|
|
|
|
diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c
|
|
index aaa761b9081c..cd2eab6aa92e 100644
|
|
--- a/drivers/ata/libahci_platform.c
|
|
+++ b/drivers/ata/libahci_platform.c
|
|
@@ -514,8 +514,9 @@ int ahci_platform_init_host(struct platform_device *pdev,
|
|
|
|
irq = platform_get_irq(pdev, 0);
|
|
if (irq <= 0) {
|
|
- dev_err(dev, "no irq\n");
|
|
- return -EINVAL;
|
|
+ if (irq != -EPROBE_DEFER)
|
|
+ dev_err(dev, "no irq\n");
|
|
+ return irq;
|
|
}
|
|
|
|
hpriv->irq = irq;
|
|
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
|
|
index 3e65ae144fde..1dd16f26e77d 100644
|
|
--- a/drivers/block/loop.c
|
|
+++ b/drivers/block/loop.c
|
|
@@ -623,6 +623,9 @@ static int loop_switch(struct loop_device *lo, struct file *file)
|
|
*/
|
|
static int loop_flush(struct loop_device *lo)
|
|
{
|
|
+ /* loop not yet configured, no running thread, nothing to flush */
|
|
+ if (lo->lo_state != Lo_bound)
|
|
+ return 0;
|
|
return loop_switch(lo, NULL);
|
|
}
|
|
|
|
diff --git a/drivers/bus/brcmstb_gisb.c b/drivers/bus/brcmstb_gisb.c
|
|
index f364fa4d24eb..f59183018280 100644
|
|
--- a/drivers/bus/brcmstb_gisb.c
|
|
+++ b/drivers/bus/brcmstb_gisb.c
|
|
@@ -1,5 +1,5 @@
|
|
/*
|
|
- * Copyright (C) 2014 Broadcom Corporation
|
|
+ * Copyright (C) 2014-2017 Broadcom
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
@@ -33,8 +33,6 @@
|
|
#define ARB_ERR_CAP_CLEAR (1 << 0)
|
|
#define ARB_ERR_CAP_STATUS_TIMEOUT (1 << 12)
|
|
#define ARB_ERR_CAP_STATUS_TEA (1 << 11)
|
|
-#define ARB_ERR_CAP_STATUS_BS_SHIFT (1 << 2)
|
|
-#define ARB_ERR_CAP_STATUS_BS_MASK 0x3c
|
|
#define ARB_ERR_CAP_STATUS_WRITE (1 << 1)
|
|
#define ARB_ERR_CAP_STATUS_VALID (1 << 0)
|
|
|
|
@@ -43,7 +41,6 @@ enum {
|
|
ARB_ERR_CAP_CLR,
|
|
ARB_ERR_CAP_HI_ADDR,
|
|
ARB_ERR_CAP_ADDR,
|
|
- ARB_ERR_CAP_DATA,
|
|
ARB_ERR_CAP_STATUS,
|
|
ARB_ERR_CAP_MASTER,
|
|
};
|
|
@@ -53,7 +50,6 @@ static const int gisb_offsets_bcm7038[] = {
|
|
[ARB_ERR_CAP_CLR] = 0x0c4,
|
|
[ARB_ERR_CAP_HI_ADDR] = -1,
|
|
[ARB_ERR_CAP_ADDR] = 0x0c8,
|
|
- [ARB_ERR_CAP_DATA] = 0x0cc,
|
|
[ARB_ERR_CAP_STATUS] = 0x0d0,
|
|
[ARB_ERR_CAP_MASTER] = -1,
|
|
};
|
|
@@ -63,7 +59,6 @@ static const int gisb_offsets_bcm7400[] = {
|
|
[ARB_ERR_CAP_CLR] = 0x0c8,
|
|
[ARB_ERR_CAP_HI_ADDR] = -1,
|
|
[ARB_ERR_CAP_ADDR] = 0x0cc,
|
|
- [ARB_ERR_CAP_DATA] = 0x0d0,
|
|
[ARB_ERR_CAP_STATUS] = 0x0d4,
|
|
[ARB_ERR_CAP_MASTER] = 0x0d8,
|
|
};
|
|
@@ -73,7 +68,6 @@ static const int gisb_offsets_bcm7435[] = {
|
|
[ARB_ERR_CAP_CLR] = 0x168,
|
|
[ARB_ERR_CAP_HI_ADDR] = -1,
|
|
[ARB_ERR_CAP_ADDR] = 0x16c,
|
|
- [ARB_ERR_CAP_DATA] = 0x170,
|
|
[ARB_ERR_CAP_STATUS] = 0x174,
|
|
[ARB_ERR_CAP_MASTER] = 0x178,
|
|
};
|
|
@@ -83,7 +77,6 @@ static const int gisb_offsets_bcm7445[] = {
|
|
[ARB_ERR_CAP_CLR] = 0x7e4,
|
|
[ARB_ERR_CAP_HI_ADDR] = 0x7e8,
|
|
[ARB_ERR_CAP_ADDR] = 0x7ec,
|
|
- [ARB_ERR_CAP_DATA] = 0x7f0,
|
|
[ARB_ERR_CAP_STATUS] = 0x7f4,
|
|
[ARB_ERR_CAP_MASTER] = 0x7f8,
|
|
};
|
|
@@ -105,9 +98,13 @@ static u32 gisb_read(struct brcmstb_gisb_arb_device *gdev, int reg)
|
|
{
|
|
int offset = gdev->gisb_offsets[reg];
|
|
|
|
- /* return 1 if the hardware doesn't have ARB_ERR_CAP_MASTER */
|
|
- if (offset == -1)
|
|
- return 1;
|
|
+ if (offset < 0) {
|
|
+ /* return 1 if the hardware doesn't have ARB_ERR_CAP_MASTER */
|
|
+ if (reg == ARB_ERR_CAP_MASTER)
|
|
+ return 1;
|
|
+ else
|
|
+ return 0;
|
|
+ }
|
|
|
|
if (gdev->big_endian)
|
|
return ioread32be(gdev->base + offset);
|
|
@@ -115,6 +112,16 @@ static u32 gisb_read(struct brcmstb_gisb_arb_device *gdev, int reg)
|
|
return ioread32(gdev->base + offset);
|
|
}
|
|
|
|
+static u64 gisb_read_address(struct brcmstb_gisb_arb_device *gdev)
|
|
+{
|
|
+ u64 value;
|
|
+
|
|
+ value = gisb_read(gdev, ARB_ERR_CAP_ADDR);
|
|
+ value |= (u64)gisb_read(gdev, ARB_ERR_CAP_HI_ADDR) << 32;
|
|
+
|
|
+ return value;
|
|
+}
|
|
+
|
|
static void gisb_write(struct brcmstb_gisb_arb_device *gdev, u32 val, int reg)
|
|
{
|
|
int offset = gdev->gisb_offsets[reg];
|
|
@@ -123,9 +130,9 @@ static void gisb_write(struct brcmstb_gisb_arb_device *gdev, u32 val, int reg)
|
|
return;
|
|
|
|
if (gdev->big_endian)
|
|
- iowrite32be(val, gdev->base + reg);
|
|
+ iowrite32be(val, gdev->base + offset);
|
|
else
|
|
- iowrite32(val, gdev->base + reg);
|
|
+ iowrite32(val, gdev->base + offset);
|
|
}
|
|
|
|
static ssize_t gisb_arb_get_timeout(struct device *dev,
|
|
@@ -181,7 +188,7 @@ static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev,
|
|
const char *reason)
|
|
{
|
|
u32 cap_status;
|
|
- unsigned long arb_addr;
|
|
+ u64 arb_addr;
|
|
u32 master;
|
|
const char *m_name;
|
|
char m_fmt[11];
|
|
@@ -193,10 +200,7 @@ static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev,
|
|
return 1;
|
|
|
|
/* Read the address and master */
|
|
- arb_addr = gisb_read(gdev, ARB_ERR_CAP_ADDR) & 0xffffffff;
|
|
-#if (IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT))
|
|
- arb_addr |= (u64)gisb_read(gdev, ARB_ERR_CAP_HI_ADDR) << 32;
|
|
-#endif
|
|
+ arb_addr = gisb_read_address(gdev);
|
|
master = gisb_read(gdev, ARB_ERR_CAP_MASTER);
|
|
|
|
m_name = brcmstb_gisb_master_to_str(gdev, master);
|
|
@@ -205,7 +209,7 @@ static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev,
|
|
m_name = m_fmt;
|
|
}
|
|
|
|
- pr_crit("%s: %s at 0x%lx [%c %s], core: %s\n",
|
|
+ pr_crit("%s: %s at 0x%llx [%c %s], core: %s\n",
|
|
__func__, reason, arb_addr,
|
|
cap_status & ARB_ERR_CAP_STATUS_WRITE ? 'W' : 'R',
|
|
cap_status & ARB_ERR_CAP_STATUS_TIMEOUT ? "timeout" : "",
|
|
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
|
|
index f53e8ba2c718..83c206f0fc98 100644
|
|
--- a/drivers/char/ipmi/ipmi_ssif.c
|
|
+++ b/drivers/char/ipmi/ipmi_ssif.c
|
|
@@ -409,6 +409,7 @@ static void start_event_fetch(struct ssif_info *ssif_info, unsigned long *flags)
|
|
msg = ipmi_alloc_smi_msg();
|
|
if (!msg) {
|
|
ssif_info->ssif_state = SSIF_NORMAL;
|
|
+ ipmi_ssif_unlock_cond(ssif_info, flags);
|
|
return;
|
|
}
|
|
|
|
@@ -431,6 +432,7 @@ static void start_recv_msg_fetch(struct ssif_info *ssif_info,
|
|
msg = ipmi_alloc_smi_msg();
|
|
if (!msg) {
|
|
ssif_info->ssif_state = SSIF_NORMAL;
|
|
+ ipmi_ssif_unlock_cond(ssif_info, flags);
|
|
return;
|
|
}
|
|
|
|
diff --git a/drivers/char/random.c b/drivers/char/random.c
|
|
index 1822472dffab..bd9fc2baa6aa 100644
|
|
--- a/drivers/char/random.c
|
|
+++ b/drivers/char/random.c
|
|
@@ -886,12 +886,16 @@ static void add_interrupt_bench(cycles_t start)
|
|
static __u32 get_reg(struct fast_pool *f, struct pt_regs *regs)
|
|
{
|
|
__u32 *ptr = (__u32 *) regs;
|
|
+ unsigned int idx;
|
|
|
|
if (regs == NULL)
|
|
return 0;
|
|
- if (f->reg_idx >= sizeof(struct pt_regs) / sizeof(__u32))
|
|
- f->reg_idx = 0;
|
|
- return *(ptr + f->reg_idx++);
|
|
+ idx = READ_ONCE(f->reg_idx);
|
|
+ if (idx >= sizeof(struct pt_regs) / sizeof(__u32))
|
|
+ idx = 0;
|
|
+ ptr += idx++;
|
|
+ WRITE_ONCE(f->reg_idx, idx);
|
|
+ return *ptr;
|
|
}
|
|
|
|
void add_interrupt_randomness(int irq, int irq_flags)
|
|
diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c
|
|
index 43a218f35b19..4ad32ce428cf 100644
|
|
--- a/drivers/clk/clk-conf.c
|
|
+++ b/drivers/clk/clk-conf.c
|
|
@@ -106,7 +106,7 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier)
|
|
|
|
rc = clk_set_rate(clk, rate);
|
|
if (rc < 0)
|
|
- pr_err("clk: couldn't set %s clk rate to %d (%d), current rate: %ld\n",
|
|
+ pr_err("clk: couldn't set %s clk rate to %u (%d), current rate: %lu\n",
|
|
__clk_get_name(clk), rate, rc,
|
|
clk_get_rate(clk));
|
|
clk_put(clk);
|
|
diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c
|
|
index cd0f2726f5e0..c40445488d3a 100644
|
|
--- a/drivers/clk/clk-scpi.c
|
|
+++ b/drivers/clk/clk-scpi.c
|
|
@@ -71,15 +71,15 @@ static const struct clk_ops scpi_clk_ops = {
|
|
};
|
|
|
|
/* find closest match to given frequency in OPP table */
|
|
-static int __scpi_dvfs_round_rate(struct scpi_clk *clk, unsigned long rate)
|
|
+static long __scpi_dvfs_round_rate(struct scpi_clk *clk, unsigned long rate)
|
|
{
|
|
int idx;
|
|
- u32 fmin = 0, fmax = ~0, ftmp;
|
|
+ unsigned long fmin = 0, fmax = ~0, ftmp;
|
|
const struct scpi_opp *opp = clk->info->opps;
|
|
|
|
for (idx = 0; idx < clk->info->count; idx++, opp++) {
|
|
ftmp = opp->freq;
|
|
- if (ftmp >= (u32)rate) {
|
|
+ if (ftmp >= rate) {
|
|
if (ftmp <= fmax)
|
|
fmax = ftmp;
|
|
break;
|
|
diff --git a/drivers/cpuidle/dt_idle_states.c b/drivers/cpuidle/dt_idle_states.c
|
|
index a5c111b67f37..ea11a33e7fff 100644
|
|
--- a/drivers/cpuidle/dt_idle_states.c
|
|
+++ b/drivers/cpuidle/dt_idle_states.c
|
|
@@ -174,8 +174,10 @@ int dt_init_idle_driver(struct cpuidle_driver *drv,
|
|
if (!state_node)
|
|
break;
|
|
|
|
- if (!of_device_is_available(state_node))
|
|
+ if (!of_device_is_available(state_node)) {
|
|
+ of_node_put(state_node);
|
|
continue;
|
|
+ }
|
|
|
|
if (!idle_state_valid(state_node, i, cpumask)) {
|
|
pr_warn("%s idle state not valid, bailing out\n",
|
|
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
|
|
index f8d740a6740d..48d4dddf4941 100644
|
|
--- a/drivers/dma/imx-sdma.c
|
|
+++ b/drivers/dma/imx-sdma.c
|
|
@@ -1722,17 +1722,24 @@ static int sdma_probe(struct platform_device *pdev)
|
|
if (IS_ERR(sdma->clk_ahb))
|
|
return PTR_ERR(sdma->clk_ahb);
|
|
|
|
- clk_prepare(sdma->clk_ipg);
|
|
- clk_prepare(sdma->clk_ahb);
|
|
+ ret = clk_prepare(sdma->clk_ipg);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ ret = clk_prepare(sdma->clk_ahb);
|
|
+ if (ret)
|
|
+ goto err_clk;
|
|
|
|
ret = devm_request_irq(&pdev->dev, irq, sdma_int_handler, 0, "sdma",
|
|
sdma);
|
|
if (ret)
|
|
- return ret;
|
|
+ goto err_irq;
|
|
|
|
sdma->script_addrs = kzalloc(sizeof(*sdma->script_addrs), GFP_KERNEL);
|
|
- if (!sdma->script_addrs)
|
|
- return -ENOMEM;
|
|
+ if (!sdma->script_addrs) {
|
|
+ ret = -ENOMEM;
|
|
+ goto err_irq;
|
|
+ }
|
|
|
|
/* initially no scripts available */
|
|
saddr_arr = (s32 *)sdma->script_addrs;
|
|
@@ -1847,6 +1854,10 @@ err_register:
|
|
dma_async_device_unregister(&sdma->dma_device);
|
|
err_init:
|
|
kfree(sdma->script_addrs);
|
|
+err_irq:
|
|
+ clk_unprepare(sdma->clk_ahb);
|
|
+err_clk:
|
|
+ clk_unprepare(sdma->clk_ipg);
|
|
return ret;
|
|
}
|
|
|
|
@@ -1857,6 +1868,8 @@ static int sdma_remove(struct platform_device *pdev)
|
|
|
|
dma_async_device_unregister(&sdma->dma_device);
|
|
kfree(sdma->script_addrs);
|
|
+ clk_unprepare(sdma->clk_ahb);
|
|
+ clk_unprepare(sdma->clk_ipg);
|
|
/* Kill the tasklet */
|
|
for (i = 0; i < MAX_DMA_CHANNELS; i++) {
|
|
struct sdma_channel *sdmac = &sdma->channel[i];
|
|
diff --git a/drivers/edac/mv64x60_edac.c b/drivers/edac/mv64x60_edac.c
|
|
index 0574e1bbe45c..3ce5609b4611 100644
|
|
--- a/drivers/edac/mv64x60_edac.c
|
|
+++ b/drivers/edac/mv64x60_edac.c
|
|
@@ -763,7 +763,7 @@ static int mv64x60_mc_err_probe(struct platform_device *pdev)
|
|
/* Non-ECC RAM? */
|
|
printk(KERN_WARNING "%s: No ECC DIMMs discovered\n", __func__);
|
|
res = -ENODEV;
|
|
- goto err2;
|
|
+ goto err;
|
|
}
|
|
|
|
edac_dbg(3, "init mci\n");
|
|
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
|
|
index 06d345b087f8..759a39906a52 100644
|
|
--- a/drivers/gpio/gpiolib.c
|
|
+++ b/drivers/gpio/gpiolib.c
|
|
@@ -2145,7 +2145,8 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
|
|
return desc;
|
|
}
|
|
|
|
- status = gpiod_request(desc, con_id);
|
|
+ /* If a connection label was passed use that, else use the device name as label */
|
|
+ status = gpiod_request(desc, con_id ? con_id : dev_name(dev));
|
|
if (status < 0)
|
|
return ERR_PTR(status);
|
|
|
|
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
|
|
index 7ed08fdc4c42..393e5335e33b 100644
|
|
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
|
|
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
|
|
@@ -158,7 +158,7 @@ static void evict_entry(struct drm_gem_object *obj,
|
|
size_t size = PAGE_SIZE * n;
|
|
loff_t off = mmap_offset(obj) +
|
|
(entry->obj_pgoff << PAGE_SHIFT);
|
|
- const int m = 1 + ((omap_obj->width << fmt) / PAGE_SIZE);
|
|
+ const int m = DIV_ROUND_UP(omap_obj->width << fmt, PAGE_SIZE);
|
|
|
|
if (m > 1) {
|
|
int i;
|
|
@@ -415,7 +415,7 @@ static int fault_2d(struct drm_gem_object *obj,
|
|
* into account in some of the math, so figure out virtual stride
|
|
* in pages
|
|
*/
|
|
- const int m = 1 + ((omap_obj->width << fmt) / PAGE_SIZE);
|
|
+ const int m = DIV_ROUND_UP(omap_obj->width << fmt, PAGE_SIZE);
|
|
|
|
/* We don't use vmf->pgoff since that has the fake offset: */
|
|
pgoff = ((unsigned long)vmf->virtual_address -
|
|
diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c
|
|
index b24f1d3045f0..a629f7c130f0 100644
|
|
--- a/drivers/hwmon/ina2xx.c
|
|
+++ b/drivers/hwmon/ina2xx.c
|
|
@@ -94,18 +94,20 @@ enum ina2xx_ids { ina219, ina226 };
|
|
|
|
struct ina2xx_config {
|
|
u16 config_default;
|
|
- int calibration_factor;
|
|
+ int calibration_value;
|
|
int registers;
|
|
int shunt_div;
|
|
int bus_voltage_shift;
|
|
int bus_voltage_lsb; /* uV */
|
|
- int power_lsb; /* uW */
|
|
+ int power_lsb_factor;
|
|
};
|
|
|
|
struct ina2xx_data {
|
|
const struct ina2xx_config *config;
|
|
|
|
long rshunt;
|
|
+ long current_lsb_uA;
|
|
+ long power_lsb_uW;
|
|
struct mutex config_lock;
|
|
struct regmap *regmap;
|
|
|
|
@@ -115,21 +117,21 @@ struct ina2xx_data {
|
|
static const struct ina2xx_config ina2xx_config[] = {
|
|
[ina219] = {
|
|
.config_default = INA219_CONFIG_DEFAULT,
|
|
- .calibration_factor = 40960000,
|
|
+ .calibration_value = 4096,
|
|
.registers = INA219_REGISTERS,
|
|
.shunt_div = 100,
|
|
.bus_voltage_shift = 3,
|
|
.bus_voltage_lsb = 4000,
|
|
- .power_lsb = 20000,
|
|
+ .power_lsb_factor = 20,
|
|
},
|
|
[ina226] = {
|
|
.config_default = INA226_CONFIG_DEFAULT,
|
|
- .calibration_factor = 5120000,
|
|
+ .calibration_value = 2048,
|
|
.registers = INA226_REGISTERS,
|
|
.shunt_div = 400,
|
|
.bus_voltage_shift = 0,
|
|
.bus_voltage_lsb = 1250,
|
|
- .power_lsb = 25000,
|
|
+ .power_lsb_factor = 25,
|
|
},
|
|
};
|
|
|
|
@@ -168,12 +170,16 @@ static u16 ina226_interval_to_reg(int interval)
|
|
return INA226_SHIFT_AVG(avg_bits);
|
|
}
|
|
|
|
+/*
|
|
+ * Calibration register is set to the best value, which eliminates
|
|
+ * truncation errors on calculating current register in hardware.
|
|
+ * According to datasheet (eq. 3) the best values are 2048 for
|
|
+ * ina226 and 4096 for ina219. They are hardcoded as calibration_value.
|
|
+ */
|
|
static int ina2xx_calibrate(struct ina2xx_data *data)
|
|
{
|
|
- u16 val = DIV_ROUND_CLOSEST(data->config->calibration_factor,
|
|
- data->rshunt);
|
|
-
|
|
- return regmap_write(data->regmap, INA2XX_CALIBRATION, val);
|
|
+ return regmap_write(data->regmap, INA2XX_CALIBRATION,
|
|
+ data->config->calibration_value);
|
|
}
|
|
|
|
/*
|
|
@@ -186,10 +192,6 @@ static int ina2xx_init(struct ina2xx_data *data)
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
- /*
|
|
- * Set current LSB to 1mA, shunt is in uOhms
|
|
- * (equation 13 in datasheet).
|
|
- */
|
|
return ina2xx_calibrate(data);
|
|
}
|
|
|
|
@@ -267,15 +269,15 @@ static int ina2xx_get_value(struct ina2xx_data *data, u8 reg,
|
|
val = DIV_ROUND_CLOSEST(val, 1000);
|
|
break;
|
|
case INA2XX_POWER:
|
|
- val = regval * data->config->power_lsb;
|
|
+ val = regval * data->power_lsb_uW;
|
|
break;
|
|
case INA2XX_CURRENT:
|
|
- /* signed register, LSB=1mA (selected), in mA */
|
|
- val = (s16)regval;
|
|
+ /* signed register, result in mA */
|
|
+ val = regval * data->current_lsb_uA;
|
|
+ val = DIV_ROUND_CLOSEST(val, 1000);
|
|
break;
|
|
case INA2XX_CALIBRATION:
|
|
- val = DIV_ROUND_CLOSEST(data->config->calibration_factor,
|
|
- regval);
|
|
+ val = regval;
|
|
break;
|
|
default:
|
|
/* programmer goofed */
|
|
@@ -303,9 +305,32 @@ static ssize_t ina2xx_show_value(struct device *dev,
|
|
ina2xx_get_value(data, attr->index, regval));
|
|
}
|
|
|
|
-static ssize_t ina2xx_set_shunt(struct device *dev,
|
|
- struct device_attribute *da,
|
|
- const char *buf, size_t count)
|
|
+/*
|
|
+ * In order to keep calibration register value fixed, the product
|
|
+ * of current_lsb and shunt_resistor should also be fixed and equal
|
|
+ * to shunt_voltage_lsb = 1 / shunt_div multiplied by 10^9 in order
|
|
+ * to keep the scale.
|
|
+ */
|
|
+static int ina2xx_set_shunt(struct ina2xx_data *data, long val)
|
|
+{
|
|
+ unsigned int dividend = DIV_ROUND_CLOSEST(1000000000,
|
|
+ data->config->shunt_div);
|
|
+ if (val <= 0 || val > dividend)
|
|
+ return -EINVAL;
|
|
+
|
|
+ mutex_lock(&data->config_lock);
|
|
+ data->rshunt = val;
|
|
+ data->current_lsb_uA = DIV_ROUND_CLOSEST(dividend, val);
|
|
+ data->power_lsb_uW = data->config->power_lsb_factor *
|
|
+ data->current_lsb_uA;
|
|
+ mutex_unlock(&data->config_lock);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static ssize_t ina2xx_store_shunt(struct device *dev,
|
|
+ struct device_attribute *da,
|
|
+ const char *buf, size_t count)
|
|
{
|
|
unsigned long val;
|
|
int status;
|
|
@@ -315,18 +340,9 @@ static ssize_t ina2xx_set_shunt(struct device *dev,
|
|
if (status < 0)
|
|
return status;
|
|
|
|
- if (val == 0 ||
|
|
- /* Values greater than the calibration factor make no sense. */
|
|
- val > data->config->calibration_factor)
|
|
- return -EINVAL;
|
|
-
|
|
- mutex_lock(&data->config_lock);
|
|
- data->rshunt = val;
|
|
- status = ina2xx_calibrate(data);
|
|
- mutex_unlock(&data->config_lock);
|
|
+ status = ina2xx_set_shunt(data, val);
|
|
if (status < 0)
|
|
return status;
|
|
-
|
|
return count;
|
|
}
|
|
|
|
@@ -386,7 +402,7 @@ static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ina2xx_show_value, NULL,
|
|
|
|
/* shunt resistance */
|
|
static SENSOR_DEVICE_ATTR(shunt_resistor, S_IRUGO | S_IWUSR,
|
|
- ina2xx_show_value, ina2xx_set_shunt,
|
|
+ ina2xx_show_value, ina2xx_store_shunt,
|
|
INA2XX_CALIBRATION);
|
|
|
|
/* update interval (ina226 only) */
|
|
@@ -441,10 +457,7 @@ static int ina2xx_probe(struct i2c_client *client,
|
|
val = INA2XX_RSHUNT_DEFAULT;
|
|
}
|
|
|
|
- if (val <= 0 || val > data->config->calibration_factor)
|
|
- return -ENODEV;
|
|
-
|
|
- data->rshunt = val;
|
|
+ ina2xx_set_shunt(data, val);
|
|
|
|
ina2xx_regmap_config.max_register = data->config->registers;
|
|
|
|
diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c
|
|
index c73c6c62a6ac..7401f102dff4 100644
|
|
--- a/drivers/iio/adc/hi8435.c
|
|
+++ b/drivers/iio/adc/hi8435.c
|
|
@@ -121,10 +121,21 @@ static int hi8435_write_event_config(struct iio_dev *idev,
|
|
enum iio_event_direction dir, int state)
|
|
{
|
|
struct hi8435_priv *priv = iio_priv(idev);
|
|
+ int ret;
|
|
+ u32 tmp;
|
|
+
|
|
+ if (state) {
|
|
+ ret = hi8435_readl(priv, HI8435_SO31_0_REG, &tmp);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
+ if (tmp & BIT(chan->channel))
|
|
+ priv->event_prev_val |= BIT(chan->channel);
|
|
+ else
|
|
+ priv->event_prev_val &= ~BIT(chan->channel);
|
|
|
|
- priv->event_scan_mask &= ~BIT(chan->channel);
|
|
- if (state)
|
|
priv->event_scan_mask |= BIT(chan->channel);
|
|
+ } else
|
|
+ priv->event_scan_mask &= ~BIT(chan->channel);
|
|
|
|
return 0;
|
|
}
|
|
@@ -442,13 +453,15 @@ static int hi8435_probe(struct spi_device *spi)
|
|
priv->spi = spi;
|
|
|
|
reset_gpio = devm_gpiod_get(&spi->dev, NULL, GPIOD_OUT_LOW);
|
|
- if (IS_ERR(reset_gpio)) {
|
|
- /* chip s/w reset if h/w reset failed */
|
|
+ if (!IS_ERR(reset_gpio)) {
|
|
+ /* need >=100ns low pulse to reset chip */
|
|
+ gpiod_set_raw_value_cansleep(reset_gpio, 0);
|
|
+ udelay(1);
|
|
+ gpiod_set_raw_value_cansleep(reset_gpio, 1);
|
|
+ } else {
|
|
+ /* s/w reset chip if h/w reset is not available */
|
|
hi8435_writeb(priv, HI8435_CTRL_REG, HI8435_CTRL_SRST);
|
|
hi8435_writeb(priv, HI8435_CTRL_REG, 0);
|
|
- } else {
|
|
- udelay(5);
|
|
- gpiod_set_value(reset_gpio, 1);
|
|
}
|
|
|
|
spi_set_drvdata(spi, idev);
|
|
diff --git a/drivers/iio/magnetometer/st_magn_spi.c b/drivers/iio/magnetometer/st_magn_spi.c
|
|
index 6325e7dc8e03..f3cb4dc05391 100644
|
|
--- a/drivers/iio/magnetometer/st_magn_spi.c
|
|
+++ b/drivers/iio/magnetometer/st_magn_spi.c
|
|
@@ -48,8 +48,6 @@ static int st_magn_spi_remove(struct spi_device *spi)
|
|
}
|
|
|
|
static const struct spi_device_id st_magn_id_table[] = {
|
|
- { LSM303DLHC_MAGN_DEV_NAME },
|
|
- { LSM303DLM_MAGN_DEV_NAME },
|
|
{ LIS3MDL_MAGN_DEV_NAME },
|
|
{ LSM303AGR_MAGN_DEV_NAME },
|
|
{},
|
|
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
|
|
index a73874508c3a..cb3a8623ff54 100644
|
|
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
|
|
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
|
|
@@ -2974,12 +2974,8 @@ static void srpt_queue_response(struct se_cmd *cmd)
|
|
}
|
|
spin_unlock_irqrestore(&ioctx->spinlock, flags);
|
|
|
|
- if (unlikely(transport_check_aborted_status(&ioctx->cmd, false)
|
|
- || WARN_ON_ONCE(state == SRPT_STATE_CMD_RSP_SENT))) {
|
|
- atomic_inc(&ch->req_lim_delta);
|
|
- srpt_abort_cmd(ioctx);
|
|
+ if (unlikely(WARN_ON_ONCE(state == SRPT_STATE_CMD_RSP_SENT)))
|
|
return;
|
|
- }
|
|
|
|
dir = ioctx->cmd.data_direction;
|
|
|
|
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
|
|
index c9d491bc85e0..3851d5715772 100644
|
|
--- a/drivers/input/mouse/elan_i2c_core.c
|
|
+++ b/drivers/input/mouse/elan_i2c_core.c
|
|
@@ -1082,6 +1082,13 @@ static int elan_probe(struct i2c_client *client,
|
|
return error;
|
|
}
|
|
|
|
+ /* Make sure there is something at this address */
|
|
+ error = i2c_smbus_read_byte(client);
|
|
+ if (error < 0) {
|
|
+ dev_dbg(&client->dev, "nothing at this address: %d\n", error);
|
|
+ return -ENXIO;
|
|
+ }
|
|
+
|
|
/* Initialize the touchpad. */
|
|
error = elan_initialize(data);
|
|
if (error)
|
|
diff --git a/drivers/input/mouse/elan_i2c_i2c.c b/drivers/input/mouse/elan_i2c_i2c.c
|
|
index a679e56c44cd..765879dcaf85 100644
|
|
--- a/drivers/input/mouse/elan_i2c_i2c.c
|
|
+++ b/drivers/input/mouse/elan_i2c_i2c.c
|
|
@@ -557,7 +557,14 @@ static int elan_i2c_finish_fw_update(struct i2c_client *client,
|
|
long ret;
|
|
int error;
|
|
int len;
|
|
- u8 buffer[ETP_I2C_INF_LENGTH];
|
|
+ u8 buffer[ETP_I2C_REPORT_LEN];
|
|
+
|
|
+ len = i2c_master_recv(client, buffer, ETP_I2C_REPORT_LEN);
|
|
+ if (len != ETP_I2C_REPORT_LEN) {
|
|
+ error = len < 0 ? len : -EIO;
|
|
+ dev_warn(dev, "failed to read I2C data after FW WDT reset: %d (%d)\n",
|
|
+ error, len);
|
|
+ }
|
|
|
|
reinit_completion(completion);
|
|
enable_irq(client->irq);
|
|
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
|
|
index 51b96e9bf793..06ea28e5d7b4 100644
|
|
--- a/drivers/input/mouse/elantech.c
|
|
+++ b/drivers/input/mouse/elantech.c
|
|
@@ -1715,6 +1715,17 @@ int elantech_init(struct psmouse *psmouse)
|
|
etd->samples[0], etd->samples[1], etd->samples[2]);
|
|
}
|
|
|
|
+ if (etd->samples[1] == 0x74 && etd->hw_version == 0x03) {
|
|
+ /*
|
|
+ * This module has a bug which makes absolute mode
|
|
+ * unusable, so let's abort so we'll be using standard
|
|
+ * PS/2 protocol.
|
|
+ */
|
|
+ psmouse_info(psmouse,
|
|
+ "absolute mode broken, forcing standard PS/2 protocol\n");
|
|
+ goto init_fail;
|
|
+ }
|
|
+
|
|
if (elantech_set_absolute_mode(psmouse)) {
|
|
psmouse_err(psmouse,
|
|
"failed to put touchpad into absolute mode.\n");
|
|
diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c
|
|
index 9cb4b621fbc3..b92a19a594a1 100644
|
|
--- a/drivers/isdn/mISDN/stack.c
|
|
+++ b/drivers/isdn/mISDN/stack.c
|
|
@@ -72,7 +72,7 @@ send_socklist(struct mISDN_sock_list *sl, struct sk_buff *skb)
|
|
if (sk->sk_state != MISDN_BOUND)
|
|
continue;
|
|
if (!cskb)
|
|
- cskb = skb_copy(skb, GFP_KERNEL);
|
|
+ cskb = skb_copy(skb, GFP_ATOMIC);
|
|
if (!cskb) {
|
|
printk(KERN_WARNING "%s no skb\n", __func__);
|
|
break;
|
|
diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c
|
|
index b775e1efecd3..b9f71a87b7e1 100644
|
|
--- a/drivers/leds/leds-pca955x.c
|
|
+++ b/drivers/leds/leds-pca955x.c
|
|
@@ -281,7 +281,7 @@ static int pca955x_probe(struct i2c_client *client,
|
|
"slave address 0x%02x\n",
|
|
id->name, chip->bits, client->addr);
|
|
|
|
- if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
|
|
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
|
|
return -EIO;
|
|
|
|
if (pdata) {
|
|
diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c
|
|
index 4d46f2ce606f..aa84fcfd59fc 100644
|
|
--- a/drivers/md/bcache/alloc.c
|
|
+++ b/drivers/md/bcache/alloc.c
|
|
@@ -514,15 +514,21 @@ struct open_bucket {
|
|
|
|
/*
|
|
* We keep multiple buckets open for writes, and try to segregate different
|
|
- * write streams for better cache utilization: first we look for a bucket where
|
|
- * the last write to it was sequential with the current write, and failing that
|
|
- * we look for a bucket that was last used by the same task.
|
|
+ * write streams for better cache utilization: first we try to segregate flash
|
|
+ * only volume write streams from cached devices, secondly we look for a bucket
|
|
+ * where the last write to it was sequential with the current write, and
|
|
+ * failing that we look for a bucket that was last used by the same task.
|
|
*
|
|
* The ideas is if you've got multiple tasks pulling data into the cache at the
|
|
* same time, you'll get better cache utilization if you try to segregate their
|
|
* data and preserve locality.
|
|
*
|
|
- * For example, say you've starting Firefox at the same time you're copying a
|
|
+ * For example, dirty sectors of flash only volume is not reclaimable, if their
|
|
+ * dirty sectors mixed with dirty sectors of cached device, such buckets will
|
|
+ * be marked as dirty and won't be reclaimed, though the dirty data of cached
|
|
+ * device have been written back to backend device.
|
|
+ *
|
|
+ * And say you've starting Firefox at the same time you're copying a
|
|
* bunch of files. Firefox will likely end up being fairly hot and stay in the
|
|
* cache awhile, but the data you copied might not be; if you wrote all that
|
|
* data to the same buckets it'd get invalidated at the same time.
|
|
@@ -539,7 +545,10 @@ static struct open_bucket *pick_data_bucket(struct cache_set *c,
|
|
struct open_bucket *ret, *ret_task = NULL;
|
|
|
|
list_for_each_entry_reverse(ret, &c->data_buckets, list)
|
|
- if (!bkey_cmp(&ret->key, search))
|
|
+ if (UUID_FLASH_ONLY(&c->uuids[KEY_INODE(&ret->key)]) !=
|
|
+ UUID_FLASH_ONLY(&c->uuids[KEY_INODE(search)]))
|
|
+ continue;
|
|
+ else if (!bkey_cmp(&ret->key, search))
|
|
goto found;
|
|
else if (ret->last_write_point == write_point)
|
|
ret_task = ret;
|
|
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
|
|
index be8307550bd7..f636af441da6 100644
|
|
--- a/drivers/md/bcache/super.c
|
|
+++ b/drivers/md/bcache/super.c
|
|
@@ -890,6 +890,12 @@ static void cached_dev_detach_finish(struct work_struct *w)
|
|
|
|
mutex_lock(&bch_register_lock);
|
|
|
|
+ cancel_delayed_work_sync(&dc->writeback_rate_update);
|
|
+ if (!IS_ERR_OR_NULL(dc->writeback_thread)) {
|
|
+ kthread_stop(dc->writeback_thread);
|
|
+ dc->writeback_thread = NULL;
|
|
+ }
|
|
+
|
|
memset(&dc->sb.set_uuid, 0, 16);
|
|
SET_BDEV_STATE(&dc->sb, BDEV_STATE_NONE);
|
|
|
|
diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c
|
|
index 494d01d0e92a..a7a561af05c9 100644
|
|
--- a/drivers/md/md-cluster.c
|
|
+++ b/drivers/md/md-cluster.c
|
|
@@ -945,8 +945,10 @@ static int add_new_disk(struct mddev *mddev, struct md_rdev *rdev)
|
|
cmsg.raid_slot = cpu_to_le32(rdev->desc_nr);
|
|
lock_comm(cinfo);
|
|
ret = __sendmsg(cinfo, &cmsg);
|
|
- if (ret)
|
|
+ if (ret) {
|
|
+ unlock_comm(cinfo);
|
|
return ret;
|
|
+ }
|
|
cinfo->no_new_dev_lockres->flags |= DLM_LKF_NOQUEUE;
|
|
ret = dlm_lock_sync(cinfo->no_new_dev_lockres, DLM_LOCK_EX);
|
|
cinfo->no_new_dev_lockres->flags &= ~DLM_LKF_NOQUEUE;
|
|
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
|
|
index ca968c3f25c7..e2130fb4597d 100644
|
|
--- a/drivers/md/raid5.c
|
|
+++ b/drivers/md/raid5.c
|
|
@@ -110,8 +110,7 @@ static inline void unlock_device_hash_lock(struct r5conf *conf, int hash)
|
|
static inline void lock_all_device_hash_locks_irq(struct r5conf *conf)
|
|
{
|
|
int i;
|
|
- local_irq_disable();
|
|
- spin_lock(conf->hash_locks);
|
|
+ spin_lock_irq(conf->hash_locks);
|
|
for (i = 1; i < NR_STRIPE_HASH_LOCKS; i++)
|
|
spin_lock_nest_lock(conf->hash_locks + i, conf->hash_locks);
|
|
spin_lock(&conf->device_lock);
|
|
@@ -121,9 +120,9 @@ static inline void unlock_all_device_hash_locks_irq(struct r5conf *conf)
|
|
{
|
|
int i;
|
|
spin_unlock(&conf->device_lock);
|
|
- for (i = NR_STRIPE_HASH_LOCKS; i; i--)
|
|
- spin_unlock(conf->hash_locks + i - 1);
|
|
- local_irq_enable();
|
|
+ for (i = NR_STRIPE_HASH_LOCKS - 1; i; i--)
|
|
+ spin_unlock(conf->hash_locks + i);
|
|
+ spin_unlock_irq(conf->hash_locks);
|
|
}
|
|
|
|
/* bio's attached to a stripe+device for I/O are linked together in bi_sector
|
|
@@ -726,12 +725,11 @@ static bool is_full_stripe_write(struct stripe_head *sh)
|
|
|
|
static void lock_two_stripes(struct stripe_head *sh1, struct stripe_head *sh2)
|
|
{
|
|
- local_irq_disable();
|
|
if (sh1 > sh2) {
|
|
- spin_lock(&sh2->stripe_lock);
|
|
+ spin_lock_irq(&sh2->stripe_lock);
|
|
spin_lock_nested(&sh1->stripe_lock, 1);
|
|
} else {
|
|
- spin_lock(&sh1->stripe_lock);
|
|
+ spin_lock_irq(&sh1->stripe_lock);
|
|
spin_lock_nested(&sh2->stripe_lock, 1);
|
|
}
|
|
}
|
|
@@ -739,8 +737,7 @@ static void lock_two_stripes(struct stripe_head *sh1, struct stripe_head *sh2)
|
|
static void unlock_two_stripes(struct stripe_head *sh1, struct stripe_head *sh2)
|
|
{
|
|
spin_unlock(&sh1->stripe_lock);
|
|
- spin_unlock(&sh2->stripe_lock);
|
|
- local_irq_enable();
|
|
+ spin_unlock_irq(&sh2->stripe_lock);
|
|
}
|
|
|
|
/* Only freshly new full stripe normal write stripe can be added to a batch list */
|
|
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
|
|
index fe6eb78b6914..a47ab1947cc4 100644
|
|
--- a/drivers/media/i2c/cx25840/cx25840-core.c
|
|
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
|
|
@@ -420,11 +420,13 @@ static void cx25840_initialize(struct i2c_client *client)
|
|
INIT_WORK(&state->fw_work, cx25840_work_handler);
|
|
init_waitqueue_head(&state->fw_wait);
|
|
q = create_singlethread_workqueue("cx25840_fw");
|
|
- prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
|
|
- queue_work(q, &state->fw_work);
|
|
- schedule();
|
|
- finish_wait(&state->fw_wait, &wait);
|
|
- destroy_workqueue(q);
|
|
+ if (q) {
|
|
+ prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
|
|
+ queue_work(q, &state->fw_work);
|
|
+ schedule();
|
|
+ finish_wait(&state->fw_wait, &wait);
|
|
+ destroy_workqueue(q);
|
|
+ }
|
|
|
|
/* 6. */
|
|
cx25840_write(client, 0x115, 0x8c);
|
|
@@ -631,11 +633,13 @@ static void cx23885_initialize(struct i2c_client *client)
|
|
INIT_WORK(&state->fw_work, cx25840_work_handler);
|
|
init_waitqueue_head(&state->fw_wait);
|
|
q = create_singlethread_workqueue("cx25840_fw");
|
|
- prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
|
|
- queue_work(q, &state->fw_work);
|
|
- schedule();
|
|
- finish_wait(&state->fw_wait, &wait);
|
|
- destroy_workqueue(q);
|
|
+ if (q) {
|
|
+ prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
|
|
+ queue_work(q, &state->fw_work);
|
|
+ schedule();
|
|
+ finish_wait(&state->fw_wait, &wait);
|
|
+ destroy_workqueue(q);
|
|
+ }
|
|
|
|
/* Call the cx23888 specific std setup func, we no longer rely on
|
|
* the generic cx24840 func.
|
|
@@ -746,11 +750,13 @@ static void cx231xx_initialize(struct i2c_client *client)
|
|
INIT_WORK(&state->fw_work, cx25840_work_handler);
|
|
init_waitqueue_head(&state->fw_wait);
|
|
q = create_singlethread_workqueue("cx25840_fw");
|
|
- prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
|
|
- queue_work(q, &state->fw_work);
|
|
- schedule();
|
|
- finish_wait(&state->fw_wait, &wait);
|
|
- destroy_workqueue(q);
|
|
+ if (q) {
|
|
+ prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
|
|
+ queue_work(q, &state->fw_work);
|
|
+ schedule();
|
|
+ finish_wait(&state->fw_wait, &wait);
|
|
+ destroy_workqueue(q);
|
|
+ }
|
|
|
|
cx25840_std_setup(client);
|
|
|
|
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
|
|
index f838d9c7ed12..0fba4a2c1602 100644
|
|
--- a/drivers/media/rc/mceusb.c
|
|
+++ b/drivers/media/rc/mceusb.c
|
|
@@ -1370,8 +1370,13 @@ static int mceusb_dev_probe(struct usb_interface *intf,
|
|
goto rc_dev_fail;
|
|
|
|
/* wire up inbound data handler */
|
|
- usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp,
|
|
- mceusb_dev_recv, ir, ep_in->bInterval);
|
|
+ if (usb_endpoint_xfer_int(ep_in))
|
|
+ usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp,
|
|
+ mceusb_dev_recv, ir, ep_in->bInterval);
|
|
+ else
|
|
+ usb_fill_bulk_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp,
|
|
+ mceusb_dev_recv, ir);
|
|
+
|
|
ir->urb_in->transfer_dma = ir->dma_in;
|
|
ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
|
|
|
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
|
|
index 3dc9ed2e0774..bb1e19f7ed5a 100644
|
|
--- a/drivers/media/v4l2-core/videobuf2-core.c
|
|
+++ b/drivers/media/v4l2-core/videobuf2-core.c
|
|
@@ -205,6 +205,10 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory,
|
|
struct vb2_buffer *vb;
|
|
int ret;
|
|
|
|
+ /* Ensure that q->num_buffers+num_buffers is below VB2_MAX_FRAME */
|
|
+ num_buffers = min_t(unsigned int, num_buffers,
|
|
+ VB2_MAX_FRAME - q->num_buffers);
|
|
+
|
|
for (buffer = 0; buffer < num_buffers; ++buffer) {
|
|
/* Allocate videobuf buffer structures */
|
|
vb = kzalloc(q->buf_struct_size, GFP_KERNEL);
|
|
diff --git a/drivers/misc/vmw_vmci/vmci_queue_pair.c b/drivers/misc/vmw_vmci/vmci_queue_pair.c
|
|
index f42d9c4e4561..cc277f7849b0 100644
|
|
--- a/drivers/misc/vmw_vmci/vmci_queue_pair.c
|
|
+++ b/drivers/misc/vmw_vmci/vmci_queue_pair.c
|
|
@@ -298,8 +298,11 @@ static void *qp_alloc_queue(u64 size, u32 flags)
|
|
size_t pas_size;
|
|
size_t vas_size;
|
|
size_t queue_size = sizeof(*queue) + sizeof(*queue->kernel_if);
|
|
- const u64 num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1;
|
|
+ u64 num_pages;
|
|
|
|
+ if (size > SIZE_MAX - PAGE_SIZE)
|
|
+ return NULL;
|
|
+ num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1;
|
|
if (num_pages >
|
|
(SIZE_MAX - queue_size) /
|
|
(sizeof(*queue->kernel_if->u.g.pas) +
|
|
@@ -624,9 +627,12 @@ static struct vmci_queue *qp_host_alloc_queue(u64 size)
|
|
{
|
|
struct vmci_queue *queue;
|
|
size_t queue_page_size;
|
|
- const u64 num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1;
|
|
+ u64 num_pages;
|
|
const size_t queue_size = sizeof(*queue) + sizeof(*(queue->kernel_if));
|
|
|
|
+ if (size > SIZE_MAX - PAGE_SIZE)
|
|
+ return NULL;
|
|
+ num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1;
|
|
if (num_pages > (SIZE_MAX - queue_size) /
|
|
sizeof(*queue->kernel_if->u.h.page))
|
|
return NULL;
|
|
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
|
|
index eadccf498589..278d12888cab 100644
|
|
--- a/drivers/net/bonding/bond_main.c
|
|
+++ b/drivers/net/bonding/bond_main.c
|
|
@@ -1490,39 +1490,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
|
goto err_close;
|
|
}
|
|
|
|
- /* If the mode uses primary, then the following is handled by
|
|
- * bond_change_active_slave().
|
|
- */
|
|
- if (!bond_uses_primary(bond)) {
|
|
- /* set promiscuity level to new slave */
|
|
- if (bond_dev->flags & IFF_PROMISC) {
|
|
- res = dev_set_promiscuity(slave_dev, 1);
|
|
- if (res)
|
|
- goto err_close;
|
|
- }
|
|
-
|
|
- /* set allmulti level to new slave */
|
|
- if (bond_dev->flags & IFF_ALLMULTI) {
|
|
- res = dev_set_allmulti(slave_dev, 1);
|
|
- if (res)
|
|
- goto err_close;
|
|
- }
|
|
-
|
|
- netif_addr_lock_bh(bond_dev);
|
|
-
|
|
- dev_mc_sync_multiple(slave_dev, bond_dev);
|
|
- dev_uc_sync_multiple(slave_dev, bond_dev);
|
|
-
|
|
- netif_addr_unlock_bh(bond_dev);
|
|
- }
|
|
-
|
|
- if (BOND_MODE(bond) == BOND_MODE_8023AD) {
|
|
- /* add lacpdu mc addr to mc list */
|
|
- u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
|
|
-
|
|
- dev_mc_add(slave_dev, lacpdu_multicast);
|
|
- }
|
|
-
|
|
res = vlan_vids_add_by_dev(slave_dev, bond_dev);
|
|
if (res) {
|
|
netdev_err(bond_dev, "Couldn't add bond vlan ids to %s\n",
|
|
@@ -1679,6 +1646,40 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
|
goto err_upper_unlink;
|
|
}
|
|
|
|
+ /* If the mode uses primary, then the following is handled by
|
|
+ * bond_change_active_slave().
|
|
+ */
|
|
+ if (!bond_uses_primary(bond)) {
|
|
+ /* set promiscuity level to new slave */
|
|
+ if (bond_dev->flags & IFF_PROMISC) {
|
|
+ res = dev_set_promiscuity(slave_dev, 1);
|
|
+ if (res)
|
|
+ goto err_sysfs_del;
|
|
+ }
|
|
+
|
|
+ /* set allmulti level to new slave */
|
|
+ if (bond_dev->flags & IFF_ALLMULTI) {
|
|
+ res = dev_set_allmulti(slave_dev, 1);
|
|
+ if (res) {
|
|
+ if (bond_dev->flags & IFF_PROMISC)
|
|
+ dev_set_promiscuity(slave_dev, -1);
|
|
+ goto err_sysfs_del;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ netif_addr_lock_bh(bond_dev);
|
|
+ dev_mc_sync_multiple(slave_dev, bond_dev);
|
|
+ dev_uc_sync_multiple(slave_dev, bond_dev);
|
|
+ netif_addr_unlock_bh(bond_dev);
|
|
+
|
|
+ if (BOND_MODE(bond) == BOND_MODE_8023AD) {
|
|
+ /* add lacpdu mc addr to mc list */
|
|
+ u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
|
|
+
|
|
+ dev_mc_add(slave_dev, lacpdu_multicast);
|
|
+ }
|
|
+ }
|
|
+
|
|
bond->slave_cnt++;
|
|
bond_compute_features(bond);
|
|
bond_set_carrier(bond);
|
|
@@ -1702,6 +1703,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
|
return 0;
|
|
|
|
/* Undo stages on error */
|
|
+err_sysfs_del:
|
|
+ bond_sysfs_slave_del(new_slave);
|
|
+
|
|
err_upper_unlink:
|
|
bond_upper_dev_unlink(bond_dev, slave_dev);
|
|
|
|
@@ -1709,9 +1713,6 @@ err_unregister:
|
|
netdev_rx_handler_unregister(slave_dev);
|
|
|
|
err_detach:
|
|
- if (!bond_uses_primary(bond))
|
|
- bond_hw_addr_flush(bond_dev, slave_dev);
|
|
-
|
|
vlan_vids_del_by_dev(slave_dev, bond_dev);
|
|
if (rcu_access_pointer(bond->primary_slave) == new_slave)
|
|
RCU_INIT_POINTER(bond->primary_slave, NULL);
|
|
@@ -2555,11 +2556,13 @@ static void bond_loadbalance_arp_mon(struct work_struct *work)
|
|
bond_for_each_slave_rcu(bond, slave, iter) {
|
|
unsigned long trans_start = dev_trans_start(slave->dev);
|
|
|
|
+ slave->new_link = BOND_LINK_NOCHANGE;
|
|
+
|
|
if (slave->link != BOND_LINK_UP) {
|
|
if (bond_time_in_interval(bond, trans_start, 1) &&
|
|
bond_time_in_interval(bond, slave->last_rx, 1)) {
|
|
|
|
- slave->link = BOND_LINK_UP;
|
|
+ slave->new_link = BOND_LINK_UP;
|
|
slave_state_changed = 1;
|
|
|
|
/* primary_slave has no meaning in round-robin
|
|
@@ -2586,7 +2589,7 @@ static void bond_loadbalance_arp_mon(struct work_struct *work)
|
|
if (!bond_time_in_interval(bond, trans_start, 2) ||
|
|
!bond_time_in_interval(bond, slave->last_rx, 2)) {
|
|
|
|
- slave->link = BOND_LINK_DOWN;
|
|
+ slave->new_link = BOND_LINK_DOWN;
|
|
slave_state_changed = 1;
|
|
|
|
if (slave->link_failure_count < UINT_MAX)
|
|
@@ -2617,6 +2620,11 @@ static void bond_loadbalance_arp_mon(struct work_struct *work)
|
|
if (!rtnl_trylock())
|
|
goto re_arm;
|
|
|
|
+ bond_for_each_slave(bond, slave, iter) {
|
|
+ if (slave->new_link != BOND_LINK_NOCHANGE)
|
|
+ slave->link = slave->new_link;
|
|
+ }
|
|
+
|
|
if (slave_state_changed) {
|
|
bond_slave_state_change(bond);
|
|
if (BOND_MODE(bond) == BOND_MODE_XOR)
|
|
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
|
|
index d1103d612d8b..949a82458a29 100644
|
|
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
|
|
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
|
|
@@ -3943,15 +3943,26 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|
/* when transmitting in a vf, start bd must hold the ethertype
|
|
* for fw to enforce it
|
|
*/
|
|
+ u16 vlan_tci = 0;
|
|
#ifndef BNX2X_STOP_ON_ERROR
|
|
- if (IS_VF(bp))
|
|
+ if (IS_VF(bp)) {
|
|
#endif
|
|
- tx_start_bd->vlan_or_ethertype =
|
|
- cpu_to_le16(ntohs(eth->h_proto));
|
|
+ /* Still need to consider inband vlan for enforced */
|
|
+ if (__vlan_get_tag(skb, &vlan_tci)) {
|
|
+ tx_start_bd->vlan_or_ethertype =
|
|
+ cpu_to_le16(ntohs(eth->h_proto));
|
|
+ } else {
|
|
+ tx_start_bd->bd_flags.as_bitfield |=
|
|
+ (X_ETH_INBAND_VLAN <<
|
|
+ ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT);
|
|
+ tx_start_bd->vlan_or_ethertype =
|
|
+ cpu_to_le16(vlan_tci);
|
|
+ }
|
|
#ifndef BNX2X_STOP_ON_ERROR
|
|
- else
|
|
+ } else {
|
|
/* used by FW for packet accounting */
|
|
tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod);
|
|
+ }
|
|
#endif
|
|
}
|
|
|
|
diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.c b/drivers/net/ethernet/brocade/bna/bfa_ioc.c
|
|
index 0f6811860ad5..a36e38676640 100644
|
|
--- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c
|
|
+++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c
|
|
@@ -2845,7 +2845,7 @@ bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc, char *optrom_ver)
|
|
static void
|
|
bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc, char *manufacturer)
|
|
{
|
|
- memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
|
|
+ strncpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
|
|
}
|
|
|
|
static void
|
|
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
|
|
index cf61a5869c6e..de23f23b41de 100644
|
|
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
|
|
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
|
|
@@ -6076,13 +6076,18 @@ int t4_fw_upgrade(struct adapter *adap, unsigned int mbox,
|
|
if (!t4_fw_matches_chip(adap, fw_hdr))
|
|
return -EINVAL;
|
|
|
|
+ /* Disable FW_OK flag so that mbox commands with FW_OK flag set
|
|
+ * wont be sent when we are flashing FW.
|
|
+ */
|
|
+ adap->flags &= ~FW_OK;
|
|
+
|
|
ret = t4_fw_halt(adap, mbox, force);
|
|
if (ret < 0 && !force)
|
|
- return ret;
|
|
+ goto out;
|
|
|
|
ret = t4_load_fw(adap, fw_data, size);
|
|
if (ret < 0)
|
|
- return ret;
|
|
+ goto out;
|
|
|
|
/*
|
|
* Older versions of the firmware don't understand the new
|
|
@@ -6093,7 +6098,17 @@ int t4_fw_upgrade(struct adapter *adap, unsigned int mbox,
|
|
* its header flags to see if it advertises the capability.
|
|
*/
|
|
reset = ((be32_to_cpu(fw_hdr->flags) & FW_HDR_FLAGS_RESET_HALT) == 0);
|
|
- return t4_fw_restart(adap, mbox, reset);
|
|
+ ret = t4_fw_restart(adap, mbox, reset);
|
|
+
|
|
+ /* Grab potentially new Firmware Device Log parameters so we can see
|
|
+ * how healthy the new Firmware is. It's okay to contact the new
|
|
+ * Firmware for these parameters even though, as far as it's
|
|
+ * concerned, we've never said "HELLO" to it ...
|
|
+ */
|
|
+ (void)t4_init_devlog_params(adap);
|
|
+out:
|
|
+ adap->flags |= FW_OK;
|
|
+ return ret;
|
|
}
|
|
|
|
/**
|
|
@@ -7696,7 +7711,16 @@ int t4_cim_read_la(struct adapter *adap, u32 *la_buf, unsigned int *wrptr)
|
|
ret = t4_cim_read(adap, UP_UP_DBG_LA_DATA_A, 1, &la_buf[i]);
|
|
if (ret)
|
|
break;
|
|
- idx = (idx + 1) & UPDBGLARDPTR_M;
|
|
+
|
|
+ /* Bits 0-3 of UpDbgLaRdPtr can be between 0000 to 1001 to
|
|
+ * identify the 32-bit portion of the full 312-bit data
|
|
+ */
|
|
+ if (is_t6(adap->params.chip) && (idx & 0xf) >= 9)
|
|
+ idx = (idx & 0xff0) + 0x10;
|
|
+ else
|
|
+ idx++;
|
|
+ /* address can't exceed 0xfff */
|
|
+ idx &= UPDBGLARDPTR_M;
|
|
}
|
|
restart:
|
|
if (cfg & UPDBGLAEN_F) {
|
|
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
|
|
index fa3786a9d30e..ec8ffd7eae33 100644
|
|
--- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
|
|
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
|
|
@@ -2604,8 +2604,8 @@ void t4vf_sge_stop(struct adapter *adapter)
|
|
int t4vf_sge_init(struct adapter *adapter)
|
|
{
|
|
struct sge_params *sge_params = &adapter->params.sge;
|
|
- u32 fl0 = sge_params->sge_fl_buffer_size[0];
|
|
- u32 fl1 = sge_params->sge_fl_buffer_size[1];
|
|
+ u32 fl_small_pg = sge_params->sge_fl_buffer_size[0];
|
|
+ u32 fl_large_pg = sge_params->sge_fl_buffer_size[1];
|
|
struct sge *s = &adapter->sge;
|
|
unsigned int ingpadboundary, ingpackboundary;
|
|
|
|
@@ -2614,9 +2614,20 @@ int t4vf_sge_init(struct adapter *adapter)
|
|
* the Physical Function Driver. Ideally we should be able to deal
|
|
* with _any_ configuration. Practice is different ...
|
|
*/
|
|
- if (fl0 != PAGE_SIZE || (fl1 != 0 && fl1 <= fl0)) {
|
|
+
|
|
+ /* We only bother using the Large Page logic if the Large Page Buffer
|
|
+ * is larger than our Page Size Buffer.
|
|
+ */
|
|
+ if (fl_large_pg <= fl_small_pg)
|
|
+ fl_large_pg = 0;
|
|
+
|
|
+ /* The Page Size Buffer must be exactly equal to our Page Size and the
|
|
+ * Large Page Size Buffer should be 0 (per above) or a power of 2.
|
|
+ */
|
|
+ if (fl_small_pg != PAGE_SIZE ||
|
|
+ (fl_large_pg & (fl_large_pg - 1)) != 0) {
|
|
dev_err(adapter->pdev_dev, "bad SGE FL buffer sizes [%d, %d]\n",
|
|
- fl0, fl1);
|
|
+ fl_small_pg, fl_large_pg);
|
|
return -EINVAL;
|
|
}
|
|
if ((sge_params->sge_control & RXPKTCPLMODE_F) == 0) {
|
|
@@ -2627,8 +2638,8 @@ int t4vf_sge_init(struct adapter *adapter)
|
|
/*
|
|
* Now translate the adapter parameters into our internal forms.
|
|
*/
|
|
- if (fl1)
|
|
- s->fl_pg_order = ilog2(fl1) - PAGE_SHIFT;
|
|
+ if (fl_large_pg)
|
|
+ s->fl_pg_order = ilog2(fl_large_pg) - PAGE_SHIFT;
|
|
s->stat_len = ((sge_params->sge_control & EGRSTATUSPAGESIZE_F)
|
|
? 128 : 64);
|
|
s->pktshift = PKTSHIFT_G(sge_params->sge_control);
|
|
diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c
|
|
index 40071dad1c57..9c76f1a2f57b 100644
|
|
--- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c
|
|
+++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c
|
|
@@ -382,7 +382,7 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev)
|
|
{
|
|
const struct of_device_id *id =
|
|
of_match_device(fsl_pq_mdio_match, &pdev->dev);
|
|
- const struct fsl_pq_mdio_data *data = id->data;
|
|
+ const struct fsl_pq_mdio_data *data;
|
|
struct device_node *np = pdev->dev.of_node;
|
|
struct resource res;
|
|
struct device_node *tbi;
|
|
@@ -390,6 +390,13 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev)
|
|
struct mii_bus *new_bus;
|
|
int err;
|
|
|
|
+ if (!id) {
|
|
+ dev_err(&pdev->dev, "Failed to match device\n");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ data = id->data;
|
|
+
|
|
dev_dbg(&pdev->dev, "found %s compatible node\n", id->compatible);
|
|
|
|
new_bus = mdiobus_alloc_size(sizeof(*priv));
|
|
diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c
|
|
index 5d7db6c01c46..f301c03c527b 100644
|
|
--- a/drivers/net/ethernet/ibm/emac/core.c
|
|
+++ b/drivers/net/ethernet/ibm/emac/core.c
|
|
@@ -342,6 +342,7 @@ static int emac_reset(struct emac_instance *dev)
|
|
{
|
|
struct emac_regs __iomem *p = dev->emacp;
|
|
int n = 20;
|
|
+ bool __maybe_unused try_internal_clock = false;
|
|
|
|
DBG(dev, "reset" NL);
|
|
|
|
@@ -354,6 +355,7 @@ static int emac_reset(struct emac_instance *dev)
|
|
}
|
|
|
|
#ifdef CONFIG_PPC_DCR_NATIVE
|
|
+do_retry:
|
|
/*
|
|
* PPC460EX/GT Embedded Processor Advanced User's Manual
|
|
* section 28.10.1 Mode Register 0 (EMACx_MR0) states:
|
|
@@ -361,10 +363,19 @@ static int emac_reset(struct emac_instance *dev)
|
|
* of the EMAC. If none is present, select the internal clock
|
|
* (SDR0_ETH_CFG[EMACx_PHY_CLK] = 1).
|
|
* After a soft reset, select the external clock.
|
|
+ *
|
|
+ * The AR8035-A PHY Meraki MR24 does not provide a TX Clk if the
|
|
+ * ethernet cable is not attached. This causes the reset to timeout
|
|
+ * and the PHY detection code in emac_init_phy() is unable to
|
|
+ * communicate and detect the AR8035-A PHY. As a result, the emac
|
|
+ * driver bails out early and the user has no ethernet.
|
|
+ * In order to stay compatible with existing configurations, the
|
|
+ * driver will temporarily switch to the internal clock, after
|
|
+ * the first reset fails.
|
|
*/
|
|
if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) {
|
|
- if (dev->phy_address == 0xffffffff &&
|
|
- dev->phy_map == 0xffffffff) {
|
|
+ if (try_internal_clock || (dev->phy_address == 0xffffffff &&
|
|
+ dev->phy_map == 0xffffffff)) {
|
|
/* No PHY: select internal loop clock before reset */
|
|
dcri_clrset(SDR0, SDR0_ETH_CFG,
|
|
0, SDR0_ETH_CFG_ECS << dev->cell_index);
|
|
@@ -382,8 +393,15 @@ static int emac_reset(struct emac_instance *dev)
|
|
|
|
#ifdef CONFIG_PPC_DCR_NATIVE
|
|
if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) {
|
|
- if (dev->phy_address == 0xffffffff &&
|
|
- dev->phy_map == 0xffffffff) {
|
|
+ if (!n && !try_internal_clock) {
|
|
+ /* first attempt has timed out. */
|
|
+ n = 20;
|
|
+ try_internal_clock = true;
|
|
+ goto do_retry;
|
|
+ }
|
|
+
|
|
+ if (try_internal_clock || (dev->phy_address == 0xffffffff &&
|
|
+ dev->phy_map == 0xffffffff)) {
|
|
/* No PHY: restore external clock source after reset */
|
|
dcri_clrset(SDR0, SDR0_ETH_CFG,
|
|
SDR0_ETH_CFG_ECS << dev->cell_index, 0);
|
|
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
|
|
index e356e9187e84..20d8806d2bff 100644
|
|
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
|
|
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
|
|
@@ -1182,6 +1182,7 @@ static void e1000e_tx_hwtstamp_work(struct work_struct *work)
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
|
if (er32(TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID) {
|
|
+ struct sk_buff *skb = adapter->tx_hwtstamp_skb;
|
|
struct skb_shared_hwtstamps shhwtstamps;
|
|
u64 txstmp;
|
|
|
|
@@ -1190,9 +1191,14 @@ static void e1000e_tx_hwtstamp_work(struct work_struct *work)
|
|
|
|
e1000e_systim_to_hwtstamp(adapter, &shhwtstamps, txstmp);
|
|
|
|
- skb_tstamp_tx(adapter->tx_hwtstamp_skb, &shhwtstamps);
|
|
- dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
|
|
+ /* Clear the global tx_hwtstamp_skb pointer and force writes
|
|
+ * prior to notifying the stack of a Tx timestamp.
|
|
+ */
|
|
adapter->tx_hwtstamp_skb = NULL;
|
|
+ wmb(); /* force write prior to skb_tstamp_tx */
|
|
+
|
|
+ skb_tstamp_tx(skb, &shhwtstamps);
|
|
+ dev_kfree_skb_any(skb);
|
|
} else if (time_after(jiffies, adapter->tx_hwtstamp_start
|
|
+ adapter->tx_timeout_factor * HZ)) {
|
|
dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
|
|
@@ -6589,12 +6595,17 @@ static int e1000e_pm_thaw(struct device *dev)
|
|
static int e1000e_pm_suspend(struct device *dev)
|
|
{
|
|
struct pci_dev *pdev = to_pci_dev(dev);
|
|
+ int rc;
|
|
|
|
e1000e_flush_lpic(pdev);
|
|
|
|
e1000e_pm_freeze(dev);
|
|
|
|
- return __e1000_shutdown(pdev, false);
|
|
+ rc = __e1000_shutdown(pdev, false);
|
|
+ if (rc)
|
|
+ e1000e_pm_thaw(dev);
|
|
+
|
|
+ return rc;
|
|
}
|
|
|
|
static int e1000e_pm_resume(struct device *dev)
|
|
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
|
|
index 4b62aa1f9ff8..6e5065f0907b 100644
|
|
--- a/drivers/net/ethernet/marvell/sky2.c
|
|
+++ b/drivers/net/ethernet/marvell/sky2.c
|
|
@@ -5079,7 +5079,7 @@ static int sky2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
INIT_WORK(&hw->restart_work, sky2_restart);
|
|
|
|
pci_set_drvdata(pdev, hw);
|
|
- pdev->d3_delay = 150;
|
|
+ pdev->d3_delay = 200;
|
|
|
|
return 0;
|
|
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
|
|
index 1d4e2e054647..897d061e4f03 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
|
|
@@ -35,6 +35,7 @@
|
|
#include <linux/etherdevice.h>
|
|
|
|
#include <linux/mlx4/cmd.h>
|
|
+#include <linux/mlx4/qp.h>
|
|
#include <linux/export.h>
|
|
|
|
#include "mlx4.h"
|
|
@@ -985,16 +986,21 @@ int mlx4_flow_attach(struct mlx4_dev *dev,
|
|
if (IS_ERR(mailbox))
|
|
return PTR_ERR(mailbox);
|
|
|
|
+ if (!mlx4_qp_lookup(dev, rule->qpn)) {
|
|
+ mlx4_err_rule(dev, "QP doesn't exist\n", rule);
|
|
+ ret = -EINVAL;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
trans_rule_ctrl_to_hw(rule, mailbox->buf);
|
|
|
|
size += sizeof(struct mlx4_net_trans_rule_hw_ctrl);
|
|
|
|
list_for_each_entry(cur, &rule->list, list) {
|
|
ret = parse_trans_rule(dev, cur, mailbox->buf + size);
|
|
- if (ret < 0) {
|
|
- mlx4_free_cmd_mailbox(dev, mailbox);
|
|
- return ret;
|
|
- }
|
|
+ if (ret < 0)
|
|
+ goto out;
|
|
+
|
|
size += ret;
|
|
}
|
|
|
|
@@ -1021,6 +1027,7 @@ int mlx4_flow_attach(struct mlx4_dev *dev,
|
|
}
|
|
}
|
|
|
|
+out:
|
|
mlx4_free_cmd_mailbox(dev, mailbox);
|
|
|
|
return ret;
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c
|
|
index d8359ffba026..62f1a3433a62 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx4/qp.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx4/qp.c
|
|
@@ -381,6 +381,19 @@ static void mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn)
|
|
__mlx4_qp_free_icm(dev, qpn);
|
|
}
|
|
|
|
+struct mlx4_qp *mlx4_qp_lookup(struct mlx4_dev *dev, u32 qpn)
|
|
+{
|
|
+ struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table;
|
|
+ struct mlx4_qp *qp;
|
|
+
|
|
+ spin_lock(&qp_table->lock);
|
|
+
|
|
+ qp = __mlx4_qp_lookup(dev, qpn);
|
|
+
|
|
+ spin_unlock(&qp_table->lock);
|
|
+ return qp;
|
|
+}
|
|
+
|
|
int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp, gfp_t gfp)
|
|
{
|
|
struct mlx4_priv *priv = mlx4_priv(dev);
|
|
@@ -468,6 +481,12 @@ int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn,
|
|
}
|
|
|
|
if (attr & MLX4_UPDATE_QP_QOS_VPORT) {
|
|
+ if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_QOS_VPP)) {
|
|
+ mlx4_warn(dev, "Granular QoS per VF is not enabled\n");
|
|
+ err = -EOPNOTSUPP;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
qp_mask |= 1ULL << MLX4_UPD_QP_MASK_QOS_VPP;
|
|
cmd->qp_context.qos_vport = params->qos_vport;
|
|
}
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
|
|
index d1fc7fa87b05..e3080fbd9d00 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
|
|
@@ -5040,6 +5040,13 @@ void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave)
|
|
mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex);
|
|
}
|
|
|
|
+static void update_qos_vpp(struct mlx4_update_qp_context *ctx,
|
|
+ struct mlx4_vf_immed_vlan_work *work)
|
|
+{
|
|
+ ctx->qp_mask |= cpu_to_be64(1ULL << MLX4_UPD_QP_MASK_QOS_VPP);
|
|
+ ctx->qp_context.qos_vport = work->qos_vport;
|
|
+}
|
|
+
|
|
void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work)
|
|
{
|
|
struct mlx4_vf_immed_vlan_work *work =
|
|
@@ -5144,11 +5151,10 @@ void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work)
|
|
qp->sched_queue & 0xC7;
|
|
upd_context->qp_context.pri_path.sched_queue |=
|
|
((work->qos & 0x7) << 3);
|
|
- upd_context->qp_mask |=
|
|
- cpu_to_be64(1ULL <<
|
|
- MLX4_UPD_QP_MASK_QOS_VPP);
|
|
- upd_context->qp_context.qos_vport =
|
|
- work->qos_vport;
|
|
+
|
|
+ if (dev->caps.flags2 &
|
|
+ MLX4_DEV_CAP_FLAG2_QOS_VPP)
|
|
+ update_qos_vpp(upd_context, work);
|
|
}
|
|
|
|
err = mlx4_cmd(dev, mailbox->dma,
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
|
|
index f5c1f4acc57b..7c42be586be8 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
|
|
@@ -513,7 +513,6 @@ static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i)
|
|
struct mlx5_priv *priv = &mdev->priv;
|
|
struct msix_entry *msix = priv->msix_arr;
|
|
int irq = msix[i + MLX5_EQ_VEC_COMP_BASE].vector;
|
|
- int err;
|
|
|
|
if (!zalloc_cpumask_var(&priv->irq_info[i].mask, GFP_KERNEL)) {
|
|
mlx5_core_warn(mdev, "zalloc_cpumask_var failed");
|
|
@@ -523,18 +522,11 @@ static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i)
|
|
cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node),
|
|
priv->irq_info[i].mask);
|
|
|
|
- err = irq_set_affinity_hint(irq, priv->irq_info[i].mask);
|
|
- if (err) {
|
|
- mlx5_core_warn(mdev, "irq_set_affinity_hint failed,irq 0x%.4x",
|
|
- irq);
|
|
- goto err_clear_mask;
|
|
- }
|
|
+ if (IS_ENABLED(CONFIG_SMP) &&
|
|
+ irq_set_affinity_hint(irq, priv->irq_info[i].mask))
|
|
+ mlx5_core_warn(mdev, "irq_set_affinity_hint failed, irq 0x%.4x", irq);
|
|
|
|
return 0;
|
|
-
|
|
-err_clear_mask:
|
|
- free_cpumask_var(priv->irq_info[i].mask);
|
|
- return err;
|
|
}
|
|
|
|
static void mlx5_irq_clear_affinity_hint(struct mlx5_core_dev *mdev, int i)
|
|
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
|
|
index b8d5270359cd..e30676515529 100644
|
|
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
|
|
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
|
|
@@ -247,7 +247,7 @@ nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu)
|
|
cmd.req.arg3 = 0;
|
|
|
|
if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE)
|
|
- netxen_issue_cmd(adapter, &cmd);
|
|
+ rcode = netxen_issue_cmd(adapter, &cmd);
|
|
|
|
if (rcode != NX_RCODE_SUCCESS)
|
|
return -EIO;
|
|
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
|
|
index 509b596cf1e8..bd1ec70fb736 100644
|
|
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
|
|
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
|
|
@@ -341,7 +341,7 @@ qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg)
|
|
}
|
|
return -EIO;
|
|
}
|
|
- usleep_range(1000, 1500);
|
|
+ udelay(1200);
|
|
}
|
|
|
|
if (id_reg)
|
|
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
|
|
index be258d90de9e..e3223f2fe2ff 100644
|
|
--- a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
|
|
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
|
|
@@ -765,7 +765,7 @@ int ql_core_dump(struct ql_adapter *qdev, struct ql_mpi_coredump *mpi_coredump)
|
|
sizeof(struct mpi_coredump_global_header);
|
|
mpi_coredump->mpi_global_header.imageSize =
|
|
sizeof(struct ql_mpi_coredump);
|
|
- memcpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump",
|
|
+ strncpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump",
|
|
sizeof(mpi_coredump->mpi_global_header.idString));
|
|
|
|
/* Get generic NIC reg dump */
|
|
@@ -1255,7 +1255,7 @@ static void ql_gen_reg_dump(struct ql_adapter *qdev,
|
|
sizeof(struct mpi_coredump_global_header);
|
|
mpi_coredump->mpi_global_header.imageSize =
|
|
sizeof(struct ql_reg_dump);
|
|
- memcpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump",
|
|
+ strncpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump",
|
|
sizeof(mpi_coredump->mpi_global_header.idString));
|
|
|
|
|
|
diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c
|
|
index 1ef03939d25f..c90ae4d4be7d 100644
|
|
--- a/drivers/net/ethernet/qualcomm/qca_spi.c
|
|
+++ b/drivers/net/ethernet/qualcomm/qca_spi.c
|
|
@@ -296,8 +296,9 @@ qcaspi_receive(struct qcaspi *qca)
|
|
|
|
/* Allocate rx SKB if we don't have one available. */
|
|
if (!qca->rx_skb) {
|
|
- qca->rx_skb = netdev_alloc_skb(net_dev,
|
|
- net_dev->mtu + VLAN_ETH_HLEN);
|
|
+ qca->rx_skb = netdev_alloc_skb_ip_align(net_dev,
|
|
+ net_dev->mtu +
|
|
+ VLAN_ETH_HLEN);
|
|
if (!qca->rx_skb) {
|
|
netdev_dbg(net_dev, "out of RX resources\n");
|
|
qca->stats.out_of_mem++;
|
|
@@ -377,7 +378,7 @@ qcaspi_receive(struct qcaspi *qca)
|
|
qca->rx_skb, qca->rx_skb->dev);
|
|
qca->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
|
|
netif_rx_ni(qca->rx_skb);
|
|
- qca->rx_skb = netdev_alloc_skb(net_dev,
|
|
+ qca->rx_skb = netdev_alloc_skb_ip_align(net_dev,
|
|
net_dev->mtu + VLAN_ETH_HLEN);
|
|
if (!qca->rx_skb) {
|
|
netdev_dbg(net_dev, "out of RX resources\n");
|
|
@@ -759,7 +760,8 @@ qcaspi_netdev_init(struct net_device *dev)
|
|
if (!qca->rx_buffer)
|
|
return -ENOBUFS;
|
|
|
|
- qca->rx_skb = netdev_alloc_skb(dev, qca->net_dev->mtu + VLAN_ETH_HLEN);
|
|
+ qca->rx_skb = netdev_alloc_skb_ip_align(dev, qca->net_dev->mtu +
|
|
+ VLAN_ETH_HLEN);
|
|
if (!qca->rx_skb) {
|
|
kfree(qca->rx_buffer);
|
|
netdev_info(qca->net_dev, "Failed to allocate RX sk_buff.\n");
|
|
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
|
|
index 3783c40f568b..a82c89af7124 100644
|
|
--- a/drivers/net/ethernet/realtek/r8169.c
|
|
+++ b/drivers/net/ethernet/realtek/r8169.c
|
|
@@ -8411,12 +8411,12 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
goto err_out_msi_4;
|
|
}
|
|
|
|
+ pci_set_drvdata(pdev, dev);
|
|
+
|
|
rc = register_netdev(dev);
|
|
if (rc < 0)
|
|
goto err_out_cnt_5;
|
|
|
|
- pci_set_drvdata(pdev, dev);
|
|
-
|
|
netif_info(tp, probe, dev, "%s at 0x%p, %pM, XID %08x IRQ %d\n",
|
|
rtl_chip_infos[chipset].name, ioaddr, dev->dev_addr,
|
|
(u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), pdev->irq);
|
|
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
|
|
index 424d1dee55c9..afaf79b8761f 100644
|
|
--- a/drivers/net/ethernet/renesas/sh_eth.c
|
|
+++ b/drivers/net/ethernet/renesas/sh_eth.c
|
|
@@ -3222,7 +3222,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
|
|
/* MDIO bus init */
|
|
ret = sh_mdio_init(mdp, pd);
|
|
if (ret) {
|
|
- dev_err(&ndev->dev, "failed to initialise MDIO\n");
|
|
+ dev_err(&pdev->dev, "failed to initialise MDIO\n");
|
|
goto out_release;
|
|
}
|
|
|
|
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
|
|
index 435466c17852..c69b0bdd891d 100644
|
|
--- a/drivers/net/ethernet/ti/cpsw.c
|
|
+++ b/drivers/net/ethernet/ti/cpsw.c
|
|
@@ -280,6 +280,10 @@ struct cpsw_ss_regs {
|
|
/* Bit definitions for the CPSW1_TS_SEQ_LTYPE register */
|
|
#define CPSW_V1_SEQ_ID_OFS_SHIFT 16
|
|
|
|
+#define CPSW_MAX_BLKS_TX 15
|
|
+#define CPSW_MAX_BLKS_TX_SHIFT 4
|
|
+#define CPSW_MAX_BLKS_RX 5
|
|
+
|
|
struct cpsw_host_regs {
|
|
u32 max_blks;
|
|
u32 blk_cnt;
|
|
@@ -1127,11 +1131,23 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
|
|
switch (priv->version) {
|
|
case CPSW_VERSION_1:
|
|
slave_write(slave, TX_PRIORITY_MAPPING, CPSW1_TX_PRI_MAP);
|
|
+ /* Increase RX FIFO size to 5 for supporting fullduplex
|
|
+ * flow control mode
|
|
+ */
|
|
+ slave_write(slave,
|
|
+ (CPSW_MAX_BLKS_TX << CPSW_MAX_BLKS_TX_SHIFT) |
|
|
+ CPSW_MAX_BLKS_RX, CPSW1_MAX_BLKS);
|
|
break;
|
|
case CPSW_VERSION_2:
|
|
case CPSW_VERSION_3:
|
|
case CPSW_VERSION_4:
|
|
slave_write(slave, TX_PRIORITY_MAPPING, CPSW2_TX_PRI_MAP);
|
|
+ /* Increase RX FIFO size to 5 for supporting fullduplex
|
|
+ * flow control mode
|
|
+ */
|
|
+ slave_write(slave,
|
|
+ (CPSW_MAX_BLKS_TX << CPSW_MAX_BLKS_TX_SHIFT) |
|
|
+ CPSW_MAX_BLKS_RX, CPSW2_MAX_BLKS);
|
|
break;
|
|
}
|
|
|
|
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
|
|
index 49fe59b180a8..a75ce9051a7f 100644
|
|
--- a/drivers/net/hamradio/hdlcdrv.c
|
|
+++ b/drivers/net/hamradio/hdlcdrv.c
|
|
@@ -574,6 +574,8 @@ static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
|
case HDLCDRVCTL_CALIBRATE:
|
|
if(!capable(CAP_SYS_RAWIO))
|
|
return -EPERM;
|
|
+ if (s->par.bitrate <= 0)
|
|
+ return -EINVAL;
|
|
if (bi.data.calibrate > INT_MAX / s->par.bitrate)
|
|
return -EINVAL;
|
|
s->hdlctx.calibrate = bi.data.calibrate * s->par.bitrate / 16;
|
|
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
|
|
index 7d0690433ee0..7d2cf015c5e7 100644
|
|
--- a/drivers/net/phy/phy.c
|
|
+++ b/drivers/net/phy/phy.c
|
|
@@ -148,6 +148,12 @@ static inline int phy_aneg_done(struct phy_device *phydev)
|
|
if (phydev->drv->aneg_done)
|
|
return phydev->drv->aneg_done(phydev);
|
|
|
|
+ /* Avoid genphy_aneg_done() if the Clause 45 PHY does not
|
|
+ * implement Clause 22 registers
|
|
+ */
|
|
+ if (phydev->is_c45 && !(phydev->c45_ids.devices_in_package & BIT(0)))
|
|
+ return -EINVAL;
|
|
+
|
|
return genphy_aneg_done(phydev);
|
|
}
|
|
|
|
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c
|
|
index f7e8c79349ad..12a627fcc02c 100644
|
|
--- a/drivers/net/ppp/pptp.c
|
|
+++ b/drivers/net/ppp/pptp.c
|
|
@@ -501,7 +501,6 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr,
|
|
po->chan.mtu = dst_mtu(&rt->dst);
|
|
if (!po->chan.mtu)
|
|
po->chan.mtu = PPP_MRU;
|
|
- ip_rt_put(rt);
|
|
po->chan.mtu -= PPTP_HEADER_OVERHEAD;
|
|
|
|
po->chan.hdrlen = 2 + sizeof(struct pptp_gre_header);
|
|
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
|
|
index 72cb30828a12..c8e98c8e29fa 100644
|
|
--- a/drivers/net/usb/cdc_ncm.c
|
|
+++ b/drivers/net/usb/cdc_ncm.c
|
|
@@ -1069,6 +1069,7 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign)
|
|
u16 n = 0, index, ndplen;
|
|
u8 ready2send = 0;
|
|
u32 delayed_ndp_size;
|
|
+ size_t padding_count;
|
|
|
|
/* When our NDP gets written in cdc_ncm_ndp(), then skb_out->len gets updated
|
|
* accordingly. Otherwise, we should check here.
|
|
@@ -1225,11 +1226,13 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign)
|
|
* a ZLP after full sized NTBs.
|
|
*/
|
|
if (!(dev->driver_info->flags & FLAG_SEND_ZLP) &&
|
|
- skb_out->len > ctx->min_tx_pkt)
|
|
- memset(skb_put(skb_out, ctx->tx_max - skb_out->len), 0,
|
|
- ctx->tx_max - skb_out->len);
|
|
- else if (skb_out->len < ctx->tx_max && (skb_out->len % dev->maxpacket) == 0)
|
|
+ skb_out->len > ctx->min_tx_pkt) {
|
|
+ padding_count = ctx->tx_max - skb_out->len;
|
|
+ memset(skb_put(skb_out, padding_count), 0, padding_count);
|
|
+ } else if (skb_out->len < ctx->tx_max &&
|
|
+ (skb_out->len % dev->maxpacket) == 0) {
|
|
*skb_put(skb_out, 1) = 0; /* force short packet */
|
|
+ }
|
|
|
|
/* set final frame length */
|
|
nth16 = (struct usb_cdc_ncm_nth16 *)skb_out->data;
|
|
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
|
|
index 8dfc75250583..d01285250204 100644
|
|
--- a/drivers/net/virtio_net.c
|
|
+++ b/drivers/net/virtio_net.c
|
|
@@ -556,7 +556,12 @@ static int add_recvbuf_small(struct virtnet_info *vi, struct receive_queue *rq,
|
|
hdr = skb_vnet_hdr(skb);
|
|
sg_init_table(rq->sg, 2);
|
|
sg_set_buf(rq->sg, hdr, vi->hdr_len);
|
|
- skb_to_sgvec(skb, rq->sg + 1, 0, skb->len);
|
|
+
|
|
+ err = skb_to_sgvec(skb, rq->sg + 1, 0, skb->len);
|
|
+ if (unlikely(err < 0)) {
|
|
+ dev_kfree_skb(skb);
|
|
+ return err;
|
|
+ }
|
|
|
|
err = virtqueue_add_inbuf(rq->vq, rq->sg, 2, skb, gfp);
|
|
if (err < 0)
|
|
@@ -858,7 +863,7 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb)
|
|
struct virtio_net_hdr_mrg_rxbuf *hdr;
|
|
const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
|
|
struct virtnet_info *vi = sq->vq->vdev->priv;
|
|
- unsigned num_sg;
|
|
+ int num_sg;
|
|
unsigned hdr_len = vi->hdr_len;
|
|
bool can_push;
|
|
|
|
@@ -911,11 +916,16 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb)
|
|
if (can_push) {
|
|
__skb_push(skb, hdr_len);
|
|
num_sg = skb_to_sgvec(skb, sq->sg, 0, skb->len);
|
|
+ if (unlikely(num_sg < 0))
|
|
+ return num_sg;
|
|
/* Pull header back to avoid skew in tx bytes calculations. */
|
|
__skb_pull(skb, hdr_len);
|
|
} else {
|
|
sg_set_buf(sq->sg, hdr, hdr_len);
|
|
- num_sg = skb_to_sgvec(skb, sq->sg + 1, 0, skb->len) + 1;
|
|
+ num_sg = skb_to_sgvec(skb, sq->sg + 1, 0, skb->len);
|
|
+ if (unlikely(num_sg < 0))
|
|
+ return num_sg;
|
|
+ num_sg++;
|
|
}
|
|
return virtqueue_add_outbuf(sq->vq, sq->sg, num_sg, skb, GFP_ATOMIC);
|
|
}
|
|
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
|
|
index 82bf85ae5d08..419c045d0752 100644
|
|
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
|
|
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
|
|
@@ -2789,6 +2789,11 @@ vmxnet3_force_close(struct vmxnet3_adapter *adapter)
|
|
/* we need to enable NAPI, otherwise dev_close will deadlock */
|
|
for (i = 0; i < adapter->num_rx_queues; i++)
|
|
napi_enable(&adapter->rx_queue[i].napi);
|
|
+ /*
|
|
+ * Need to clear the quiesce bit to ensure that vmxnet3_close
|
|
+ * can quiesce the device properly
|
|
+ */
|
|
+ clear_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state);
|
|
dev_close(adapter->netdev);
|
|
}
|
|
|
|
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
|
|
index ac945f8781ac..d3d59122a357 100644
|
|
--- a/drivers/net/vrf.c
|
|
+++ b/drivers/net/vrf.c
|
|
@@ -550,13 +550,15 @@ static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *s
|
|
neigh = __ipv4_neigh_lookup_noref(dev, nexthop);
|
|
if (unlikely(!neigh))
|
|
neigh = __neigh_create(&arp_tbl, &nexthop, dev, false);
|
|
- if (!IS_ERR(neigh))
|
|
+ if (!IS_ERR(neigh)) {
|
|
ret = dst_neigh_output(dst, neigh, skb);
|
|
+ rcu_read_unlock_bh();
|
|
+ return ret;
|
|
+ }
|
|
|
|
rcu_read_unlock_bh();
|
|
err:
|
|
- if (unlikely(ret < 0))
|
|
- vrf_tx_error(skb->dev, skb);
|
|
+ vrf_tx_error(skb->dev, skb);
|
|
return ret;
|
|
}
|
|
|
|
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
|
|
index e4ff1e45c02e..c41378214ede 100644
|
|
--- a/drivers/net/vxlan.c
|
|
+++ b/drivers/net/vxlan.c
|
|
@@ -962,7 +962,7 @@ static bool vxlan_snoop(struct net_device *dev,
|
|
return false;
|
|
|
|
/* Don't migrate static entries, drop packets */
|
|
- if (f->state & NUD_NOARP)
|
|
+ if (f->state & (NUD_PERMANENT | NUD_NOARP))
|
|
return true;
|
|
|
|
if (net_ratelimit())
|
|
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
|
|
index 654a1e33f827..7c5f189cace7 100644
|
|
--- a/drivers/net/wireless/ath/ath5k/debug.c
|
|
+++ b/drivers/net/wireless/ath/ath5k/debug.c
|
|
@@ -939,7 +939,10 @@ static int open_file_eeprom(struct inode *inode, struct file *file)
|
|
}
|
|
|
|
for (i = 0; i < eesize; ++i) {
|
|
- AR5K_EEPROM_READ(i, val);
|
|
+ if (!ath5k_hw_nvram_read(ah, i, &val)) {
|
|
+ ret = -EIO;
|
|
+ goto freebuf;
|
|
+ }
|
|
buf[i] = val;
|
|
}
|
|
|
|
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
|
|
index 0881ba8535f4..c78abfc7bd96 100644
|
|
--- a/drivers/net/wireless/ray_cs.c
|
|
+++ b/drivers/net/wireless/ray_cs.c
|
|
@@ -247,7 +247,10 @@ static const UCHAR b4_default_startup_parms[] = {
|
|
0x04, 0x08, /* Noise gain, limit offset */
|
|
0x28, 0x28, /* det rssi, med busy offsets */
|
|
7, /* det sync thresh */
|
|
- 0, 2, 2 /* test mode, min, max */
|
|
+ 0, 2, 2, /* test mode, min, max */
|
|
+ 0, /* rx/tx delay */
|
|
+ 0, 0, 0, 0, 0, 0, /* current BSS id */
|
|
+ 0 /* hop set */
|
|
};
|
|
|
|
/*===========================================================================*/
|
|
@@ -598,7 +601,7 @@ static void init_startup_params(ray_dev_t *local)
|
|
* a_beacon_period = hops a_beacon_period = KuS
|
|
*//* 64ms = 010000 */
|
|
if (local->fw_ver == 0x55) {
|
|
- memcpy((UCHAR *) &local->sparm.b4, b4_default_startup_parms,
|
|
+ memcpy(&local->sparm.b4, b4_default_startup_parms,
|
|
sizeof(struct b4_startup_params));
|
|
/* Translate sane kus input values to old build 4/5 format */
|
|
/* i = hop time in uS truncated to 3 bytes */
|
|
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
|
|
index 9bee3f11898a..869411f55d88 100644
|
|
--- a/drivers/net/wireless/ti/wl1251/main.c
|
|
+++ b/drivers/net/wireless/ti/wl1251/main.c
|
|
@@ -1196,8 +1196,7 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
|
|
WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);
|
|
|
|
enable = bss_conf->arp_addr_cnt == 1 && bss_conf->assoc;
|
|
- wl1251_acx_arp_ip_filter(wl, enable, addr);
|
|
-
|
|
+ ret = wl1251_acx_arp_ip_filter(wl, enable, addr);
|
|
if (ret < 0)
|
|
goto out_sleep;
|
|
}
|
|
diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c
|
|
index 84419af16f77..fd12ccc11e26 100644
|
|
--- a/drivers/powercap/powercap_sys.c
|
|
+++ b/drivers/powercap/powercap_sys.c
|
|
@@ -538,6 +538,7 @@ struct powercap_zone *powercap_register_zone(
|
|
|
|
power_zone->id = result;
|
|
idr_init(&power_zone->idr);
|
|
+ result = -ENOMEM;
|
|
power_zone->name = kstrdup(name, GFP_KERNEL);
|
|
if (!power_zone->name)
|
|
goto err_name_alloc;
|
|
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
|
|
index dcfd3655ef0a..c2cf9485fe32 100644
|
|
--- a/drivers/rtc/interface.c
|
|
+++ b/drivers/rtc/interface.c
|
|
@@ -217,6 +217,13 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
|
|
missing = year;
|
|
}
|
|
|
|
+ /* Can't proceed if alarm is still invalid after replacing
|
|
+ * missing fields.
|
|
+ */
|
|
+ err = rtc_valid_tm(&alarm->time);
|
|
+ if (err)
|
|
+ goto done;
|
|
+
|
|
/* with luck, no rollover is needed */
|
|
t_now = rtc_tm_to_time64(&now);
|
|
t_alm = rtc_tm_to_time64(&alarm->time);
|
|
@@ -268,9 +275,9 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
|
|
dev_warn(&rtc->dev, "alarm rollover not handled\n");
|
|
}
|
|
|
|
-done:
|
|
err = rtc_valid_tm(&alarm->time);
|
|
|
|
+done:
|
|
if (err) {
|
|
dev_warn(&rtc->dev, "invalid alarm value: %d-%d-%d %d:%d:%d\n",
|
|
alarm->time.tm_year + 1900, alarm->time.tm_mon + 1,
|
|
diff --git a/drivers/rtc/rtc-opal.c b/drivers/rtc/rtc-opal.c
|
|
index 229dd2fe8f45..c6b0c7ed7a30 100644
|
|
--- a/drivers/rtc/rtc-opal.c
|
|
+++ b/drivers/rtc/rtc-opal.c
|
|
@@ -150,6 +150,16 @@ static int opal_get_tpo_time(struct device *dev, struct rtc_wkalrm *alarm)
|
|
|
|
y_m_d = be32_to_cpu(__y_m_d);
|
|
h_m_s_ms = ((u64)be32_to_cpu(__h_m) << 32);
|
|
+
|
|
+ /* check if no alarm is set */
|
|
+ if (y_m_d == 0 && h_m_s_ms == 0) {
|
|
+ pr_debug("No alarm is set\n");
|
|
+ rc = -ENOENT;
|
|
+ goto exit;
|
|
+ } else {
|
|
+ pr_debug("Alarm set to %x %llx\n", y_m_d, h_m_s_ms);
|
|
+ }
|
|
+
|
|
opal_to_tm(y_m_d, h_m_s_ms, &alarm->time);
|
|
|
|
exit:
|
|
diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c
|
|
index 950c5d0b6dca..afab89f5be48 100644
|
|
--- a/drivers/rtc/rtc-snvs.c
|
|
+++ b/drivers/rtc/rtc-snvs.c
|
|
@@ -257,7 +257,7 @@ static int snvs_rtc_probe(struct platform_device *pdev)
|
|
of_property_read_u32(pdev->dev.of_node, "offset", &data->offset);
|
|
}
|
|
|
|
- if (!data->regmap) {
|
|
+ if (IS_ERR(data->regmap)) {
|
|
dev_err(&pdev->dev, "Can't find snvs syscon\n");
|
|
return -ENODEV;
|
|
}
|
|
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
|
|
index e7a6f1222642..b76a85d14ef0 100644
|
|
--- a/drivers/s390/block/dasd.c
|
|
+++ b/drivers/s390/block/dasd.c
|
|
@@ -1881,8 +1881,12 @@ static int __dasd_device_is_unusable(struct dasd_device *device,
|
|
{
|
|
int mask = ~(DASD_STOPPED_DC_WAIT | DASD_UNRESUMED_PM);
|
|
|
|
- if (test_bit(DASD_FLAG_OFFLINE, &device->flags)) {
|
|
- /* dasd is being set offline. */
|
|
+ if (test_bit(DASD_FLAG_OFFLINE, &device->flags) &&
|
|
+ !test_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags)) {
|
|
+ /*
|
|
+ * dasd is being set offline
|
|
+ * but it is no safe offline where we have to allow I/O
|
|
+ */
|
|
return 1;
|
|
}
|
|
if (device->stopped) {
|
|
diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h
|
|
index 499e369eabf0..8bc1625337f6 100644
|
|
--- a/drivers/scsi/bnx2fc/bnx2fc.h
|
|
+++ b/drivers/scsi/bnx2fc/bnx2fc.h
|
|
@@ -191,6 +191,7 @@ struct bnx2fc_hba {
|
|
struct bnx2fc_cmd_mgr *cmd_mgr;
|
|
spinlock_t hba_lock;
|
|
struct mutex hba_mutex;
|
|
+ struct mutex hba_stats_mutex;
|
|
unsigned long adapter_state;
|
|
#define ADAPTER_STATE_UP 0
|
|
#define ADAPTER_STATE_GOING_DOWN 1
|
|
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
|
|
index 67405c628864..d0b227ffbd5f 100644
|
|
--- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
|
|
+++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
|
|
@@ -641,15 +641,17 @@ static struct fc_host_statistics *bnx2fc_get_host_stats(struct Scsi_Host *shost)
|
|
if (!fw_stats)
|
|
return NULL;
|
|
|
|
+ mutex_lock(&hba->hba_stats_mutex);
|
|
+
|
|
bnx2fc_stats = fc_get_host_stats(shost);
|
|
|
|
init_completion(&hba->stat_req_done);
|
|
if (bnx2fc_send_stat_req(hba))
|
|
- return bnx2fc_stats;
|
|
+ goto unlock_stats_mutex;
|
|
rc = wait_for_completion_timeout(&hba->stat_req_done, (2 * HZ));
|
|
if (!rc) {
|
|
BNX2FC_HBA_DBG(lport, "FW stat req timed out\n");
|
|
- return bnx2fc_stats;
|
|
+ goto unlock_stats_mutex;
|
|
}
|
|
BNX2FC_STATS(hba, rx_stat2, fc_crc_cnt);
|
|
bnx2fc_stats->invalid_crc_count += hba->bfw_stats.fc_crc_cnt;
|
|
@@ -671,6 +673,9 @@ static struct fc_host_statistics *bnx2fc_get_host_stats(struct Scsi_Host *shost)
|
|
|
|
memcpy(&hba->prev_stats, hba->stats_buffer,
|
|
sizeof(struct fcoe_statistics_params));
|
|
+
|
|
+unlock_stats_mutex:
|
|
+ mutex_unlock(&hba->hba_stats_mutex);
|
|
return bnx2fc_stats;
|
|
}
|
|
|
|
@@ -1302,6 +1307,7 @@ static struct bnx2fc_hba *bnx2fc_hba_create(struct cnic_dev *cnic)
|
|
}
|
|
spin_lock_init(&hba->hba_lock);
|
|
mutex_init(&hba->hba_mutex);
|
|
+ mutex_init(&hba->hba_stats_mutex);
|
|
|
|
hba->cnic = cnic;
|
|
|
|
diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c
|
|
index 622bdabc8894..dab195f04da7 100644
|
|
--- a/drivers/scsi/csiostor/csio_hw.c
|
|
+++ b/drivers/scsi/csiostor/csio_hw.c
|
|
@@ -1769,7 +1769,6 @@ csio_hw_use_fwconfig(struct csio_hw *hw, int reset, u32 *fw_cfg_param)
|
|
goto bye;
|
|
}
|
|
|
|
- mempool_free(mbp, hw->mb_mempool);
|
|
if (finicsum != cfcsum) {
|
|
csio_warn(hw,
|
|
"Config File checksum mismatch: csum=%#x, computed=%#x\n",
|
|
@@ -1780,6 +1779,10 @@ csio_hw_use_fwconfig(struct csio_hw *hw, int reset, u32 *fw_cfg_param)
|
|
rv = csio_hw_validate_caps(hw, mbp);
|
|
if (rv != 0)
|
|
goto bye;
|
|
+
|
|
+ mempool_free(mbp, hw->mb_mempool);
|
|
+ mbp = NULL;
|
|
+
|
|
/*
|
|
* Note that we're operating with parameters
|
|
* not supplied by the driver, rather than from hard-wired
|
|
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
|
|
index efce04df2109..9f0b00c38658 100644
|
|
--- a/drivers/scsi/libiscsi.c
|
|
+++ b/drivers/scsi/libiscsi.c
|
|
@@ -1695,6 +1695,15 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc)
|
|
*/
|
|
switch (session->state) {
|
|
case ISCSI_STATE_FAILED:
|
|
+ /*
|
|
+ * cmds should fail during shutdown, if the session
|
|
+ * state is bad, allowing completion to happen
|
|
+ */
|
|
+ if (unlikely(system_state != SYSTEM_RUNNING)) {
|
|
+ reason = FAILURE_SESSION_FAILED;
|
|
+ sc->result = DID_NO_CONNECT << 16;
|
|
+ break;
|
|
+ }
|
|
case ISCSI_STATE_IN_RECOVERY:
|
|
reason = FAILURE_SESSION_IN_RECOVERY;
|
|
sc->result = DID_IMM_RETRY << 16;
|
|
@@ -1979,6 +1988,19 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc)
|
|
}
|
|
|
|
if (session->state != ISCSI_STATE_LOGGED_IN) {
|
|
+ /*
|
|
+ * During shutdown, if session is prematurely disconnected,
|
|
+ * recovery won't happen and there will be hung cmds. Not
|
|
+ * handling cmds would trigger EH, also bad in this case.
|
|
+ * Instead, handle cmd, allow completion to happen and let
|
|
+ * upper layer to deal with the result.
|
|
+ */
|
|
+ if (unlikely(system_state != SYSTEM_RUNNING)) {
|
|
+ sc->result = DID_NO_CONNECT << 16;
|
|
+ ISCSI_DBG_EH(session, "sc on shutdown, handled\n");
|
|
+ rc = BLK_EH_HANDLED;
|
|
+ goto done;
|
|
+ }
|
|
/*
|
|
* We are probably in the middle of iscsi recovery so let
|
|
* that complete and handle the error.
|
|
@@ -2083,7 +2105,7 @@ done:
|
|
task->last_timeout = jiffies;
|
|
spin_unlock(&session->frwd_lock);
|
|
ISCSI_DBG_EH(session, "return %s\n", rc == BLK_EH_RESET_TIMER ?
|
|
- "timer reset" : "nh");
|
|
+ "timer reset" : "shutdown or nh");
|
|
return rc;
|
|
}
|
|
|
|
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
|
|
index 022bb6e10d98..12886f96b286 100644
|
|
--- a/drivers/scsi/libsas/sas_expander.c
|
|
+++ b/drivers/scsi/libsas/sas_expander.c
|
|
@@ -282,6 +282,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)
|
|
phy->phy->minimum_linkrate = dr->pmin_linkrate;
|
|
phy->phy->maximum_linkrate = dr->pmax_linkrate;
|
|
phy->phy->negotiated_linkrate = phy->linkrate;
|
|
+ phy->phy->enabled = (phy->linkrate != SAS_PHY_DISABLED);
|
|
|
|
skip:
|
|
if (new_phy)
|
|
@@ -675,7 +676,7 @@ int sas_smp_get_phy_events(struct sas_phy *phy)
|
|
res = smp_execute_task(dev, req, RPEL_REQ_SIZE,
|
|
resp, RPEL_RESP_SIZE);
|
|
|
|
- if (!res)
|
|
+ if (res)
|
|
goto out;
|
|
|
|
phy->invalid_dword_count = scsi_to_u32(&resp[12]);
|
|
@@ -684,6 +685,7 @@ int sas_smp_get_phy_events(struct sas_phy *phy)
|
|
phy->phy_reset_problem_count = scsi_to_u32(&resp[24]);
|
|
|
|
out:
|
|
+ kfree(req);
|
|
kfree(resp);
|
|
return res;
|
|
|
|
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
|
|
index e111c3d8c5d6..b868ef3b2ca3 100644
|
|
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
|
|
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
|
|
@@ -3886,19 +3886,6 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
|
|
return 0;
|
|
}
|
|
|
|
- /*
|
|
- * Bug work around for firmware SATL handling. The loop
|
|
- * is based on atomic operations and ensures consistency
|
|
- * since we're lockless at this point
|
|
- */
|
|
- do {
|
|
- if (test_bit(0, &sas_device_priv_data->ata_command_pending)) {
|
|
- scmd->result = SAM_STAT_BUSY;
|
|
- scmd->scsi_done(scmd);
|
|
- return 0;
|
|
- }
|
|
- } while (_scsih_set_satl_pending(scmd, true));
|
|
-
|
|
sas_target_priv_data = sas_device_priv_data->sas_target;
|
|
|
|
/* invalid device handle */
|
|
@@ -3924,6 +3911,19 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
|
|
sas_device_priv_data->block)
|
|
return SCSI_MLQUEUE_DEVICE_BUSY;
|
|
|
|
+ /*
|
|
+ * Bug work around for firmware SATL handling. The loop
|
|
+ * is based on atomic operations and ensures consistency
|
|
+ * since we're lockless at this point
|
|
+ */
|
|
+ do {
|
|
+ if (test_bit(0, &sas_device_priv_data->ata_command_pending)) {
|
|
+ scmd->result = SAM_STAT_BUSY;
|
|
+ scmd->scsi_done(scmd);
|
|
+ return 0;
|
|
+ }
|
|
+ } while (_scsih_set_satl_pending(scmd, true));
|
|
+
|
|
if (scmd->sc_data_direction == DMA_FROM_DEVICE)
|
|
mpi_control = MPI2_SCSIIO_CONTROL_READ;
|
|
else if (scmd->sc_data_direction == DMA_TO_DEVICE)
|
|
@@ -3945,6 +3945,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
|
|
if (!smid) {
|
|
pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
|
|
ioc->name, __func__);
|
|
+ _scsih_set_satl_pending(scmd, false);
|
|
goto out;
|
|
}
|
|
mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
|
|
@@ -3975,6 +3976,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
|
|
if (mpi_request->DataLength) {
|
|
if (ioc->build_sg_scmd(ioc, scmd, smid)) {
|
|
mpt3sas_base_free_smid(ioc, smid);
|
|
+ _scsih_set_satl_pending(scmd, false);
|
|
goto out;
|
|
}
|
|
} else
|
|
diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c
|
|
index 013a6240f193..c1ad0aea23b9 100644
|
|
--- a/drivers/staging/wlan-ng/prism2mgmt.c
|
|
+++ b/drivers/staging/wlan-ng/prism2mgmt.c
|
|
@@ -169,7 +169,7 @@ int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp)
|
|
hw->ident_sta_fw.variant) >
|
|
HFA384x_FIRMWARE_VERSION(1, 5, 0)) {
|
|
if (msg->scantype.data != P80211ENUM_scantype_active)
|
|
- word = cpu_to_le16(msg->maxchanneltime.data);
|
|
+ word = msg->maxchanneltime.data;
|
|
else
|
|
word = 0;
|
|
|
|
diff --git a/drivers/thermal/power_allocator.c b/drivers/thermal/power_allocator.c
|
|
index 1246aa6fcab0..737635f0bec0 100644
|
|
--- a/drivers/thermal/power_allocator.c
|
|
+++ b/drivers/thermal/power_allocator.c
|
|
@@ -523,6 +523,7 @@ static void allow_maximum_power(struct thermal_zone_device *tz)
|
|
struct thermal_instance *instance;
|
|
struct power_allocator_params *params = tz->governor_data;
|
|
|
|
+ mutex_lock(&tz->lock);
|
|
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
|
|
if ((instance->trip != params->trip_max_desired_temperature) ||
|
|
(!cdev_is_power_actor(instance->cdev)))
|
|
@@ -532,6 +533,7 @@ static void allow_maximum_power(struct thermal_zone_device *tz)
|
|
instance->cdev->updated = false;
|
|
thermal_cdev_update(instance->cdev);
|
|
}
|
|
+ mutex_unlock(&tz->lock);
|
|
}
|
|
|
|
/**
|
|
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
|
|
index 9aff37186246..78bd121ecede 100644
|
|
--- a/drivers/tty/n_gsm.c
|
|
+++ b/drivers/tty/n_gsm.c
|
|
@@ -1467,6 +1467,10 @@ static void gsm_dlci_open(struct gsm_dlci *dlci)
|
|
* in which case an opening port goes back to closed and a closing port
|
|
* is simply put into closed state (any further frames from the other
|
|
* end will get a DM response)
|
|
+ *
|
|
+ * Some control dlci can stay in ADM mode with other dlci working just
|
|
+ * fine. In that case we can just keep the control dlci open after the
|
|
+ * DLCI_OPENING retries time out.
|
|
*/
|
|
|
|
static void gsm_dlci_t1(unsigned long data)
|
|
@@ -1480,8 +1484,15 @@ static void gsm_dlci_t1(unsigned long data)
|
|
if (dlci->retries) {
|
|
gsm_command(dlci->gsm, dlci->addr, SABM|PF);
|
|
mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100);
|
|
- } else
|
|
+ } else if (!dlci->addr && gsm->control == (DM | PF)) {
|
|
+ if (debug & 8)
|
|
+ pr_info("DLCI %d opening in ADM mode.\n",
|
|
+ dlci->addr);
|
|
+ gsm_dlci_open(dlci);
|
|
+ } else {
|
|
gsm_dlci_close(dlci);
|
|
+ }
|
|
+
|
|
break;
|
|
case DLCI_CLOSING:
|
|
dlci->retries--;
|
|
@@ -1499,8 +1510,8 @@ static void gsm_dlci_t1(unsigned long data)
|
|
* @dlci: DLCI to open
|
|
*
|
|
* Commence opening a DLCI from the Linux side. We issue SABM messages
|
|
- * to the modem which should then reply with a UA, at which point we
|
|
- * will move into open state. Opening is done asynchronously with retry
|
|
+ * to the modem which should then reply with a UA or ADM, at which point
|
|
+ * we will move into open state. Opening is done asynchronously with retry
|
|
* running off timers and the responses.
|
|
*/
|
|
|
|
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
|
|
index e8dd296fb25b..c4383573cf66 100644
|
|
--- a/drivers/tty/serial/8250/8250_omap.c
|
|
+++ b/drivers/tty/serial/8250/8250_omap.c
|
|
@@ -608,6 +608,10 @@ static int omap_8250_startup(struct uart_port *port)
|
|
up->lsr_saved_flags = 0;
|
|
up->msr_saved_flags = 0;
|
|
|
|
+ /* Disable DMA for console UART */
|
|
+ if (uart_console(port))
|
|
+ up->dma = NULL;
|
|
+
|
|
if (up->dma) {
|
|
ret = serial8250_request_dma(up);
|
|
if (ret) {
|
|
diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c
|
|
index fcf803ffad19..cdd2f942317c 100644
|
|
--- a/drivers/tty/serial/sccnxp.c
|
|
+++ b/drivers/tty/serial/sccnxp.c
|
|
@@ -884,14 +884,19 @@ static int sccnxp_probe(struct platform_device *pdev)
|
|
|
|
clk = devm_clk_get(&pdev->dev, NULL);
|
|
if (IS_ERR(clk)) {
|
|
- if (PTR_ERR(clk) == -EPROBE_DEFER) {
|
|
- ret = -EPROBE_DEFER;
|
|
+ ret = PTR_ERR(clk);
|
|
+ if (ret == -EPROBE_DEFER)
|
|
goto err_out;
|
|
- }
|
|
+ uartclk = 0;
|
|
+ } else {
|
|
+ clk_prepare_enable(clk);
|
|
+ uartclk = clk_get_rate(clk);
|
|
+ }
|
|
+
|
|
+ if (!uartclk) {
|
|
dev_notice(&pdev->dev, "Using default clock frequency\n");
|
|
uartclk = s->chip->freq_std;
|
|
- } else
|
|
- uartclk = clk_get_rate(clk);
|
|
+ }
|
|
|
|
/* Check input frequency */
|
|
if ((uartclk < s->chip->freq_min) || (uartclk > s->chip->freq_max)) {
|
|
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
|
|
index fc7711c75b01..8dd822feb972 100644
|
|
--- a/drivers/tty/serial/sh-sci.c
|
|
+++ b/drivers/tty/serial/sh-sci.c
|
|
@@ -1457,7 +1457,16 @@ static void sci_free_dma(struct uart_port *port)
|
|
if (s->chan_rx)
|
|
sci_rx_dma_release(s, false);
|
|
}
|
|
-#else
|
|
+
|
|
+static void sci_flush_buffer(struct uart_port *port)
|
|
+{
|
|
+ /*
|
|
+ * In uart_flush_buffer(), the xmit circular buffer has just been
|
|
+ * cleared, so we have to reset tx_dma_len accordingly.
|
|
+ */
|
|
+ to_sci_port(port)->tx_dma_len = 0;
|
|
+}
|
|
+#else /* !CONFIG_SERIAL_SH_SCI_DMA */
|
|
static inline void sci_request_dma(struct uart_port *port)
|
|
{
|
|
}
|
|
@@ -1465,7 +1474,9 @@ static inline void sci_request_dma(struct uart_port *port)
|
|
static inline void sci_free_dma(struct uart_port *port)
|
|
{
|
|
}
|
|
-#endif
|
|
+
|
|
+#define sci_flush_buffer NULL
|
|
+#endif /* !CONFIG_SERIAL_SH_SCI_DMA */
|
|
|
|
static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
|
|
{
|
|
@@ -2205,6 +2216,7 @@ static struct uart_ops sci_uart_ops = {
|
|
.break_ctl = sci_break_ctl,
|
|
.startup = sci_startup,
|
|
.shutdown = sci_shutdown,
|
|
+ .flush_buffer = sci_flush_buffer,
|
|
.set_termios = sci_set_termios,
|
|
.pm = sci_pm,
|
|
.type = sci_type,
|
|
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
|
|
index 939c6ad71068..57ee43512992 100644
|
|
--- a/drivers/usb/chipidea/core.c
|
|
+++ b/drivers/usb/chipidea/core.c
|
|
@@ -851,7 +851,7 @@ static inline void ci_role_destroy(struct ci_hdrc *ci)
|
|
{
|
|
ci_hdrc_gadget_destroy(ci);
|
|
ci_hdrc_host_destroy(ci);
|
|
- if (ci->is_otg)
|
|
+ if (ci->is_otg && ci->roles[CI_ROLE_GADGET])
|
|
ci_hdrc_otg_destroy(ci);
|
|
}
|
|
|
|
@@ -951,27 +951,35 @@ static int ci_hdrc_probe(struct platform_device *pdev)
|
|
/* initialize role(s) before the interrupt is requested */
|
|
if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
|
|
ret = ci_hdrc_host_init(ci);
|
|
- if (ret)
|
|
- dev_info(dev, "doesn't support host\n");
|
|
+ if (ret) {
|
|
+ if (ret == -ENXIO)
|
|
+ dev_info(dev, "doesn't support host\n");
|
|
+ else
|
|
+ goto deinit_phy;
|
|
+ }
|
|
}
|
|
|
|
if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_PERIPHERAL) {
|
|
ret = ci_hdrc_gadget_init(ci);
|
|
- if (ret)
|
|
- dev_info(dev, "doesn't support gadget\n");
|
|
+ if (ret) {
|
|
+ if (ret == -ENXIO)
|
|
+ dev_info(dev, "doesn't support gadget\n");
|
|
+ else
|
|
+ goto deinit_host;
|
|
+ }
|
|
}
|
|
|
|
if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) {
|
|
dev_err(dev, "no supported roles\n");
|
|
ret = -ENODEV;
|
|
- goto deinit_phy;
|
|
+ goto deinit_gadget;
|
|
}
|
|
|
|
if (ci->is_otg && ci->roles[CI_ROLE_GADGET]) {
|
|
ret = ci_hdrc_otg_init(ci);
|
|
if (ret) {
|
|
dev_err(dev, "init otg fails, ret = %d\n", ret);
|
|
- goto stop;
|
|
+ goto deinit_gadget;
|
|
}
|
|
}
|
|
|
|
@@ -1036,7 +1044,12 @@ static int ci_hdrc_probe(struct platform_device *pdev)
|
|
|
|
ci_extcon_unregister(ci);
|
|
stop:
|
|
- ci_role_destroy(ci);
|
|
+ if (ci->is_otg && ci->roles[CI_ROLE_GADGET])
|
|
+ ci_hdrc_otg_destroy(ci);
|
|
+deinit_gadget:
|
|
+ ci_hdrc_gadget_destroy(ci);
|
|
+deinit_host:
|
|
+ ci_hdrc_host_destroy(ci);
|
|
deinit_phy:
|
|
ci_usb_phy_exit(ci);
|
|
|
|
diff --git a/drivers/usb/dwc3/dwc3-keystone.c b/drivers/usb/dwc3/dwc3-keystone.c
|
|
index 2be268d2423d..03a926ebf34b 100644
|
|
--- a/drivers/usb/dwc3/dwc3-keystone.c
|
|
+++ b/drivers/usb/dwc3/dwc3-keystone.c
|
|
@@ -112,6 +112,10 @@ static int kdwc3_probe(struct platform_device *pdev)
|
|
dev->dma_mask = &kdwc3_dma_mask;
|
|
|
|
kdwc->clk = devm_clk_get(kdwc->dev, "usb");
|
|
+ if (IS_ERR(kdwc->clk)) {
|
|
+ dev_err(kdwc->dev, "unable to get usb clock\n");
|
|
+ return PTR_ERR(kdwc->clk);
|
|
+ }
|
|
|
|
error = clk_prepare_enable(kdwc->clk);
|
|
if (error < 0) {
|
|
diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c
|
|
index 091e8ec7a6c0..962bb6376b0c 100644
|
|
--- a/drivers/usb/storage/ene_ub6250.c
|
|
+++ b/drivers/usb/storage/ene_ub6250.c
|
|
@@ -1953,6 +1953,8 @@ static int ene_load_bincode(struct us_data *us, unsigned char flag)
|
|
bcb->CDB[0] = 0xEF;
|
|
|
|
result = ene_send_scsi_cmd(us, FDIR_WRITE, buf, 0);
|
|
+ if (us->srb != NULL)
|
|
+ scsi_set_resid(us->srb, 0);
|
|
info->BIN_FLAG = flag;
|
|
kfree(buf);
|
|
|
|
@@ -2306,21 +2308,22 @@ static int ms_scsi_irp(struct us_data *us, struct scsi_cmnd *srb)
|
|
|
|
static int ene_transport(struct scsi_cmnd *srb, struct us_data *us)
|
|
{
|
|
- int result = 0;
|
|
+ int result = USB_STOR_XFER_GOOD;
|
|
struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra);
|
|
|
|
/*US_DEBUG(usb_stor_show_command(us, srb)); */
|
|
scsi_set_resid(srb, 0);
|
|
- if (unlikely(!(info->SD_Status.Ready || info->MS_Status.Ready))) {
|
|
+ if (unlikely(!(info->SD_Status.Ready || info->MS_Status.Ready)))
|
|
result = ene_init(us);
|
|
- } else {
|
|
+ if (result == USB_STOR_XFER_GOOD) {
|
|
+ result = USB_STOR_TRANSPORT_ERROR;
|
|
if (info->SD_Status.Ready)
|
|
result = sd_scsi_irp(us, srb);
|
|
|
|
if (info->MS_Status.Ready)
|
|
result = ms_scsi_irp(us, srb);
|
|
}
|
|
- return 0;
|
|
+ return result;
|
|
}
|
|
|
|
static struct scsi_host_template ene_ub6250_host_template;
|
|
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
|
|
index ad2146a9ab2d..675819a1af37 100644
|
|
--- a/drivers/vhost/vhost.c
|
|
+++ b/drivers/vhost/vhost.c
|
|
@@ -173,8 +173,7 @@ int vhost_poll_start(struct vhost_poll *poll, struct file *file)
|
|
if (mask)
|
|
vhost_poll_wakeup(&poll->wait, 0, 0, (void *)mask);
|
|
if (mask & POLLERR) {
|
|
- if (poll->wqh)
|
|
- remove_wait_queue(poll->wqh, &poll->wait);
|
|
+ vhost_poll_stop(poll);
|
|
ret = -EINVAL;
|
|
}
|
|
|
|
diff --git a/drivers/video/fbdev/vfb.c b/drivers/video/fbdev/vfb.c
|
|
index b9c2f81fb6b9..556c39997aab 100644
|
|
--- a/drivers/video/fbdev/vfb.c
|
|
+++ b/drivers/video/fbdev/vfb.c
|
|
@@ -291,8 +291,23 @@ static int vfb_check_var(struct fb_var_screeninfo *var,
|
|
*/
|
|
static int vfb_set_par(struct fb_info *info)
|
|
{
|
|
+ switch (info->var.bits_per_pixel) {
|
|
+ case 1:
|
|
+ info->fix.visual = FB_VISUAL_MONO01;
|
|
+ break;
|
|
+ case 8:
|
|
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
|
|
+ break;
|
|
+ case 16:
|
|
+ case 24:
|
|
+ case 32:
|
|
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
|
|
+ break;
|
|
+ }
|
|
+
|
|
info->fix.line_length = get_line_length(info->var.xres_virtual,
|
|
info->var.bits_per_pixel);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -525,6 +540,8 @@ static int vfb_probe(struct platform_device *dev)
|
|
goto err2;
|
|
platform_set_drvdata(dev, info);
|
|
|
|
+ vfb_set_par(info);
|
|
+
|
|
fb_info(info, "Virtual frame buffer device, using %ldK of video memory\n",
|
|
videomemorysize >> 10);
|
|
return 0;
|
|
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
|
|
index e767f347f2b1..88bee6703cc0 100644
|
|
--- a/fs/btrfs/extent_io.c
|
|
+++ b/fs/btrfs/extent_io.c
|
|
@@ -2534,7 +2534,7 @@ int end_extent_writepage(struct page *page, int err, u64 start, u64 end)
|
|
if (!uptodate) {
|
|
ClearPageUptodate(page);
|
|
SetPageError(page);
|
|
- ret = ret < 0 ? ret : -EIO;
|
|
+ ret = err < 0 ? err : -EIO;
|
|
mapping_set_error(page->mapping, ret);
|
|
}
|
|
return 0;
|
|
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
|
|
index 744be3c146f5..0141aba9eca6 100644
|
|
--- a/fs/cifs/file.c
|
|
+++ b/fs/cifs/file.c
|
|
@@ -589,7 +589,7 @@ cifs_relock_file(struct cifsFileInfo *cfile)
|
|
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
|
|
int rc = 0;
|
|
|
|
- down_read(&cinode->lock_sem);
|
|
+ down_read_nested(&cinode->lock_sem, SINGLE_DEPTH_NESTING);
|
|
if (cinode->can_cache_brlcks) {
|
|
/* can cache locks - no need to relock */
|
|
up_read(&cinode->lock_sem);
|
|
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
|
|
index 33b1bc21a120..807e989f436a 100644
|
|
--- a/fs/cifs/smb2pdu.c
|
|
+++ b/fs/cifs/smb2pdu.c
|
|
@@ -999,15 +999,19 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
|
|
goto tcon_exit;
|
|
}
|
|
|
|
- if (rsp->ShareType & SMB2_SHARE_TYPE_DISK)
|
|
+ switch (rsp->ShareType) {
|
|
+ case SMB2_SHARE_TYPE_DISK:
|
|
cifs_dbg(FYI, "connection to disk share\n");
|
|
- else if (rsp->ShareType & SMB2_SHARE_TYPE_PIPE) {
|
|
+ break;
|
|
+ case SMB2_SHARE_TYPE_PIPE:
|
|
tcon->ipc = true;
|
|
cifs_dbg(FYI, "connection to pipe share\n");
|
|
- } else if (rsp->ShareType & SMB2_SHARE_TYPE_PRINT) {
|
|
- tcon->print = true;
|
|
+ break;
|
|
+ case SMB2_SHARE_TYPE_PRINT:
|
|
+ tcon->ipc = true;
|
|
cifs_dbg(FYI, "connection to printer\n");
|
|
- } else {
|
|
+ break;
|
|
+ default:
|
|
cifs_dbg(VFS, "unknown share type %d\n", rsp->ShareType);
|
|
rc = -EOPNOTSUPP;
|
|
goto tcon_error_exit;
|
|
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
|
|
index a8b1749d79a8..debf0707789d 100644
|
|
--- a/fs/ext4/file.c
|
|
+++ b/fs/ext4/file.c
|
|
@@ -460,7 +460,7 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
|
|
int i, num;
|
|
unsigned long nr_pages;
|
|
|
|
- num = min_t(pgoff_t, end - index, PAGEVEC_SIZE);
|
|
+ num = min_t(pgoff_t, end - index, PAGEVEC_SIZE - 1) + 1;
|
|
nr_pages = pagevec_lookup(&pvec, inode->i_mapping, index,
|
|
(pgoff_t)num);
|
|
if (nr_pages == 0)
|
|
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
|
|
index 1ba82dc5afa3..d98ff184d94a 100644
|
|
--- a/fs/ext4/mballoc.c
|
|
+++ b/fs/ext4/mballoc.c
|
|
@@ -3874,7 +3874,8 @@ ext4_mb_discard_group_preallocations(struct super_block *sb,
|
|
|
|
err = ext4_mb_load_buddy(sb, group, &e4b);
|
|
if (err) {
|
|
- ext4_error(sb, "Error loading buddy information for %u", group);
|
|
+ ext4_warning(sb, "Error %d loading buddy information for %u",
|
|
+ err, group);
|
|
put_bh(bitmap_bh);
|
|
return 0;
|
|
}
|
|
@@ -4031,10 +4032,11 @@ repeat:
|
|
BUG_ON(pa->pa_type != MB_INODE_PA);
|
|
group = ext4_get_group_number(sb, pa->pa_pstart);
|
|
|
|
- err = ext4_mb_load_buddy(sb, group, &e4b);
|
|
+ err = ext4_mb_load_buddy_gfp(sb, group, &e4b,
|
|
+ GFP_NOFS|__GFP_NOFAIL);
|
|
if (err) {
|
|
- ext4_error(sb, "Error loading buddy information for %u",
|
|
- group);
|
|
+ ext4_error(sb, "Error %d loading buddy information for %u",
|
|
+ err, group);
|
|
continue;
|
|
}
|
|
|
|
@@ -4290,11 +4292,14 @@ ext4_mb_discard_lg_preallocations(struct super_block *sb,
|
|
spin_unlock(&lg->lg_prealloc_lock);
|
|
|
|
list_for_each_entry_safe(pa, tmp, &discard_list, u.pa_tmp_list) {
|
|
+ int err;
|
|
|
|
group = ext4_get_group_number(sb, pa->pa_pstart);
|
|
- if (ext4_mb_load_buddy(sb, group, &e4b)) {
|
|
- ext4_error(sb, "Error loading buddy information for %u",
|
|
- group);
|
|
+ err = ext4_mb_load_buddy_gfp(sb, group, &e4b,
|
|
+ GFP_NOFS|__GFP_NOFAIL);
|
|
+ if (err) {
|
|
+ ext4_error(sb, "Error %d loading buddy information for %u",
|
|
+ err, group);
|
|
continue;
|
|
}
|
|
ext4_lock_group(sb, group);
|
|
@@ -5116,8 +5121,8 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
|
|
|
|
ret = ext4_mb_load_buddy(sb, group, &e4b);
|
|
if (ret) {
|
|
- ext4_error(sb, "Error in loading buddy "
|
|
- "information for %u", group);
|
|
+ ext4_warning(sb, "Error %d loading buddy information for %u",
|
|
+ ret, group);
|
|
return ret;
|
|
}
|
|
bitmap = e4b.bd_bitmap;
|
|
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
|
|
index 5f31ebd96c06..a2edb0049eb5 100644
|
|
--- a/fs/lockd/svc.c
|
|
+++ b/fs/lockd/svc.c
|
|
@@ -129,6 +129,8 @@ lockd(void *vrqstp)
|
|
{
|
|
int err = 0;
|
|
struct svc_rqst *rqstp = vrqstp;
|
|
+ struct net *net = &init_net;
|
|
+ struct lockd_net *ln = net_generic(net, lockd_net_id);
|
|
|
|
/* try_to_freeze() is called from svc_recv() */
|
|
set_freezable();
|
|
@@ -173,6 +175,8 @@ lockd(void *vrqstp)
|
|
if (nlmsvc_ops)
|
|
nlmsvc_invalidate_all();
|
|
nlm_shutdown_hosts();
|
|
+ cancel_delayed_work_sync(&ln->grace_period_end);
|
|
+ locks_end_grace(&ln->lockd_manager);
|
|
return 0;
|
|
}
|
|
|
|
@@ -267,8 +271,6 @@ static void lockd_down_net(struct svc_serv *serv, struct net *net)
|
|
if (ln->nlmsvc_users) {
|
|
if (--ln->nlmsvc_users == 0) {
|
|
nlm_shutdown_hosts_net(net);
|
|
- cancel_delayed_work_sync(&ln->grace_period_end);
|
|
- locks_end_grace(&ln->lockd_manager);
|
|
svc_shutdown_net(serv, net);
|
|
dprintk("lockd_down_net: per-net data destroyed; net=%p\n", net);
|
|
}
|
|
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
|
|
index 54313322ee5b..c8e90152b61b 100644
|
|
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
|
|
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
|
|
@@ -461,6 +461,7 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
|
|
goto out_err_free;
|
|
|
|
/* fh */
|
|
+ rc = -EIO;
|
|
p = xdr_inline_decode(&stream, 4);
|
|
if (!p)
|
|
goto out_err_free;
|
|
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
|
|
index 8ef6f70c9e25..0f397e62de5a 100644
|
|
--- a/fs/nfs/nfs4proc.c
|
|
+++ b/fs/nfs/nfs4proc.c
|
|
@@ -3025,6 +3025,7 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
|
|
.rpc_resp = &res,
|
|
};
|
|
int status;
|
|
+ int i;
|
|
|
|
bitmask[0] = FATTR4_WORD0_SUPPORTED_ATTRS |
|
|
FATTR4_WORD0_FH_EXPIRE_TYPE |
|
|
@@ -3090,8 +3091,13 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
|
|
server->cache_consistency_bitmask[0] &= FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE;
|
|
server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
|
|
server->cache_consistency_bitmask[2] = 0;
|
|
+
|
|
+ /* Avoid a regression due to buggy server */
|
|
+ for (i = 0; i < ARRAY_SIZE(res.exclcreat_bitmask); i++)
|
|
+ res.exclcreat_bitmask[i] &= res.attr_bitmask[i];
|
|
memcpy(server->exclcreat_bitmask, res.exclcreat_bitmask,
|
|
sizeof(server->exclcreat_bitmask));
|
|
+
|
|
server->acl_bitmask = res.acl_bitmask;
|
|
server->fh_expire_type = res.fh_expire_type;
|
|
}
|
|
@@ -7670,6 +7676,12 @@ static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nf
|
|
/* fall through */
|
|
case -NFS4ERR_RETRY_UNCACHED_REP:
|
|
return -EAGAIN;
|
|
+ case -NFS4ERR_BADSESSION:
|
|
+ case -NFS4ERR_DEADSESSION:
|
|
+ case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
|
|
+ nfs4_schedule_session_recovery(clp->cl_session,
|
|
+ task->tk_status);
|
|
+ break;
|
|
default:
|
|
nfs4_schedule_lease_recovery(clp);
|
|
}
|
|
@@ -7748,7 +7760,6 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp,
|
|
if (status == 0)
|
|
status = task->tk_status;
|
|
rpc_put_task(task);
|
|
- return 0;
|
|
out:
|
|
dprintk("<-- %s status=%d\n", __func__, status);
|
|
return status;
|
|
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
|
|
index 9a0b219ff74d..83fba40396ae 100644
|
|
--- a/fs/nfs/nfs4state.c
|
|
+++ b/fs/nfs/nfs4state.c
|
|
@@ -1593,13 +1593,14 @@ static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp)
|
|
nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_reboot);
|
|
}
|
|
|
|
-static void nfs4_reclaim_complete(struct nfs_client *clp,
|
|
+static int nfs4_reclaim_complete(struct nfs_client *clp,
|
|
const struct nfs4_state_recovery_ops *ops,
|
|
struct rpc_cred *cred)
|
|
{
|
|
/* Notify the server we're done reclaiming our state */
|
|
if (ops->reclaim_complete)
|
|
- (void)ops->reclaim_complete(clp, cred);
|
|
+ return ops->reclaim_complete(clp, cred);
|
|
+ return 0;
|
|
}
|
|
|
|
static void nfs4_clear_reclaim_server(struct nfs_server *server)
|
|
@@ -1646,13 +1647,16 @@ static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
|
|
{
|
|
const struct nfs4_state_recovery_ops *ops;
|
|
struct rpc_cred *cred;
|
|
+ int err;
|
|
|
|
if (!nfs4_state_clear_reclaim_reboot(clp))
|
|
return;
|
|
ops = clp->cl_mvops->reboot_recovery_ops;
|
|
cred = nfs4_get_clid_cred(clp);
|
|
- nfs4_reclaim_complete(clp, ops, cred);
|
|
+ err = nfs4_reclaim_complete(clp, ops, cred);
|
|
put_rpccred(cred);
|
|
+ if (err == -NFS4ERR_CONN_NOT_BOUND_TO_SESSION)
|
|
+ set_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state);
|
|
}
|
|
|
|
static void nfs_delegation_clear_all(struct nfs_client *clp)
|
|
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
|
|
index 220b04f04523..985a4cdae06d 100644
|
|
--- a/fs/overlayfs/inode.c
|
|
+++ b/fs/overlayfs/inode.c
|
|
@@ -272,6 +272,16 @@ ssize_t ovl_getxattr(struct dentry *dentry, const char *name,
|
|
return vfs_getxattr(realpath.dentry, name, value, size);
|
|
}
|
|
|
|
+static bool ovl_can_list(const char *s)
|
|
+{
|
|
+ /* List all non-trusted xatts */
|
|
+ if (strncmp(s, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) != 0)
|
|
+ return true;
|
|
+
|
|
+ /* Never list trusted.overlay, list other trusted for superuser only */
|
|
+ return !ovl_is_private_xattr(s) && capable(CAP_SYS_ADMIN);
|
|
+}
|
|
+
|
|
ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
|
|
{
|
|
struct path realpath;
|
|
@@ -296,7 +306,7 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
|
|
return -EIO;
|
|
|
|
len -= slen;
|
|
- if (ovl_is_private_xattr(s)) {
|
|
+ if (!ovl_can_list(s)) {
|
|
res -= slen;
|
|
memmove(s, s + slen, len);
|
|
} else {
|
|
diff --git a/include/linux/mlx4/qp.h b/include/linux/mlx4/qp.h
|
|
index fe052e234906..bb1018882199 100644
|
|
--- a/include/linux/mlx4/qp.h
|
|
+++ b/include/linux/mlx4/qp.h
|
|
@@ -465,6 +465,7 @@ struct mlx4_update_qp_params {
|
|
u16 rate_val;
|
|
};
|
|
|
|
+struct mlx4_qp *mlx4_qp_lookup(struct mlx4_dev *dev, u32 qpn);
|
|
int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn,
|
|
enum mlx4_update_qp_attr attr,
|
|
struct mlx4_update_qp_params *params);
|
|
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
|
|
index a91b67b18a73..5c93f4a89afa 100644
|
|
--- a/include/linux/mlx5/device.h
|
|
+++ b/include/linux/mlx5/device.h
|
|
@@ -635,8 +635,14 @@ enum {
|
|
};
|
|
|
|
enum {
|
|
- CQE_RSS_HTYPE_IP = 0x3 << 6,
|
|
- CQE_RSS_HTYPE_L4 = 0x3 << 2,
|
|
+ CQE_RSS_HTYPE_IP = 0x3 << 2,
|
|
+ /* cqe->rss_hash_type[3:2] - IP destination selected for hash
|
|
+ * (00 = none, 01 = IPv4, 10 = IPv6, 11 = Reserved)
|
|
+ */
|
|
+ CQE_RSS_HTYPE_L4 = 0x3 << 6,
|
|
+ /* cqe->rss_hash_type[7:6] - L4 destination selected for hash
|
|
+ * (00 = none, 01 = TCP. 10 = UDP, 11 = IPSEC.SPI
|
|
+ */
|
|
};
|
|
|
|
enum {
|
|
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
|
|
index b5421f6f155a..a6da214d0584 100644
|
|
--- a/include/linux/skbuff.h
|
|
+++ b/include/linux/skbuff.h
|
|
@@ -879,10 +879,10 @@ struct sk_buff *skb_realloc_headroom(struct sk_buff *skb,
|
|
unsigned int headroom);
|
|
struct sk_buff *skb_copy_expand(const struct sk_buff *skb, int newheadroom,
|
|
int newtailroom, gfp_t priority);
|
|
-int skb_to_sgvec_nomark(struct sk_buff *skb, struct scatterlist *sg,
|
|
- int offset, int len);
|
|
-int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset,
|
|
- int len);
|
|
+int __must_check skb_to_sgvec_nomark(struct sk_buff *skb, struct scatterlist *sg,
|
|
+ int offset, int len);
|
|
+int __must_check skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg,
|
|
+ int offset, int len);
|
|
int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer);
|
|
int skb_pad(struct sk_buff *skb, int pad);
|
|
#define dev_kfree_skb(a) consume_skb(a)
|
|
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
|
|
index b5f3693fe5b6..c05748cc1b20 100644
|
|
--- a/include/net/cfg80211.h
|
|
+++ b/include/net/cfg80211.h
|
|
@@ -933,9 +933,9 @@ enum rate_info_flags {
|
|
* @RATE_INFO_BW_160: 160 MHz bandwidth
|
|
*/
|
|
enum rate_info_bw {
|
|
+ RATE_INFO_BW_20 = 0,
|
|
RATE_INFO_BW_5,
|
|
RATE_INFO_BW_10,
|
|
- RATE_INFO_BW_20,
|
|
RATE_INFO_BW_40,
|
|
RATE_INFO_BW_80,
|
|
RATE_INFO_BW_160,
|
|
diff --git a/include/net/x25.h b/include/net/x25.h
|
|
index c383aa4edbf0..6d30a01d281d 100644
|
|
--- a/include/net/x25.h
|
|
+++ b/include/net/x25.h
|
|
@@ -298,10 +298,10 @@ void x25_check_rbuf(struct sock *);
|
|
|
|
/* sysctl_net_x25.c */
|
|
#ifdef CONFIG_SYSCTL
|
|
-void x25_register_sysctl(void);
|
|
+int x25_register_sysctl(void);
|
|
void x25_unregister_sysctl(void);
|
|
#else
|
|
-static inline void x25_register_sysctl(void) {};
|
|
+static inline int x25_register_sysctl(void) { return 0; };
|
|
static inline void x25_unregister_sysctl(void) {};
|
|
#endif /* CONFIG_SYSCTL */
|
|
|
|
diff --git a/kernel/events/core.c b/kernel/events/core.c
|
|
index 8f75386e61a7..835ac4d9f349 100644
|
|
--- a/kernel/events/core.c
|
|
+++ b/kernel/events/core.c
|
|
@@ -5271,9 +5271,6 @@ static void perf_output_read_one(struct perf_output_handle *handle,
|
|
__output_copy(handle, values, n * sizeof(u64));
|
|
}
|
|
|
|
-/*
|
|
- * XXX PERF_FORMAT_GROUP vs inherited events seems difficult.
|
|
- */
|
|
static void perf_output_read_group(struct perf_output_handle *handle,
|
|
struct perf_event *event,
|
|
u64 enabled, u64 running)
|
|
@@ -5318,6 +5315,13 @@ static void perf_output_read_group(struct perf_output_handle *handle,
|
|
#define PERF_FORMAT_TOTAL_TIMES (PERF_FORMAT_TOTAL_TIME_ENABLED|\
|
|
PERF_FORMAT_TOTAL_TIME_RUNNING)
|
|
|
|
+/*
|
|
+ * XXX PERF_SAMPLE_READ vs inherited events seems difficult.
|
|
+ *
|
|
+ * The problem is that its both hard and excessively expensive to iterate the
|
|
+ * child list, not to mention that its impossible to IPI the children running
|
|
+ * on another CPU, from interrupt/NMI context.
|
|
+ */
|
|
static void perf_output_read(struct perf_output_handle *handle,
|
|
struct perf_event *event)
|
|
{
|
|
@@ -7958,9 +7962,10 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
|
|
local64_set(&hwc->period_left, hwc->sample_period);
|
|
|
|
/*
|
|
- * we currently do not support PERF_FORMAT_GROUP on inherited events
|
|
+ * We currently do not support PERF_SAMPLE_READ on inherited events.
|
|
+ * See perf_output_read().
|
|
*/
|
|
- if (attr->inherit && (attr->read_format & PERF_FORMAT_GROUP))
|
|
+ if (attr->inherit && (attr->sample_type & PERF_SAMPLE_READ))
|
|
goto err_ns;
|
|
|
|
if (!has_branch_stack(event))
|
|
diff --git a/kernel/futex.c b/kernel/futex.c
|
|
index 1fce19fc824c..a12aa6785361 100644
|
|
--- a/kernel/futex.c
|
|
+++ b/kernel/futex.c
|
|
@@ -470,6 +470,7 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
|
|
unsigned long address = (unsigned long)uaddr;
|
|
struct mm_struct *mm = current->mm;
|
|
struct page *page, *page_head;
|
|
+ struct address_space *mapping;
|
|
int err, ro = 0;
|
|
|
|
/*
|
|
@@ -555,7 +556,19 @@ again:
|
|
}
|
|
#endif
|
|
|
|
- lock_page(page_head);
|
|
+ /*
|
|
+ * The treatment of mapping from this point on is critical. The page
|
|
+ * lock protects many things but in this context the page lock
|
|
+ * stabilizes mapping, prevents inode freeing in the shared
|
|
+ * file-backed region case and guards against movement to swap cache.
|
|
+ *
|
|
+ * Strictly speaking the page lock is not needed in all cases being
|
|
+ * considered here and page lock forces unnecessarily serialization
|
|
+ * From this point on, mapping will be re-verified if necessary and
|
|
+ * page lock will be acquired only if it is unavoidable
|
|
+ */
|
|
+
|
|
+ mapping = READ_ONCE(page_head->mapping);
|
|
|
|
/*
|
|
* If page_head->mapping is NULL, then it cannot be a PageAnon
|
|
@@ -572,18 +585,31 @@ again:
|
|
* shmem_writepage move it from filecache to swapcache beneath us:
|
|
* an unlikely race, but we do need to retry for page_head->mapping.
|
|
*/
|
|
- if (!page_head->mapping) {
|
|
- int shmem_swizzled = PageSwapCache(page_head);
|
|
+ if (unlikely(!mapping)) {
|
|
+ int shmem_swizzled;
|
|
+
|
|
+ /*
|
|
+ * Page lock is required to identify which special case above
|
|
+ * applies. If this is really a shmem page then the page lock
|
|
+ * will prevent unexpected transitions.
|
|
+ */
|
|
+ lock_page(page);
|
|
+ shmem_swizzled = PageSwapCache(page) || page->mapping;
|
|
unlock_page(page_head);
|
|
put_page(page_head);
|
|
+
|
|
if (shmem_swizzled)
|
|
goto again;
|
|
+
|
|
return -EFAULT;
|
|
}
|
|
|
|
/*
|
|
* Private mappings are handled in a simple way.
|
|
*
|
|
+ * If the futex key is stored on an anonymous page, then the associated
|
|
+ * object is the mm which is implicitly pinned by the calling process.
|
|
+ *
|
|
* NOTE: When userspace waits on a MAP_SHARED mapping, even if
|
|
* it's a read-only handle, it's expected that futexes attach to
|
|
* the object not the particular process.
|
|
@@ -601,16 +627,74 @@ again:
|
|
key->both.offset |= FUT_OFF_MMSHARED; /* ref taken on mm */
|
|
key->private.mm = mm;
|
|
key->private.address = address;
|
|
+
|
|
+ get_futex_key_refs(key); /* implies smp_mb(); (B) */
|
|
+
|
|
} else {
|
|
+ struct inode *inode;
|
|
+
|
|
+ /*
|
|
+ * The associated futex object in this case is the inode and
|
|
+ * the page->mapping must be traversed. Ordinarily this should
|
|
+ * be stabilised under page lock but it's not strictly
|
|
+ * necessary in this case as we just want to pin the inode, not
|
|
+ * update the radix tree or anything like that.
|
|
+ *
|
|
+ * The RCU read lock is taken as the inode is finally freed
|
|
+ * under RCU. If the mapping still matches expectations then the
|
|
+ * mapping->host can be safely accessed as being a valid inode.
|
|
+ */
|
|
+ rcu_read_lock();
|
|
+
|
|
+ if (READ_ONCE(page_head->mapping) != mapping) {
|
|
+ rcu_read_unlock();
|
|
+ put_page(page_head);
|
|
+
|
|
+ goto again;
|
|
+ }
|
|
+
|
|
+ inode = READ_ONCE(mapping->host);
|
|
+ if (!inode) {
|
|
+ rcu_read_unlock();
|
|
+ put_page(page_head);
|
|
+
|
|
+ goto again;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Take a reference unless it is about to be freed. Previously
|
|
+ * this reference was taken by ihold under the page lock
|
|
+ * pinning the inode in place so i_lock was unnecessary. The
|
|
+ * only way for this check to fail is if the inode was
|
|
+ * truncated in parallel so warn for now if this happens.
|
|
+ *
|
|
+ * We are not calling into get_futex_key_refs() in file-backed
|
|
+ * cases, therefore a successful atomic_inc return below will
|
|
+ * guarantee that get_futex_key() will still imply smp_mb(); (B).
|
|
+ */
|
|
+ if (WARN_ON_ONCE(!atomic_inc_not_zero(&inode->i_count))) {
|
|
+ rcu_read_unlock();
|
|
+ put_page(page_head);
|
|
+
|
|
+ goto again;
|
|
+ }
|
|
+
|
|
+ /* Should be impossible but lets be paranoid for now */
|
|
+ if (WARN_ON_ONCE(inode->i_mapping != mapping)) {
|
|
+ err = -EFAULT;
|
|
+ rcu_read_unlock();
|
|
+ iput(inode);
|
|
+
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
key->both.offset |= FUT_OFF_INODE; /* inode-based key */
|
|
- key->shared.inode = page_head->mapping->host;
|
|
+ key->shared.inode = inode;
|
|
key->shared.pgoff = basepage_index(page);
|
|
+ rcu_read_unlock();
|
|
}
|
|
|
|
- get_futex_key_refs(key); /* implies MB (B) */
|
|
-
|
|
out:
|
|
- unlock_page(page_head);
|
|
put_page(page_head);
|
|
return err;
|
|
}
|
|
diff --git a/kernel/pid.c b/kernel/pid.c
|
|
index b17263be9082..5fe7cdb6d05f 100644
|
|
--- a/kernel/pid.c
|
|
+++ b/kernel/pid.c
|
|
@@ -322,8 +322,10 @@ struct pid *alloc_pid(struct pid_namespace *ns)
|
|
}
|
|
|
|
if (unlikely(is_child_reaper(pid))) {
|
|
- if (pid_ns_prepare_proc(ns))
|
|
+ if (pid_ns_prepare_proc(ns)) {
|
|
+ disable_pid_allocation(ns);
|
|
goto out_free;
|
|
+ }
|
|
}
|
|
|
|
get_pid_ns(ns);
|
|
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
|
|
index 812069b66f47..3b136fb4422c 100644
|
|
--- a/kernel/sched/fair.c
|
|
+++ b/kernel/sched/fair.c
|
|
@@ -2223,7 +2223,8 @@ void task_numa_work(struct callback_head *work)
|
|
return;
|
|
|
|
|
|
- down_read(&mm->mmap_sem);
|
|
+ if (!down_read_trylock(&mm->mmap_sem))
|
|
+ return;
|
|
vma = find_vma(mm, start);
|
|
if (!vma) {
|
|
reset_ptenuma_scan(p);
|
|
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
|
|
index 89da689b6433..ac9791dd4768 100644
|
|
--- a/net/8021q/vlan_dev.c
|
|
+++ b/net/8021q/vlan_dev.c
|
|
@@ -29,6 +29,7 @@
|
|
#include <linux/net_tstamp.h>
|
|
#include <linux/etherdevice.h>
|
|
#include <linux/ethtool.h>
|
|
+#include <linux/phy.h>
|
|
#include <net/arp.h>
|
|
|
|
#include "vlan.h"
|
|
@@ -654,8 +655,11 @@ static int vlan_ethtool_get_ts_info(struct net_device *dev,
|
|
{
|
|
const struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
|
|
const struct ethtool_ops *ops = vlan->real_dev->ethtool_ops;
|
|
+ struct phy_device *phydev = vlan->real_dev->phydev;
|
|
|
|
- if (ops->get_ts_info) {
|
|
+ if (phydev && phydev->drv && phydev->drv->ts_info) {
|
|
+ return phydev->drv->ts_info(phydev, info);
|
|
+ } else if (ops->get_ts_info) {
|
|
return ops->get_ts_info(vlan->real_dev, info);
|
|
} else {
|
|
info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE |
|
|
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
|
|
index 62edbf1b114e..5d0b1358c754 100644
|
|
--- a/net/bluetooth/hci_core.c
|
|
+++ b/net/bluetooth/hci_core.c
|
|
@@ -716,6 +716,7 @@ static void hci_set_event_mask_page_2(struct hci_request *req)
|
|
{
|
|
struct hci_dev *hdev = req->hdev;
|
|
u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
|
+ bool changed = false;
|
|
|
|
/* If Connectionless Slave Broadcast master role is supported
|
|
* enable all necessary events for it.
|
|
@@ -725,6 +726,7 @@ static void hci_set_event_mask_page_2(struct hci_request *req)
|
|
events[1] |= 0x80; /* Synchronization Train Complete */
|
|
events[2] |= 0x10; /* Slave Page Response Timeout */
|
|
events[2] |= 0x20; /* CSB Channel Map Change */
|
|
+ changed = true;
|
|
}
|
|
|
|
/* If Connectionless Slave Broadcast slave role is supported
|
|
@@ -735,13 +737,24 @@ static void hci_set_event_mask_page_2(struct hci_request *req)
|
|
events[2] |= 0x02; /* CSB Receive */
|
|
events[2] |= 0x04; /* CSB Timeout */
|
|
events[2] |= 0x08; /* Truncated Page Complete */
|
|
+ changed = true;
|
|
}
|
|
|
|
/* Enable Authenticated Payload Timeout Expired event if supported */
|
|
- if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING)
|
|
+ if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING) {
|
|
events[2] |= 0x80;
|
|
+ changed = true;
|
|
+ }
|
|
|
|
- hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
|
|
+ /* Some Broadcom based controllers indicate support for Set Event
|
|
+ * Mask Page 2 command, but then actually do not support it. Since
|
|
+ * the default value is all bits set to zero, the command is only
|
|
+ * required if the event mask has to be changed. In case no change
|
|
+ * to the event mask is needed, skip this command.
|
|
+ */
|
|
+ if (changed)
|
|
+ hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2,
|
|
+ sizeof(events), events);
|
|
}
|
|
|
|
static void hci_init3_req(struct hci_request *req, unsigned long opt)
|
|
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
|
|
index bc95e48d5cfb..378c9ed00d40 100644
|
|
--- a/net/ceph/osdmap.c
|
|
+++ b/net/ceph/osdmap.c
|
|
@@ -295,6 +295,7 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
|
|
u32 yes;
|
|
struct crush_rule *r;
|
|
|
|
+ err = -EINVAL;
|
|
ceph_decode_32_safe(p, end, yes, bad);
|
|
if (!yes) {
|
|
dout("crush_decode NO rule %d off %x %p to %p\n",
|
|
diff --git a/net/core/dev.c b/net/core/dev.c
|
|
index b2f589012c6b..dc63c37d5301 100644
|
|
--- a/net/core/dev.c
|
|
+++ b/net/core/dev.c
|
|
@@ -989,7 +989,7 @@ bool dev_valid_name(const char *name)
|
|
{
|
|
if (*name == '\0')
|
|
return false;
|
|
- if (strlen(name) >= IFNAMSIZ)
|
|
+ if (strnlen(name, IFNAMSIZ) == IFNAMSIZ)
|
|
return false;
|
|
if (!strcmp(name, ".") || !strcmp(name, ".."))
|
|
return false;
|
|
@@ -2515,7 +2515,7 @@ __be16 skb_network_protocol(struct sk_buff *skb, int *depth)
|
|
if (unlikely(!pskb_may_pull(skb, sizeof(struct ethhdr))))
|
|
return 0;
|
|
|
|
- eth = (struct ethhdr *)skb_mac_header(skb);
|
|
+ eth = (struct ethhdr *)skb->data;
|
|
type = eth->h_proto;
|
|
}
|
|
|
|
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
|
|
index 253c86b78ff0..33432e64804c 100644
|
|
--- a/net/core/neighbour.c
|
|
+++ b/net/core/neighbour.c
|
|
@@ -1132,10 +1132,6 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
|
|
lladdr = neigh->ha;
|
|
}
|
|
|
|
- if (new & NUD_CONNECTED)
|
|
- neigh->confirmed = jiffies;
|
|
- neigh->updated = jiffies;
|
|
-
|
|
/* If entry was valid and address is not changed,
|
|
do not change entry state, if new one is STALE.
|
|
*/
|
|
@@ -1159,6 +1155,16 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
|
|
}
|
|
}
|
|
|
|
+ /* Update timestamps only once we know we will make a change to the
|
|
+ * neighbour entry. Otherwise we risk to move the locktime window with
|
|
+ * noop updates and ignore relevant ARP updates.
|
|
+ */
|
|
+ if (new != old || lladdr != neigh->ha) {
|
|
+ if (new & NUD_CONNECTED)
|
|
+ neigh->confirmed = jiffies;
|
|
+ neigh->updated = jiffies;
|
|
+ }
|
|
+
|
|
if (new != old) {
|
|
neigh_del_timer(neigh);
|
|
if (new & NUD_PROBE)
|
|
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
|
|
index b5c351d2830b..ccd20669ac00 100644
|
|
--- a/net/core/net_namespace.c
|
|
+++ b/net/core/net_namespace.c
|
|
@@ -310,6 +310,25 @@ out_undo:
|
|
goto out;
|
|
}
|
|
|
|
+static int __net_init net_defaults_init_net(struct net *net)
|
|
+{
|
|
+ net->core.sysctl_somaxconn = SOMAXCONN;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static struct pernet_operations net_defaults_ops = {
|
|
+ .init = net_defaults_init_net,
|
|
+};
|
|
+
|
|
+static __init int net_defaults_init(void)
|
|
+{
|
|
+ if (register_pernet_subsys(&net_defaults_ops))
|
|
+ panic("Cannot initialize net default settings");
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+core_initcall(net_defaults_init);
|
|
|
|
#ifdef CONFIG_NET_NS
|
|
static struct kmem_cache *net_cachep;
|
|
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
|
|
index 284370b61b8c..7d3442594e0d 100644
|
|
--- a/net/core/skbuff.c
|
|
+++ b/net/core/skbuff.c
|
|
@@ -2551,7 +2551,8 @@ void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len)
|
|
{
|
|
int pos = skb_headlen(skb);
|
|
|
|
- skb_shinfo(skb1)->tx_flags = skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG;
|
|
+ skb_shinfo(skb1)->tx_flags |= skb_shinfo(skb)->tx_flags &
|
|
+ SKBTX_SHARED_FRAG;
|
|
if (len < pos) /* Split line is inside header. */
|
|
skb_split_inside_header(skb, skb1, len, pos);
|
|
else /* Second chunk has no header, nothing to copy. */
|
|
@@ -3115,8 +3116,8 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
|
|
skb_copy_from_linear_data_offset(head_skb, offset,
|
|
skb_put(nskb, hsize), hsize);
|
|
|
|
- skb_shinfo(nskb)->tx_flags = skb_shinfo(head_skb)->tx_flags &
|
|
- SKBTX_SHARED_FRAG;
|
|
+ skb_shinfo(nskb)->tx_flags |= skb_shinfo(head_skb)->tx_flags &
|
|
+ SKBTX_SHARED_FRAG;
|
|
|
|
while (pos < offset + len) {
|
|
if (i >= nfrags) {
|
|
@@ -3329,24 +3330,18 @@ void __init skb_init(void)
|
|
NULL);
|
|
}
|
|
|
|
-/**
|
|
- * skb_to_sgvec - Fill a scatter-gather list from a socket buffer
|
|
- * @skb: Socket buffer containing the buffers to be mapped
|
|
- * @sg: The scatter-gather list to map into
|
|
- * @offset: The offset into the buffer's contents to start mapping
|
|
- * @len: Length of buffer space to be mapped
|
|
- *
|
|
- * Fill the specified scatter-gather list with mappings/pointers into a
|
|
- * region of the buffer space attached to a socket buffer.
|
|
- */
|
|
static int
|
|
-__skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
|
|
+__skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len,
|
|
+ unsigned int recursion_level)
|
|
{
|
|
int start = skb_headlen(skb);
|
|
int i, copy = start - offset;
|
|
struct sk_buff *frag_iter;
|
|
int elt = 0;
|
|
|
|
+ if (unlikely(recursion_level >= 24))
|
|
+ return -EMSGSIZE;
|
|
+
|
|
if (copy > 0) {
|
|
if (copy > len)
|
|
copy = len;
|
|
@@ -3365,6 +3360,8 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
|
|
end = start + skb_frag_size(&skb_shinfo(skb)->frags[i]);
|
|
if ((copy = end - offset) > 0) {
|
|
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
|
|
+ if (unlikely(elt && sg_is_last(&sg[elt - 1])))
|
|
+ return -EMSGSIZE;
|
|
|
|
if (copy > len)
|
|
copy = len;
|
|
@@ -3379,16 +3376,22 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
|
|
}
|
|
|
|
skb_walk_frags(skb, frag_iter) {
|
|
- int end;
|
|
+ int end, ret;
|
|
|
|
WARN_ON(start > offset + len);
|
|
|
|
end = start + frag_iter->len;
|
|
if ((copy = end - offset) > 0) {
|
|
+ if (unlikely(elt && sg_is_last(&sg[elt - 1])))
|
|
+ return -EMSGSIZE;
|
|
+
|
|
if (copy > len)
|
|
copy = len;
|
|
- elt += __skb_to_sgvec(frag_iter, sg+elt, offset - start,
|
|
- copy);
|
|
+ ret = __skb_to_sgvec(frag_iter, sg+elt, offset - start,
|
|
+ copy, recursion_level + 1);
|
|
+ if (unlikely(ret < 0))
|
|
+ return ret;
|
|
+ elt += ret;
|
|
if ((len -= copy) == 0)
|
|
return elt;
|
|
offset += copy;
|
|
@@ -3399,6 +3402,31 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
|
|
return elt;
|
|
}
|
|
|
|
+/**
|
|
+ * skb_to_sgvec - Fill a scatter-gather list from a socket buffer
|
|
+ * @skb: Socket buffer containing the buffers to be mapped
|
|
+ * @sg: The scatter-gather list to map into
|
|
+ * @offset: The offset into the buffer's contents to start mapping
|
|
+ * @len: Length of buffer space to be mapped
|
|
+ *
|
|
+ * Fill the specified scatter-gather list with mappings/pointers into a
|
|
+ * region of the buffer space attached to a socket buffer. Returns either
|
|
+ * the number of scatterlist items used, or -EMSGSIZE if the contents
|
|
+ * could not fit.
|
|
+ */
|
|
+int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
|
|
+{
|
|
+ int nsg = __skb_to_sgvec(skb, sg, offset, len, 0);
|
|
+
|
|
+ if (nsg <= 0)
|
|
+ return nsg;
|
|
+
|
|
+ sg_mark_end(&sg[nsg - 1]);
|
|
+
|
|
+ return nsg;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(skb_to_sgvec);
|
|
+
|
|
/* As compared with skb_to_sgvec, skb_to_sgvec_nomark only map skb to given
|
|
* sglist without mark the sg which contain last skb data as the end.
|
|
* So the caller can mannipulate sg list as will when padding new data after
|
|
@@ -3421,19 +3449,11 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
|
|
int skb_to_sgvec_nomark(struct sk_buff *skb, struct scatterlist *sg,
|
|
int offset, int len)
|
|
{
|
|
- return __skb_to_sgvec(skb, sg, offset, len);
|
|
+ return __skb_to_sgvec(skb, sg, offset, len, 0);
|
|
}
|
|
EXPORT_SYMBOL_GPL(skb_to_sgvec_nomark);
|
|
|
|
-int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
|
|
-{
|
|
- int nsg = __skb_to_sgvec(skb, sg, offset, len);
|
|
|
|
- sg_mark_end(&sg[nsg - 1]);
|
|
-
|
|
- return nsg;
|
|
-}
|
|
-EXPORT_SYMBOL_GPL(skb_to_sgvec);
|
|
|
|
/**
|
|
* skb_cow_data - Check that a socket buffer's data buffers are writable
|
|
@@ -3715,7 +3735,8 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
|
|
return;
|
|
|
|
if (tsonly) {
|
|
- skb_shinfo(skb)->tx_flags = skb_shinfo(orig_skb)->tx_flags;
|
|
+ skb_shinfo(skb)->tx_flags |= skb_shinfo(orig_skb)->tx_flags &
|
|
+ SKBTX_ANY_TSTAMP;
|
|
skb_shinfo(skb)->tskey = skb_shinfo(orig_skb)->tskey;
|
|
}
|
|
|
|
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
|
|
index 6578a0a2f708..32898247d8bf 100644
|
|
--- a/net/core/sysctl_net_core.c
|
|
+++ b/net/core/sysctl_net_core.c
|
|
@@ -429,8 +429,6 @@ static __net_init int sysctl_core_net_init(struct net *net)
|
|
{
|
|
struct ctl_table *tbl;
|
|
|
|
- net->core.sysctl_somaxconn = SOMAXCONN;
|
|
-
|
|
tbl = netns_core_table;
|
|
if (!net_eq(net, &init_net)) {
|
|
tbl = kmemdup(tbl, sizeof(netns_core_table), GFP_KERNEL);
|
|
diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c
|
|
index a548be247e15..47b397264f24 100644
|
|
--- a/net/ieee802154/socket.c
|
|
+++ b/net/ieee802154/socket.c
|
|
@@ -302,12 +302,12 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
|
|
skb->sk = sk;
|
|
skb->protocol = htons(ETH_P_IEEE802154);
|
|
|
|
- dev_put(dev);
|
|
-
|
|
err = dev_queue_xmit(skb);
|
|
if (err > 0)
|
|
err = net_xmit_errno(err);
|
|
|
|
+ dev_put(dev);
|
|
+
|
|
return err ?: size;
|
|
|
|
out_skb:
|
|
@@ -689,12 +689,12 @@ static int dgram_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
|
|
skb->sk = sk;
|
|
skb->protocol = htons(ETH_P_IEEE802154);
|
|
|
|
- dev_put(dev);
|
|
-
|
|
err = dev_queue_xmit(skb);
|
|
if (err > 0)
|
|
err = net_xmit_errno(err);
|
|
|
|
+ dev_put(dev);
|
|
+
|
|
return err ?: size;
|
|
|
|
out_skb:
|
|
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
|
|
index 22377c8ff14b..e8f862358518 100644
|
|
--- a/net/ipv4/ah4.c
|
|
+++ b/net/ipv4/ah4.c
|
|
@@ -220,7 +220,9 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb)
|
|
ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output.low);
|
|
|
|
sg_init_table(sg, nfrags + sglists);
|
|
- skb_to_sgvec_nomark(skb, sg, 0, skb->len);
|
|
+ err = skb_to_sgvec_nomark(skb, sg, 0, skb->len);
|
|
+ if (unlikely(err < 0))
|
|
+ goto out_free;
|
|
|
|
if (x->props.flags & XFRM_STATE_ESN) {
|
|
/* Attach seqhi sg right after packet payload */
|
|
@@ -393,7 +395,9 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
|
|
skb_push(skb, ihl);
|
|
|
|
sg_init_table(sg, nfrags + sglists);
|
|
- skb_to_sgvec_nomark(skb, sg, 0, skb->len);
|
|
+ err = skb_to_sgvec_nomark(skb, sg, 0, skb->len);
|
|
+ if (unlikely(err < 0))
|
|
+ goto out_free;
|
|
|
|
if (x->props.flags & XFRM_STATE_ESN) {
|
|
/* Attach seqhi sg right after packet payload */
|
|
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
|
|
index cb5eb649ad5f..bfa79831873f 100644
|
|
--- a/net/ipv4/arp.c
|
|
+++ b/net/ipv4/arp.c
|
|
@@ -437,7 +437,7 @@ static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev)
|
|
/*unsigned long now; */
|
|
struct net *net = dev_net(dev);
|
|
|
|
- rt = ip_route_output(net, sip, tip, 0, 0);
|
|
+ rt = ip_route_output(net, sip, tip, 0, l3mdev_master_ifindex_rcu(dev));
|
|
if (IS_ERR(rt))
|
|
return 1;
|
|
if (rt->dst.dev != dev) {
|
|
@@ -658,6 +658,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
|
|
unsigned char *arp_ptr;
|
|
struct rtable *rt;
|
|
unsigned char *sha;
|
|
+ unsigned char *tha = NULL;
|
|
__be32 sip, tip;
|
|
u16 dev_type = dev->type;
|
|
int addr_type;
|
|
@@ -729,6 +730,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
|
|
break;
|
|
#endif
|
|
default:
|
|
+ tha = arp_ptr;
|
|
arp_ptr += dev->addr_len;
|
|
}
|
|
memcpy(&tip, arp_ptr, 4);
|
|
@@ -839,8 +841,18 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
|
|
It is possible, that this option should be enabled for some
|
|
devices (strip is candidate)
|
|
*/
|
|
- is_garp = arp->ar_op == htons(ARPOP_REQUEST) && tip == sip &&
|
|
- addr_type == RTN_UNICAST;
|
|
+ is_garp = tip == sip && addr_type == RTN_UNICAST;
|
|
+
|
|
+ /* Unsolicited ARP _replies_ also require target hwaddr to be
|
|
+ * the same as source.
|
|
+ */
|
|
+ if (is_garp && arp->ar_op == htons(ARPOP_REPLY))
|
|
+ is_garp =
|
|
+ /* IPv4 over IEEE 1394 doesn't provide target
|
|
+ * hardware address field in its ARP payload.
|
|
+ */
|
|
+ tha &&
|
|
+ !memcmp(tha, sha, dev->addr_len);
|
|
|
|
if (!n &&
|
|
((arp->ar_op == htons(ARPOP_REPLY) &&
|
|
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
|
|
index 20fb25e3027b..3d8021d55336 100644
|
|
--- a/net/ipv4/esp4.c
|
|
+++ b/net/ipv4/esp4.c
|
|
@@ -268,10 +268,11 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
|
|
esph->spi = x->id.spi;
|
|
|
|
sg_init_table(sg, nfrags);
|
|
- skb_to_sgvec(skb, sg,
|
|
- (unsigned char *)esph - skb->data,
|
|
- assoclen + ivlen + clen + alen);
|
|
-
|
|
+ err = skb_to_sgvec(skb, sg,
|
|
+ (unsigned char *)esph - skb->data,
|
|
+ assoclen + ivlen + clen + alen);
|
|
+ if (unlikely(err < 0))
|
|
+ goto error;
|
|
aead_request_set_crypt(req, sg, sg, ivlen + clen, iv);
|
|
aead_request_set_ad(req, assoclen);
|
|
|
|
@@ -481,7 +482,9 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
|
|
}
|
|
|
|
sg_init_table(sg, nfrags);
|
|
- skb_to_sgvec(skb, sg, 0, skb->len);
|
|
+ err = skb_to_sgvec(skb, sg, 0, skb->len);
|
|
+ if (unlikely(err < 0))
|
|
+ goto out;
|
|
|
|
aead_request_set_crypt(req, sg, sg, elen + ivlen, iv);
|
|
aead_request_set_ad(req, assoclen);
|
|
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
|
|
index 80e2d1b0c08c..3d62feb65932 100644
|
|
--- a/net/ipv4/ip_tunnel.c
|
|
+++ b/net/ipv4/ip_tunnel.c
|
|
@@ -253,13 +253,14 @@ static struct net_device *__ip_tunnel_create(struct net *net,
|
|
struct net_device *dev;
|
|
char name[IFNAMSIZ];
|
|
|
|
- if (parms->name[0])
|
|
+ err = -E2BIG;
|
|
+ if (parms->name[0]) {
|
|
+ if (!dev_valid_name(parms->name))
|
|
+ goto failed;
|
|
strlcpy(name, parms->name, IFNAMSIZ);
|
|
- else {
|
|
- if (strlen(ops->kind) > (IFNAMSIZ - 3)) {
|
|
- err = -E2BIG;
|
|
+ } else {
|
|
+ if (strlen(ops->kind) > (IFNAMSIZ - 3))
|
|
goto failed;
|
|
- }
|
|
strlcpy(name, ops->kind, IFNAMSIZ);
|
|
strncat(name, "%d", 2);
|
|
}
|
|
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
|
|
index 75433ed6714b..96115d1e0d90 100644
|
|
--- a/net/ipv4/tcp_input.c
|
|
+++ b/net/ipv4/tcp_input.c
|
|
@@ -117,6 +117,7 @@ int sysctl_tcp_invalid_ratelimit __read_mostly = HZ/2;
|
|
#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */
|
|
#define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */
|
|
#define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */
|
|
+#define FLAG_NO_CHALLENGE_ACK 0x8000 /* do not call tcp_send_challenge_ack() */
|
|
|
|
#define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED)
|
|
#define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED)
|
|
@@ -3543,7 +3544,8 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
|
|
if (before(ack, prior_snd_una)) {
|
|
/* RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] */
|
|
if (before(ack, prior_snd_una - tp->max_window)) {
|
|
- tcp_send_challenge_ack(sk, skb);
|
|
+ if (!(flag & FLAG_NO_CHALLENGE_ACK))
|
|
+ tcp_send_challenge_ack(sk, skb);
|
|
return -1;
|
|
}
|
|
goto old_ack;
|
|
@@ -5832,13 +5834,17 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
|
|
|
|
/* step 5: check the ACK field */
|
|
acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH |
|
|
- FLAG_UPDATE_TS_RECENT) > 0;
|
|
+ FLAG_UPDATE_TS_RECENT |
|
|
+ FLAG_NO_CHALLENGE_ACK) > 0;
|
|
|
|
+ if (!acceptable) {
|
|
+ if (sk->sk_state == TCP_SYN_RECV)
|
|
+ return 1; /* send one RST */
|
|
+ tcp_send_challenge_ack(sk, skb);
|
|
+ goto discard;
|
|
+ }
|
|
switch (sk->sk_state) {
|
|
case TCP_SYN_RECV:
|
|
- if (!acceptable)
|
|
- return 1;
|
|
-
|
|
if (!tp->srtt_us)
|
|
tcp_synack_rtt_meas(sk, req);
|
|
|
|
@@ -5907,14 +5913,6 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
|
|
* our SYNACK so stop the SYNACK timer.
|
|
*/
|
|
if (req) {
|
|
- /* Return RST if ack_seq is invalid.
|
|
- * Note that RFC793 only says to generate a
|
|
- * DUPACK for it but for TCP Fast Open it seems
|
|
- * better to treat this case like TCP_SYN_RECV
|
|
- * above.
|
|
- */
|
|
- if (!acceptable)
|
|
- return 1;
|
|
/* We no longer need the request sock. */
|
|
reqsk_fastopen_remove(sk, req, false);
|
|
tcp_rearm_rto(sk);
|
|
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
|
|
index 92174881844d..0613be57513e 100644
|
|
--- a/net/ipv6/addrconf.c
|
|
+++ b/net/ipv6/addrconf.c
|
|
@@ -957,7 +957,10 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
|
|
INIT_HLIST_NODE(&ifa->addr_lst);
|
|
ifa->scope = scope;
|
|
ifa->prefix_len = pfxlen;
|
|
- ifa->flags = flags | IFA_F_TENTATIVE;
|
|
+ ifa->flags = flags;
|
|
+ /* No need to add the TENTATIVE flag for addresses with NODAD */
|
|
+ if (!(flags & IFA_F_NODAD))
|
|
+ ifa->flags |= IFA_F_TENTATIVE;
|
|
ifa->valid_lft = valid_lft;
|
|
ifa->prefered_lft = prefered_lft;
|
|
ifa->cstamp = ifa->tstamp = jiffies;
|
|
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
|
|
index 0630a4d5daaa..0edc44cb254e 100644
|
|
--- a/net/ipv6/ah6.c
|
|
+++ b/net/ipv6/ah6.c
|
|
@@ -423,7 +423,9 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
|
|
ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output.low);
|
|
|
|
sg_init_table(sg, nfrags + sglists);
|
|
- skb_to_sgvec_nomark(skb, sg, 0, skb->len);
|
|
+ err = skb_to_sgvec_nomark(skb, sg, 0, skb->len);
|
|
+ if (unlikely(err < 0))
|
|
+ goto out_free;
|
|
|
|
if (x->props.flags & XFRM_STATE_ESN) {
|
|
/* Attach seqhi sg right after packet payload */
|
|
@@ -603,7 +605,9 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
|
|
ip6h->hop_limit = 0;
|
|
|
|
sg_init_table(sg, nfrags + sglists);
|
|
- skb_to_sgvec_nomark(skb, sg, 0, skb->len);
|
|
+ err = skb_to_sgvec_nomark(skb, sg, 0, skb->len);
|
|
+ if (unlikely(err < 0))
|
|
+ goto out_free;
|
|
|
|
if (x->props.flags & XFRM_STATE_ESN) {
|
|
/* Attach seqhi sg right after packet payload */
|
|
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
|
|
index 111ba55fd512..6a924be66e37 100644
|
|
--- a/net/ipv6/esp6.c
|
|
+++ b/net/ipv6/esp6.c
|
|
@@ -248,9 +248,11 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
|
|
esph->spi = x->id.spi;
|
|
|
|
sg_init_table(sg, nfrags);
|
|
- skb_to_sgvec(skb, sg,
|
|
- (unsigned char *)esph - skb->data,
|
|
- assoclen + ivlen + clen + alen);
|
|
+ err = skb_to_sgvec(skb, sg,
|
|
+ (unsigned char *)esph - skb->data,
|
|
+ assoclen + ivlen + clen + alen);
|
|
+ if (unlikely(err < 0))
|
|
+ goto error;
|
|
|
|
aead_request_set_crypt(req, sg, sg, ivlen + clen, iv);
|
|
aead_request_set_ad(req, assoclen);
|
|
@@ -423,7 +425,9 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
|
|
}
|
|
|
|
sg_init_table(sg, nfrags);
|
|
- skb_to_sgvec(skb, sg, 0, skb->len);
|
|
+ ret = skb_to_sgvec(skb, sg, 0, skb->len);
|
|
+ if (unlikely(ret < 0))
|
|
+ goto out;
|
|
|
|
aead_request_set_crypt(req, sg, sg, elen + ivlen, iv);
|
|
aead_request_set_ad(req, assoclen);
|
|
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
|
|
index 9ada1095c1cd..b25f4ad28b03 100644
|
|
--- a/net/ipv6/ip6_gre.c
|
|
+++ b/net/ipv6/ip6_gre.c
|
|
@@ -320,11 +320,13 @@ static struct ip6_tnl *ip6gre_tunnel_locate(struct net *net,
|
|
if (t || !create)
|
|
return t;
|
|
|
|
- if (parms->name[0])
|
|
+ if (parms->name[0]) {
|
|
+ if (!dev_valid_name(parms->name))
|
|
+ return NULL;
|
|
strlcpy(name, parms->name, IFNAMSIZ);
|
|
- else
|
|
+ } else {
|
|
strcpy(name, "ip6gre%d");
|
|
-
|
|
+ }
|
|
dev = alloc_netdev(sizeof(*t), name, NET_NAME_UNKNOWN,
|
|
ip6gre_tunnel_setup);
|
|
if (!dev)
|
|
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
|
|
index 3ef81c387923..bfa710e8b615 100644
|
|
--- a/net/ipv6/ip6_output.c
|
|
+++ b/net/ipv6/ip6_output.c
|
|
@@ -340,6 +340,10 @@ static int ip6_forward_proxy_check(struct sk_buff *skb)
|
|
static inline int ip6_forward_finish(struct net *net, struct sock *sk,
|
|
struct sk_buff *skb)
|
|
{
|
|
+ struct dst_entry *dst = skb_dst(skb);
|
|
+
|
|
+ IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS);
|
|
+ IP6_ADD_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTOCTETS, skb->len);
|
|
skb_sender_cpu_clear(skb);
|
|
return dst_output(net, sk, skb);
|
|
}
|
|
@@ -534,8 +538,6 @@ int ip6_forward(struct sk_buff *skb)
|
|
|
|
hdr->hop_limit--;
|
|
|
|
- IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS);
|
|
- IP6_ADD_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTOCTETS, skb->len);
|
|
return NF_HOOK(NFPROTO_IPV6, NF_INET_FORWARD,
|
|
net, NULL, skb, skb->dev, dst->dev,
|
|
ip6_forward_finish);
|
|
@@ -1276,7 +1278,7 @@ static int __ip6_append_data(struct sock *sk,
|
|
unsigned int flags, int dontfrag)
|
|
{
|
|
struct sk_buff *skb, *skb_prev = NULL;
|
|
- unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu;
|
|
+ unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu, pmtu;
|
|
int exthdrlen = 0;
|
|
int dst_exthdrlen = 0;
|
|
int hh_len;
|
|
@@ -1312,6 +1314,12 @@ static int __ip6_append_data(struct sock *sk,
|
|
sizeof(struct frag_hdr) : 0) +
|
|
rt->rt6i_nfheader_len;
|
|
|
|
+ /* as per RFC 7112 section 5, the entire IPv6 Header Chain must fit
|
|
+ * the first fragment
|
|
+ */
|
|
+ if (headersize + transhdrlen > mtu)
|
|
+ goto emsgsize;
|
|
+
|
|
if (cork->length + length > mtu - headersize && dontfrag &&
|
|
(sk->sk_protocol == IPPROTO_UDP ||
|
|
sk->sk_protocol == IPPROTO_RAW)) {
|
|
@@ -1327,9 +1335,8 @@ static int __ip6_append_data(struct sock *sk,
|
|
|
|
if (cork->length + length > maxnonfragsize - headersize) {
|
|
emsgsize:
|
|
- ipv6_local_error(sk, EMSGSIZE, fl6,
|
|
- mtu - headersize +
|
|
- sizeof(struct ipv6hdr));
|
|
+ pmtu = max_t(int, mtu - headersize + sizeof(struct ipv6hdr), 0);
|
|
+ ipv6_local_error(sk, EMSGSIZE, fl6, pmtu);
|
|
return -EMSGSIZE;
|
|
}
|
|
|
|
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
|
|
index 946c2d015b94..e8f21dd520b2 100644
|
|
--- a/net/ipv6/ip6_tunnel.c
|
|
+++ b/net/ipv6/ip6_tunnel.c
|
|
@@ -286,13 +286,16 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p)
|
|
struct net_device *dev;
|
|
struct ip6_tnl *t;
|
|
char name[IFNAMSIZ];
|
|
- int err = -ENOMEM;
|
|
+ int err = -E2BIG;
|
|
|
|
- if (p->name[0])
|
|
+ if (p->name[0]) {
|
|
+ if (!dev_valid_name(p->name))
|
|
+ goto failed;
|
|
strlcpy(name, p->name, IFNAMSIZ);
|
|
- else
|
|
+ } else {
|
|
sprintf(name, "ip6tnl%%d");
|
|
-
|
|
+ }
|
|
+ err = -ENOMEM;
|
|
dev = alloc_netdev(sizeof(*t), name, NET_NAME_UNKNOWN,
|
|
ip6_tnl_dev_setup);
|
|
if (!dev)
|
|
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
|
|
index d7105422bc63..40bb7a5e6d47 100644
|
|
--- a/net/ipv6/ip6_vti.c
|
|
+++ b/net/ipv6/ip6_vti.c
|
|
@@ -212,10 +212,13 @@ static struct ip6_tnl *vti6_tnl_create(struct net *net, struct __ip6_tnl_parm *p
|
|
char name[IFNAMSIZ];
|
|
int err;
|
|
|
|
- if (p->name[0])
|
|
+ if (p->name[0]) {
|
|
+ if (!dev_valid_name(p->name))
|
|
+ goto failed;
|
|
strlcpy(name, p->name, IFNAMSIZ);
|
|
- else
|
|
+ } else {
|
|
sprintf(name, "ip6_vti%%d");
|
|
+ }
|
|
|
|
dev = alloc_netdev(sizeof(*t), name, NET_NAME_UNKNOWN, vti6_dev_setup);
|
|
if (!dev)
|
|
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
|
|
index 48db6f5cec2c..99920fcea97c 100644
|
|
--- a/net/ipv6/route.c
|
|
+++ b/net/ipv6/route.c
|
|
@@ -851,6 +851,9 @@ static struct rt6_info *ip6_pol_route_lookup(struct net *net,
|
|
struct fib6_node *fn;
|
|
struct rt6_info *rt;
|
|
|
|
+ if (fl6->flowi6_flags & FLOWI_FLAG_SKIP_NH_OIF)
|
|
+ flags &= ~RT6_LOOKUP_F_IFACE;
|
|
+
|
|
read_lock_bh(&table->tb6_lock);
|
|
fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
|
|
restart:
|
|
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
|
|
index bbba435d0639..51f7c32f04d7 100644
|
|
--- a/net/ipv6/sit.c
|
|
+++ b/net/ipv6/sit.c
|
|
@@ -244,11 +244,13 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net,
|
|
if (!create)
|
|
goto failed;
|
|
|
|
- if (parms->name[0])
|
|
+ if (parms->name[0]) {
|
|
+ if (!dev_valid_name(parms->name))
|
|
+ goto failed;
|
|
strlcpy(name, parms->name, IFNAMSIZ);
|
|
- else
|
|
+ } else {
|
|
strcpy(name, "sit%d");
|
|
-
|
|
+ }
|
|
dev = alloc_netdev(sizeof(*t), name, NET_NAME_UNKNOWN,
|
|
ipip6_tunnel_setup);
|
|
if (!dev)
|
|
@@ -690,6 +692,7 @@ static int ipip6_rcv(struct sk_buff *skb)
|
|
|
|
if (iptunnel_pull_header(skb, 0, htons(ETH_P_IPV6)))
|
|
goto out;
|
|
+ iph = ip_hdr(skb);
|
|
|
|
err = IP_ECN_decapsulate(iph, skb);
|
|
if (unlikely(err)) {
|
|
diff --git a/net/key/af_key.c b/net/key/af_key.c
|
|
index 6482b001f19a..15150b412930 100644
|
|
--- a/net/key/af_key.c
|
|
+++ b/net/key/af_key.c
|
|
@@ -3305,7 +3305,7 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt,
|
|
p += pol->sadb_x_policy_len*8;
|
|
sec_ctx = (struct sadb_x_sec_ctx *)p;
|
|
if (len < pol->sadb_x_policy_len*8 +
|
|
- sec_ctx->sadb_x_sec_len) {
|
|
+ sec_ctx->sadb_x_sec_len*8) {
|
|
*dir = -EINVAL;
|
|
goto out;
|
|
}
|
|
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
|
|
index fb3248ff8b48..ae3438685caa 100644
|
|
--- a/net/l2tp/l2tp_netlink.c
|
|
+++ b/net/l2tp/l2tp_netlink.c
|
|
@@ -732,6 +732,8 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int fl
|
|
|
|
if ((session->ifname[0] &&
|
|
nla_put_string(skb, L2TP_ATTR_IFNAME, session->ifname)) ||
|
|
+ (session->offset &&
|
|
+ nla_put_u16(skb, L2TP_ATTR_OFFSET, session->offset)) ||
|
|
(session->cookie_len &&
|
|
nla_put(skb, L2TP_ATTR_COOKIE, session->cookie_len,
|
|
&session->cookie[0])) ||
|
|
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
|
|
index bb8edb9ef506..1e698768aca8 100644
|
|
--- a/net/llc/af_llc.c
|
|
+++ b/net/llc/af_llc.c
|
|
@@ -309,6 +309,8 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
|
|
int rc = -EINVAL;
|
|
|
|
dprintk("%s: binding %02X\n", __func__, addr->sllc_sap);
|
|
+
|
|
+ lock_sock(sk);
|
|
if (unlikely(!sock_flag(sk, SOCK_ZAPPED) || addrlen != sizeof(*addr)))
|
|
goto out;
|
|
rc = -EAFNOSUPPORT;
|
|
@@ -380,6 +382,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
|
|
out_put:
|
|
llc_sap_put(sap);
|
|
out:
|
|
+ release_sock(sk);
|
|
return rc;
|
|
}
|
|
|
|
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
|
|
index 23095d5e0199..005cd8796505 100644
|
|
--- a/net/mac80211/mlme.c
|
|
+++ b/net/mac80211/mlme.c
|
|
@@ -4326,6 +4326,10 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
|
|
if (WARN_ON(!ifmgd->auth_data && !ifmgd->assoc_data))
|
|
return -EINVAL;
|
|
|
|
+ /* If a reconfig is happening, bail out */
|
|
+ if (local->in_reconfig)
|
|
+ return -EBUSY;
|
|
+
|
|
if (assoc) {
|
|
rcu_read_lock();
|
|
have_sta = sta_info_get(sdata, cbss->bssid);
|
|
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
|
|
index 4ece07c68b3f..c68e020427ab 100644
|
|
--- a/net/netfilter/nf_conntrack_netlink.c
|
|
+++ b/net/netfilter/nf_conntrack_netlink.c
|
|
@@ -887,8 +887,13 @@ restart:
|
|
}
|
|
out:
|
|
local_bh_enable();
|
|
- if (last)
|
|
+ if (last) {
|
|
+ /* nf ct hash resize happened, now clear the leftover. */
|
|
+ if ((struct nf_conn *)cb->args[1] == last)
|
|
+ cb->args[1] = 0;
|
|
+
|
|
nf_ct_put(last);
|
|
+ }
|
|
|
|
return skb->len;
|
|
}
|
|
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
|
|
index 48e1608414e6..98fe9691337c 100644
|
|
--- a/net/netlink/af_netlink.c
|
|
+++ b/net/netlink/af_netlink.c
|
|
@@ -1054,6 +1054,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
|
|
if (addr->sa_family != AF_NETLINK)
|
|
return -EINVAL;
|
|
|
|
+ if (alen < sizeof(struct sockaddr_nl))
|
|
+ return -EINVAL;
|
|
+
|
|
if ((nladdr->nl_groups || nladdr->nl_pid) &&
|
|
!netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
|
|
return -EPERM;
|
|
diff --git a/net/rds/bind.c b/net/rds/bind.c
|
|
index b22ea956522b..e29b47193645 100644
|
|
--- a/net/rds/bind.c
|
|
+++ b/net/rds/bind.c
|
|
@@ -108,6 +108,7 @@ static int rds_add_bound(struct rds_sock *rs, __be32 addr, __be16 *port)
|
|
rs, &addr, (int)ntohs(*port));
|
|
break;
|
|
} else {
|
|
+ rs->rs_bound_addr = 0;
|
|
rds_sock_put(rs);
|
|
ret = -ENOMEM;
|
|
break;
|
|
diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c
|
|
index d7a9ab5a9d9c..6c65fb229e50 100644
|
|
--- a/net/rxrpc/rxkad.c
|
|
+++ b/net/rxrpc/rxkad.c
|
|
@@ -209,7 +209,7 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
|
|
struct sk_buff *trailer;
|
|
unsigned int len;
|
|
u16 check;
|
|
- int nsg;
|
|
+ int nsg, err;
|
|
|
|
sp = rxrpc_skb(skb);
|
|
|
|
@@ -240,7 +240,9 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
|
|
len &= ~(call->conn->size_align - 1);
|
|
|
|
sg_init_table(sg, nsg);
|
|
- skb_to_sgvec(skb, sg, 0, len);
|
|
+ err = skb_to_sgvec(skb, sg, 0, len);
|
|
+ if (unlikely(err < 0))
|
|
+ return err;
|
|
crypto_blkcipher_encrypt_iv(&desc, sg, sg, len);
|
|
|
|
_leave(" = 0");
|
|
@@ -336,7 +338,7 @@ static int rxkad_verify_packet_auth(const struct rxrpc_call *call,
|
|
struct sk_buff *trailer;
|
|
u32 data_size, buf;
|
|
u16 check;
|
|
- int nsg;
|
|
+ int nsg, ret;
|
|
|
|
_enter("");
|
|
|
|
@@ -348,7 +350,9 @@ static int rxkad_verify_packet_auth(const struct rxrpc_call *call,
|
|
goto nomem;
|
|
|
|
sg_init_table(sg, nsg);
|
|
- skb_to_sgvec(skb, sg, 0, 8);
|
|
+ ret = skb_to_sgvec(skb, sg, 0, 8);
|
|
+ if (unlikely(ret < 0))
|
|
+ return ret;
|
|
|
|
/* start the decryption afresh */
|
|
memset(&iv, 0, sizeof(iv));
|
|
@@ -411,7 +415,7 @@ static int rxkad_verify_packet_encrypt(const struct rxrpc_call *call,
|
|
struct sk_buff *trailer;
|
|
u32 data_size, buf;
|
|
u16 check;
|
|
- int nsg;
|
|
+ int nsg, ret;
|
|
|
|
_enter(",{%d}", skb->len);
|
|
|
|
@@ -430,7 +434,12 @@ static int rxkad_verify_packet_encrypt(const struct rxrpc_call *call,
|
|
}
|
|
|
|
sg_init_table(sg, nsg);
|
|
- skb_to_sgvec(skb, sg, 0, skb->len);
|
|
+ ret = skb_to_sgvec(skb, sg, 0, skb->len);
|
|
+ if (unlikely(ret < 0)) {
|
|
+ if (sg != _sg)
|
|
+ kfree(sg);
|
|
+ return ret;
|
|
+ }
|
|
|
|
/* decrypt from the session key */
|
|
token = call->conn->key->payload.data[0];
|
|
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
|
|
index 694a06f1e0d5..f44fea22d69c 100644
|
|
--- a/net/sched/act_api.c
|
|
+++ b/net/sched/act_api.c
|
|
@@ -101,8 +101,10 @@ static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb,
|
|
a->order = n_i;
|
|
|
|
nest = nla_nest_start(skb, a->order);
|
|
- if (nest == NULL)
|
|
+ if (nest == NULL) {
|
|
+ index--;
|
|
goto nla_put_failure;
|
|
+ }
|
|
err = tcf_action_dump_1(skb, a, 0, 0);
|
|
if (err < 0) {
|
|
index--;
|
|
diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c
|
|
index 0bc6f912f870..bd155e59be1c 100644
|
|
--- a/net/sched/act_bpf.c
|
|
+++ b/net/sched/act_bpf.c
|
|
@@ -249,10 +249,14 @@ static int tcf_bpf_init_from_efd(struct nlattr **tb, struct tcf_bpf_cfg *cfg)
|
|
|
|
static void tcf_bpf_cfg_cleanup(const struct tcf_bpf_cfg *cfg)
|
|
{
|
|
- if (cfg->is_ebpf)
|
|
- bpf_prog_put(cfg->filter);
|
|
- else
|
|
- bpf_prog_destroy(cfg->filter);
|
|
+ struct bpf_prog *filter = cfg->filter;
|
|
+
|
|
+ if (filter) {
|
|
+ if (cfg->is_ebpf)
|
|
+ bpf_prog_put(filter);
|
|
+ else
|
|
+ bpf_prog_destroy(filter);
|
|
+ }
|
|
|
|
kfree(cfg->bpf_ops);
|
|
kfree(cfg->bpf_name);
|
|
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
|
|
index 481806b43de8..edb8514b4e00 100644
|
|
--- a/net/sctp/ipv6.c
|
|
+++ b/net/sctp/ipv6.c
|
|
@@ -723,8 +723,10 @@ static int sctp_v6_addr_to_user(struct sctp_sock *sp, union sctp_addr *addr)
|
|
sctp_v6_map_v4(addr);
|
|
}
|
|
|
|
- if (addr->sa.sa_family == AF_INET)
|
|
+ if (addr->sa.sa_family == AF_INET) {
|
|
+ memset(addr->v4.sin_zero, 0, sizeof(addr->v4.sin_zero));
|
|
return sizeof(struct sockaddr_in);
|
|
+ }
|
|
return sizeof(struct sockaddr_in6);
|
|
}
|
|
|
|
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
|
|
index df6a4b2d0728..13c7f42b7040 100644
|
|
--- a/net/sctp/socket.c
|
|
+++ b/net/sctp/socket.c
|
|
@@ -335,11 +335,14 @@ static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt,
|
|
if (!opt->pf->af_supported(addr->sa.sa_family, opt))
|
|
return NULL;
|
|
|
|
- /* V4 mapped address are really of AF_INET family */
|
|
- if (addr->sa.sa_family == AF_INET6 &&
|
|
- ipv6_addr_v4mapped(&addr->v6.sin6_addr) &&
|
|
- !opt->pf->af_supported(AF_INET, opt))
|
|
- return NULL;
|
|
+ if (addr->sa.sa_family == AF_INET6) {
|
|
+ if (len < SIN6_LEN_RFC2133)
|
|
+ return NULL;
|
|
+ /* V4 mapped address are really of AF_INET family */
|
|
+ if (ipv6_addr_v4mapped(&addr->v6.sin6_addr) &&
|
|
+ !opt->pf->af_supported(AF_INET, opt))
|
|
+ return NULL;
|
|
+ }
|
|
|
|
/* If we get this far, af is valid. */
|
|
af = sctp_get_af_specific(addr->sa.sa_family);
|
|
@@ -1518,7 +1521,7 @@ static void sctp_close(struct sock *sk, long timeout)
|
|
|
|
pr_debug("%s: sk:%p, timeout:%ld\n", __func__, sk, timeout);
|
|
|
|
- lock_sock(sk);
|
|
+ lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
|
|
sk->sk_shutdown = SHUTDOWN_MASK;
|
|
sk->sk_state = SCTP_SS_CLOSING;
|
|
|
|
@@ -1569,7 +1572,7 @@ static void sctp_close(struct sock *sk, long timeout)
|
|
* held and that should be grabbed before socket lock.
|
|
*/
|
|
spin_lock_bh(&net->sctp.addr_wq_lock);
|
|
- bh_lock_sock(sk);
|
|
+ bh_lock_sock_nested(sk);
|
|
|
|
/* Hold the sock, since sk_common_release() will put sock_put()
|
|
* and we have just a little more cleanup.
|
|
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
|
|
index 728d65fbab0c..c9c0976d3bbb 100644
|
|
--- a/net/sunrpc/xprtsock.c
|
|
+++ b/net/sunrpc/xprtsock.c
|
|
@@ -2363,7 +2363,12 @@ static void xs_tcp_setup_socket(struct work_struct *work)
|
|
case -EHOSTUNREACH:
|
|
case -EADDRINUSE:
|
|
case -ENOBUFS:
|
|
- /* retry with existing socket, after a delay */
|
|
+ /*
|
|
+ * xs_tcp_force_close() wakes tasks with -EIO.
|
|
+ * We need to wake them first to ensure the
|
|
+ * correct error code.
|
|
+ */
|
|
+ xprt_wake_pending_tasks(xprt, status);
|
|
xs_tcp_force_close(xprt);
|
|
goto out;
|
|
}
|
|
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
|
|
index a750f330b8dd..c6ab4da4b8e2 100644
|
|
--- a/net/x25/af_x25.c
|
|
+++ b/net/x25/af_x25.c
|
|
@@ -1794,32 +1794,40 @@ void x25_kill_by_neigh(struct x25_neigh *nb)
|
|
|
|
static int __init x25_init(void)
|
|
{
|
|
- int rc = proto_register(&x25_proto, 0);
|
|
+ int rc;
|
|
|
|
- if (rc != 0)
|
|
+ rc = proto_register(&x25_proto, 0);
|
|
+ if (rc)
|
|
goto out;
|
|
|
|
rc = sock_register(&x25_family_ops);
|
|
- if (rc != 0)
|
|
+ if (rc)
|
|
goto out_proto;
|
|
|
|
dev_add_pack(&x25_packet_type);
|
|
|
|
rc = register_netdevice_notifier(&x25_dev_notifier);
|
|
- if (rc != 0)
|
|
+ if (rc)
|
|
goto out_sock;
|
|
|
|
- pr_info("Linux Version 0.2\n");
|
|
+ rc = x25_register_sysctl();
|
|
+ if (rc)
|
|
+ goto out_dev;
|
|
|
|
- x25_register_sysctl();
|
|
rc = x25_proc_init();
|
|
- if (rc != 0)
|
|
- goto out_dev;
|
|
+ if (rc)
|
|
+ goto out_sysctl;
|
|
+
|
|
+ pr_info("Linux Version 0.2\n");
|
|
+
|
|
out:
|
|
return rc;
|
|
+out_sysctl:
|
|
+ x25_unregister_sysctl();
|
|
out_dev:
|
|
unregister_netdevice_notifier(&x25_dev_notifier);
|
|
out_sock:
|
|
+ dev_remove_pack(&x25_packet_type);
|
|
sock_unregister(AF_X25);
|
|
out_proto:
|
|
proto_unregister(&x25_proto);
|
|
diff --git a/net/x25/sysctl_net_x25.c b/net/x25/sysctl_net_x25.c
|
|
index 43239527a205..703d46aae7a2 100644
|
|
--- a/net/x25/sysctl_net_x25.c
|
|
+++ b/net/x25/sysctl_net_x25.c
|
|
@@ -73,9 +73,12 @@ static struct ctl_table x25_table[] = {
|
|
{ 0, },
|
|
};
|
|
|
|
-void __init x25_register_sysctl(void)
|
|
+int __init x25_register_sysctl(void)
|
|
{
|
|
x25_table_header = register_net_sysctl(&init_net, "net/x25", x25_table);
|
|
+ if (!x25_table_header)
|
|
+ return -ENOMEM;
|
|
+ return 0;
|
|
}
|
|
|
|
void x25_unregister_sysctl(void)
|
|
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
|
|
index 34b5b4bcf5cb..62d87f859566 100644
|
|
--- a/net/xfrm/xfrm_state.c
|
|
+++ b/net/xfrm/xfrm_state.c
|
|
@@ -1208,6 +1208,8 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig)
|
|
x->curlft.add_time = orig->curlft.add_time;
|
|
x->km.state = orig->km.state;
|
|
x->km.seq = orig->km.seq;
|
|
+ x->replay = orig->replay;
|
|
+ x->preplay = orig->preplay;
|
|
|
|
return x;
|
|
|
|
diff --git a/scripts/tags.sh b/scripts/tags.sh
|
|
index 262889046703..45e246595d10 100755
|
|
--- a/scripts/tags.sh
|
|
+++ b/scripts/tags.sh
|
|
@@ -106,6 +106,7 @@ all_compiled_sources()
|
|
case "$i" in
|
|
*.[cS])
|
|
j=${i/\.[cS]/\.o}
|
|
+ j="${j#$tree}"
|
|
if [ -e $j ]; then
|
|
echo $i
|
|
fi
|
|
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
|
|
index 4f690ab0feed..99212ff6a568 100644
|
|
--- a/security/selinux/hooks.c
|
|
+++ b/security/selinux/hooks.c
|
|
@@ -1942,8 +1942,9 @@ static inline u32 file_to_av(struct file *file)
|
|
static inline u32 open_file_to_av(struct file *file)
|
|
{
|
|
u32 av = file_to_av(file);
|
|
+ struct inode *inode = file_inode(file);
|
|
|
|
- if (selinux_policycap_openperm)
|
|
+ if (selinux_policycap_openperm && inode->i_sb->s_magic != SOCKFS_MAGIC)
|
|
av |= FILE__OPEN;
|
|
|
|
return av;
|
|
@@ -2912,6 +2913,7 @@ static int selinux_inode_permission(struct inode *inode, int mask)
|
|
static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
|
|
{
|
|
const struct cred *cred = current_cred();
|
|
+ struct inode *inode = d_backing_inode(dentry);
|
|
unsigned int ia_valid = iattr->ia_valid;
|
|
__u32 av = FILE__WRITE;
|
|
|
|
@@ -2927,8 +2929,10 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
|
|
ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
|
|
return dentry_has_perm(cred, dentry, FILE__SETATTR);
|
|
|
|
- if (selinux_policycap_openperm && (ia_valid & ATTR_SIZE)
|
|
- && !(ia_valid & ATTR_FILE))
|
|
+ if (selinux_policycap_openperm &&
|
|
+ inode->i_sb->s_magic != SOCKFS_MAGIC &&
|
|
+ (ia_valid & ATTR_SIZE) &&
|
|
+ !(ia_valid & ATTR_FILE))
|
|
av |= FILE__OPEN;
|
|
|
|
return dentry_has_perm(cred, dentry, av);
|
|
diff --git a/sound/soc/intel/atom/sst/sst_stream.c b/sound/soc/intel/atom/sst/sst_stream.c
|
|
index a74c64c7053c..e83da42a8c03 100644
|
|
--- a/sound/soc/intel/atom/sst/sst_stream.c
|
|
+++ b/sound/soc/intel/atom/sst/sst_stream.c
|
|
@@ -221,7 +221,7 @@ int sst_send_byte_stream_mrfld(struct intel_sst_drv *sst_drv_ctx,
|
|
sst_free_block(sst_drv_ctx, block);
|
|
out:
|
|
test_and_clear_bit(pvt_id, &sst_drv_ctx->pvt_id);
|
|
- return 0;
|
|
+ return ret;
|
|
}
|
|
|
|
/*
|
|
diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c
|
|
index 38d65a3529c4..44d560966e9c 100644
|
|
--- a/sound/soc/intel/boards/cht_bsw_rt5645.c
|
|
+++ b/sound/soc/intel/boards/cht_bsw_rt5645.c
|
|
@@ -96,6 +96,7 @@ static const struct snd_soc_dapm_widget cht_dapm_widgets[] = {
|
|
SND_SOC_DAPM_HP("Headphone", NULL),
|
|
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
|
SND_SOC_DAPM_MIC("Int Mic", NULL),
|
|
+ SND_SOC_DAPM_MIC("Int Analog Mic", NULL),
|
|
SND_SOC_DAPM_SPK("Ext Spk", NULL),
|
|
SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
|
|
platform_clock_control, SND_SOC_DAPM_POST_PMD),
|
|
@@ -106,6 +107,8 @@ static const struct snd_soc_dapm_route cht_rt5645_audio_map[] = {
|
|
{"IN1N", NULL, "Headset Mic"},
|
|
{"DMIC L1", NULL, "Int Mic"},
|
|
{"DMIC R1", NULL, "Int Mic"},
|
|
+ {"IN2P", NULL, "Int Analog Mic"},
|
|
+ {"IN2N", NULL, "Int Analog Mic"},
|
|
{"Headphone", NULL, "HPOL"},
|
|
{"Headphone", NULL, "HPOR"},
|
|
{"Ext Spk", NULL, "SPOL"},
|
|
@@ -119,6 +122,9 @@ static const struct snd_soc_dapm_route cht_rt5645_audio_map[] = {
|
|
{"Headphone", NULL, "Platform Clock"},
|
|
{"Headset Mic", NULL, "Platform Clock"},
|
|
{"Int Mic", NULL, "Platform Clock"},
|
|
+ {"Int Analog Mic", NULL, "Platform Clock"},
|
|
+ {"Int Analog Mic", NULL, "micbias1"},
|
|
+ {"Int Analog Mic", NULL, "micbias2"},
|
|
{"Ext Spk", NULL, "Platform Clock"},
|
|
};
|
|
|
|
@@ -147,6 +153,7 @@ static const struct snd_kcontrol_new cht_mc_controls[] = {
|
|
SOC_DAPM_PIN_SWITCH("Headphone"),
|
|
SOC_DAPM_PIN_SWITCH("Headset Mic"),
|
|
SOC_DAPM_PIN_SWITCH("Int Mic"),
|
|
+ SOC_DAPM_PIN_SWITCH("Int Analog Mic"),
|
|
SOC_DAPM_PIN_SWITCH("Ext Spk"),
|
|
};
|
|
|
|
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
|
|
index a001331a53c1..df79d7c846ea 100644
|
|
--- a/sound/soc/sh/rcar/ssi.c
|
|
+++ b/sound/soc/sh/rcar/ssi.c
|
|
@@ -453,6 +453,13 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
|
|
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
|
u32 *buf = (u32 *)(runtime->dma_area +
|
|
rsnd_dai_pointer_offset(io, 0));
|
|
+ int shift = 0;
|
|
+
|
|
+ switch (runtime->sample_bits) {
|
|
+ case 32:
|
|
+ shift = 8;
|
|
+ break;
|
|
+ }
|
|
|
|
/*
|
|
* 8/16/32 data can be assesse to TDR/RDR register
|
|
@@ -460,9 +467,9 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
|
|
* see rsnd_ssi_init()
|
|
*/
|
|
if (rsnd_io_is_play(io))
|
|
- rsnd_mod_write(mod, SSITDR, *buf);
|
|
+ rsnd_mod_write(mod, SSITDR, (*buf) << shift);
|
|
else
|
|
- *buf = rsnd_mod_read(mod, SSIRDR);
|
|
+ *buf = (rsnd_mod_read(mod, SSIRDR) >> shift);
|
|
|
|
elapsed = rsnd_dai_pointer_update(io, sizeof(*buf));
|
|
}
|
|
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
|
|
index ebe7115c751a..da8afc121118 100644
|
|
--- a/tools/perf/builtin-trace.c
|
|
+++ b/tools/perf/builtin-trace.c
|
|
@@ -1152,6 +1152,10 @@ static struct syscall_fmt {
|
|
{ .name = "mlockall", .errmsg = true,
|
|
.arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
|
|
{ .name = "mmap", .hexret = true,
|
|
+/* The standard mmap maps to old_mmap on s390x */
|
|
+#if defined(__s390x__)
|
|
+ .alias = "old_mmap",
|
|
+#endif
|
|
.arg_scnprintf = { [0] = SCA_HEX, /* addr */
|
|
[2] = SCA_MMAP_PROT, /* prot */
|
|
[3] = SCA_MMAP_FLAGS, /* flags */
|
|
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
|
|
index a767a6400c5c..6ea4fcfaab36 100644
|
|
--- a/tools/perf/tests/code-reading.c
|
|
+++ b/tools/perf/tests/code-reading.c
|
|
@@ -182,6 +182,8 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
|
|
unsigned char buf2[BUFSZ];
|
|
size_t ret_len;
|
|
u64 objdump_addr;
|
|
+ const char *objdump_name;
|
|
+ char decomp_name[KMOD_DECOMP_LEN];
|
|
int ret;
|
|
|
|
pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr);
|
|
@@ -242,9 +244,25 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
|
|
state->done[state->done_cnt++] = al.map->start;
|
|
}
|
|
|
|
+ objdump_name = al.map->dso->long_name;
|
|
+ if (dso__needs_decompress(al.map->dso)) {
|
|
+ if (dso__decompress_kmodule_path(al.map->dso, objdump_name,
|
|
+ decomp_name,
|
|
+ sizeof(decomp_name)) < 0) {
|
|
+ pr_debug("decompression failed\n");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ objdump_name = decomp_name;
|
|
+ }
|
|
+
|
|
/* Read the object code using objdump */
|
|
objdump_addr = map__rip_2objdump(al.map, al.addr);
|
|
- ret = read_via_objdump(al.map->dso->long_name, objdump_addr, buf2, len);
|
|
+ ret = read_via_objdump(objdump_name, objdump_addr, buf2, len);
|
|
+
|
|
+ if (dso__needs_decompress(al.map->dso))
|
|
+ unlink(objdump_name);
|
|
+
|
|
if (ret > 0) {
|
|
/*
|
|
* The kernel maps are inaccurate - assume objdump is right in
|
|
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
|
|
index 43838003c1a1..304f5d710143 100644
|
|
--- a/tools/perf/util/header.c
|
|
+++ b/tools/perf/util/header.c
|
|
@@ -1258,8 +1258,16 @@ static int __event_process_build_id(struct build_id_event *bev,
|
|
|
|
dso__set_build_id(dso, &bev->build_id);
|
|
|
|
- if (!is_kernel_module(filename, cpumode))
|
|
- dso->kernel = dso_type;
|
|
+ if (dso_type != DSO_TYPE_USER) {
|
|
+ struct kmod_path m = { .name = NULL, };
|
|
+
|
|
+ if (!kmod_path__parse_name(&m, filename) && m.kmod)
|
|
+ dso__set_short_name(dso, strdup(m.name), true);
|
|
+ else
|
|
+ dso->kernel = dso_type;
|
|
+
|
|
+ free(m.name);
|
|
+ }
|
|
|
|
build_id__sprintf(dso->build_id, sizeof(dso->build_id),
|
|
sbuild_id);
|
|
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
|
|
index 03875f9154e7..0195b7e8c54a 100644
|
|
--- a/tools/perf/util/probe-event.c
|
|
+++ b/tools/perf/util/probe-event.c
|
|
@@ -2349,6 +2349,14 @@ static int get_new_event_name(char *buf, size_t len, const char *base,
|
|
|
|
out:
|
|
free(nbase);
|
|
+
|
|
+ /* Final validation */
|
|
+ if (ret >= 0 && !is_c_func_name(buf)) {
|
|
+ pr_warning("Internal error: \"%s\" is an invalid event name.\n",
|
|
+ buf);
|
|
+ ret = -EINVAL;
|
|
+ }
|
|
+
|
|
return ret;
|
|
}
|
|
|
|
diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c
|
|
index 2dcfe9a7c8d0..60edec383281 100644
|
|
--- a/tools/perf/util/unwind-libdw.c
|
|
+++ b/tools/perf/util/unwind-libdw.c
|
|
@@ -37,6 +37,14 @@ static int __report_module(struct addr_location *al, u64 ip,
|
|
return 0;
|
|
|
|
mod = dwfl_addrmodule(ui->dwfl, ip);
|
|
+ if (mod) {
|
|
+ Dwarf_Addr s;
|
|
+
|
|
+ dwfl_module_info(mod, NULL, &s, NULL, NULL, NULL, NULL, NULL);
|
|
+ if (s != al->map->start)
|
|
+ mod = 0;
|
|
+ }
|
|
+
|
|
if (!mod)
|
|
mod = dwfl_report_elf(ui->dwfl, dso->short_name,
|
|
dso->long_name, -1, al->map->start,
|
|
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
|
|
index 47b1e36c7ea0..9adc9af8b048 100644
|
|
--- a/tools/perf/util/util.c
|
|
+++ b/tools/perf/util/util.c
|
|
@@ -162,7 +162,7 @@ int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size)
|
|
|
|
size -= ret;
|
|
off_in += ret;
|
|
- off_out -= ret;
|
|
+ off_out += ret;
|
|
}
|
|
munmap(ptr, off_in + size);
|
|
|
|
diff --git a/tools/testing/selftests/powerpc/tm/tm-resched-dscr.c b/tools/testing/selftests/powerpc/tm/tm-resched-dscr.c
|
|
index 42d4c8caad81..de8dc82e2567 100644
|
|
--- a/tools/testing/selftests/powerpc/tm/tm-resched-dscr.c
|
|
+++ b/tools/testing/selftests/powerpc/tm/tm-resched-dscr.c
|
|
@@ -45,12 +45,12 @@ int test_body(void)
|
|
printf("Check DSCR TM context switch: ");
|
|
fflush(stdout);
|
|
for (;;) {
|
|
- rv = 1;
|
|
asm __volatile__ (
|
|
/* set a known value into the DSCR */
|
|
"ld 3, %[dscr1];"
|
|
"mtspr %[sprn_dscr], 3;"
|
|
|
|
+ "li %[rv], 1;"
|
|
/* start and suspend a transaction */
|
|
TBEGIN
|
|
"beq 1f;"
|