]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
Merge branch 'rcu-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 18 Jan 2017 18:47:11 +0000 (10:47 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 18 Jan 2017 18:47:11 +0000 (10:47 -0800)
Pull RCU fixes from Ingo Molnar:
 "This fixes sporadic ACPI related hangs in synchronize_rcu() that were
  caused by the ACPI code mistakenly relying on an aspect of RCU that
  was neither promised to work nor reliable but which happened to work -
  until in v4.9 we changed the RCU implementation, which made the hangs
  more prominent.

  Since the mis-use of the RCU facility wasn't properly detected and
  prevented either, these fixes make the RCU side work reliably instead
  of working around the problem in the ACPI code.

  Hence the slightly larger diffstat that goes beyond the normal scope
  of RCU fixes in -rc kernels"

* 'rcu-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  rcu: Narrow early boot window of illegal synchronous grace periods
  rcu: Remove cond_resched() from Tiny synchronize_sched()

166 files changed:
Documentation/ABI/testing/sysfs-devices-deferred_probe [deleted file]
Documentation/devicetree/bindings/i2c/i2c.txt
Documentation/devicetree/bindings/mtd/tango-nand.txt
Documentation/devicetree/bindings/net/ti,dp83867.txt
Makefile
arch/x86/boot/string.c
arch/x86/boot/string.h
arch/x86/entry/entry_32.S
arch/x86/entry/entry_64.S
arch/x86/events/core.c
arch/x86/events/intel/core.c
arch/x86/events/intel/cstate.c
arch/x86/events/intel/ds.c
arch/x86/events/intel/rapl.c
arch/x86/events/intel/uncore.c
arch/x86/events/intel/uncore_snbep.c
arch/x86/include/asm/intel-family.h
arch/x86/include/asm/microcode_intel.h
arch/x86/include/asm/processor.h
arch/x86/include/asm/stacktrace.h
arch/x86/include/asm/switch_to.h
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/cpu/microcode/intel.c
arch/x86/kernel/tsc.c
arch/x86/kernel/unwind_frame.c
arch/x86/mm/mpx.c
arch/x86/platform/efi/efi.c
arch/x86/platform/efi/quirks.c
arch/x86/platform/intel-mid/device_libs/Makefile
arch/x86/platform/intel-mid/device_libs/platform_mrfld_spidev.c [new file with mode: 0644]
arch/x86/platform/intel-mid/device_libs/platform_spidev.c [deleted file]
drivers/auxdisplay/Kconfig
drivers/base/base.h
drivers/base/core.c
drivers/base/dd.c
drivers/char/mem.c
drivers/char/ppdev.c
drivers/extcon/extcon.c
drivers/firmware/efi/fake_mem.c
drivers/firmware/efi/libstub/efistub.h
drivers/firmware/efi/libstub/fdt.c
drivers/firmware/efi/memmap.c
drivers/i2c/busses/i2c-piix4.c
drivers/i2c/i2c-core.c
drivers/i2c/i2c-dev.c
drivers/misc/mei/bus-fixup.c
drivers/misc/mei/debugfs.c
drivers/misc/mei/hbm.c
drivers/misc/mei/hw.h
drivers/misc/mei/mei_dev.h
drivers/mmc/core/mmc_ops.c
drivers/mmc/host/meson-gx-mmc.c
drivers/mmc/host/mxs-mmc.c
drivers/mmc/host/sdhci-acpi.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/lpc32xx_mlc.c
drivers/mtd/nand/tango_nand.c
drivers/mtd/nand/xway_nand.c
drivers/net/ethernet/broadcom/bcmsysport.c
drivers/net/ethernet/cavium/thunder/thunder_bgx.c
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/mellanox/mlx4/cq.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/mellanox/mlx4/eq.c
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mellanox/mlxsw/switchx2.c
drivers/net/ethernet/qualcomm/emac/emac-phy.c
drivers/net/ethernet/qualcomm/emac/emac.c
drivers/net/ethernet/renesas/ravb_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/ti/cpmac.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/ieee802154/at86rf230.c
drivers/net/ieee802154/atusb.c
drivers/net/phy/dp83867.c
drivers/net/usb/r8152.c
drivers/net/vxlan.c
drivers/tty/serial/8250/8250_core.c
drivers/tty/serial/8250/8250_pci.c
drivers/tty/serial/8250/8250_port.c
drivers/tty/serial/atmel_serial.c
drivers/tty/sysrq.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/musb/musb_debugfs.c
drivers/usb/serial/ch341.c
drivers/usb/serial/kl5kusb105.c
drivers/usb/wusbcore/crypto.c
drivers/vme/bridges/vme_ca91cx42.c
fs/dcache.c
fs/libfs.c
fs/namespace.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/proc/proc_sysctl.c
include/linux/bpf.h
include/linux/efi.h
include/linux/filter.h
include/linux/i2c.h
include/linux/kernel.h
include/linux/perf_event.h
include/linux/sunrpc/svc_xprt.h
include/linux/tcp.h
include/uapi/linux/nl80211.h
include/uapi/linux/pkt_cls.h
include/uapi/linux/tc_act/tc_bpf.h
kernel/bpf/core.c
kernel/bpf/syscall.c
kernel/bpf/verifier.c
kernel/events/core.c
kernel/module.c
kernel/panic.c
kernel/pid_namespace.c
kernel/time/tick-sched.c
kernel/time/tick-sched.h
lib/swiotlb.c
net/ax25/ax25_subr.c
net/ipv4/fib_semantics.c
net/ipv4/route.c
net/ipv4/tcp_fastopen.c
net/ipv6/ip6_tunnel.c
net/ipv6/mcast.c
net/ipv6/route.c
net/ipv6/seg6_hmac.c
net/ipv6/seg6_iptunnel.c
net/mac80211/chan.c
net/mac80211/iface.c
net/mac80211/main.c
net/mac80211/rate.c
net/mac80211/rx.c
net/mac80211/sta_info.c
net/mac80211/tx.c
net/mac80211/vht.c
net/openvswitch/conntrack.c
net/sched/act_api.c
net/sched/act_bpf.c
net/sched/cls_bpf.c
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/svc_xprt.c
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
net/tipc/discover.c
net/tipc/link.c
net/tipc/msg.c
net/tipc/msg.h
net/tipc/name_distr.c
net/wireless/nl80211.c
samples/bpf/sock_example.h
samples/bpf/trace_output_user.c
tools/lib/subcmd/parse-options.c
tools/lib/subcmd/parse-options.h
tools/lib/traceevent/plugin_sched_switch.c
tools/perf/Documentation/perf-record.txt
tools/perf/Makefile.perf
tools/perf/builtin-record.c
tools/perf/builtin-sched.c
tools/perf/util/probe-event.c
tools/perf/util/probe-finder.c
tools/perf/util/probe-finder.h
tools/perf/util/symbol-elf.c

diff --git a/Documentation/ABI/testing/sysfs-devices-deferred_probe b/Documentation/ABI/testing/sysfs-devices-deferred_probe
deleted file mode 100644 (file)
index 58553d7..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-What:          /sys/devices/.../deferred_probe
-Date:          August 2016
-Contact:       Ben Hutchings <ben.hutchings@codethink.co.uk>
-Description:
-               The /sys/devices/.../deferred_probe attribute is
-               present for all devices.  If a driver detects during
-               probing a device that a related device is not yet
-               ready, it may defer probing of the first device.  The
-               kernel will retry probing the first device after any
-               other device is successfully probed.  This attribute
-               reads as 1 if probing of this device is currently
-               deferred, or 0 otherwise.
index 5fa691e6f6388320acd4199995ef0072e9e70faa..cee9d5055fa27c7593f5a9da09661c4f7eed9647 100644 (file)
@@ -62,6 +62,9 @@ wants to support one of the below features, it should adapt the bindings below.
        "irq" and "wakeup" names are recognized by I2C core, other names are
        left to individual drivers.
 
+- host-notify
+       device uses SMBus host notify protocol instead of interrupt line.
+
 - multi-master
        states that there is another master active on this bus. The OS can use
        this information to adapt power management to keep the arbitration awake
@@ -81,6 +84,11 @@ Binding may contain optional "interrupts" property, describing interrupts
 used by the device. I2C core will assign "irq" interrupt (or the very first
 interrupt if not using interrupt names) as primary interrupt for the slave.
 
+Alternatively, devices supporting SMbus Host Notify, and connected to
+adapters that support this feature, may use "host-notify" property. I2C
+core will create a virtual interrupt for Host Notify and assign it as
+primary interrupt for the slave.
+
 Also, if device is marked as a wakeup source, I2C core will set up "wakeup"
 interrupt for the device. If "wakeup" interrupt name is not present in the
 binding, then primary interrupt will be used as wakeup interrupt.
index ad5a02f2ac8c9da32eb72192ba9f313fa82d2e4b..cd1bf2ac9055fc3561dbf6da805c8aa5ca3ea49c 100644 (file)
@@ -5,7 +5,7 @@ Required properties:
 - compatible: "sigma,smp8758-nand"
 - reg: address/size of nfc_reg, nfc_mem, and pbus_reg
 - dmas: reference to the DMA channel used by the controller
-- dma-names: "nfc_sbox"
+- dma-names: "rxtx"
 - clocks: reference to the system clock
 - #address-cells: <1>
 - #size-cells: <0>
@@ -17,9 +17,9 @@ Example:
 
        nandc: nand-controller@2c000 {
                compatible = "sigma,smp8758-nand";
-               reg = <0x2c000 0x30 0x2d000 0x800 0x20000 0x1000>;
+               reg = <0x2c000 0x30>, <0x2d000 0x800>, <0x20000 0x1000>;
                dmas = <&dma0 3>;
-               dma-names = "nfc_sbox";
+               dma-names = "rxtx";
                clocks = <&clkgen SYS_CLK>;
                #address-cells = <1>;
                #size-cells = <0>;
index 85bf945b898f0d156702f16d76be315c9108e1aa..afe9630a5e7de1ff01806675d6a8908cc200d465 100644 (file)
@@ -3,9 +3,11 @@
 Required properties:
        - reg - The ID number for the phy, usually a small integer
        - ti,rx-internal-delay - RGMII Receive Clock Delay - see dt-bindings/net/ti-dp83867.h
-               for applicable values
+               for applicable values. Required only if interface type is
+               PHY_INTERFACE_MODE_RGMII_ID or PHY_INTERFACE_MODE_RGMII_RXID
        - ti,tx-internal-delay - RGMII Transmit Clock Delay - see dt-bindings/net/ti-dp83867.h
-               for applicable values
+               for applicable values. Required only if interface type is
+               PHY_INTERFACE_MODE_RGMII_ID or PHY_INTERFACE_MODE_RGMII_TXID
        - ti,fifo-depth - Transmitt FIFO depth- see dt-bindings/net/ti-dp83867.h
                for applicable values
 
index 5f1a84735ff61a18fddd4bbad964f8ac89ecc8e4..96e2352d10a8cc830812b819cfebb888603c4038 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 4
 PATCHLEVEL = 10
 SUBLEVEL = 0
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc4
 NAME = Roaring Lionus
 
 # *DOCUMENTATION*
index cc3bd583dce1abc5fafe6b92417b8a713cd4cdfd..9e240fcba784b085bd55e77dc79c08d21d1a23e2 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/types.h>
 #include "ctype.h"
+#include "string.h"
 
 int memcmp(const void *s1, const void *s2, size_t len)
 {
index 725e820602b1781308b863a10c105dd3d2734d31..113588ddb43f8d7e7be66283118a2f33c46fb7e1 100644 (file)
@@ -18,4 +18,13 @@ int memcmp(const void *s1, const void *s2, size_t len);
 #define memset(d,c,l) __builtin_memset(d,c,l)
 #define memcmp __builtin_memcmp
 
+extern int strcmp(const char *str1, const char *str2);
+extern int strncmp(const char *cs, const char *ct, size_t count);
+extern size_t strlen(const char *s);
+extern char *strstr(const char *s1, const char *s2);
+extern size_t strnlen(const char *s, size_t maxlen);
+extern unsigned int atou(const char *s);
+extern unsigned long long simple_strtoull(const char *cp, char **endp,
+                                         unsigned int base);
+
 #endif /* BOOT_STRING_H */
index 701d29f8e4d300ac01553e5d8317a5e40dbdcc6d..57f7ec35216ef5e2a78efa0d303f8f343b010d68 100644 (file)
@@ -254,23 +254,6 @@ ENTRY(__switch_to_asm)
        jmp     __switch_to
 END(__switch_to_asm)
 
-/*
- * The unwinder expects the last frame on the stack to always be at the same
- * offset from the end of the page, which allows it to validate the stack.
- * Calling schedule_tail() directly would break that convention because its an
- * asmlinkage function so its argument has to be pushed on the stack.  This
- * wrapper creates a proper "end of stack" frame header before the call.
- */
-ENTRY(schedule_tail_wrapper)
-       FRAME_BEGIN
-
-       pushl   %eax
-       call    schedule_tail
-       popl    %eax
-
-       FRAME_END
-       ret
-ENDPROC(schedule_tail_wrapper)
 /*
  * A newly forked process directly context switches into this address.
  *
@@ -279,15 +262,24 @@ ENDPROC(schedule_tail_wrapper)
  * edi: kernel thread arg
  */
 ENTRY(ret_from_fork)
-       call    schedule_tail_wrapper
+       FRAME_BEGIN             /* help unwinder find end of stack */
+
+       /*
+        * schedule_tail() is asmlinkage so we have to put its 'prev' argument
+        * on the stack.
+        */
+       pushl   %eax
+       call    schedule_tail
+       popl    %eax
 
        testl   %ebx, %ebx
        jnz     1f              /* kernel threads are uncommon */
 
 2:
        /* When we fork, we trace the syscall return in the child, too. */
-       movl    %esp, %eax
+       leal    FRAME_OFFSET(%esp), %eax
        call    syscall_return_slowpath
+       FRAME_END
        jmp     restore_all
 
        /* kernel thread */
index 5b219707c2f236cfcf1a856cf9a5023dd93775c3..044d18ebc43ce96a512abd1e5f36eb8dfaee0636 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/smap.h>
 #include <asm/pgtable_types.h>
 #include <asm/export.h>
+#include <asm/frame.h>
 #include <linux/err.h>
 
 .code64
@@ -408,17 +409,19 @@ END(__switch_to_asm)
  * r12: kernel thread arg
  */
 ENTRY(ret_from_fork)
+       FRAME_BEGIN                     /* help unwinder find end of stack */
        movq    %rax, %rdi
-       call    schedule_tail                   /* rdi: 'prev' task parameter */
+       call    schedule_tail           /* rdi: 'prev' task parameter */
 
-       testq   %rbx, %rbx                      /* from kernel_thread? */
-       jnz     1f                              /* kernel threads are uncommon */
+       testq   %rbx, %rbx              /* from kernel_thread? */
+       jnz     1f                      /* kernel threads are uncommon */
 
 2:
-       movq    %rsp, %rdi
+       leaq    FRAME_OFFSET(%rsp),%rdi /* pt_regs pointer */
        call    syscall_return_slowpath /* returns with IRQs disabled */
        TRACE_IRQS_ON                   /* user mode is traced as IRQS on */
        SWAPGS
+       FRAME_END
        jmp     restore_regs_and_iret
 
 1:
index 019c5887b698af2a5fbf322c7cc5d6d3f8ab7e57..1635c0c8df23a697a93a8a7bd0dbbfd534c3caef 100644 (file)
@@ -505,6 +505,10 @@ int x86_pmu_hw_config(struct perf_event *event)
 
                if (event->attr.precise_ip > precise)
                        return -EOPNOTSUPP;
+
+               /* There's no sense in having PEBS for non sampling events: */
+               if (!is_sampling_event(event))
+                       return -EINVAL;
        }
        /*
         * check that PEBS LBR correction does not conflict with
index 86138267b68a77753737ffd4c4be2ece6a24cc84..eb1484c86bb4b4611450c49df01aab1a18d8fa5f 100644 (file)
@@ -3176,13 +3176,16 @@ static void intel_pmu_cpu_starting(int cpu)
 
        if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) {
                for_each_cpu(i, topology_sibling_cpumask(cpu)) {
+                       struct cpu_hw_events *sibling;
                        struct intel_excl_cntrs *c;
 
-                       c = per_cpu(cpu_hw_events, i).excl_cntrs;
+                       sibling = &per_cpu(cpu_hw_events, i);
+                       c = sibling->excl_cntrs;
                        if (c && c->core_id == core_id) {
                                cpuc->kfree_on_online[1] = cpuc->excl_cntrs;
                                cpuc->excl_cntrs = c;
-                               cpuc->excl_thread_id = 1;
+                               if (!sibling->excl_thread_id)
+                                       cpuc->excl_thread_id = 1;
                                break;
                        }
                }
@@ -3987,7 +3990,7 @@ __init int intel_pmu_init(void)
                     x86_pmu.num_counters, INTEL_PMC_MAX_GENERIC);
                x86_pmu.num_counters = INTEL_PMC_MAX_GENERIC;
        }
-       x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1;
+       x86_pmu.intel_ctrl = (1ULL << x86_pmu.num_counters) - 1;
 
        if (x86_pmu.num_counters_fixed > INTEL_PMC_MAX_FIXED) {
                WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!",
index fec8a461bdef6da49c0e7f46c655f235e7fc1275..1076c9a77292d77e5dbb34adbd5ce526121daa73 100644 (file)
@@ -434,6 +434,7 @@ static struct pmu cstate_core_pmu = {
        .stop           = cstate_pmu_event_stop,
        .read           = cstate_pmu_event_update,
        .capabilities   = PERF_PMU_CAP_NO_INTERRUPT,
+       .module         = THIS_MODULE,
 };
 
 static struct pmu cstate_pkg_pmu = {
@@ -447,6 +448,7 @@ static struct pmu cstate_pkg_pmu = {
        .stop           = cstate_pmu_event_stop,
        .read           = cstate_pmu_event_update,
        .capabilities   = PERF_PMU_CAP_NO_INTERRUPT,
+       .module         = THIS_MODULE,
 };
 
 static const struct cstate_model nhm_cstates __initconst = {
index be202390bbd37b00106864123a647786497ce2cd..9dfeeeca0ea8f11a3beb4c23eeb1d115e77189db 100644 (file)
@@ -1389,9 +1389,13 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
                        continue;
 
                /* log dropped samples number */
-               if (error[bit])
+               if (error[bit]) {
                        perf_log_lost_samples(event, error[bit]);
 
+                       if (perf_event_account_interrupt(event))
+                               x86_pmu_stop(event, 0);
+               }
+
                if (counts[bit]) {
                        __intel_pmu_pebs_event(event, iregs, base,
                                               top, bit, counts[bit]);
index bd34124449b08a4be95f114b3295c22e4d57cd34..17c3564d087a48bc24e41417fe6f128b5d7b9f0d 100644 (file)
@@ -697,6 +697,7 @@ static int __init init_rapl_pmus(void)
        rapl_pmus->pmu.start            = rapl_pmu_event_start;
        rapl_pmus->pmu.stop             = rapl_pmu_event_stop;
        rapl_pmus->pmu.read             = rapl_pmu_event_read;
+       rapl_pmus->pmu.module           = THIS_MODULE;
        return 0;
 }
 
index 97c246f84dea1e79d0f4517376763dcb88a18aea..8c4ccdc3a3f3607ee0af4f4006029df3000e0839 100644 (file)
@@ -733,6 +733,7 @@ static int uncore_pmu_register(struct intel_uncore_pmu *pmu)
                        .start          = uncore_pmu_event_start,
                        .stop           = uncore_pmu_event_stop,
                        .read           = uncore_pmu_event_read,
+                       .module         = THIS_MODULE,
                };
        } else {
                pmu->pmu = *pmu->type->pmu;
index e6832be714bc6e76965e1faa7cedcc3ad309c8fa..dae2fedc16015e691ad6ae85ce4bc4122011eefc 100644 (file)
@@ -2686,7 +2686,7 @@ static struct intel_uncore_type *hswep_msr_uncores[] = {
 
 void hswep_uncore_cpu_init(void)
 {
-       int pkg = topology_phys_to_logical_pkg(0);
+       int pkg = boot_cpu_data.logical_proc_id;
 
        if (hswep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
                hswep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
index 34a46dc076d3610212e6f5c9f0abfb2ab9bc3629..8167fdb67ae846a0da668006159abfc56f3d99fc 100644 (file)
@@ -57,7 +57,7 @@
 #define INTEL_FAM6_ATOM_SILVERMONT2    0x4D /* Avaton/Rangely */
 #define INTEL_FAM6_ATOM_AIRMONT                0x4C /* CherryTrail / Braswell */
 #define INTEL_FAM6_ATOM_MERRIFIELD     0x4A /* Tangier */
-#define INTEL_FAM6_ATOM_MOOREFIELD     0x5A /* Annidale */
+#define INTEL_FAM6_ATOM_MOOREFIELD     0x5A /* Anniedale */
 #define INTEL_FAM6_ATOM_GOLDMONT       0x5C
 #define INTEL_FAM6_ATOM_DENVERTON      0x5F /* Goldmont Microserver */
 
index 195becc6f78074f23f25dc7d5d14da4bd90aac76..e793fc9a9b20c36d2e0d0e8e2a359fd1c70f2d8e 100644 (file)
@@ -52,6 +52,21 @@ struct extended_sigtable {
 
 #define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE)
 
+static inline u32 intel_get_microcode_revision(void)
+{
+       u32 rev, dummy;
+
+       native_wrmsrl(MSR_IA32_UCODE_REV, 0);
+
+       /* As documented in the SDM: Do a CPUID 1 here */
+       native_cpuid_eax(1);
+
+       /* get the current revision from MSR 0x8B */
+       native_rdmsr(MSR_IA32_UCODE_REV, dummy, rev);
+
+       return rev;
+}
+
 #ifdef CONFIG_MICROCODE_INTEL
 extern void __init load_ucode_intel_bsp(void);
 extern void load_ucode_intel_ap(void);
index eaf100508c36203ad888c0b4484ba264e20bd0ad..1be64da0384ed8d5dea85563633c2740f5587888 100644 (file)
@@ -219,6 +219,24 @@ static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
            : "memory");
 }
 
+#define native_cpuid_reg(reg)                                  \
+static inline unsigned int native_cpuid_##reg(unsigned int op) \
+{                                                              \
+       unsigned int eax = op, ebx, ecx = 0, edx;               \
+                                                               \
+       native_cpuid(&eax, &ebx, &ecx, &edx);                   \
+                                                               \
+       return reg;                                             \
+}
+
+/*
+ * Native CPUID functions returning a single datum.
+ */
+native_cpuid_reg(eax)
+native_cpuid_reg(ebx)
+native_cpuid_reg(ecx)
+native_cpuid_reg(edx)
+
 static inline void load_cr3(pgd_t *pgdir)
 {
        write_cr3(__pa(pgdir));
index a3269c897ec578508fd41c6f7ab9b3622934e623..2e41c50ddf47f414c8f2e4b0a99965ceafffb4bf 100644 (file)
@@ -58,7 +58,7 @@ get_frame_pointer(struct task_struct *task, struct pt_regs *regs)
        if (task == current)
                return __builtin_frame_address(0);
 
-       return (unsigned long *)((struct inactive_task_frame *)task->thread.sp)->bp;
+       return &((struct inactive_task_frame *)task->thread.sp)->bp;
 }
 #else
 static inline unsigned long *
index 5cb436acd46315b75ba40aacc780373ea2cc4f7c..fcc5cd387fd17a59e5f28ba5fc8fb65fc57ae5af 100644 (file)
@@ -36,7 +36,10 @@ static inline void prepare_switch_to(struct task_struct *prev,
 
 asmlinkage void ret_from_fork(void);
 
-/* data that is pointed to by thread.sp */
+/*
+ * This is the structure pointed to by thread.sp for an inactive task.  The
+ * order of the fields must match the code in __switch_to_asm().
+ */
 struct inactive_task_frame {
 #ifdef CONFIG_X86_64
        unsigned long r15;
@@ -48,6 +51,11 @@ struct inactive_task_frame {
        unsigned long di;
 #endif
        unsigned long bx;
+
+       /*
+        * These two fields must be together.  They form a stack frame header,
+        * needed by get_frame_pointer().
+        */
        unsigned long bp;
        unsigned long ret_addr;
 };
index 71cae73a507617a2559aa0815a9e178a22f33385..1d3167269a6717902149171fe755123a5c654eb6 100644 (file)
@@ -309,15 +309,8 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
 
        /* get information required for multi-node processors */
        if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
-               u32 eax, ebx, ecx, edx;
 
-               cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
-               node_id = ecx & 7;
-
-               /* get compute unit information */
-               smp_num_siblings = ((ebx >> 8) & 3) + 1;
-               c->x86_max_cores /= smp_num_siblings;
-               c->cpu_core_id = ebx & 0xff;
+               node_id = cpuid_ecx(0x8000001e) & 7;
 
                /*
                 * We may have multiple LLCs if L3 caches exist, so check if we
index dc1697ca5191ce87cd9f27a78236ede3897243ab..9bab7a8a42936e32270e3573a17a1cd87fb580e0 100644 (file)
@@ -1221,7 +1221,7 @@ static __init int setup_disablecpuid(char *arg)
 {
        int bit;
 
-       if (get_option(&arg, &bit) && bit < NCAPINTS*32)
+       if (get_option(&arg, &bit) && bit >= 0 && bit < NCAPINTS * 32)
                setup_clear_cpu_cap(bit);
        else
                return 0;
index fcd484d2bb034a4533d3c4355d3ace82c92060dd..203f860d2ab3339c11ddc34d976f56ffa6ef069c 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/bugs.h>
 #include <asm/cpu.h>
 #include <asm/intel-family.h>
+#include <asm/microcode_intel.h>
 
 #ifdef CONFIG_X86_64
 #include <linux/topology.h>
@@ -78,14 +79,8 @@ static void early_init_intel(struct cpuinfo_x86 *c)
                (c->x86 == 0x6 && c->x86_model >= 0x0e))
                set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
 
-       if (c->x86 >= 6 && !cpu_has(c, X86_FEATURE_IA64)) {
-               unsigned lower_word;
-
-               wrmsr(MSR_IA32_UCODE_REV, 0, 0);
-               /* Required by the SDM */
-               sync_core();
-               rdmsr(MSR_IA32_UCODE_REV, lower_word, c->microcode);
-       }
+       if (c->x86 >= 6 && !cpu_has(c, X86_FEATURE_IA64))
+               c->microcode = intel_get_microcode_revision();
 
        /*
         * Atom erratum AAE44/AAF40/AAG38/AAH41:
index b624b54912e11e4e58992b9e1ca2d7cab20ce9e4..3f329b74e040c23b6b85dfd12a85f80d630c63ac 100644 (file)
@@ -150,7 +150,7 @@ static struct ucode_patch *__alloc_microcode_buf(void *data, unsigned int size)
 {
        struct ucode_patch *p;
 
-       p = kzalloc(size, GFP_KERNEL);
+       p = kzalloc(sizeof(struct ucode_patch), GFP_KERNEL);
        if (!p)
                return ERR_PTR(-ENOMEM);
 
@@ -368,26 +368,6 @@ next:
        return patch;
 }
 
-static void cpuid_1(void)
-{
-       /*
-        * According to the Intel SDM, Volume 3, 9.11.7:
-        *
-        *   CPUID returns a value in a model specific register in
-        *   addition to its usual register return values. The
-        *   semantics of CPUID cause it to deposit an update ID value
-        *   in the 64-bit model-specific register at address 08BH
-        *   (IA32_BIOS_SIGN_ID). If no update is present in the
-        *   processor, the value in the MSR remains unmodified.
-        *
-        * Use native_cpuid -- this code runs very early and we don't
-        * want to mess with paravirt.
-        */
-       unsigned int eax = 1, ebx, ecx = 0, edx;
-
-       native_cpuid(&eax, &ebx, &ecx, &edx);
-}
-
 static int collect_cpu_info_early(struct ucode_cpu_info *uci)
 {
        unsigned int val[2];
@@ -410,15 +390,8 @@ static int collect_cpu_info_early(struct ucode_cpu_info *uci)
                native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
                csig.pf = 1 << ((val[1] >> 18) & 7);
        }
-       native_wrmsrl(MSR_IA32_UCODE_REV, 0);
-
-       /* As documented in the SDM: Do a CPUID 1 here */
-       cpuid_1();
 
-       /* get the current revision from MSR 0x8B */
-       native_rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
-
-       csig.rev = val[1];
+       csig.rev = intel_get_microcode_revision();
 
        uci->cpu_sig = csig;
        uci->valid = 1;
@@ -602,7 +575,7 @@ static inline void print_ucode(struct ucode_cpu_info *uci)
 static int apply_microcode_early(struct ucode_cpu_info *uci, bool early)
 {
        struct microcode_intel *mc;
-       unsigned int val[2];
+       u32 rev;
 
        mc = uci->mc;
        if (!mc)
@@ -610,21 +583,16 @@ static int apply_microcode_early(struct ucode_cpu_info *uci, bool early)
 
        /* write microcode via MSR 0x79 */
        native_wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits);
-       native_wrmsrl(MSR_IA32_UCODE_REV, 0);
 
-       /* As documented in the SDM: Do a CPUID 1 here */
-       cpuid_1();
-
-       /* get the current revision from MSR 0x8B */
-       native_rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
-       if (val[1] != mc->hdr.rev)
+       rev = intel_get_microcode_revision();
+       if (rev != mc->hdr.rev)
                return -1;
 
 #ifdef CONFIG_X86_64
        /* Flush global tlb. This is precaution. */
        flush_tlb_early();
 #endif
-       uci->cpu_sig.rev = val[1];
+       uci->cpu_sig.rev = rev;
 
        if (early)
                print_ucode(uci);
@@ -804,8 +772,8 @@ static int apply_microcode_intel(int cpu)
        struct microcode_intel *mc;
        struct ucode_cpu_info *uci;
        struct cpuinfo_x86 *c;
-       unsigned int val[2];
        static int prev_rev;
+       u32 rev;
 
        /* We should bind the task to the CPU */
        if (WARN_ON(raw_smp_processor_id() != cpu))
@@ -822,33 +790,28 @@ static int apply_microcode_intel(int cpu)
 
        /* write microcode via MSR 0x79 */
        wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits);
-       wrmsrl(MSR_IA32_UCODE_REV, 0);
-
-       /* As documented in the SDM: Do a CPUID 1 here */
-       cpuid_1();
 
-       /* get the current revision from MSR 0x8B */
-       rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
+       rev = intel_get_microcode_revision();
 
-       if (val[1] != mc->hdr.rev) {
+       if (rev != mc->hdr.rev) {
                pr_err("CPU%d update to revision 0x%x failed\n",
                       cpu, mc->hdr.rev);
                return -1;
        }
 
-       if (val[1] != prev_rev) {
+       if (rev != prev_rev) {
                pr_info("updated to revision 0x%x, date = %04x-%02x-%02x\n",
-                       val[1],
+                       rev,
                        mc->hdr.date & 0xffff,
                        mc->hdr.date >> 24,
                        (mc->hdr.date >> 16) & 0xff);
-               prev_rev = val[1];
+               prev_rev = rev;
        }
 
        c = &cpu_data(cpu);
 
-       uci->cpu_sig.rev = val[1];
-       c->microcode = val[1];
+       uci->cpu_sig.rev = rev;
+       c->microcode = rev;
 
        return 0;
 }
@@ -860,7 +823,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
        u8 *ucode_ptr = data, *new_mc = NULL, *mc = NULL;
        int new_rev = uci->cpu_sig.rev;
        unsigned int leftover = size;
-       unsigned int curr_mc_size = 0;
+       unsigned int curr_mc_size = 0, new_mc_size = 0;
        unsigned int csig, cpf;
 
        while (leftover) {
@@ -901,6 +864,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
                        vfree(new_mc);
                        new_rev = mc_header.rev;
                        new_mc  = mc;
+                       new_mc_size = mc_size;
                        mc = NULL;      /* trigger new vmalloc */
                }
 
@@ -926,7 +890,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
         * permanent memory. So it will be loaded early when a CPU is hot added
         * or resumes.
         */
-       save_mc_for_early(new_mc, curr_mc_size);
+       save_mc_for_early(new_mc, new_mc_size);
 
        pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n",
                 cpu, new_rev, uci->cpu_sig.rev);
index be3a49ee035650f1f1eac68c07ad0e8898c40585..e41af597aed8e2e454965f8459f26b372c091b4f 100644 (file)
@@ -694,6 +694,7 @@ unsigned long native_calibrate_tsc(void)
                        crystal_khz = 24000;    /* 24.0 MHz */
                        break;
                case INTEL_FAM6_SKYLAKE_X:
+               case INTEL_FAM6_ATOM_DENVERTON:
                        crystal_khz = 25000;    /* 25.0 MHz */
                        break;
                case INTEL_FAM6_ATOM_GOLDMONT:
index 4443e499f2790923e6510bc57a88d5a9e0578051..23d15565d02ad780529091e5004557081bb62844 100644 (file)
@@ -6,6 +6,21 @@
 
 #define FRAME_HEADER_SIZE (sizeof(long) * 2)
 
+/*
+ * This disables KASAN checking when reading a value from another task's stack,
+ * since the other task could be running on another CPU and could have poisoned
+ * the stack in the meantime.
+ */
+#define READ_ONCE_TASK_STACK(task, x)                  \
+({                                                     \
+       unsigned long val;                              \
+       if (task == current)                            \
+               val = READ_ONCE(x);                     \
+       else                                            \
+               val = READ_ONCE_NOCHECK(x);             \
+       val;                                            \
+})
+
 static void unwind_dump(struct unwind_state *state, unsigned long *sp)
 {
        static bool dumped_before = false;
@@ -48,7 +63,8 @@ unsigned long unwind_get_return_address(struct unwind_state *state)
        if (state->regs && user_mode(state->regs))
                return 0;
 
-       addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, *addr_p,
+       addr = READ_ONCE_TASK_STACK(state->task, *addr_p);
+       addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, addr,
                                     addr_p);
 
        return __kernel_text_address(addr) ? addr : 0;
@@ -162,7 +178,7 @@ bool unwind_next_frame(struct unwind_state *state)
        if (state->regs)
                next_bp = (unsigned long *)state->regs->bp;
        else
-               next_bp = (unsigned long *)*state->bp;
+               next_bp = (unsigned long *)READ_ONCE_TASK_STACK(state->task,*state->bp);
 
        /* is the next frame pointer an encoded pointer to pt_regs? */
        regs = decode_frame_pointer(next_bp);
@@ -207,6 +223,16 @@ bool unwind_next_frame(struct unwind_state *state)
        return true;
 
 bad_address:
+       /*
+        * When unwinding a non-current task, the task might actually be
+        * running on another CPU, in which case it could be modifying its
+        * stack while we're reading it.  This is generally not a problem and
+        * can be ignored as long as the caller understands that unwinding
+        * another task will not always succeed.
+        */
+       if (state->task != current)
+               goto the_end;
+
        if (state->regs) {
                printk_deferred_once(KERN_WARNING
                        "WARNING: kernel stack regs at %p in %s:%d has bad 'bp' value %p\n",
index 324e5713d386f0ed235b0394f71c0290df870fae..af59f808742f94df84ab0aaed1ac2db3ea27e016 100644 (file)
@@ -293,7 +293,7 @@ siginfo_t *mpx_generate_siginfo(struct pt_regs *regs)
         * We were not able to extract an address from the instruction,
         * probably because there was something invalid in it.
         */
-       if (info->si_addr == (void *)-1) {
+       if (info->si_addr == (void __user *)-1) {
                err = -EINVAL;
                goto err_out;
        }
index 936a488d6cf6df3c2aadbbdbc036b8eb06701cb0..274dfc48184977db435a9c5c78607cd8a182067c 100644 (file)
@@ -210,6 +210,70 @@ int __init efi_memblock_x86_reserve_range(void)
        return 0;
 }
 
+#define OVERFLOW_ADDR_SHIFT    (64 - EFI_PAGE_SHIFT)
+#define OVERFLOW_ADDR_MASK     (U64_MAX << OVERFLOW_ADDR_SHIFT)
+#define U64_HIGH_BIT           (~(U64_MAX >> 1))
+
+static bool __init efi_memmap_entry_valid(const efi_memory_desc_t *md, int i)
+{
+       u64 end = (md->num_pages << EFI_PAGE_SHIFT) + md->phys_addr - 1;
+       u64 end_hi = 0;
+       char buf[64];
+
+       if (md->num_pages == 0) {
+               end = 0;
+       } else if (md->num_pages > EFI_PAGES_MAX ||
+                  EFI_PAGES_MAX - md->num_pages <
+                  (md->phys_addr >> EFI_PAGE_SHIFT)) {
+               end_hi = (md->num_pages & OVERFLOW_ADDR_MASK)
+                       >> OVERFLOW_ADDR_SHIFT;
+
+               if ((md->phys_addr & U64_HIGH_BIT) && !(end & U64_HIGH_BIT))
+                       end_hi += 1;
+       } else {
+               return true;
+       }
+
+       pr_warn_once(FW_BUG "Invalid EFI memory map entries:\n");
+
+       if (end_hi) {
+               pr_warn("mem%02u: %s range=[0x%016llx-0x%llx%016llx] (invalid)\n",
+                       i, efi_md_typeattr_format(buf, sizeof(buf), md),
+                       md->phys_addr, end_hi, end);
+       } else {
+               pr_warn("mem%02u: %s range=[0x%016llx-0x%016llx] (invalid)\n",
+                       i, efi_md_typeattr_format(buf, sizeof(buf), md),
+                       md->phys_addr, end);
+       }
+       return false;
+}
+
+static void __init efi_clean_memmap(void)
+{
+       efi_memory_desc_t *out = efi.memmap.map;
+       const efi_memory_desc_t *in = out;
+       const efi_memory_desc_t *end = efi.memmap.map_end;
+       int i, n_removal;
+
+       for (i = n_removal = 0; in < end; i++) {
+               if (efi_memmap_entry_valid(in, i)) {
+                       if (out != in)
+                               memcpy(out, in, efi.memmap.desc_size);
+                       out = (void *)out + efi.memmap.desc_size;
+               } else {
+                       n_removal++;
+               }
+               in = (void *)in + efi.memmap.desc_size;
+       }
+
+       if (n_removal > 0) {
+               u64 size = efi.memmap.nr_map - n_removal;
+
+               pr_warn("Removing %d invalid memory map entries.\n", n_removal);
+               efi_memmap_install(efi.memmap.phys_map, size);
+       }
+}
+
 void __init efi_print_memmap(void)
 {
        efi_memory_desc_t *md;
@@ -472,6 +536,8 @@ void __init efi_init(void)
                }
        }
 
+       efi_clean_memmap();
+
        if (efi_enabled(EFI_DBG))
                efi_print_memmap();
 }
index 10aca63a50d7bbff9fa94dec60e0df00591ccbd5..30031d5293c483202c526d5045cda23be6617359 100644 (file)
@@ -214,7 +214,7 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size)
 
        new_size = efi.memmap.desc_size * num_entries;
 
-       new_phys = memblock_alloc(new_size, 0);
+       new_phys = efi_memmap_alloc(num_entries);
        if (!new_phys) {
                pr_err("Could not allocate boot services memmap\n");
                return;
@@ -355,7 +355,7 @@ void __init efi_free_boot_services(void)
        }
 
        new_size = efi.memmap.desc_size * num_entries;
-       new_phys = memblock_alloc(new_size, 0);
+       new_phys = efi_memmap_alloc(num_entries);
        if (!new_phys) {
                pr_err("Failed to allocate new EFI memmap\n");
                return;
index 61b5ed2b7d400339053d933d82c3938c94bbc766..90e4f2a6625b6ae2a87cf7c5ec9792a5459cd0e1 100644 (file)
@@ -15,7 +15,7 @@ obj-$(subst m,y,$(CONFIG_INTEL_MID_POWER_BUTTON)) += platform_msic_power_btn.o
 obj-$(subst m,y,$(CONFIG_GPIO_INTEL_PMIC)) += platform_pmic_gpio.o
 obj-$(subst m,y,$(CONFIG_INTEL_MFLD_THERMAL)) += platform_msic_thermal.o
 # SPI Devices
-obj-$(subst m,y,$(CONFIG_SPI_SPIDEV)) += platform_spidev.o
+obj-$(subst m,y,$(CONFIG_SPI_SPIDEV)) += platform_mrfld_spidev.o
 # I2C Devices
 obj-$(subst m,y,$(CONFIG_SENSORS_EMC1403)) += platform_emc1403.o
 obj-$(subst m,y,$(CONFIG_SENSORS_LIS3LV02D)) += platform_lis331.o
diff --git a/arch/x86/platform/intel-mid/device_libs/platform_mrfld_spidev.c b/arch/x86/platform/intel-mid/device_libs/platform_mrfld_spidev.c
new file mode 100644 (file)
index 0000000..27186ad
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * spidev platform data initilization file
+ *
+ * (C) Copyright 2014, 2016 Intel Corporation
+ * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+ *         Dan O'Donovan <dan@emutex.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/sfi.h>
+#include <linux/spi/pxa2xx_spi.h>
+#include <linux/spi/spi.h>
+
+#include <asm/intel-mid.h>
+
+#define MRFLD_SPI_DEFAULT_DMA_BURST    8
+#define MRFLD_SPI_DEFAULT_TIMEOUT      500
+
+/* GPIO pin for spidev chipselect */
+#define MRFLD_SPIDEV_GPIO_CS           111
+
+static struct pxa2xx_spi_chip spidev_spi_chip = {
+       .dma_burst_size         = MRFLD_SPI_DEFAULT_DMA_BURST,
+       .timeout                = MRFLD_SPI_DEFAULT_TIMEOUT,
+       .gpio_cs                = MRFLD_SPIDEV_GPIO_CS,
+};
+
+static void __init *spidev_platform_data(void *info)
+{
+       struct spi_board_info *spi_info = info;
+
+       if (intel_mid_identify_cpu() != INTEL_MID_CPU_CHIP_TANGIER)
+               return ERR_PTR(-ENODEV);
+
+       spi_info->mode = SPI_MODE_0;
+       spi_info->controller_data = &spidev_spi_chip;
+
+       return NULL;
+}
+
+static const struct devs_id spidev_dev_id __initconst = {
+       .name                   = "spidev",
+       .type                   = SFI_DEV_TYPE_SPI,
+       .delay                  = 0,
+       .get_platform_data      = &spidev_platform_data,
+};
+
+sfi_device(spidev_dev_id);
diff --git a/arch/x86/platform/intel-mid/device_libs/platform_spidev.c b/arch/x86/platform/intel-mid/device_libs/platform_spidev.c
deleted file mode 100644 (file)
index 30c601b..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * spidev platform data initilization file
- *
- * (C) Copyright 2014, 2016 Intel Corporation
- * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- *         Dan O'Donovan <dan@emutex.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; version 2
- * of the License.
- */
-
-#include <linux/init.h>
-#include <linux/sfi.h>
-#include <linux/spi/pxa2xx_spi.h>
-#include <linux/spi/spi.h>
-
-#include <asm/intel-mid.h>
-
-#define MRFLD_SPI_DEFAULT_DMA_BURST    8
-#define MRFLD_SPI_DEFAULT_TIMEOUT      500
-
-/* GPIO pin for spidev chipselect */
-#define MRFLD_SPIDEV_GPIO_CS           111
-
-static struct pxa2xx_spi_chip spidev_spi_chip = {
-       .dma_burst_size         = MRFLD_SPI_DEFAULT_DMA_BURST,
-       .timeout                = MRFLD_SPI_DEFAULT_TIMEOUT,
-       .gpio_cs                = MRFLD_SPIDEV_GPIO_CS,
-};
-
-static void __init *spidev_platform_data(void *info)
-{
-       struct spi_board_info *spi_info = info;
-
-       spi_info->mode = SPI_MODE_0;
-       spi_info->controller_data = &spidev_spi_chip;
-
-       return NULL;
-}
-
-static const struct devs_id spidev_dev_id __initconst = {
-       .name                   = "spidev",
-       .type                   = SFI_DEV_TYPE_SPI,
-       .delay                  = 0,
-       .get_platform_data      = &spidev_platform_data,
-};
-
-sfi_device(spidev_dev_id);
index 4ef4c5caed4f57bece96aa4efdae4a2ea34313f1..8a8e403644d6e0d6ce838105dfceb30ae5625460 100644 (file)
@@ -132,9 +132,9 @@ config HT16K33
        tristate "Holtek Ht16K33 LED controller with keyscan"
        depends on FB && OF && I2C && INPUT
        select FB_SYS_FOPS
-       select FB_CFB_FILLRECT
-       select FB_CFB_COPYAREA
-       select FB_CFB_IMAGEBLIT
+       select FB_SYS_FILLRECT
+       select FB_SYS_COPYAREA
+       select FB_SYS_IMAGEBLIT
        select INPUT_MATRIXKMAP
        select FB_BACKLIGHT
        help
index ada9dce34e6d8a8373d3d08d5c28b3f6b55ac427..e19b1008e5fb08b1099e5f5d8f0dc86dfc24bde5 100644 (file)
@@ -141,8 +141,6 @@ extern void device_unblock_probing(void);
 extern struct kset *devices_kset;
 extern void devices_kset_move_last(struct device *dev);
 
-extern struct device_attribute dev_attr_deferred_probe;
-
 #if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS)
 extern void module_add_driver(struct module *mod, struct device_driver *drv);
 extern void module_remove_driver(struct device_driver *drv);
index 020ea7f0552073c62c91e55d62e0c0151917251e..8c25e68e67d7354005dc81a92342eb10519449ed 100644 (file)
@@ -1060,14 +1060,8 @@ static int device_add_attrs(struct device *dev)
                        goto err_remove_dev_groups;
        }
 
-       error = device_create_file(dev, &dev_attr_deferred_probe);
-       if (error)
-               goto err_remove_online;
-
        return 0;
 
- err_remove_online:
-       device_remove_file(dev, &dev_attr_online);
  err_remove_dev_groups:
        device_remove_groups(dev, dev->groups);
  err_remove_type_groups:
@@ -1085,7 +1079,6 @@ static void device_remove_attrs(struct device *dev)
        struct class *class = dev->class;
        const struct device_type *type = dev->type;
 
-       device_remove_file(dev, &dev_attr_deferred_probe);
        device_remove_file(dev, &dev_attr_online);
        device_remove_groups(dev, dev->groups);
 
index a8b258e5407bae02c48b03b39941ee238c22a2e3..a1fbf55c4d3abbea786ef5585b96d769ca3a144a 100644 (file)
@@ -53,19 +53,6 @@ static LIST_HEAD(deferred_probe_pending_list);
 static LIST_HEAD(deferred_probe_active_list);
 static atomic_t deferred_trigger_count = ATOMIC_INIT(0);
 
-static ssize_t deferred_probe_show(struct device *dev,
-                                  struct device_attribute *attr, char *buf)
-{
-       bool value;
-
-       mutex_lock(&deferred_probe_mutex);
-       value = !list_empty(&dev->p->deferred_probe);
-       mutex_unlock(&deferred_probe_mutex);
-
-       return sprintf(buf, "%d\n", value);
-}
-DEVICE_ATTR_RO(deferred_probe);
-
 /*
  * In some cases, like suspend to RAM or hibernation, It might be reasonable
  * to prohibit probing of devices as it could be unsafe.
index 5bb1985ec484aef267e3c551c3068ec0dee14b1c..6d9cc2d39d22306fd68f30bac6f4a60e6cfa5a87 100644 (file)
@@ -381,9 +381,6 @@ static ssize_t read_kmem(struct file *file, char __user *buf,
        char *kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
        int err = 0;
 
-       if (!pfn_valid(PFN_DOWN(p)))
-               return -EIO;
-
        read = 0;
        if (p < (unsigned long) high_memory) {
                low_count = count;
@@ -412,6 +409,8 @@ static ssize_t read_kmem(struct file *file, char __user *buf,
                         * by the kernel or data corruption may occur
                         */
                        kbuf = xlate_dev_kmem_ptr((void *)p);
+                       if (!virt_addr_valid(kbuf))
+                               return -ENXIO;
 
                        if (copy_to_user(buf, kbuf, sz))
                                return -EFAULT;
@@ -482,6 +481,8 @@ static ssize_t do_write_kmem(unsigned long p, const char __user *buf,
                 * corruption may occur.
                 */
                ptr = xlate_dev_kmem_ptr((void *)p);
+               if (!virt_addr_valid(ptr))
+                       return -ENXIO;
 
                copied = copy_from_user(ptr, buf, sz);
                if (copied) {
@@ -512,9 +513,6 @@ static ssize_t write_kmem(struct file *file, const char __user *buf,
        char *kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
        int err = 0;
 
-       if (!pfn_valid(PFN_DOWN(p)))
-               return -EIO;
-
        if (p < (unsigned long) high_memory) {
                unsigned long to_write = min_t(unsigned long, count,
                                               (unsigned long)high_memory - p);
index 02819e0703c8eef503baf8333c88f105a591444b..87885d146dbb02ed9ed08979dda96579bd5bc652 100644 (file)
@@ -290,6 +290,7 @@ static int register_device(int minor, struct pp_struct *pp)
        struct pardevice *pdev = NULL;
        char *name;
        struct pardev_cb ppdev_cb;
+       int rc = 0;
 
        name = kasprintf(GFP_KERNEL, CHRDEV "%x", minor);
        if (name == NULL)
@@ -298,8 +299,8 @@ static int register_device(int minor, struct pp_struct *pp)
        port = parport_find_number(minor);
        if (!port) {
                pr_warn("%s: no associated port!\n", name);
-               kfree(name);
-               return -ENXIO;
+               rc = -ENXIO;
+               goto err;
        }
 
        memset(&ppdev_cb, 0, sizeof(ppdev_cb));
@@ -308,16 +309,18 @@ static int register_device(int minor, struct pp_struct *pp)
        ppdev_cb.private = pp;
        pdev = parport_register_dev_model(port, name, &ppdev_cb, minor);
        parport_put_port(port);
-       kfree(name);
 
        if (!pdev) {
                pr_warn("%s: failed to register device!\n", name);
-               return -ENXIO;
+               rc = -ENXIO;
+               goto err;
        }
 
        pp->pdev = pdev;
        dev_dbg(&pdev->dev, "registered pardevice\n");
-       return 0;
+err:
+       kfree(name);
+       return rc;
 }
 
 static enum ieee1284_phase init_phase(int mode)
index 78298460d1686a79864c57d228ac6af5e114acf9..7c1e3a7b14e0c1f540a0bbe7d6b924b124561729 100644 (file)
@@ -453,7 +453,7 @@ int extcon_sync(struct extcon_dev *edev, unsigned int id)
                dev_err(&edev->dev, "out of memory in extcon_set_state\n");
                kobject_uevent(&edev->dev.kobj, KOBJ_CHANGE);
 
-               return 0;
+               return -ENOMEM;
        }
 
        length = name_show(&edev->dev, NULL, prop_buf);
index 520a40e5e0e431129cf1fe66a7604d32d7e20061..6c7d60c239b5b459b1f45e1d1110f7ed5a265cb6 100644 (file)
@@ -71,8 +71,7 @@ void __init efi_fake_memmap(void)
        }
 
        /* allocate memory for new EFI memmap */
-       new_memmap_phy = memblock_alloc(efi.memmap.desc_size * new_nr_map,
-                                       PAGE_SIZE);
+       new_memmap_phy = efi_memmap_alloc(new_nr_map);
        if (!new_memmap_phy)
                return;
 
index b98824e3800abbb57b110d7cc92c0ca8417791d2..0e2a96b12cb3647635db19912ec0ab4004f71572 100644 (file)
@@ -39,14 +39,6 @@ efi_status_t efi_file_close(void *handle);
 
 unsigned long get_dram_base(efi_system_table_t *sys_table_arg);
 
-efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
-                       unsigned long orig_fdt_size,
-                       void *fdt, int new_fdt_size, char *cmdline_ptr,
-                       u64 initrd_addr, u64 initrd_size,
-                       efi_memory_desc_t *memory_map,
-                       unsigned long map_size, unsigned long desc_size,
-                       u32 desc_ver);
-
 efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
                                            void *handle,
                                            unsigned long *new_fdt_addr,
index a6a93116a8f053f6c14911376ffa6da7f1dff44e..921dfa047202952c9064cd39971e68e0e3c28b49 100644 (file)
 
 #include "efistub.h"
 
-efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
-                       unsigned long orig_fdt_size,
-                       void *fdt, int new_fdt_size, char *cmdline_ptr,
-                       u64 initrd_addr, u64 initrd_size,
-                       efi_memory_desc_t *memory_map,
-                       unsigned long map_size, unsigned long desc_size,
-                       u32 desc_ver)
+static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
+                              unsigned long orig_fdt_size,
+                              void *fdt, int new_fdt_size, char *cmdline_ptr,
+                              u64 initrd_addr, u64 initrd_size)
 {
        int node, num_rsv;
        int status;
@@ -101,25 +98,23 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
        if (status)
                goto fdt_set_fail;
 
-       fdt_val64 = cpu_to_fdt64((u64)(unsigned long)memory_map);
+       fdt_val64 = U64_MAX; /* placeholder */
        status = fdt_setprop(fdt, node, "linux,uefi-mmap-start",
                             &fdt_val64,  sizeof(fdt_val64));
        if (status)
                goto fdt_set_fail;
 
-       fdt_val32 = cpu_to_fdt32(map_size);
+       fdt_val32 = U32_MAX; /* placeholder */
        status = fdt_setprop(fdt, node, "linux,uefi-mmap-size",
                             &fdt_val32,  sizeof(fdt_val32));
        if (status)
                goto fdt_set_fail;
 
-       fdt_val32 = cpu_to_fdt32(desc_size);
        status = fdt_setprop(fdt, node, "linux,uefi-mmap-desc-size",
                             &fdt_val32, sizeof(fdt_val32));
        if (status)
                goto fdt_set_fail;
 
-       fdt_val32 = cpu_to_fdt32(desc_ver);
        status = fdt_setprop(fdt, node, "linux,uefi-mmap-desc-ver",
                             &fdt_val32, sizeof(fdt_val32));
        if (status)
@@ -148,6 +143,43 @@ fdt_set_fail:
        return EFI_LOAD_ERROR;
 }
 
+static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map)
+{
+       int node = fdt_path_offset(fdt, "/chosen");
+       u64 fdt_val64;
+       u32 fdt_val32;
+       int err;
+
+       if (node < 0)
+               return EFI_LOAD_ERROR;
+
+       fdt_val64 = cpu_to_fdt64((unsigned long)*map->map);
+       err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-start",
+                                 &fdt_val64, sizeof(fdt_val64));
+       if (err)
+               return EFI_LOAD_ERROR;
+
+       fdt_val32 = cpu_to_fdt32(*map->map_size);
+       err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-size",
+                                 &fdt_val32, sizeof(fdt_val32));
+       if (err)
+               return EFI_LOAD_ERROR;
+
+       fdt_val32 = cpu_to_fdt32(*map->desc_size);
+       err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-desc-size",
+                                 &fdt_val32, sizeof(fdt_val32));
+       if (err)
+               return EFI_LOAD_ERROR;
+
+       fdt_val32 = cpu_to_fdt32(*map->desc_ver);
+       err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-desc-ver",
+                                 &fdt_val32, sizeof(fdt_val32));
+       if (err)
+               return EFI_LOAD_ERROR;
+
+       return EFI_SUCCESS;
+}
+
 #ifndef EFI_FDT_ALIGN
 #define EFI_FDT_ALIGN EFI_PAGE_SIZE
 #endif
@@ -243,20 +275,10 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
                        goto fail;
                }
 
-               /*
-                * Now that we have done our final memory allocation (and free)
-                * we can get the memory map key  needed for
-                * exit_boot_services().
-                */
-               status = efi_get_memory_map(sys_table, &map);
-               if (status != EFI_SUCCESS)
-                       goto fail_free_new_fdt;
-
                status = update_fdt(sys_table,
                                    (void *)fdt_addr, fdt_size,
                                    (void *)*new_fdt_addr, new_fdt_size,
-                                   cmdline_ptr, initrd_addr, initrd_size,
-                                   memory_map, map_size, desc_size, desc_ver);
+                                   cmdline_ptr, initrd_addr, initrd_size);
 
                /* Succeeding the first time is the expected case. */
                if (status == EFI_SUCCESS)
@@ -266,20 +288,16 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
                        /*
                         * We need to allocate more space for the new
                         * device tree, so free existing buffer that is
-                        * too small.  Also free memory map, as we will need
-                        * to get new one that reflects the free/alloc we do
-                        * on the device tree buffer.
+                        * too small.
                         */
                        efi_free(sys_table, new_fdt_size, *new_fdt_addr);
-                       sys_table->boottime->free_pool(memory_map);
                        new_fdt_size += EFI_PAGE_SIZE;
                } else {
                        pr_efi_err(sys_table, "Unable to construct new device tree.\n");
-                       goto fail_free_mmap;
+                       goto fail_free_new_fdt;
                }
        }
 
-       sys_table->boottime->free_pool(memory_map);
        priv.runtime_map = runtime_map;
        priv.runtime_entry_count = &runtime_entry_count;
        status = efi_exit_boot_services(sys_table, handle, &map, &priv,
@@ -288,6 +306,16 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
        if (status == EFI_SUCCESS) {
                efi_set_virtual_address_map_t *svam;
 
+               status = update_fdt_memmap((void *)*new_fdt_addr, &map);
+               if (status != EFI_SUCCESS) {
+                       /*
+                        * The kernel won't get far without the memory map, but
+                        * may still be able to print something meaningful so
+                        * return success here.
+                        */
+                       return EFI_SUCCESS;
+               }
+
                /* Install the new virtual address map */
                svam = sys_table->runtime->set_virtual_address_map;
                status = svam(runtime_entry_count * desc_size, desc_size,
@@ -319,9 +347,6 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
 
        pr_efi_err(sys_table, "Exit boot services failed.\n");
 
-fail_free_mmap:
-       sys_table->boottime->free_pool(memory_map);
-
 fail_free_new_fdt:
        efi_free(sys_table, new_fdt_size, *new_fdt_addr);
 
index f03ddecd232b542ce4c7163506b69da0d29ad2c7..78686443cb378abf616c7cfe595b82d3a51c9cd6 100644 (file)
@@ -9,6 +9,44 @@
 #include <linux/efi.h>
 #include <linux/io.h>
 #include <asm/early_ioremap.h>
+#include <linux/memblock.h>
+#include <linux/slab.h>
+
+static phys_addr_t __init __efi_memmap_alloc_early(unsigned long size)
+{
+       return memblock_alloc(size, 0);
+}
+
+static phys_addr_t __init __efi_memmap_alloc_late(unsigned long size)
+{
+       unsigned int order = get_order(size);
+       struct page *p = alloc_pages(GFP_KERNEL, order);
+
+       if (!p)
+               return 0;
+
+       return PFN_PHYS(page_to_pfn(p));
+}
+
+/**
+ * efi_memmap_alloc - Allocate memory for the EFI memory map
+ * @num_entries: Number of entries in the allocated map.
+ *
+ * Depending on whether mm_init() has already been invoked or not,
+ * either memblock or "normal" page allocation is used.
+ *
+ * Returns the physical address of the allocated memory map on
+ * success, zero on failure.
+ */
+phys_addr_t __init efi_memmap_alloc(unsigned int num_entries)
+{
+       unsigned long size = num_entries * efi.memmap.desc_size;
+
+       if (slab_is_available())
+               return __efi_memmap_alloc_late(size);
+
+       return __efi_memmap_alloc_early(size);
+}
 
 /**
  * __efi_memmap_init - Common code for mapping the EFI memory map
index c2268cdf38e82348ae883c99d1f140a7fc2d0ecc..e34d82e79b988a781010cad1e0f283617dfb8471 100644 (file)
@@ -585,10 +585,29 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
                 u8 command, int size, union i2c_smbus_data *data)
 {
        struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(adap);
+       unsigned short piix4_smba = adapdata->smba;
+       int retries = MAX_TIMEOUT;
+       int smbslvcnt;
        u8 smba_en_lo;
        u8 port;
        int retval;
 
+       /* Request the SMBUS semaphore, avoid conflicts with the IMC */
+       smbslvcnt  = inb_p(SMBSLVCNT);
+       do {
+               outb_p(smbslvcnt | 0x10, SMBSLVCNT);
+
+               /* Check the semaphore status */
+               smbslvcnt  = inb_p(SMBSLVCNT);
+               if (smbslvcnt & 0x10)
+                       break;
+
+               usleep_range(1000, 2000);
+       } while (--retries);
+       /* SMBus is still owned by the IMC, we give up */
+       if (!retries)
+               return -EBUSY;
+
        mutex_lock(&piix4_mutex_sb800);
 
        outb_p(piix4_port_sel_sb800, SB800_PIIX4_SMB_IDX);
@@ -606,6 +625,9 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
 
        mutex_unlock(&piix4_mutex_sb800);
 
+       /* Release the semaphore */
+       outb_p(smbslvcnt | 0x20, SMBSLVCNT);
+
        return retval;
 }
 
index cf9e396d7702c6c769e2106a6938f90c6ddbb7a9..583e95042a21d86fe235d2e9784a1f6a6723205b 100644 (file)
@@ -931,7 +931,10 @@ static int i2c_device_probe(struct device *dev)
        if (!client->irq) {
                int irq = -ENOENT;
 
-               if (dev->of_node) {
+               if (client->flags & I2C_CLIENT_HOST_NOTIFY) {
+                       dev_dbg(dev, "Using Host Notify IRQ\n");
+                       irq = i2c_smbus_host_notify_to_irq(client);
+               } else if (dev->of_node) {
                        irq = of_irq_get_byname(dev->of_node, "irq");
                        if (irq == -EINVAL || irq == -ENODATA)
                                irq = of_irq_get(dev->of_node, 0);
@@ -940,14 +943,7 @@ static int i2c_device_probe(struct device *dev)
                }
                if (irq == -EPROBE_DEFER)
                        return irq;
-               /*
-                * ACPI and OF did not find any useful IRQ, try to see
-                * if Host Notify can be used.
-                */
-               if (irq < 0) {
-                       dev_dbg(dev, "Using Host Notify IRQ\n");
-                       irq = i2c_smbus_host_notify_to_irq(client);
-               }
+
                if (irq < 0)
                        irq = 0;
 
@@ -1708,7 +1704,7 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
 
        if (i2c_check_addr_validity(addr, info.flags)) {
                dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
-                       info.addr, node->full_name);
+                       addr, node->full_name);
                return ERR_PTR(-EINVAL);
        }
 
@@ -1716,6 +1712,9 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
        info.of_node = of_node_get(node);
        info.archdata = &dev_ad;
 
+       if (of_property_read_bool(node, "host-notify"))
+               info.flags |= I2C_CLIENT_HOST_NOTIFY;
+
        if (of_get_property(node, "wakeup-source", NULL))
                info.flags |= I2C_CLIENT_WAKE;
 
@@ -3633,7 +3632,7 @@ int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb)
        int ret;
 
        if (!client || !slave_cb) {
-               WARN(1, "insufficent data\n");
+               WARN(1, "insufficient data\n");
                return -EINVAL;
        }
 
index 66f323fd39826ebe9a738d55724ee2e124b45419..6f638bbc922db4fd366e1e3dcdd11c8655215622 100644 (file)
@@ -331,7 +331,7 @@ static noinline int i2cdev_ioctl_smbus(struct i2c_client *client,
                unsigned long arg)
 {
        struct i2c_smbus_ioctl_data data_arg;
-       union i2c_smbus_data temp;
+       union i2c_smbus_data temp = {};
        int datasize, res;
 
        if (copy_from_user(&data_arg,
index 18e05ca7584f9723ba12bf26a0aaf145b5903896..3600c9993a9830504d0cc5bcd61c4b8f19376762 100644 (file)
@@ -152,6 +152,9 @@ static void mei_mkhi_fix(struct mei_cl_device *cldev)
 {
        int ret;
 
+       if (!cldev->bus->hbm_f_os_supported)
+               return;
+
        ret = mei_cldev_enable(cldev);
        if (ret)
                return;
index c6c051b52f55faf1b5896164a4e5e3e251f86899..c6217a4993ad4da05094978e50cc3f1acb1b1fd5 100644 (file)
@@ -180,6 +180,8 @@ static ssize_t mei_dbgfs_read_devstate(struct file *fp, char __user *ubuf,
                                 dev->hbm_f_ev_supported);
                pos += scnprintf(buf + pos, bufsz - pos, "\tFA: %01d\n",
                                 dev->hbm_f_fa_supported);
+               pos += scnprintf(buf + pos, bufsz - pos, "\tOS: %01d\n",
+                                dev->hbm_f_os_supported);
        }
 
        pos += scnprintf(buf + pos, bufsz - pos, "pg:  %s, %s\n",
index dd7f15a65eeddbdf53bd2b6c094bfa98be969caf..25b4a1ba522df87fa60f0c8a9555607aa76df6d6 100644 (file)
@@ -989,6 +989,10 @@ static void mei_hbm_config_features(struct mei_device *dev)
        /* Fixed Address Client Support */
        if (dev->version.major_version >= HBM_MAJOR_VERSION_FA)
                dev->hbm_f_fa_supported = 1;
+
+       /* OS ver message Support */
+       if (dev->version.major_version >= HBM_MAJOR_VERSION_OS)
+               dev->hbm_f_os_supported = 1;
 }
 
 /**
index 9daf3f9aed2508e08070cb3ef96a53fc43f8d5f9..e1e4d47d4d7d21f5d62a7b514b2886277f9ae9bb 100644 (file)
 #define HBM_MINOR_VERSION_FA               0
 #define HBM_MAJOR_VERSION_FA               2
 
+/*
+ * MEI version with OS ver message support
+ */
+#define HBM_MINOR_VERSION_OS               0
+#define HBM_MAJOR_VERSION_OS               2
+
 /* Host bus message command opcode */
 #define MEI_HBM_CMD_OP_MSK                  0x7f
 /* Host bus message command RESPONSE */
index 699693cd8c59ddde7cd109c550d92f955b0f4c0e..8dadb98662a9e61da14ed8d95268bc9b4ec23d2b 100644 (file)
@@ -406,6 +406,7 @@ const char *mei_pg_state_str(enum mei_pg_state state);
  * @hbm_f_ev_supported  : hbm feature event notification
  * @hbm_f_fa_supported  : hbm feature fixed address client
  * @hbm_f_ie_supported  : hbm feature immediate reply to enum request
+ * @hbm_f_os_supported  : hbm feature support OS ver message
  *
  * @me_clients_rwsem: rw lock over me_clients list
  * @me_clients  : list of FW clients
@@ -487,6 +488,7 @@ struct mei_device {
        unsigned int hbm_f_ev_supported:1;
        unsigned int hbm_f_fa_supported:1;
        unsigned int hbm_f_ie_supported:1;
+       unsigned int hbm_f_os_supported:1;
 
        struct rw_semaphore me_clients_rwsem;
        struct list_head me_clients;
index b11c3455b040c5b03e8083e9b8e4f234b0752537..e6ea8503f40c8466643db34f6ee36ff19345aa89 100644 (file)
@@ -506,9 +506,6 @@ static int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
                }
        } while (busy);
 
-       if (host->ops->card_busy && send_status)
-               return mmc_switch_status(card);
-
        return 0;
 }
 
@@ -577,24 +574,26 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
        if (!use_busy_signal)
                goto out;
 
-       /* Switch to new timing before poll and check switch status. */
-       if (timing)
-               mmc_set_timing(host, timing);
-
        /*If SPI or used HW busy detection above, then we don't need to poll. */
        if (((host->caps & MMC_CAP_WAIT_WHILE_BUSY) && use_r1b_resp) ||
-               mmc_host_is_spi(host)) {
-               if (send_status)
-                       err = mmc_switch_status(card);
+               mmc_host_is_spi(host))
                goto out_tim;
-       }
 
        /* Let's try to poll to find out when the command is completed. */
        err = mmc_poll_for_busy(card, timeout_ms, send_status, retry_crc_err);
+       if (err)
+               goto out;
 
 out_tim:
-       if (err && timing)
-               mmc_set_timing(host, old_timing);
+       /* Switch to new timing before check switch status. */
+       if (timing)
+               mmc_set_timing(host, timing);
+
+       if (send_status) {
+               err = mmc_switch_status(card);
+               if (err && timing)
+                       mmc_set_timing(host, old_timing);
+       }
 out:
        mmc_retune_release(host);
 
index b352760c041ee5332be4eddc61a6f0cf0816bba6..09739352834c8253eedac3000b703e42c37eacfc 100644 (file)
@@ -578,13 +578,15 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id)
 {
        struct meson_host *host = dev_id;
        struct mmc_request *mrq;
-       struct mmc_command *cmd = host->cmd;
+       struct mmc_command *cmd;
        u32 irq_en, status, raw_status;
        irqreturn_t ret = IRQ_HANDLED;
 
        if (WARN_ON(!host))
                return IRQ_NONE;
 
+       cmd = host->cmd;
+
        mrq = host->mrq;
 
        if (WARN_ON(!mrq))
@@ -670,10 +672,10 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id)
        int ret = IRQ_HANDLED;
 
        if (WARN_ON(!mrq))
-               ret = IRQ_NONE;
+               return IRQ_NONE;
 
        if (WARN_ON(!cmd))
-               ret = IRQ_NONE;
+               return IRQ_NONE;
 
        data = cmd->data;
        if (data) {
index 44ecebd1ea8c1834a5d311fbe36ddfc8383e3ecd..c8b8ac66ff7e3a4839ba4943c9069e540846c87e 100644 (file)
@@ -309,6 +309,9 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host)
        cmd0 = BF_SSP(cmd->opcode, CMD0_CMD);
        cmd1 = cmd->arg;
 
+       if (cmd->opcode == MMC_STOP_TRANSMISSION)
+               cmd0 |= BM_SSP_CMD0_APPEND_8CYC;
+
        if (host->sdio_irq_en) {
                ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
                cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN;
@@ -417,8 +420,7 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
                       ssp->base + HW_SSP_BLOCK_SIZE);
        }
 
-       if ((cmd->opcode == MMC_STOP_TRANSMISSION) ||
-           (cmd->opcode == SD_IO_RW_EXTENDED))
+       if (cmd->opcode == SD_IO_RW_EXTENDED)
                cmd0 |= BM_SSP_CMD0_APPEND_8CYC;
 
        cmd1 = cmd->arg;
index 160f695cc09c611cf4aabdeeff236d672c66b639..278a5a435ab76bc422dd748617c96611fe09b105 100644 (file)
@@ -395,7 +395,8 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
        /* Power on the SDHCI controller and its children */
        acpi_device_fix_up_power(device);
        list_for_each_entry(child, &device->children, node)
-               acpi_device_fix_up_power(child);
+               if (child->status.present && child->status.enabled)
+                       acpi_device_fix_up_power(child);
 
        if (acpi_bus_get_status(device) || !device->status.present)
                return -ENODEV;
index 353a9ddf6b975d48d522da646761660b35b44d4c..9ce5dcb4abd0f5026384ed4e0466d1ddfa44c617 100644 (file)
@@ -426,6 +426,7 @@ config MTD_NAND_ORION
 
 config MTD_NAND_OXNAS
        tristate "NAND Flash support for Oxford Semiconductor SoC"
+       depends on HAS_IOMEM
        help
          This enables the NAND flash controller on Oxford Semiconductor SoCs.
 
@@ -540,7 +541,7 @@ config MTD_NAND_FSMC
          Flexible Static Memory Controller (FSMC)
 
 config MTD_NAND_XWAY
-       tristate "Support for NAND on Lantiq XWAY SoC"
+       bool "Support for NAND on Lantiq XWAY SoC"
        depends on LANTIQ && SOC_TYPE_XWAY
        help
          Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
index 5553a5d9efd1144b276a20290f5cb2be9fc302f0..846a66c1b1338f92e65a9548c6fa32e63d834294 100644 (file)
@@ -775,7 +775,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
        init_completion(&host->comp_controller);
 
        host->irq = platform_get_irq(pdev, 0);
-       if ((host->irq < 0) || (host->irq >= NR_IRQS)) {
+       if (host->irq < 0) {
                dev_err(&pdev->dev, "failed to get platform irq\n");
                res = -EINVAL;
                goto err_exit3;
index 28c7f474be77b8b7ccab3379d81bdaa6006594ae..4a5e948c62df1b7d29ff9fe78b50e7d0858b01d5 100644 (file)
@@ -632,11 +632,13 @@ static int tango_nand_probe(struct platform_device *pdev)
        if (IS_ERR(nfc->pbus_base))
                return PTR_ERR(nfc->pbus_base);
 
+       writel_relaxed(MODE_RAW, nfc->pbus_base + PBUS_PAD_MODE);
+
        clk = clk_get(&pdev->dev, NULL);
        if (IS_ERR(clk))
                return PTR_ERR(clk);
 
-       nfc->chan = dma_request_chan(&pdev->dev, "nfc_sbox");
+       nfc->chan = dma_request_chan(&pdev->dev, "rxtx");
        if (IS_ERR(nfc->chan))
                return PTR_ERR(nfc->chan);
 
index 1f2948c0c458d60ec60e898bb1b4893ddba33ecf..895101a5e686457c0dc63237efcb33a79c43a559 100644 (file)
@@ -232,7 +232,6 @@ static const struct of_device_id xway_nand_match[] = {
        { .compatible = "lantiq,nand-xway" },
        {},
 };
-MODULE_DEVICE_TABLE(of, xway_nand_match);
 
 static struct platform_driver xway_nand_driver = {
        .probe  = xway_nand_probe,
@@ -243,6 +242,4 @@ static struct platform_driver xway_nand_driver = {
        },
 };
 
-module_platform_driver(xway_nand_driver);
-
-MODULE_LICENSE("GPL");
+builtin_platform_driver(xway_nand_driver);
index 7e8cf213fd813d8530f65c8439a77fd16ffeff9b..744ed6ddaf373964a2b3526a2b73613932c73c87 100644 (file)
@@ -710,11 +710,8 @@ static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
        unsigned int c_index, last_c_index, last_tx_cn, num_tx_cbs;
        unsigned int pkts_compl = 0, bytes_compl = 0;
        struct bcm_sysport_cb *cb;
-       struct netdev_queue *txq;
        u32 hw_ind;
 
-       txq = netdev_get_tx_queue(ndev, ring->index);
-
        /* Compute how many descriptors have been processed since last call */
        hw_ind = tdma_readl(priv, TDMA_DESC_RING_PROD_CONS_INDEX(ring->index));
        c_index = (hw_ind >> RING_CONS_INDEX_SHIFT) & RING_CONS_INDEX_MASK;
@@ -745,9 +742,6 @@ static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
 
        ring->c_index = c_index;
 
-       if (netif_tx_queue_stopped(txq) && pkts_compl)
-               netif_tx_wake_queue(txq);
-
        netif_dbg(priv, tx_done, ndev,
                  "ring=%d c_index=%d pkts_compl=%d, bytes_compl=%d\n",
                  ring->index, ring->c_index, pkts_compl, bytes_compl);
@@ -759,16 +753,33 @@ static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
 static unsigned int bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
                                           struct bcm_sysport_tx_ring *ring)
 {
+       struct netdev_queue *txq;
        unsigned int released;
        unsigned long flags;
 
+       txq = netdev_get_tx_queue(priv->netdev, ring->index);
+
        spin_lock_irqsave(&ring->lock, flags);
        released = __bcm_sysport_tx_reclaim(priv, ring);
+       if (released)
+               netif_tx_wake_queue(txq);
+
        spin_unlock_irqrestore(&ring->lock, flags);
 
        return released;
 }
 
+/* Locked version of the per-ring TX reclaim, but does not wake the queue */
+static void bcm_sysport_tx_clean(struct bcm_sysport_priv *priv,
+                                struct bcm_sysport_tx_ring *ring)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&ring->lock, flags);
+       __bcm_sysport_tx_reclaim(priv, ring);
+       spin_unlock_irqrestore(&ring->lock, flags);
+}
+
 static int bcm_sysport_tx_poll(struct napi_struct *napi, int budget)
 {
        struct bcm_sysport_tx_ring *ring =
@@ -1252,7 +1263,7 @@ static void bcm_sysport_fini_tx_ring(struct bcm_sysport_priv *priv,
        napi_disable(&ring->napi);
        netif_napi_del(&ring->napi);
 
-       bcm_sysport_tx_reclaim(priv, ring);
+       bcm_sysport_tx_clean(priv, ring);
 
        kfree(ring->cbs);
        ring->cbs = NULL;
index 9211c750e0642660bfdd79bb023f9058a89c18af..2f85b64f01fa06d708e52bde776708f96b55c30e 100644 (file)
@@ -47,8 +47,9 @@ struct lmac {
 struct bgx {
        u8                      bgx_id;
        struct  lmac            lmac[MAX_LMAC_PER_BGX];
-       int                     lmac_count;
+       u8                      lmac_count;
        u8                      max_lmac;
+       u8                      acpi_lmac_idx;
        void __iomem            *reg_base;
        struct pci_dev          *pdev;
        bool                    is_dlm;
@@ -1143,13 +1144,13 @@ static acpi_status bgx_acpi_register_phy(acpi_handle handle,
        if (acpi_bus_get_device(handle, &adev))
                goto out;
 
-       acpi_get_mac_address(dev, adev, bgx->lmac[bgx->lmac_count].mac);
+       acpi_get_mac_address(dev, adev, bgx->lmac[bgx->acpi_lmac_idx].mac);
 
-       SET_NETDEV_DEV(&bgx->lmac[bgx->lmac_count].netdev, dev);
+       SET_NETDEV_DEV(&bgx->lmac[bgx->acpi_lmac_idx].netdev, dev);
 
-       bgx->lmac[bgx->lmac_count].lmacid = bgx->lmac_count;
+       bgx->lmac[bgx->acpi_lmac_idx].lmacid = bgx->acpi_lmac_idx;
+       bgx->acpi_lmac_idx++; /* move to next LMAC */
 out:
-       bgx->lmac_count++;
        return AE_OK;
 }
 
index 0e74529a42095b311c97dc367c2ba3b20bdfc27c..30e855004c57592f9ab6c0cea2eb73f63b59b7ca 100644 (file)
@@ -1118,7 +1118,7 @@ int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
 err:
        mutex_unlock(&adapter->mcc_lock);
 
-        if (status == MCC_STATUS_UNAUTHORIZED_REQUEST)
+        if (base_status(status) == MCC_STATUS_UNAUTHORIZED_REQUEST)
                status = -EPERM;
 
        return status;
index ec010ced6c99626c610609efc7933f7d54ae2619..1a7f8ad7b9c6111ea2f8839a5d28c82af1ef13a8 100644 (file)
@@ -318,6 +318,13 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
        if (ether_addr_equal(addr->sa_data, adapter->dev_mac))
                return 0;
 
+       /* BE3 VFs without FILTMGMT privilege are not allowed to set its MAC
+        * address
+        */
+       if (BEx_chip(adapter) && be_virtfn(adapter) &&
+           !check_privilege(adapter, BE_PRIV_FILTMGMT))
+               return -EPERM;
+
        /* if device is not running, copy MAC to netdev->dev_addr */
        if (!netif_running(netdev))
                goto done;
@@ -3609,7 +3616,11 @@ static void be_rx_qs_destroy(struct be_adapter *adapter)
 
 static void be_disable_if_filters(struct be_adapter *adapter)
 {
-       be_dev_mac_del(adapter, adapter->pmac_id[0]);
+       /* Don't delete MAC on BE3 VFs without FILTMGMT privilege  */
+       if (!BEx_chip(adapter) || !be_virtfn(adapter) ||
+           check_privilege(adapter, BE_PRIV_FILTMGMT))
+               be_dev_mac_del(adapter, adapter->pmac_id[0]);
+
        be_clear_uc_list(adapter);
        be_clear_mc_list(adapter);
 
@@ -3762,8 +3773,9 @@ static int be_enable_if_filters(struct be_adapter *adapter)
        if (status)
                return status;
 
-       /* For BE3 VFs, the PF programs the initial MAC address */
-       if (!(BEx_chip(adapter) && be_virtfn(adapter))) {
+       /* Don't add MAC on BE3 VFs without FILTMGMT privilege */
+       if (!BEx_chip(adapter) || !be_virtfn(adapter) ||
+           check_privilege(adapter, BE_PRIV_FILTMGMT)) {
                status = be_dev_mac_add(adapter, adapter->netdev->dev_addr);
                if (status)
                        return status;
index a849da92f857e5c22cd1ec93158cecbff9c75d90..6b8635378f1fcb2aae4e8ac390bcd09d552c2256 100644 (file)
@@ -101,13 +101,19 @@ void mlx4_cq_completion(struct mlx4_dev *dev, u32 cqn)
 {
        struct mlx4_cq *cq;
 
+       rcu_read_lock();
        cq = radix_tree_lookup(&mlx4_priv(dev)->cq_table.tree,
                               cqn & (dev->caps.num_cqs - 1));
+       rcu_read_unlock();
+
        if (!cq) {
                mlx4_dbg(dev, "Completion event for bogus CQ %08x\n", cqn);
                return;
        }
 
+       /* Acessing the CQ outside of rcu_read_lock is safe, because
+        * the CQ is freed only after interrupt handling is completed.
+        */
        ++cq->arm_sn;
 
        cq->comp(cq);
@@ -118,23 +124,19 @@ void mlx4_cq_event(struct mlx4_dev *dev, u32 cqn, int event_type)
        struct mlx4_cq_table *cq_table = &mlx4_priv(dev)->cq_table;
        struct mlx4_cq *cq;
 
-       spin_lock(&cq_table->lock);
-
+       rcu_read_lock();
        cq = radix_tree_lookup(&cq_table->tree, cqn & (dev->caps.num_cqs - 1));
-       if (cq)
-               atomic_inc(&cq->refcount);
-
-       spin_unlock(&cq_table->lock);
+       rcu_read_unlock();
 
        if (!cq) {
-               mlx4_warn(dev, "Async event for bogus CQ %08x\n", cqn);
+               mlx4_dbg(dev, "Async event for bogus CQ %08x\n", cqn);
                return;
        }
 
+       /* Acessing the CQ outside of rcu_read_lock is safe, because
+        * the CQ is freed only after interrupt handling is completed.
+        */
        cq->event(cq, event_type);
-
-       if (atomic_dec_and_test(&cq->refcount))
-               complete(&cq->free);
 }
 
 static int mlx4_SW2HW_CQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
@@ -301,9 +303,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent,
        if (err)
                return err;
 
-       spin_lock_irq(&cq_table->lock);
+       spin_lock(&cq_table->lock);
        err = radix_tree_insert(&cq_table->tree, cq->cqn, cq);
-       spin_unlock_irq(&cq_table->lock);
+       spin_unlock(&cq_table->lock);
        if (err)
                goto err_icm;
 
@@ -349,9 +351,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent,
        return 0;
 
 err_radix:
-       spin_lock_irq(&cq_table->lock);
+       spin_lock(&cq_table->lock);
        radix_tree_delete(&cq_table->tree, cq->cqn);
-       spin_unlock_irq(&cq_table->lock);
+       spin_unlock(&cq_table->lock);
 
 err_icm:
        mlx4_cq_free_icm(dev, cq->cqn);
@@ -370,15 +372,15 @@ void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq)
        if (err)
                mlx4_warn(dev, "HW2SW_CQ failed (%d) for CQN %06x\n", err, cq->cqn);
 
+       spin_lock(&cq_table->lock);
+       radix_tree_delete(&cq_table->tree, cq->cqn);
+       spin_unlock(&cq_table->lock);
+
        synchronize_irq(priv->eq_table.eq[MLX4_CQ_TO_EQ_VECTOR(cq->vector)].irq);
        if (priv->eq_table.eq[MLX4_CQ_TO_EQ_VECTOR(cq->vector)].irq !=
            priv->eq_table.eq[MLX4_EQ_ASYNC].irq)
                synchronize_irq(priv->eq_table.eq[MLX4_EQ_ASYNC].irq);
 
-       spin_lock_irq(&cq_table->lock);
-       radix_tree_delete(&cq_table->tree, cq->cqn);
-       spin_unlock_irq(&cq_table->lock);
-
        if (atomic_dec_and_test(&cq->refcount))
                complete(&cq->free);
        wait_for_completion(&cq->free);
index 4910d9af19335d4b97d39760c163b41eecc26242..761f8b12399cab245abccc0f7d7f84fde742c14d 100644 (file)
@@ -1748,8 +1748,11 @@ int mlx4_en_start_port(struct net_device *dev)
        /* Process all completions if exist to prevent
         * the queues freezing if they are full
         */
-       for (i = 0; i < priv->rx_ring_num; i++)
+       for (i = 0; i < priv->rx_ring_num; i++) {
+               local_bh_disable();
                napi_schedule(&priv->rx_cq[i]->napi);
+               local_bh_enable();
+       }
 
        netif_tx_start_all_queues(dev);
        netif_device_attach(dev);
index cd3638e6fe25b2f8db4ea5e771535df51652faae..0509996957d9664b612358dd805359f4bc67b8dc 100644 (file)
@@ -554,8 +554,9 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
                        break;
 
                case MLX4_EVENT_TYPE_SRQ_LIMIT:
-                       mlx4_dbg(dev, "%s: MLX4_EVENT_TYPE_SRQ_LIMIT\n",
-                                __func__);
+                       mlx4_dbg(dev, "%s: MLX4_EVENT_TYPE_SRQ_LIMIT. srq_no=0x%x, eq 0x%x\n",
+                                __func__, be32_to_cpu(eqe->event.srq.srqn),
+                                eq->eqn);
                case MLX4_EVENT_TYPE_SRQ_CATAS_ERROR:
                        if (mlx4_is_master(dev)) {
                                /* forward only to slave owning the SRQ */
@@ -570,15 +571,19 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
                                                  eq->eqn, eq->cons_index, ret);
                                        break;
                                }
-                               mlx4_warn(dev, "%s: slave:%d, srq_no:0x%x, event: %02x(%02x)\n",
-                                         __func__, slave,
-                                         be32_to_cpu(eqe->event.srq.srqn),
-                                         eqe->type, eqe->subtype);
+                               if (eqe->type ==
+                                   MLX4_EVENT_TYPE_SRQ_CATAS_ERROR)
+                                       mlx4_warn(dev, "%s: slave:%d, srq_no:0x%x, event: %02x(%02x)\n",
+                                                 __func__, slave,
+                                                 be32_to_cpu(eqe->event.srq.srqn),
+                                                 eqe->type, eqe->subtype);
 
                                if (!ret && slave != dev->caps.function) {
-                                       mlx4_warn(dev, "%s: sending event %02x(%02x) to slave:%d\n",
-                                                 __func__, eqe->type,
-                                                 eqe->subtype, slave);
+                                       if (eqe->type ==
+                                           MLX4_EVENT_TYPE_SRQ_CATAS_ERROR)
+                                               mlx4_warn(dev, "%s: sending event %02x(%02x) to slave:%d\n",
+                                                         __func__, eqe->type,
+                                                         eqe->subtype, slave);
                                        mlx4_slave_event(dev, slave, eqe);
                                        break;
                                }
index 56185a0b827df6394a1edba70cf6925683ffb403..1822382212eed5d77fb290598fbe2d0834480aa9 100644 (file)
@@ -2980,6 +2980,9 @@ int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev *dev, int slave,
                put_res(dev, slave, srqn, RES_SRQ);
                qp->srq = srq;
        }
+
+       /* Save param3 for dynamic changes from VST back to VGT */
+       qp->param3 = qpc->param3;
        put_res(dev, slave, rcqn, RES_CQ);
        put_res(dev, slave, mtt_base, RES_MTT);
        res_end_move(dev, slave, RES_QP, qpn);
@@ -3772,7 +3775,6 @@ int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave,
        int qpn = vhcr->in_modifier & 0x7fffff;
        struct res_qp *qp;
        u8 orig_sched_queue;
-       __be32  orig_param3 = qpc->param3;
        u8 orig_vlan_control = qpc->pri_path.vlan_control;
        u8 orig_fvl_rx = qpc->pri_path.fvl_rx;
        u8 orig_pri_path_fl = qpc->pri_path.fl;
@@ -3814,7 +3816,6 @@ out:
         */
        if (!err) {
                qp->sched_queue = orig_sched_queue;
-               qp->param3      = orig_param3;
                qp->vlan_control = orig_vlan_control;
                qp->fvl_rx      =  orig_fvl_rx;
                qp->pri_path_fl = orig_pri_path_fl;
index 118cea5e5489e69f7496f6772b7f189d66b3ac10..46bef6a26a8cdbebf268b6275271367c4109a77d 100644 (file)
@@ -668,9 +668,12 @@ static int mlx5e_route_lookup_ipv4(struct mlx5e_priv *priv,
        int ttl;
 
 #if IS_ENABLED(CONFIG_INET)
+       int ret;
+
        rt = ip_route_output_key(dev_net(mirred_dev), fl4);
-       if (IS_ERR(rt))
-               return PTR_ERR(rt);
+       ret = PTR_ERR_OR_ZERO(rt);
+       if (ret)
+               return ret;
 #else
        return -EOPNOTSUPP;
 #endif
@@ -741,8 +744,8 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
        struct flowi4 fl4 = {};
        char *encap_header;
        int encap_size;
-       __be32 saddr = 0;
-       int ttl = 0;
+       __be32 saddr;
+       int ttl;
        int err;
 
        encap_header = kzalloc(max_encap_size, GFP_KERNEL);
index d147ddd97997e3c2018f6ae9613a04474990b37e..0af3338bfcb4fbe4681afccaba3a6ca41e59a4e0 100644 (file)
@@ -209,21 +209,21 @@ MLXSW_ITEM32(pci, eqe, owner, 0x0C, 0, 1);
 /* pci_eqe_cmd_token
  * Command completion event - token
  */
-MLXSW_ITEM32(pci, eqe, cmd_token, 0x08, 16, 16);
+MLXSW_ITEM32(pci, eqe, cmd_token, 0x00, 16, 16);
 
 /* pci_eqe_cmd_status
  * Command completion event - status
  */
-MLXSW_ITEM32(pci, eqe, cmd_status, 0x08, 0, 8);
+MLXSW_ITEM32(pci, eqe, cmd_status, 0x00, 0, 8);
 
 /* pci_eqe_cmd_out_param_h
  * Command completion event - output parameter - higher part
  */
-MLXSW_ITEM32(pci, eqe, cmd_out_param_h, 0x0C, 0, 32);
+MLXSW_ITEM32(pci, eqe, cmd_out_param_h, 0x04, 0, 32);
 
 /* pci_eqe_cmd_out_param_l
  * Command completion event - output parameter - lower part
  */
-MLXSW_ITEM32(pci, eqe, cmd_out_param_l, 0x10, 0, 32);
+MLXSW_ITEM32(pci, eqe, cmd_out_param_l, 0x08, 0, 32);
 
 #endif
index d768c7b6c6d6688c46077c48e25df45cdf9ad7dc..003093abb1707f0a6cdefe465e073c005d2ee3f9 100644 (file)
@@ -684,6 +684,7 @@ static netdev_tx_t mlxsw_sp_port_xmit(struct sk_buff *skb,
                        dev_kfree_skb_any(skb_orig);
                        return NETDEV_TX_OK;
                }
+               dev_consume_skb_any(skb_orig);
        }
 
        if (eth_skb_pad(skb)) {
index 150ccf5192a9895d8e6dc1d41c3510c207d870e5..2e88115e87359777279872efaad3581078aaa59e 100644 (file)
@@ -345,6 +345,7 @@ static netdev_tx_t mlxsw_sx_port_xmit(struct sk_buff *skb,
                        dev_kfree_skb_any(skb_orig);
                        return NETDEV_TX_OK;
                }
+               dev_consume_skb_any(skb_orig);
        }
        mlxsw_sx_txhdr_construct(skb, &tx_info);
        /* TX header is consumed by HW on the way so we shouldn't count its
index 99a14df28b9634dd8e6fdeb6bc9bce2d219a3e1a..2851b4c5657049600c6df2c9c9fa90649cbb832a 100644 (file)
@@ -201,6 +201,13 @@ int emac_phy_config(struct platform_device *pdev, struct emac_adapter *adpt)
                else
                        adpt->phydev = mdiobus_get_phy(mii_bus, phy_addr);
 
+               /* of_phy_find_device() claims a reference to the phydev,
+                * so we do that here manually as well. When the driver
+                * later unloads, it can unilaterally drop the reference
+                * without worrying about ACPI vs DT.
+                */
+               if (adpt->phydev)
+                       get_device(&adpt->phydev->mdio.dev);
        } else {
                struct device_node *phy_np;
 
index 422289c232bc77b2c08c49e5646967b94aeedff8..f46d300bd58597ce64cc4cefe3be2b1aa4b03afa 100644 (file)
@@ -719,8 +719,7 @@ static int emac_probe(struct platform_device *pdev)
 err_undo_napi:
        netif_napi_del(&adpt->rx_q.napi);
 err_undo_mdiobus:
-       if (!has_acpi_companion(&pdev->dev))
-               put_device(&adpt->phydev->mdio.dev);
+       put_device(&adpt->phydev->mdio.dev);
        mdiobus_unregister(adpt->mii_bus);
 err_undo_clocks:
        emac_clks_teardown(adpt);
@@ -740,8 +739,7 @@ static int emac_remove(struct platform_device *pdev)
 
        emac_clks_teardown(adpt);
 
-       if (!has_acpi_companion(&pdev->dev))
-               put_device(&adpt->phydev->mdio.dev);
+       put_device(&adpt->phydev->mdio.dev);
        mdiobus_unregister(adpt->mii_bus);
        free_netdev(netdev);
 
index 92d7692c840dbc67e33ca9fe61d3496893def71d..89ac1e3f617599238d35fa444ff66c20abd48dc6 100644 (file)
@@ -926,14 +926,10 @@ static int ravb_poll(struct napi_struct *napi, int budget)
        /* Receive error message handling */
        priv->rx_over_errors =  priv->stats[RAVB_BE].rx_over_errors;
        priv->rx_over_errors += priv->stats[RAVB_NC].rx_over_errors;
-       if (priv->rx_over_errors != ndev->stats.rx_over_errors) {
+       if (priv->rx_over_errors != ndev->stats.rx_over_errors)
                ndev->stats.rx_over_errors = priv->rx_over_errors;
-               netif_err(priv, rx_err, ndev, "Receive Descriptor Empty\n");
-       }
-       if (priv->rx_fifo_errors != ndev->stats.rx_fifo_errors) {
+       if (priv->rx_fifo_errors != ndev->stats.rx_fifo_errors)
                ndev->stats.rx_fifo_errors = priv->rx_fifo_errors;
-               netif_err(priv, rx_err, ndev, "Receive FIFO Overflow\n");
-       }
 out:
        return budget - quota;
 }
@@ -1508,6 +1504,19 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev)
        buffer = PTR_ALIGN(priv->tx_align[q], DPTR_ALIGN) +
                 entry / NUM_TX_DESC * DPTR_ALIGN;
        len = PTR_ALIGN(skb->data, DPTR_ALIGN) - skb->data;
+       /* Zero length DMA descriptors are problematic as they seem to
+        * terminate DMA transfers. Avoid them by simply using a length of
+        * DPTR_ALIGN (4) when skb data is aligned to DPTR_ALIGN.
+        *
+        * As skb is guaranteed to have at least ETH_ZLEN (60) bytes of
+        * data by the call to skb_put_padto() above this is safe with
+        * respect to both the length of the first DMA descriptor (len)
+        * overflowing the available data and the length of the second DMA
+        * descriptor (skb->len - len) being negative.
+        */
+       if (len == 0)
+               len = DPTR_ALIGN;
+
        memcpy(buffer, skb->data, len);
        dma_addr = dma_map_single(ndev->dev.parent, buffer, len, DMA_TO_DEVICE);
        if (dma_mapping_error(ndev->dev.parent, dma_addr))
index a276a32d57f24374444ec06c02b3707fec8fae0a..e3f6389e1b01c5bba89c9cf3b632113fa9b4db42 100644 (file)
@@ -3326,9 +3326,9 @@ int stmmac_dvr_probe(struct device *device,
            (priv->plat->maxmtu >= ndev->min_mtu))
                ndev->max_mtu = priv->plat->maxmtu;
        else if (priv->plat->maxmtu < ndev->min_mtu)
-               netdev_warn(priv->dev,
-                           "%s: warning: maxmtu having invalid value (%d)\n",
-                           __func__, priv->plat->maxmtu);
+               dev_warn(priv->device,
+                        "%s: warning: maxmtu having invalid value (%d)\n",
+                        __func__, priv->plat->maxmtu);
 
        if (flow_ctrl)
                priv->flow_ctrl = FLOW_AUTO;    /* RX/TX pause on */
@@ -3340,7 +3340,8 @@ int stmmac_dvr_probe(struct device *device,
         */
        if ((priv->synopsys_id >= DWMAC_CORE_3_50) && (!priv->plat->riwt_off)) {
                priv->use_riwt = 1;
-               netdev_info(priv->dev, "Enable RX Mitigation via HW Watchdog Timer\n");
+               dev_info(priv->device,
+                        "Enable RX Mitigation via HW Watchdog Timer\n");
        }
 
        netif_napi_add(ndev, &priv->napi, stmmac_poll, 64);
@@ -3366,17 +3367,17 @@ int stmmac_dvr_probe(struct device *device,
                /* MDIO bus Registration */
                ret = stmmac_mdio_register(ndev);
                if (ret < 0) {
-                       netdev_err(priv->dev,
-                                  "%s: MDIO bus (id: %d) registration failed",
-                                  __func__, priv->plat->bus_id);
+                       dev_err(priv->device,
+                               "%s: MDIO bus (id: %d) registration failed",
+                               __func__, priv->plat->bus_id);
                        goto error_mdio_register;
                }
        }
 
        ret = register_netdev(ndev);
        if (ret) {
-               netdev_err(priv->dev, "%s: ERROR %i registering the device\n",
-                          __func__, ret);
+               dev_err(priv->device, "%s: ERROR %i registering the device\n",
+                       __func__, ret);
                goto error_netdev_register;
        }
 
index 77c88fcf2b86f610d8797aec75fba1ac0ba83561..9b8a30bf939bf946baed5f93228178e5fa686037 100644 (file)
@@ -1210,7 +1210,7 @@ int cpmac_init(void)
                goto fail_alloc;
        }
 
-#warning FIXME: unhardcode gpio&reset bits
+       /* FIXME: unhardcode gpio&reset bits */
        ar7_gpio_disable(26);
        ar7_gpio_disable(27);
        ar7_device_reset(AR7_RESET_BIT_CPMAC_LO);
index c9414c0548526657e78f77eb792f14df278eb376..fcab8019dda08ad430d126f9f044f39291a7a154 100644 (file)
@@ -659,6 +659,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
         * policy filters on the host). Deliver these via the VF
         * interface in the guest.
         */
+       rcu_read_lock();
        vf_netdev = rcu_dereference(net_device_ctx->vf_netdev);
        if (vf_netdev && (vf_netdev->flags & IFF_UP))
                net = vf_netdev;
@@ -667,6 +668,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
        skb = netvsc_alloc_recv_skb(net, packet, csum_info, *data, vlan_tci);
        if (unlikely(!skb)) {
                ++net->stats.rx_dropped;
+               rcu_read_unlock();
                return NVSP_STAT_FAIL;
        }
 
@@ -696,6 +698,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
         * TODO - use NAPI?
         */
        netif_rx(skb);
+       rcu_read_unlock();
 
        return 0;
 }
index 46d53a6c8cf868a18ab82a27e730c36e1bc6fb0b..76ba7ecfe14290c7800879c0f80b284f54299ca7 100644 (file)
@@ -1715,9 +1715,9 @@ static int at86rf230_probe(struct spi_device *spi)
        /* Reset */
        if (gpio_is_valid(rstn)) {
                udelay(1);
-               gpio_set_value(rstn, 0);
+               gpio_set_value_cansleep(rstn, 0);
                udelay(1);
-               gpio_set_value(rstn, 1);
+               gpio_set_value_cansleep(rstn, 1);
                usleep_range(120, 240);
        }
 
index 1253f864737ae3cfb10a95ee8c916b5c04dd94b6..ef688518ad77d7ec004e265c3ee9a0086228271a 100644 (file)
@@ -117,13 +117,26 @@ static int atusb_read_reg(struct atusb *atusb, uint8_t reg)
 {
        struct usb_device *usb_dev = atusb->usb_dev;
        int ret;
+       uint8_t *buffer;
        uint8_t value;
 
+       buffer = kmalloc(1, GFP_KERNEL);
+       if (!buffer)
+               return -ENOMEM;
+
        dev_dbg(&usb_dev->dev, "atusb: reg = 0x%x\n", reg);
        ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0),
                                ATUSB_REG_READ, ATUSB_REQ_FROM_DEV,
-                               0, reg, &value, 1, 1000);
-       return ret >= 0 ? value : ret;
+                               0, reg, buffer, 1, 1000);
+
+       if (ret >= 0) {
+               value = buffer[0];
+               kfree(buffer);
+               return value;
+       } else {
+               kfree(buffer);
+               return ret;
+       }
 }
 
 static int atusb_write_subreg(struct atusb *atusb, uint8_t reg, uint8_t mask,
@@ -549,13 +562,6 @@ static int
 atusb_set_frame_retries(struct ieee802154_hw *hw, s8 retries)
 {
        struct atusb *atusb = hw->priv;
-       struct device *dev = &atusb->usb_dev->dev;
-
-       if (atusb->fw_ver_maj == 0 && atusb->fw_ver_min < 3) {
-               dev_info(dev, "Automatic frame retransmission is only available from "
-                       "firmware version 0.3. Please update if you want this feature.");
-               return -EINVAL;
-       }
 
        return atusb_write_subreg(atusb, SR_MAX_FRAME_RETRIES, retries);
 }
@@ -608,9 +614,13 @@ static const struct ieee802154_ops atusb_ops = {
 static int atusb_get_and_show_revision(struct atusb *atusb)
 {
        struct usb_device *usb_dev = atusb->usb_dev;
-       unsigned char buffer[3];
+       unsigned char *buffer;
        int ret;
 
+       buffer = kmalloc(3, GFP_KERNEL);
+       if (!buffer)
+               return -ENOMEM;
+
        /* Get a couple of the ATMega Firmware values */
        ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0),
                                ATUSB_ID, ATUSB_REQ_FROM_DEV, 0, 0,
@@ -631,15 +641,20 @@ static int atusb_get_and_show_revision(struct atusb *atusb)
                dev_info(&usb_dev->dev, "Please update to version 0.2 or newer");
        }
 
+       kfree(buffer);
        return ret;
 }
 
 static int atusb_get_and_show_build(struct atusb *atusb)
 {
        struct usb_device *usb_dev = atusb->usb_dev;
-       char build[ATUSB_BUILD_SIZE + 1];
+       char *build;
        int ret;
 
+       build = kmalloc(ATUSB_BUILD_SIZE + 1, GFP_KERNEL);
+       if (!build)
+               return -ENOMEM;
+
        ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0),
                                ATUSB_BUILD, ATUSB_REQ_FROM_DEV, 0, 0,
                                build, ATUSB_BUILD_SIZE, 1000);
@@ -648,6 +663,7 @@ static int atusb_get_and_show_build(struct atusb *atusb)
                dev_info(&usb_dev->dev, "Firmware: build %s\n", build);
        }
 
+       kfree(build);
        return ret;
 }
 
@@ -698,7 +714,7 @@ fail:
 static int atusb_set_extended_addr(struct atusb *atusb)
 {
        struct usb_device *usb_dev = atusb->usb_dev;
-       unsigned char buffer[IEEE802154_EXTENDED_ADDR_LEN];
+       unsigned char *buffer;
        __le64 extended_addr;
        u64 addr;
        int ret;
@@ -710,12 +726,20 @@ static int atusb_set_extended_addr(struct atusb *atusb)
                return 0;
        }
 
+       buffer = kmalloc(IEEE802154_EXTENDED_ADDR_LEN, GFP_KERNEL);
+       if (!buffer)
+               return -ENOMEM;
+
        /* Firmware is new enough so we fetch the address from EEPROM */
        ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0),
                                ATUSB_EUI64_READ, ATUSB_REQ_FROM_DEV, 0, 0,
                                buffer, IEEE802154_EXTENDED_ADDR_LEN, 1000);
-       if (ret < 0)
-               dev_err(&usb_dev->dev, "failed to fetch extended address\n");
+       if (ret < 0) {
+               dev_err(&usb_dev->dev, "failed to fetch extended address, random address set\n");
+               ieee802154_random_extended_addr(&atusb->hw->phy->perm_extended_addr);
+               kfree(buffer);
+               return ret;
+       }
 
        memcpy(&extended_addr, buffer, IEEE802154_EXTENDED_ADDR_LEN);
        /* Check if read address is not empty and the unicast bit is set correctly */
@@ -729,6 +753,7 @@ static int atusb_set_extended_addr(struct atusb *atusb)
                        &addr);
        }
 
+       kfree(buffer);
        return ret;
 }
 
@@ -770,8 +795,7 @@ static int atusb_probe(struct usb_interface *interface,
 
        hw->parent = &usb_dev->dev;
        hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT |
-                   IEEE802154_HW_PROMISCUOUS | IEEE802154_HW_CSMA_PARAMS |
-                   IEEE802154_HW_FRAME_RETRIES;
+                   IEEE802154_HW_PROMISCUOUS | IEEE802154_HW_CSMA_PARAMS;
 
        hw->phy->flags = WPAN_PHY_FLAG_TXPOWER | WPAN_PHY_FLAG_CCA_ED_LEVEL |
                         WPAN_PHY_FLAG_CCA_MODE;
@@ -800,6 +824,9 @@ static int atusb_probe(struct usb_interface *interface,
        atusb_get_and_show_build(atusb);
        atusb_set_extended_addr(atusb);
 
+       if (atusb->fw_ver_maj >= 0 && atusb->fw_ver_min >= 3)
+               hw->flags |= IEEE802154_HW_FRAME_RETRIES;
+
        ret = atusb_get_and_clear_error(atusb);
        if (ret) {
                dev_err(&atusb->usb_dev->dev,
index e84ae084e259c90649277532f64e563e1091bf28..ca1b462bf7b2782412014b63a0578aa328d9d4e1 100644 (file)
@@ -132,12 +132,16 @@ static int dp83867_of_init(struct phy_device *phydev)
 
        ret = of_property_read_u32(of_node, "ti,rx-internal-delay",
                                   &dp83867->rx_id_delay);
-       if (ret)
+       if (ret &&
+           (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+            phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID))
                return ret;
 
        ret = of_property_read_u32(of_node, "ti,tx-internal-delay",
                                   &dp83867->tx_id_delay);
-       if (ret)
+       if (ret &&
+           (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+            phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID))
                return ret;
 
        return of_property_read_u32(of_node, "ti,fifo-depth",
index be418563cb18c6132cb29d4201b831072749d43b..f3b48ad90865d036845b34ae0fa326dcb4fea297 100644 (file)
@@ -1730,7 +1730,7 @@ static u8 r8152_rx_csum(struct r8152 *tp, struct rx_desc *rx_desc)
        u8 checksum = CHECKSUM_NONE;
        u32 opts2, opts3;
 
-       if (tp->version == RTL_VER_01 || tp->version == RTL_VER_02)
+       if (!(tp->netdev->features & NETIF_F_RXCSUM))
                goto return_result;
 
        opts2 = le32_to_cpu(rx_desc->opts2);
@@ -4356,6 +4356,11 @@ static int rtl8152_probe(struct usb_interface *intf,
                                NETIF_F_HIGHDMA | NETIF_F_FRAGLIST |
                                NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
 
+       if (tp->version == RTL_VER_01) {
+               netdev->features &= ~NETIF_F_RXCSUM;
+               netdev->hw_features &= ~NETIF_F_RXCSUM;
+       }
+
        netdev->ethtool_ops = &ops;
        netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE);
 
index bb70dd5723b587c7d886446547dcec3659a583e4..ca7196c400609b8cfe6fe9da5efae19770258de8 100644 (file)
@@ -1798,7 +1798,7 @@ static int vxlan_build_skb(struct sk_buff *skb, struct dst_entry *dst,
 static struct rtable *vxlan_get_route(struct vxlan_dev *vxlan, struct net_device *dev,
                                      struct vxlan_sock *sock4,
                                      struct sk_buff *skb, int oif, u8 tos,
-                                     __be32 daddr, __be32 *saddr,
+                                     __be32 daddr, __be32 *saddr, __be16 dport, __be16 sport,
                                      struct dst_cache *dst_cache,
                                      const struct ip_tunnel_info *info)
 {
@@ -1824,6 +1824,8 @@ static struct rtable *vxlan_get_route(struct vxlan_dev *vxlan, struct net_device
        fl4.flowi4_proto = IPPROTO_UDP;
        fl4.daddr = daddr;
        fl4.saddr = *saddr;
+       fl4.fl4_dport = dport;
+       fl4.fl4_sport = sport;
 
        rt = ip_route_output_key(vxlan->net, &fl4);
        if (likely(!IS_ERR(rt))) {
@@ -1851,6 +1853,7 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
                                          __be32 label,
                                          const struct in6_addr *daddr,
                                          struct in6_addr *saddr,
+                                         __be16 dport, __be16 sport,
                                          struct dst_cache *dst_cache,
                                          const struct ip_tunnel_info *info)
 {
@@ -1877,6 +1880,8 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
        fl6.flowlabel = ip6_make_flowinfo(RT_TOS(tos), label);
        fl6.flowi6_mark = skb->mark;
        fl6.flowi6_proto = IPPROTO_UDP;
+       fl6.fl6_dport = dport;
+       fl6.fl6_sport = sport;
 
        err = ipv6_stub->ipv6_dst_lookup(vxlan->net,
                                         sock6->sock->sk,
@@ -2068,6 +2073,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                                     rdst ? rdst->remote_ifindex : 0, tos,
                                     dst->sin.sin_addr.s_addr,
                                     &src->sin.sin_addr.s_addr,
+                                    dst_port, src_port,
                                     dst_cache, info);
                if (IS_ERR(rt)) {
                        err = PTR_ERR(rt);
@@ -2104,6 +2110,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                                        rdst ? rdst->remote_ifindex : 0, tos,
                                        label, &dst->sin6.sin6_addr,
                                        &src->sin6.sin6_addr,
+                                       dst_port, src_port,
                                        dst_cache, info);
                if (IS_ERR(ndst)) {
                        err = PTR_ERR(ndst);
@@ -2430,7 +2437,7 @@ static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
 
                rt = vxlan_get_route(vxlan, dev, sock4, skb, 0, info->key.tos,
                                     info->key.u.ipv4.dst,
-                                    &info->key.u.ipv4.src, NULL, info);
+                                    &info->key.u.ipv4.src, dport, sport, NULL, info);
                if (IS_ERR(rt))
                        return PTR_ERR(rt);
                ip_rt_put(rt);
@@ -2441,7 +2448,7 @@ static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
 
                ndst = vxlan6_get_route(vxlan, dev, sock6, skb, 0, info->key.tos,
                                        info->key.label, &info->key.u.ipv6.dst,
-                                       &info->key.u.ipv6.src, NULL, info);
+                                       &info->key.u.ipv6.src, dport, sport, NULL, info);
                if (IS_ERR(ndst))
                        return PTR_ERR(ndst);
                dst_release(ndst);
index 61569a765d9ee17213052db6f0d3a1c41d4d9293..76e03a7de9cc3d790a230948f599ef2db4b93249 100644 (file)
@@ -675,7 +675,7 @@ static struct console univ8250_console = {
        .device         = uart_console_device,
        .setup          = univ8250_console_setup,
        .match          = univ8250_console_match,
-       .flags          = CON_PRINTBUFFER | CON_ANYTIME | CON_CONSDEV,
+       .flags          = CON_PRINTBUFFER | CON_ANYTIME,
        .index          = -1,
        .data           = &serial8250_reg,
 };
index aa0166b6d450dcadc85b89d3939c7ae3dd4f0cbc..116436b7fa52a96c740e025d7b5c613e1d365fa8 100644 (file)
@@ -5642,17 +5642,15 @@ static pci_ers_result_t serial8250_io_slot_reset(struct pci_dev *dev)
 static void serial8250_io_resume(struct pci_dev *dev)
 {
        struct serial_private *priv = pci_get_drvdata(dev);
-       const struct pciserial_board *board;
+       struct serial_private *new;
 
        if (!priv)
                return;
 
-       board = priv->board;
-       kfree(priv);
-       priv = pciserial_init_ports(dev, board);
-
-       if (!IS_ERR(priv)) {
-               pci_set_drvdata(dev, priv);
+       new = pciserial_init_ports(dev, priv->board);
+       if (!IS_ERR(new)) {
+               pci_set_drvdata(dev, new);
+               kfree(priv);
        }
 }
 
index fe4399b41df6cea4904edcee4749bb67532f7e18..c13fec451d03db3bfc382d77ea3b1fdf7b3d04e1 100644 (file)
@@ -1413,7 +1413,7 @@ static void __do_stop_tx_rs485(struct uart_8250_port *p)
         * Enable previously disabled RX interrupts.
         */
        if (!(p->port.rs485.flags & SER_RS485_RX_DURING_TX)) {
-               serial8250_clear_fifos(p);
+               serial8250_clear_and_reinit_fifos(p);
 
                p->ier |= UART_IER_RLSI | UART_IER_RDI;
                serial_port_out(&p->port, UART_IER, p->ier);
index 168b10cad47b5437c2152313fcad026e2747300a..fabbe76203bb76a541775792828d3a8662c78348 100644 (file)
@@ -481,6 +481,14 @@ static void atmel_stop_tx(struct uart_port *port)
                /* disable PDC transmit */
                atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS);
        }
+
+       /*
+        * Disable the transmitter.
+        * This is mandatory when DMA is used, otherwise the DMA buffer
+        * is fully transmitted.
+        */
+       atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS);
+
        /* Disable interrupts */
        atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
 
@@ -513,6 +521,9 @@ static void atmel_start_tx(struct uart_port *port)
 
        /* Enable interrupts */
        atmel_uart_writel(port, ATMEL_US_IER, atmel_port->tx_done_mask);
+
+       /* re-enable the transmitter */
+       atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN);
 }
 
 /*
@@ -798,6 +809,11 @@ static void atmel_complete_tx_dma(void *arg)
         */
        if (!uart_circ_empty(xmit))
                atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_tx);
+       else if ((port->rs485.flags & SER_RS485_ENABLED) &&
+                !(port->rs485.flags & SER_RS485_RX_DURING_TX)) {
+               /* DMA done, stop TX, start RX for RS485 */
+               atmel_start_rx(port);
+       }
 
        spin_unlock_irqrestore(&port->lock, flags);
 }
@@ -900,12 +916,6 @@ static void atmel_tx_dma(struct uart_port *port)
                desc->callback = atmel_complete_tx_dma;
                desc->callback_param = atmel_port;
                atmel_port->cookie_tx = dmaengine_submit(desc);
-
-       } else {
-               if (port->rs485.flags & SER_RS485_ENABLED) {
-                       /* DMA done, stop TX, start RX for RS485 */
-                       atmel_start_rx(port);
-               }
        }
 
        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
index 52bbd27e93ae7a83af92489b6d27fe0309437afe..701c085bb19b8e03f67316133fa5a4be7e0b05fe 100644 (file)
@@ -946,8 +946,8 @@ static const struct input_device_id sysrq_ids[] = {
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
                                INPUT_DEVICE_ID_MATCH_KEYBIT,
-               .evbit = { BIT_MASK(EV_KEY) },
-               .keybit = { BIT_MASK(KEY_LEFTALT) },
+               .evbit = { [BIT_WORD(EV_KEY)] = BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(KEY_LEFTALT)] = BIT_MASK(KEY_LEFTALT) },
        },
        { },
 };
index 25f522b09dd9746938168e6f675464db9f2e6740..e32029a31ca4d2ed5856c18e6e10b4b40de1132a 100644 (file)
@@ -913,17 +913,6 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
        spin_lock_irqsave(&xhci->lock, flags);
 
        ep->stop_cmds_pending--;
-       if (xhci->xhc_state & XHCI_STATE_REMOVING) {
-               spin_unlock_irqrestore(&xhci->lock, flags);
-               return;
-       }
-       if (xhci->xhc_state & XHCI_STATE_DYING) {
-               xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
-                               "Stop EP timer ran, but another timer marked "
-                               "xHCI as DYING, exiting.");
-               spin_unlock_irqrestore(&xhci->lock, flags);
-               return;
-       }
        if (!(ep->stop_cmds_pending == 0 && (ep->ep_state & EP_HALT_PENDING))) {
                xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
                                "Stop EP timer ran, but no command pending, "
index 0c8deb9ed42def112efc8ad1aaf95526315c164f..9a0ec116654acd27740d497c76ba1a6bb6ab6dd9 100644 (file)
@@ -1534,19 +1534,6 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
                xhci_urb_free_priv(urb_priv);
                return ret;
        }
-       if ((xhci->xhc_state & XHCI_STATE_DYING) ||
-                       (xhci->xhc_state & XHCI_STATE_HALTED)) {
-               xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
-                               "Ep 0x%x: URB %p to be canceled on "
-                               "non-responsive xHCI host.",
-                               urb->ep->desc.bEndpointAddress, urb);
-               /* Let the stop endpoint command watchdog timer (which set this
-                * state) finish cleaning up the endpoint TD lists.  We must
-                * have caught it in the middle of dropping a lock and giving
-                * back an URB.
-                */
-               goto done;
-       }
 
        ep_index = xhci_get_endpoint_index(&urb->ep->desc);
        ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index];
index 4fef50e5c8c1295364aca0a28ba9cf8da005ac21..dd70c88419d20798b738c3da2df009887fdfec7f 100644 (file)
@@ -114,6 +114,7 @@ static int musb_regdump_show(struct seq_file *s, void *unused)
        unsigned                i;
 
        seq_printf(s, "MUSB (M)HDRC Register Dump\n");
+       pm_runtime_get_sync(musb->controller);
 
        for (i = 0; i < ARRAY_SIZE(musb_regmap); i++) {
                switch (musb_regmap[i].size) {
@@ -132,6 +133,8 @@ static int musb_regdump_show(struct seq_file *s, void *unused)
                }
        }
 
+       pm_runtime_mark_last_busy(musb->controller);
+       pm_runtime_put_autosuspend(musb->controller);
        return 0;
 }
 
@@ -145,7 +148,10 @@ static int musb_test_mode_show(struct seq_file *s, void *unused)
        struct musb             *musb = s->private;
        unsigned                test;
 
+       pm_runtime_get_sync(musb->controller);
        test = musb_readb(musb->mregs, MUSB_TESTMODE);
+       pm_runtime_mark_last_busy(musb->controller);
+       pm_runtime_put_autosuspend(musb->controller);
 
        if (test & MUSB_TEST_FORCE_HOST)
                seq_printf(s, "force host\n");
@@ -194,11 +200,12 @@ static ssize_t musb_test_mode_write(struct file *file,
        u8                      test;
        char                    buf[18];
 
+       pm_runtime_get_sync(musb->controller);
        test = musb_readb(musb->mregs, MUSB_TESTMODE);
        if (test) {
                dev_err(musb->controller, "Error: test mode is already set. "
                        "Please do USB Bus Reset to start a new test.\n");
-               return count;
+               goto ret;
        }
 
        memset(buf, 0x00, sizeof(buf));
@@ -234,6 +241,9 @@ static ssize_t musb_test_mode_write(struct file *file,
 
        musb_writeb(musb->mregs, MUSB_TESTMODE, test);
 
+ret:
+       pm_runtime_mark_last_busy(musb->controller);
+       pm_runtime_put_autosuspend(musb->controller);
        return count;
 }
 
@@ -254,8 +264,13 @@ static int musb_softconnect_show(struct seq_file *s, void *unused)
        switch (musb->xceiv->otg->state) {
        case OTG_STATE_A_HOST:
        case OTG_STATE_A_WAIT_BCON:
+               pm_runtime_get_sync(musb->controller);
+
                reg = musb_readb(musb->mregs, MUSB_DEVCTL);
                connect = reg & MUSB_DEVCTL_SESSION ? 1 : 0;
+
+               pm_runtime_mark_last_busy(musb->controller);
+               pm_runtime_put_autosuspend(musb->controller);
                break;
        default:
                connect = -1;
@@ -284,6 +299,7 @@ static ssize_t musb_softconnect_write(struct file *file,
        if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
                return -EFAULT;
 
+       pm_runtime_get_sync(musb->controller);
        if (!strncmp(buf, "0", 1)) {
                switch (musb->xceiv->otg->state) {
                case OTG_STATE_A_HOST:
@@ -314,6 +330,8 @@ static ssize_t musb_softconnect_write(struct file *file,
                }
        }
 
+       pm_runtime_mark_last_busy(musb->controller);
+       pm_runtime_put_autosuspend(musb->controller);
        return count;
 }
 
index 2597b83a8ae254d0eff28b2d2d124ff51c196248..95aa5233726cf86166ae5aad2ea88c446e894d13 100644 (file)
@@ -95,6 +95,7 @@ struct ch341_private {
        unsigned baud_rate; /* set baud rate */
        u8 line_control; /* set line control value RTS/DTR */
        u8 line_status; /* active status of modem control inputs */
+       u8 lcr;
 };
 
 static void ch341_set_termios(struct tty_struct *tty,
@@ -112,6 +113,8 @@ static int ch341_control_out(struct usb_device *dev, u8 request,
        r = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request,
                            USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
                            value, index, NULL, 0, DEFAULT_TIMEOUT);
+       if (r < 0)
+               dev_err(&dev->dev, "failed to send control message: %d\n", r);
 
        return r;
 }
@@ -129,11 +132,24 @@ static int ch341_control_in(struct usb_device *dev,
        r = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request,
                            USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
                            value, index, buf, bufsize, DEFAULT_TIMEOUT);
-       return r;
+       if (r < bufsize) {
+               if (r >= 0) {
+                       dev_err(&dev->dev,
+                               "short control message received (%d < %u)\n",
+                               r, bufsize);
+                       r = -EIO;
+               }
+
+               dev_err(&dev->dev, "failed to receive control message: %d\n",
+                       r);
+               return r;
+       }
+
+       return 0;
 }
 
-static int ch341_init_set_baudrate(struct usb_device *dev,
-                                  struct ch341_private *priv, unsigned ctrl)
+static int ch341_set_baudrate_lcr(struct usb_device *dev,
+                                 struct ch341_private *priv, u8 lcr)
 {
        short a;
        int r;
@@ -156,9 +172,19 @@ static int ch341_init_set_baudrate(struct usb_device *dev,
        factor = 0x10000 - factor;
        a = (factor & 0xff00) | divisor;
 
-       /* 0x9c is "enable SFR_UART Control register and timer" */
-       r = ch341_control_out(dev, CH341_REQ_SERIAL_INIT,
-                             0x9c | (ctrl << 8), a | 0x80);
+       /*
+        * CH341A buffers data until a full endpoint-size packet (32 bytes)
+        * has been received unless bit 7 is set.
+        */
+       a |= BIT(7);
+
+       r = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x1312, a);
+       if (r)
+               return r;
+
+       r = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x2518, lcr);
+       if (r)
+               return r;
 
        return r;
 }
@@ -170,9 +196,9 @@ static int ch341_set_handshake(struct usb_device *dev, u8 control)
 
 static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv)
 {
+       const unsigned int size = 2;
        char *buffer;
        int r;
-       const unsigned size = 8;
        unsigned long flags;
 
        buffer = kmalloc(size, GFP_KERNEL);
@@ -183,14 +209,9 @@ static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv)
        if (r < 0)
                goto out;
 
-       /* setup the private status if available */
-       if (r == 2) {
-               r = 0;
-               spin_lock_irqsave(&priv->lock, flags);
-               priv->line_status = (~(*buffer)) & CH341_BITS_MODEM_STAT;
-               spin_unlock_irqrestore(&priv->lock, flags);
-       } else
-               r = -EPROTO;
+       spin_lock_irqsave(&priv->lock, flags);
+       priv->line_status = (~(*buffer)) & CH341_BITS_MODEM_STAT;
+       spin_unlock_irqrestore(&priv->lock, flags);
 
 out:   kfree(buffer);
        return r;
@@ -200,9 +221,9 @@ out:        kfree(buffer);
 
 static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)
 {
+       const unsigned int size = 2;
        char *buffer;
        int r;
-       const unsigned size = 8;
 
        buffer = kmalloc(size, GFP_KERNEL);
        if (!buffer)
@@ -232,7 +253,7 @@ static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)
        if (r < 0)
                goto out;
 
-       r = ch341_init_set_baudrate(dev, priv, 0);
+       r = ch341_set_baudrate_lcr(dev, priv, priv->lcr);
        if (r < 0)
                goto out;
 
@@ -258,7 +279,6 @@ static int ch341_port_probe(struct usb_serial_port *port)
 
        spin_lock_init(&priv->lock);
        priv->baud_rate = DEFAULT_BAUD_RATE;
-       priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;
 
        r = ch341_configure(port->serial->dev, priv);
        if (r < 0)
@@ -320,7 +340,7 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port)
 
        r = ch341_configure(serial->dev, priv);
        if (r)
-               goto out;
+               return r;
 
        if (tty)
                ch341_set_termios(tty, port, NULL);
@@ -330,12 +350,19 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port)
        if (r) {
                dev_err(&port->dev, "%s - failed to submit interrupt urb: %d\n",
                        __func__, r);
-               goto out;
+               return r;
        }
 
        r = usb_serial_generic_open(tty, port);
+       if (r)
+               goto err_kill_interrupt_urb;
+
+       return 0;
+
+err_kill_interrupt_urb:
+       usb_kill_urb(port->interrupt_in_urb);
 
-out:   return r;
+       return r;
 }
 
 /* Old_termios contains the original termios settings and
@@ -356,7 +383,6 @@ static void ch341_set_termios(struct tty_struct *tty,
 
        baud_rate = tty_get_baud_rate(tty);
 
-       priv->baud_rate = baud_rate;
        ctrl = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX;
 
        switch (C_CSIZE(tty)) {
@@ -386,22 +412,25 @@ static void ch341_set_termios(struct tty_struct *tty,
                ctrl |= CH341_LCR_STOP_BITS_2;
 
        if (baud_rate) {
-               spin_lock_irqsave(&priv->lock, flags);
-               priv->line_control |= (CH341_BIT_DTR | CH341_BIT_RTS);
-               spin_unlock_irqrestore(&priv->lock, flags);
-               r = ch341_init_set_baudrate(port->serial->dev, priv, ctrl);
+               priv->baud_rate = baud_rate;
+
+               r = ch341_set_baudrate_lcr(port->serial->dev, priv, ctrl);
                if (r < 0 && old_termios) {
                        priv->baud_rate = tty_termios_baud_rate(old_termios);
                        tty_termios_copy_hw(&tty->termios, old_termios);
+               } else if (r == 0) {
+                       priv->lcr = ctrl;
                }
-       } else {
-               spin_lock_irqsave(&priv->lock, flags);
-               priv->line_control &= ~(CH341_BIT_DTR | CH341_BIT_RTS);
-               spin_unlock_irqrestore(&priv->lock, flags);
        }
 
-       ch341_set_handshake(port->serial->dev, priv->line_control);
+       spin_lock_irqsave(&priv->lock, flags);
+       if (C_BAUD(tty) == B0)
+               priv->line_control &= ~(CH341_BIT_DTR | CH341_BIT_RTS);
+       else if (old_termios && (old_termios->c_cflag & CBAUD) == B0)
+               priv->line_control |= (CH341_BIT_DTR | CH341_BIT_RTS);
+       spin_unlock_irqrestore(&priv->lock, flags);
 
+       ch341_set_handshake(port->serial->dev, priv->line_control);
 }
 
 static void ch341_break_ctl(struct tty_struct *tty, int break_state)
@@ -576,14 +605,23 @@ static int ch341_tiocmget(struct tty_struct *tty)
 
 static int ch341_reset_resume(struct usb_serial *serial)
 {
-       struct ch341_private *priv;
-
-       priv = usb_get_serial_port_data(serial->port[0]);
+       struct usb_serial_port *port = serial->port[0];
+       struct ch341_private *priv = usb_get_serial_port_data(port);
+       int ret;
 
        /* reconfigure ch341 serial port after bus-reset */
        ch341_configure(serial->dev, priv);
 
-       return 0;
+       if (tty_port_initialized(&port->port)) {
+               ret = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
+               if (ret) {
+                       dev_err(&port->dev, "failed to submit interrupt urb: %d\n",
+                               ret);
+                       return ret;
+               }
+       }
+
+       return usb_serial_generic_resume(serial);
 }
 
 static struct usb_serial_driver ch341_device = {
index 0ee190fc1bf8ce7154a4a4eac7023a377aa03365..6cb45757818fae2222383358b4d38d7c87b2dbf4 100644 (file)
@@ -192,10 +192,11 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
                             status_buf, KLSI_STATUSBUF_LEN,
                             10000
                             );
-       if (rc < 0)
-               dev_err(&port->dev, "Reading line status failed (error = %d)\n",
-                       rc);
-       else {
+       if (rc != KLSI_STATUSBUF_LEN) {
+               dev_err(&port->dev, "reading line status failed: %d\n", rc);
+               if (rc >= 0)
+                       rc = -EIO;
+       } else {
                status = get_unaligned_le16(status_buf);
 
                dev_info(&port->serial->dev->dev, "read status %x %x\n",
index 79451f7ef1b76301cc881379ad28ce12e4b4dc33..062c205f00469faf1f7226e152f61d920d71f27b 100644 (file)
@@ -216,7 +216,6 @@ static int wusb_ccm_mac(struct crypto_skcipher *tfm_cbc,
        struct scatterlist sg[4], sg_dst;
        void *dst_buf;
        size_t dst_size;
-       const u8 bzero[16] = { 0 };
        u8 iv[crypto_skcipher_ivsize(tfm_cbc)];
        size_t zero_padding;
 
@@ -261,7 +260,7 @@ static int wusb_ccm_mac(struct crypto_skcipher *tfm_cbc,
        sg_set_buf(&sg[1], &scratch->b1, sizeof(scratch->b1));
        sg_set_buf(&sg[2], b, blen);
        /* 0 if well behaved :) */
-       sg_set_buf(&sg[3], bzero, zero_padding);
+       sg_set_page(&sg[3], ZERO_PAGE(0), zero_padding, 0);
        sg_init_one(&sg_dst, dst_buf, dst_size);
 
        skcipher_request_set_tfm(req, tfm_cbc);
index 6b5ee896af6318e9b50c384fcf3e062d24d89c47..7cc51223db1cbe8e905307850b7bd42b6c739279 100644 (file)
@@ -464,7 +464,7 @@ static int ca91cx42_slave_get(struct vme_slave_resource *image, int *enabled,
        vme_bound = ioread32(bridge->base + CA91CX42_VSI_BD[i]);
        pci_offset = ioread32(bridge->base + CA91CX42_VSI_TO[i]);
 
-       *pci_base = (dma_addr_t)vme_base + pci_offset;
+       *pci_base = (dma_addr_t)*vme_base + pci_offset;
        *size = (unsigned long long)((vme_bound - *vme_base) + granularity);
 
        *enabled = 0;
index 769903dbc19df53199b4aca2e79607145e179c98..95d71eda81420a506c5a1f4a4f5283b31310d5e4 100644 (file)
@@ -1336,8 +1336,11 @@ int d_set_mounted(struct dentry *dentry)
        }
        spin_lock(&dentry->d_lock);
        if (!d_unlinked(dentry)) {
-               dentry->d_flags |= DCACHE_MOUNTED;
-               ret = 0;
+               ret = -EBUSY;
+               if (!d_mountpoint(dentry)) {
+                       dentry->d_flags |= DCACHE_MOUNTED;
+                       ret = 0;
+               }
        }
        spin_unlock(&dentry->d_lock);
 out:
index e973cd51f12632eff2c17929c85d1e8b2e955730..28d6f35feed62855e26ede0073b3bcaf6b6564a9 100644 (file)
@@ -245,7 +245,8 @@ struct dentry *mount_pseudo_xattr(struct file_system_type *fs_type, char *name,
        struct inode *root;
        struct qstr d_name = QSTR_INIT(name, strlen(name));
 
-       s = sget(fs_type, NULL, set_anon_super, MS_NOUSER, NULL);
+       s = sget_userns(fs_type, NULL, set_anon_super, MS_KERNMOUNT|MS_NOUSER,
+                       &init_user_ns, NULL);
        if (IS_ERR(s))
                return ERR_CAST(s);
 
index b5b1259e064f8d9661110ba1f1f73d1a0ff19d51..487ba30bb5c67a8f66bdaadb5b13e8240c937f7a 100644 (file)
@@ -742,26 +742,50 @@ static struct mountpoint *lookup_mountpoint(struct dentry *dentry)
        return NULL;
 }
 
-static struct mountpoint *new_mountpoint(struct dentry *dentry)
+static struct mountpoint *get_mountpoint(struct dentry *dentry)
 {
-       struct hlist_head *chain = mp_hash(dentry);
-       struct mountpoint *mp;
+       struct mountpoint *mp, *new = NULL;
        int ret;
 
-       mp = kmalloc(sizeof(struct mountpoint), GFP_KERNEL);
-       if (!mp)
+       if (d_mountpoint(dentry)) {
+mountpoint:
+               read_seqlock_excl(&mount_lock);
+               mp = lookup_mountpoint(dentry);
+               read_sequnlock_excl(&mount_lock);
+               if (mp)
+                       goto done;
+       }
+
+       if (!new)
+               new = kmalloc(sizeof(struct mountpoint), GFP_KERNEL);
+       if (!new)
                return ERR_PTR(-ENOMEM);
 
+
+       /* Exactly one processes may set d_mounted */
        ret = d_set_mounted(dentry);
-       if (ret) {
-               kfree(mp);
-               return ERR_PTR(ret);
-       }
 
-       mp->m_dentry = dentry;
-       mp->m_count = 1;
-       hlist_add_head(&mp->m_hash, chain);
-       INIT_HLIST_HEAD(&mp->m_list);
+       /* Someone else set d_mounted? */
+       if (ret == -EBUSY)
+               goto mountpoint;
+
+       /* The dentry is not available as a mountpoint? */
+       mp = ERR_PTR(ret);
+       if (ret)
+               goto done;
+
+       /* Add the new mountpoint to the hash table */
+       read_seqlock_excl(&mount_lock);
+       new->m_dentry = dentry;
+       new->m_count = 1;
+       hlist_add_head(&new->m_hash, mp_hash(dentry));
+       INIT_HLIST_HEAD(&new->m_list);
+       read_sequnlock_excl(&mount_lock);
+
+       mp = new;
+       new = NULL;
+done:
+       kfree(new);
        return mp;
 }
 
@@ -1595,11 +1619,11 @@ void __detach_mounts(struct dentry *dentry)
        struct mount *mnt;
 
        namespace_lock();
+       lock_mount_hash();
        mp = lookup_mountpoint(dentry);
        if (IS_ERR_OR_NULL(mp))
                goto out_unlock;
 
-       lock_mount_hash();
        event++;
        while (!hlist_empty(&mp->m_list)) {
                mnt = hlist_entry(mp->m_list.first, struct mount, mnt_mp_list);
@@ -1609,9 +1633,9 @@ void __detach_mounts(struct dentry *dentry)
                }
                else umount_tree(mnt, UMOUNT_CONNECTED);
        }
-       unlock_mount_hash();
        put_mountpoint(mp);
 out_unlock:
+       unlock_mount_hash();
        namespace_unlock();
 }
 
@@ -2038,9 +2062,7 @@ retry:
        namespace_lock();
        mnt = lookup_mnt(path);
        if (likely(!mnt)) {
-               struct mountpoint *mp = lookup_mountpoint(dentry);
-               if (!mp)
-                       mp = new_mountpoint(dentry);
+               struct mountpoint *mp = get_mountpoint(dentry);
                if (IS_ERR(mp)) {
                        namespace_unlock();
                        inode_unlock(dentry->d_inode);
@@ -2059,7 +2081,11 @@ retry:
 static void unlock_mount(struct mountpoint *where)
 {
        struct dentry *dentry = where->m_dentry;
+
+       read_seqlock_excl(&mount_lock);
        put_mountpoint(where);
+       read_sequnlock_excl(&mount_lock);
+
        namespace_unlock();
        inode_unlock(dentry->d_inode);
 }
@@ -3135,9 +3161,9 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
        touch_mnt_namespace(current->nsproxy->mnt_ns);
        /* A moved mount should not expire automatically */
        list_del_init(&new_mnt->mnt_expire);
+       put_mountpoint(root_mp);
        unlock_mount_hash();
        chroot_fs_refs(&root, &new);
-       put_mountpoint(root_mp);
        error = 0;
 out4:
        unlock_mount(old_mp);
index 6dcbc5defb7a8dd670b63995eb553c379e47a0d4..ecc151697fd4bd81288941848a4b6a76e7563a24 100644 (file)
@@ -38,7 +38,6 @@
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
-#include <linux/file.h>
 #include <linux/string.h>
 #include <linux/ratelimit.h>
 #include <linux/printk.h>
@@ -1083,7 +1082,8 @@ int nfs4_call_sync(struct rpc_clnt *clnt,
        return nfs4_call_sync_sequence(clnt, server, msg, args, res);
 }
 
-static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
+static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo,
+               unsigned long timestamp)
 {
        struct nfs_inode *nfsi = NFS_I(dir);
 
@@ -1099,6 +1099,7 @@ static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
                                NFS_INO_INVALID_ACL;
        }
        dir->i_version = cinfo->after;
+       nfsi->read_cache_jiffies = timestamp;
        nfsi->attr_gencount = nfs_inc_attr_generation_counter();
        nfs_fscache_invalidate(dir);
        spin_unlock(&dir->i_lock);
@@ -2391,11 +2392,13 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
        nfs_fattr_map_and_free_names(server, &data->f_attr);
 
        if (o_arg->open_flags & O_CREAT) {
-               update_changeattr(dir, &o_res->cinfo);
                if (o_arg->open_flags & O_EXCL)
                        data->file_created = 1;
                else if (o_res->cinfo.before != o_res->cinfo.after)
                        data->file_created = 1;
+               if (data->file_created || dir->i_version != o_res->cinfo.after)
+                       update_changeattr(dir, &o_res->cinfo,
+                                       o_res->f_attr->time_start);
        }
        if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0)
                server->caps &= ~NFS_CAP_POSIX_LOCK;
@@ -4073,11 +4076,12 @@ static int _nfs4_proc_remove(struct inode *dir, const struct qstr *name)
                .rpc_argp = &args,
                .rpc_resp = &res,
        };
+       unsigned long timestamp = jiffies;
        int status;
 
        status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 1);
        if (status == 0)
-               update_changeattr(dir, &res.cinfo);
+               update_changeattr(dir, &res.cinfo, timestamp);
        return status;
 }
 
@@ -4125,7 +4129,8 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
        if (nfs4_async_handle_error(task, res->server, NULL,
                                    &data->timeout) == -EAGAIN)
                return 0;
-       update_changeattr(dir, &res->cinfo);
+       if (task->tk_status == 0)
+               update_changeattr(dir, &res->cinfo, res->dir_attr->time_start);
        return 1;
 }
 
@@ -4159,8 +4164,11 @@ static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
        if (nfs4_async_handle_error(task, res->server, NULL, &data->timeout) == -EAGAIN)
                return 0;
 
-       update_changeattr(old_dir, &res->old_cinfo);
-       update_changeattr(new_dir, &res->new_cinfo);
+       if (task->tk_status == 0) {
+               update_changeattr(old_dir, &res->old_cinfo, res->old_fattr->time_start);
+               if (new_dir != old_dir)
+                       update_changeattr(new_dir, &res->new_cinfo, res->new_fattr->time_start);
+       }
        return 1;
 }
 
@@ -4197,7 +4205,7 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, const struct
 
        status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
        if (!status) {
-               update_changeattr(dir, &res.cinfo);
+               update_changeattr(dir, &res.cinfo, res.fattr->time_start);
                status = nfs_post_op_update_inode(inode, res.fattr);
                if (!status)
                        nfs_setsecurity(inode, res.fattr, res.label);
@@ -4272,7 +4280,8 @@ static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_
        int status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &data->msg,
                                    &data->arg.seq_args, &data->res.seq_res, 1);
        if (status == 0) {
-               update_changeattr(dir, &data->res.dir_cinfo);
+               update_changeattr(dir, &data->res.dir_cinfo,
+                               data->res.fattr->time_start);
                status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, data->res.label);
        }
        return status;
@@ -6127,7 +6136,6 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
        p->server = server;
        atomic_inc(&lsp->ls_count);
        p->ctx = get_nfs_open_context(ctx);
-       get_file(fl->fl_file);
        memcpy(&p->fl, fl, sizeof(p->fl));
        return p;
 out_free_seqid:
@@ -6240,7 +6248,6 @@ static void nfs4_lock_release(void *calldata)
                nfs_free_seqid(data->arg.lock_seqid);
        nfs4_put_lock_state(data->lsp);
        put_nfs_open_context(data->ctx);
-       fput(data->fl.fl_file);
        kfree(data);
        dprintk("%s: done!\n", __func__);
 }
index 1d152f4470cd6f6b0bcc6f73fd572e331b18778b..90e6193ce6bed300ddadb1aa1a9aca64a8c2aafc 100644 (file)
@@ -1729,7 +1729,6 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
                        break;
                case -NFS4ERR_STALE_CLIENTID:
                        set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
-                       nfs4_state_clear_reclaim_reboot(clp);
                        nfs4_state_start_reclaim_reboot(clp);
                        break;
                case -NFS4ERR_EXPIRED:
index 7ecf16be4a444ec250678e89ad210c7f19cbbc18..8fae53ce21d16c8406ff01425d924eb044edee34 100644 (file)
@@ -2440,7 +2440,9 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
        p++;                /* to be backfilled later */
 
        if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
-               u32 *supp = nfsd_suppattrs[minorversion];
+               u32 supp[3];
+
+               memcpy(supp, nfsd_suppattrs[minorversion], sizeof(supp));
 
                if (!IS_POSIXACL(dentry->d_inode))
                        supp[0] &= ~FATTR4_WORD0_ACL;
index 55313d9948954bbe4bff5769e487eb78012776db..d4e37acd48217dcb1090a1ee68bb4ec4cb7226e5 100644 (file)
@@ -709,7 +709,7 @@ static int proc_sys_readdir(struct file *file, struct dir_context *ctx)
        ctl_dir = container_of(head, struct ctl_dir, header);
 
        if (!dir_emit_dots(file, ctx))
-               return 0;
+               goto out;
 
        pos = 2;
 
@@ -719,6 +719,7 @@ static int proc_sys_readdir(struct file *file, struct dir_context *ctx)
                        break;
                }
        }
+out:
        sysctl_head_finish(head);
        return 0;
 }
index f74ae68086dc69b3c02ced58a13f6daed0b4cd77..05cf951df3fedd12b742b9478af13aeace86749c 100644 (file)
@@ -216,7 +216,7 @@ u64 bpf_tail_call(u64 ctx, u64 r2, u64 index, u64 r4, u64 r5);
 u64 bpf_get_stackid(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
 
 bool bpf_prog_array_compatible(struct bpf_array *array, const struct bpf_prog *fp);
-int bpf_prog_calc_digest(struct bpf_prog *fp);
+int bpf_prog_calc_tag(struct bpf_prog *fp);
 
 const struct bpf_func_proto *bpf_get_trace_printk_proto(void);
 
index a07a476178cd1b4c59295ba2c1ee420c1bbb696e..5b1af30ece55828e655b2bf02a149fd71354f3eb 100644 (file)
@@ -103,6 +103,7 @@ typedef     struct {
 
 #define EFI_PAGE_SHIFT         12
 #define EFI_PAGE_SIZE          (1UL << EFI_PAGE_SHIFT)
+#define EFI_PAGES_MAX          (U64_MAX >> EFI_PAGE_SHIFT)
 
 typedef struct {
        u32 type;
@@ -950,6 +951,7 @@ static inline efi_status_t efi_query_variable_store(u32 attributes,
 #endif
 extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr);
 
+extern phys_addr_t __init efi_memmap_alloc(unsigned int num_entries);
 extern int __init efi_memmap_init_early(struct efi_memory_map_data *data);
 extern int __init efi_memmap_init_late(phys_addr_t addr, unsigned long size);
 extern void __init efi_memmap_unmap(void);
index a0934e6c9babf8436a18b28f4dea285894e5dca5..e4eb2546339afbf2764f5ba335e1e66947fc5af3 100644 (file)
@@ -57,6 +57,8 @@ struct bpf_prog_aux;
 /* BPF program can access up to 512 bytes of stack space. */
 #define MAX_BPF_STACK  512
 
+#define BPF_TAG_SIZE   8
+
 /* Helper macros for filter block array initializers. */
 
 /* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */
@@ -408,7 +410,7 @@ struct bpf_prog {
        kmemcheck_bitfield_end(meta);
        enum bpf_prog_type      type;           /* Type of BPF program */
        u32                     len;            /* Number of filter blocks */
-       u32                     digest[SHA_DIGEST_WORDS]; /* Program digest */
+       u8                      tag[BPF_TAG_SIZE];
        struct bpf_prog_aux     *aux;           /* Auxiliary fields */
        struct sock_fprog_kern  *orig_prog;     /* Original BPF program */
        unsigned int            (*bpf_func)(const void *ctx,
@@ -519,7 +521,7 @@ static inline u32 bpf_prog_insn_size(const struct bpf_prog *prog)
        return prog->len * sizeof(struct bpf_insn);
 }
 
-static inline u32 bpf_prog_digest_scratch_size(const struct bpf_prog *prog)
+static inline u32 bpf_prog_tag_scratch_size(const struct bpf_prog *prog)
 {
        return round_up(bpf_prog_insn_size(prog) +
                        sizeof(__be64) + 1, SHA_MESSAGE_BYTES);
index b2109c522dec0726d6e6e390358a79be4bcdf891..4b45ec46161fd66d6e7fd32f53dd71b8ac1cab42 100644 (file)
@@ -665,6 +665,7 @@ i2c_unlock_adapter(struct i2c_adapter *adapter)
 #define I2C_CLIENT_TEN         0x10    /* we have a ten bit chip address */
                                        /* Must equal I2C_M_TEN below */
 #define I2C_CLIENT_SLAVE       0x20    /* we are the slave */
+#define I2C_CLIENT_HOST_NOTIFY 0x40    /* We want to use I2C host notify */
 #define I2C_CLIENT_WAKE                0x80    /* for board_info; true iff can wake */
 #define I2C_CLIENT_SCCB                0x9000  /* Use Omnivision SCCB protocol */
                                        /* Must match I2C_M_STOP|IGNORE_NAK */
index 56aec84237ad5b7b55c3a43eb04a882f9eb24d5e..cb09238f6d32be355a9b7e2347e48746de7eae77 100644 (file)
@@ -514,8 +514,8 @@ extern enum system_states {
 #define TAINT_FLAGS_COUNT              16
 
 struct taint_flag {
-       char true;      /* character printed when tainted */
-       char false;     /* character printed when not tainted */
+       char c_true;    /* character printed when tainted */
+       char c_false;   /* character printed when not tainted */
        bool module;    /* also show as a per-module taint flag */
 };
 
index 4741ecdb981743151b70afff63b10740dfaa4132..78ed8105e64d1ae0341104c8d129cfeba9402800 100644 (file)
@@ -1259,6 +1259,7 @@ extern void perf_event_disable(struct perf_event *event);
 extern void perf_event_disable_local(struct perf_event *event);
 extern void perf_event_disable_inatomic(struct perf_event *event);
 extern void perf_event_task_tick(void);
+extern int perf_event_account_interrupt(struct perf_event *event);
 #else /* !CONFIG_PERF_EVENTS: */
 static inline void *
 perf_aux_output_begin(struct perf_output_handle *handle,
index e5d19344037491651c6c80f6b310842ee5715126..7440290f64acd3694dfc5c17618c55f6253aae01 100644 (file)
@@ -66,6 +66,7 @@ struct svc_xprt {
 #define XPT_LISTENER   10              /* listening endpoint */
 #define XPT_CACHE_AUTH 11              /* cache auth info */
 #define XPT_LOCAL      12              /* connection from loopback interface */
+#define XPT_KILL_TEMP   13             /* call xpo_kill_temp_xprt before closing */
 
        struct svc_serv         *xpt_server;    /* service for transport */
        atomic_t                xpt_reserved;   /* space on outq that is rsvd */
index fc5848dad7a43216b3f124c4afdaa6b64b23910c..c93f4b3a59cb7a9f578ec18dd2f6c56014195a90 100644 (file)
@@ -62,8 +62,13 @@ static inline unsigned int tcp_optlen(const struct sk_buff *skb)
 
 /* TCP Fast Open Cookie as stored in memory */
 struct tcp_fastopen_cookie {
+       union {
+               u8      val[TCP_FASTOPEN_COOKIE_MAX];
+#if IS_ENABLED(CONFIG_IPV6)
+               struct in6_addr addr;
+#endif
+       };
        s8      len;
-       u8      val[TCP_FASTOPEN_COOKIE_MAX];
        bool    exp;    /* In RFC6994 experimental option format */
 };
 
index 6b76e3b0c18eac57491268b5ce395050914cef99..bea982af9cfb80a3081f50af90145a3b9758185c 100644 (file)
@@ -1772,7 +1772,9 @@ enum nl80211_commands {
  *
  * @NL80211_ATTR_OPMODE_NOTIF: Operating mode field from Operating Mode
  *     Notification Element based on association request when used with
- *     %NL80211_CMD_NEW_STATION; u8 attribute.
+ *     %NL80211_CMD_NEW_STATION or %NL80211_CMD_SET_STATION (only when
+ *     %NL80211_FEATURE_FULL_AP_CLIENT_STATE is supported, or with TDLS);
+ *     u8 attribute.
  *
  * @NL80211_ATTR_VENDOR_ID: The vendor ID, either a 24-bit OUI or, if
  *     %NL80211_VENDOR_ID_IS_LINUX is set, a special Linux ID (not used yet)
index cb4bcdc5854372e514865c30315e65ae30080527..a4dcd88ec2718621c2cf8e801566e5264c75c071 100644 (file)
@@ -397,7 +397,7 @@ enum {
        TCA_BPF_NAME,
        TCA_BPF_FLAGS,
        TCA_BPF_FLAGS_GEN,
-       TCA_BPF_DIGEST,
+       TCA_BPF_TAG,
        __TCA_BPF_MAX,
 };
 
index a6b88a6f7f712b271f07e809ee7a79697e6cb8cf..975b50dc8d1d466bb60c6279de7ebde1d05bd54f 100644 (file)
@@ -27,7 +27,7 @@ enum {
        TCA_ACT_BPF_FD,
        TCA_ACT_BPF_NAME,
        TCA_ACT_BPF_PAD,
-       TCA_ACT_BPF_DIGEST,
+       TCA_ACT_BPF_TAG,
        __TCA_ACT_BPF_MAX,
 };
 #define TCA_ACT_BPF_MAX (__TCA_ACT_BPF_MAX - 1)
index 1eb4f1303756164f2893d964198eecd40b0bcd62..503d4211988afe1d3eddd6d39aba520dc4c245ef 100644 (file)
@@ -146,10 +146,11 @@ void __bpf_prog_free(struct bpf_prog *fp)
        vfree(fp);
 }
 
-int bpf_prog_calc_digest(struct bpf_prog *fp)
+int bpf_prog_calc_tag(struct bpf_prog *fp)
 {
        const u32 bits_offset = SHA_MESSAGE_BYTES - sizeof(__be64);
-       u32 raw_size = bpf_prog_digest_scratch_size(fp);
+       u32 raw_size = bpf_prog_tag_scratch_size(fp);
+       u32 digest[SHA_DIGEST_WORDS];
        u32 ws[SHA_WORKSPACE_WORDS];
        u32 i, bsize, psize, blocks;
        struct bpf_insn *dst;
@@ -162,7 +163,7 @@ int bpf_prog_calc_digest(struct bpf_prog *fp)
        if (!raw)
                return -ENOMEM;
 
-       sha_init(fp->digest);
+       sha_init(digest);
        memset(ws, 0, sizeof(ws));
 
        /* We need to take out the map fd for the digest calculation
@@ -204,13 +205,14 @@ int bpf_prog_calc_digest(struct bpf_prog *fp)
        *bits = cpu_to_be64((psize - 1) << 3);
 
        while (blocks--) {
-               sha_transform(fp->digest, todo, ws);
+               sha_transform(digest, todo, ws);
                todo += SHA_MESSAGE_BYTES;
        }
 
-       result = (__force __be32 *)fp->digest;
+       result = (__force __be32 *)digest;
        for (i = 0; i < SHA_DIGEST_WORDS; i++)
-               result[i] = cpu_to_be32(fp->digest[i]);
+               result[i] = cpu_to_be32(digest[i]);
+       memcpy(fp->tag, result, sizeof(fp->tag));
 
        vfree(raw);
        return 0;
index e89acea22ecfc9a625de1924b2e4f997d88d158b..1d6b29e4e2c35ec14cec0a0d68bb7b636102a395 100644 (file)
@@ -688,17 +688,17 @@ static int bpf_prog_release(struct inode *inode, struct file *filp)
 static void bpf_prog_show_fdinfo(struct seq_file *m, struct file *filp)
 {
        const struct bpf_prog *prog = filp->private_data;
-       char prog_digest[sizeof(prog->digest) * 2 + 1] = { };
+       char prog_tag[sizeof(prog->tag) * 2 + 1] = { };
 
-       bin2hex(prog_digest, prog->digest, sizeof(prog->digest));
+       bin2hex(prog_tag, prog->tag, sizeof(prog->tag));
        seq_printf(m,
                   "prog_type:\t%u\n"
                   "prog_jited:\t%u\n"
-                  "prog_digest:\t%s\n"
+                  "prog_tag:\t%s\n"
                   "memlock:\t%llu\n",
                   prog->type,
                   prog->jited,
-                  prog_digest,
+                  prog_tag,
                   prog->pages * 1ULL << PAGE_SHIFT);
 }
 #endif
index 83ed2f8f6f228b1ae90f66d89e436b71a5c6a27c..cdc43b899f281ebd01dd8cf8110e6fb966c2a1fa 100644 (file)
@@ -2936,7 +2936,7 @@ static int replace_map_fd_with_map_ptr(struct bpf_verifier_env *env)
        int insn_cnt = env->prog->len;
        int i, j, err;
 
-       err = bpf_prog_calc_digest(env->prog);
+       err = bpf_prog_calc_tag(env->prog);
        if (err)
                return err;
 
index ab15509fab8c0659c3f422036f5649718a9e4437..110b38a58493ee4ba4c19763d2678dae8815e1af 100644 (file)
@@ -2249,7 +2249,7 @@ static int  __perf_install_in_context(void *info)
        struct perf_event_context *ctx = event->ctx;
        struct perf_cpu_context *cpuctx = __get_cpu_context(ctx);
        struct perf_event_context *task_ctx = cpuctx->task_ctx;
-       bool activate = true;
+       bool reprogram = true;
        int ret = 0;
 
        raw_spin_lock(&cpuctx->ctx.lock);
@@ -2257,27 +2257,26 @@ static int  __perf_install_in_context(void *info)
                raw_spin_lock(&ctx->lock);
                task_ctx = ctx;
 
-               /* If we're on the wrong CPU, try again */
-               if (task_cpu(ctx->task) != smp_processor_id()) {
-                       ret = -ESRCH;
-                       goto unlock;
-               }
+               reprogram = (ctx->task == current);
 
                /*
-                * If we're on the right CPU, see if the task we target is
-                * current, if not we don't have to activate the ctx, a future
-                * context switch will do that for us.
+                * If the task is running, it must be running on this CPU,
+                * otherwise we cannot reprogram things.
+                *
+                * If its not running, we don't care, ctx->lock will
+                * serialize against it becoming runnable.
                 */
-               if (ctx->task != current)
-                       activate = false;
-               else
-                       WARN_ON_ONCE(cpuctx->task_ctx && cpuctx->task_ctx != ctx);
+               if (task_curr(ctx->task) && !reprogram) {
+                       ret = -ESRCH;
+                       goto unlock;
+               }
 
+               WARN_ON_ONCE(reprogram && cpuctx->task_ctx && cpuctx->task_ctx != ctx);
        } else if (task_ctx) {
                raw_spin_lock(&task_ctx->lock);
        }
 
-       if (activate) {
+       if (reprogram) {
                ctx_sched_out(ctx, cpuctx, EVENT_TIME);
                add_event_to_ctx(event, ctx);
                ctx_resched(cpuctx, task_ctx);
@@ -2328,13 +2327,36 @@ perf_install_in_context(struct perf_event_context *ctx,
        /*
         * Installing events is tricky because we cannot rely on ctx->is_active
         * to be set in case this is the nr_events 0 -> 1 transition.
+        *
+        * Instead we use task_curr(), which tells us if the task is running.
+        * However, since we use task_curr() outside of rq::lock, we can race
+        * against the actual state. This means the result can be wrong.
+        *
+        * If we get a false positive, we retry, this is harmless.
+        *
+        * If we get a false negative, things are complicated. If we are after
+        * perf_event_context_sched_in() ctx::lock will serialize us, and the
+        * value must be correct. If we're before, it doesn't matter since
+        * perf_event_context_sched_in() will program the counter.
+        *
+        * However, this hinges on the remote context switch having observed
+        * our task->perf_event_ctxp[] store, such that it will in fact take
+        * ctx::lock in perf_event_context_sched_in().
+        *
+        * We do this by task_function_call(), if the IPI fails to hit the task
+        * we know any future context switch of task must see the
+        * perf_event_ctpx[] store.
         */
-again:
+
        /*
-        * Cannot use task_function_call() because we need to run on the task's
-        * CPU regardless of whether its current or not.
+        * This smp_mb() orders the task->perf_event_ctxp[] store with the
+        * task_cpu() load, such that if the IPI then does not find the task
+        * running, a future context switch of that task must observe the
+        * store.
         */
-       if (!cpu_function_call(task_cpu(task), __perf_install_in_context, event))
+       smp_mb();
+again:
+       if (!task_function_call(task, __perf_install_in_context, event))
                return;
 
        raw_spin_lock_irq(&ctx->lock);
@@ -2348,12 +2370,16 @@ again:
                raw_spin_unlock_irq(&ctx->lock);
                return;
        }
-       raw_spin_unlock_irq(&ctx->lock);
        /*
-        * Since !ctx->is_active doesn't mean anything, we must IPI
-        * unconditionally.
+        * If the task is not running, ctx->lock will avoid it becoming so,
+        * thus we can safely install the event.
         */
-       goto again;
+       if (task_curr(task)) {
+               raw_spin_unlock_irq(&ctx->lock);
+               goto again;
+       }
+       add_event_to_ctx(event, ctx);
+       raw_spin_unlock_irq(&ctx->lock);
 }
 
 /*
@@ -7034,25 +7060,12 @@ static void perf_log_itrace_start(struct perf_event *event)
        perf_output_end(&handle);
 }
 
-/*
- * Generic event overflow handling, sampling.
- */
-
-static int __perf_event_overflow(struct perf_event *event,
-                                  int throttle, struct perf_sample_data *data,
-                                  struct pt_regs *regs)
+static int
+__perf_event_account_interrupt(struct perf_event *event, int throttle)
 {
-       int events = atomic_read(&event->event_limit);
        struct hw_perf_event *hwc = &event->hw;
-       u64 seq;
        int ret = 0;
-
-       /*
-        * Non-sampling counters might still use the PMI to fold short
-        * hardware counters, ignore those.
-        */
-       if (unlikely(!is_sampling_event(event)))
-               return 0;
+       u64 seq;
 
        seq = __this_cpu_read(perf_throttled_seq);
        if (seq != hwc->interrupts_seq) {
@@ -7080,6 +7093,34 @@ static int __perf_event_overflow(struct perf_event *event,
                        perf_adjust_period(event, delta, hwc->last_period, true);
        }
 
+       return ret;
+}
+
+int perf_event_account_interrupt(struct perf_event *event)
+{
+       return __perf_event_account_interrupt(event, 1);
+}
+
+/*
+ * Generic event overflow handling, sampling.
+ */
+
+static int __perf_event_overflow(struct perf_event *event,
+                                  int throttle, struct perf_sample_data *data,
+                                  struct pt_regs *regs)
+{
+       int events = atomic_read(&event->event_limit);
+       int ret = 0;
+
+       /*
+        * Non-sampling counters might still use the PMI to fold short
+        * hardware counters, ignore those.
+        */
+       if (unlikely(!is_sampling_event(event)))
+               return 0;
+
+       ret = __perf_event_account_interrupt(event, throttle);
+
        /*
         * XXX event_limit might not quite work as expected on inherited
         * events
@@ -9503,6 +9544,37 @@ static int perf_event_set_clock(struct perf_event *event, clockid_t clk_id)
        return 0;
 }
 
+/*
+ * Variation on perf_event_ctx_lock_nested(), except we take two context
+ * mutexes.
+ */
+static struct perf_event_context *
+__perf_event_ctx_lock_double(struct perf_event *group_leader,
+                            struct perf_event_context *ctx)
+{
+       struct perf_event_context *gctx;
+
+again:
+       rcu_read_lock();
+       gctx = READ_ONCE(group_leader->ctx);
+       if (!atomic_inc_not_zero(&gctx->refcount)) {
+               rcu_read_unlock();
+               goto again;
+       }
+       rcu_read_unlock();
+
+       mutex_lock_double(&gctx->mutex, &ctx->mutex);
+
+       if (group_leader->ctx != gctx) {
+               mutex_unlock(&ctx->mutex);
+               mutex_unlock(&gctx->mutex);
+               put_ctx(gctx);
+               goto again;
+       }
+
+       return gctx;
+}
+
 /**
  * sys_perf_event_open - open a performance event, associate it to a task/cpu
  *
@@ -9746,12 +9818,31 @@ SYSCALL_DEFINE5(perf_event_open,
        }
 
        if (move_group) {
-               gctx = group_leader->ctx;
-               mutex_lock_double(&gctx->mutex, &ctx->mutex);
+               gctx = __perf_event_ctx_lock_double(group_leader, ctx);
+
                if (gctx->task == TASK_TOMBSTONE) {
                        err = -ESRCH;
                        goto err_locked;
                }
+
+               /*
+                * Check if we raced against another sys_perf_event_open() call
+                * moving the software group underneath us.
+                */
+               if (!(group_leader->group_caps & PERF_EV_CAP_SOFTWARE)) {
+                       /*
+                        * If someone moved the group out from under us, check
+                        * if this new event wound up on the same ctx, if so
+                        * its the regular !move_group case, otherwise fail.
+                        */
+                       if (gctx != ctx) {
+                               err = -EINVAL;
+                               goto err_locked;
+                       } else {
+                               perf_event_ctx_unlock(group_leader, gctx);
+                               move_group = 0;
+                       }
+               }
        } else {
                mutex_lock(&ctx->mutex);
        }
@@ -9853,7 +9944,7 @@ SYSCALL_DEFINE5(perf_event_open,
        perf_unpin_context(ctx);
 
        if (move_group)
-               mutex_unlock(&gctx->mutex);
+               perf_event_ctx_unlock(group_leader, gctx);
        mutex_unlock(&ctx->mutex);
 
        if (task) {
@@ -9879,7 +9970,7 @@ SYSCALL_DEFINE5(perf_event_open,
 
 err_locked:
        if (move_group)
-               mutex_unlock(&gctx->mutex);
+               perf_event_ctx_unlock(group_leader, gctx);
        mutex_unlock(&ctx->mutex);
 /* err_file: */
        fput(event_file);
index 5088784c0cf9e97c166b7dc06afed9d1c7709d2e..38d4270925d4d13619d725052aa3f9844f23bc96 100644 (file)
@@ -1145,7 +1145,7 @@ static size_t module_flags_taint(struct module *mod, char *buf)
 
        for (i = 0; i < TAINT_FLAGS_COUNT; i++) {
                if (taint_flags[i].module && test_bit(i, &mod->taints))
-                       buf[l++] = taint_flags[i].true;
+                       buf[l++] = taint_flags[i].c_true;
        }
 
        return l;
index c51edaa04fce389bfcf5a62e59fe7a76bf853c6f..901c4fb46002e38c98394110c49aa50230d58180 100644 (file)
@@ -355,7 +355,7 @@ const char *print_tainted(void)
                for (i = 0; i < TAINT_FLAGS_COUNT; i++) {
                        const struct taint_flag *t = &taint_flags[i];
                        *s++ = test_bit(i, &tainted_mask) ?
-                                       t->true : t->false;
+                                       t->c_true : t->c_false;
                }
                *s = 0;
        } else
index df9e8e9e0be7714fa580b547492c940b11221008..eef2ce9686366a72e9dadaa9056bcda8295ae93d 100644 (file)
@@ -151,8 +151,12 @@ out:
 
 static void delayed_free_pidns(struct rcu_head *p)
 {
-       kmem_cache_free(pid_ns_cachep,
-                       container_of(p, struct pid_namespace, rcu));
+       struct pid_namespace *ns = container_of(p, struct pid_namespace, rcu);
+
+       dec_pid_namespaces(ns->ucounts);
+       put_user_ns(ns->user_ns);
+
+       kmem_cache_free(pid_ns_cachep, ns);
 }
 
 static void destroy_pid_namespace(struct pid_namespace *ns)
@@ -162,8 +166,6 @@ static void destroy_pid_namespace(struct pid_namespace *ns)
        ns_free_inum(&ns->ns);
        for (i = 0; i < PIDMAP_ENTRIES; i++)
                kfree(ns->pidmap[i].page);
-       dec_pid_namespaces(ns->ucounts);
-       put_user_ns(ns->user_ns);
        call_rcu(&ns->rcu, delayed_free_pidns);
 }
 
index 2c115fdab39765f4ecbeaade9fa74008e711d08a..74e0388cc88d4d17b340d102ec8e053257d6ef55 100644 (file)
@@ -767,7 +767,7 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts,
        tick = expires;
 
        /* Skip reprogram of event if its not changed */
-       if (ts->tick_stopped && (expires == dev->next_event))
+       if (ts->tick_stopped && (expires == ts->next_tick))
                goto out;
 
        /*
@@ -787,6 +787,8 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts,
                trace_tick_stop(1, TICK_DEP_MASK_NONE);
        }
 
+       ts->next_tick = tick;
+
        /*
         * If the expiration time == KTIME_MAX, then we simply stop
         * the tick timer.
@@ -802,7 +804,10 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts,
        else
                tick_program_event(tick, 1);
 out:
-       /* Update the estimated sleep length */
+       /*
+        * Update the estimated sleep length until the next timer
+        * (not only the tick).
+        */
        ts->sleep_length = ktime_sub(dev->next_event, now);
        return tick;
 }
index bf38226e5c17c15e276c2e4e8c5f4fe423e071f3..075444e3d48e643549ba5c7fbcc3c792fb90e1db 100644 (file)
@@ -27,6 +27,7 @@ enum tick_nohz_mode {
  *                     timer is modified for nohz sleeps. This is necessary
  *                     to resume the tick timer operation in the timeline
  *                     when the CPU returns from nohz sleep.
+ * @next_tick:         Next tick to be fired when in dynticks mode.
  * @tick_stopped:      Indicator that the idle tick has been stopped
  * @idle_jiffies:      jiffies at the entry to idle for idle time accounting
  * @idle_calls:                Total number of idle calls
@@ -44,6 +45,7 @@ struct tick_sched {
        unsigned long                   check_clocks;
        enum tick_nohz_mode             nohz_mode;
        ktime_t                         last_tick;
+       ktime_t                         next_tick;
        int                             inidle;
        int                             tick_stopped;
        unsigned long                   idle_jiffies;
index 975b8fc4f1e1143dcdd295731cf1fc18cf0561fe..a8d74a733a38b54a912f5e292f0a15a2cfff4a95 100644 (file)
@@ -483,11 +483,11 @@ phys_addr_t swiotlb_tbl_map_single(struct device *hwdev,
                    : 1UL << (BITS_PER_LONG - IO_TLB_SHIFT);
 
        /*
-        * For mappings greater than a page, we limit the stride (and
-        * hence alignment) to a page size.
+        * For mappings greater than or equal to a page, we limit the stride
+        * (and hence alignment) to a page size.
         */
        nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
-       if (size > PAGE_SIZE)
+       if (size >= PAGE_SIZE)
                stride = (1 << (PAGE_SHIFT - IO_TLB_SHIFT));
        else
                stride = 1;
index 4855d18a8511072b499043d1160ad1ff4b2f9f3e..038b109b2be70e8da91589a1bf3c82e73a3903ca 100644 (file)
@@ -264,7 +264,7 @@ void ax25_disconnect(ax25_cb *ax25, int reason)
 {
        ax25_clear_queues(ax25);
 
-       if (!sock_flag(ax25->sk, SOCK_DESTROY))
+       if (!ax25->sk || !sock_flag(ax25->sk, SOCK_DESTROY))
                ax25_stop_heartbeat(ax25);
        ax25_stop_t1timer(ax25);
        ax25_stop_t2timer(ax25);
index eba1546b5031e6e280a558118e55b13befc4c8ea..9a375b908d01fae08b46b46df2e2579a4c268027 100644 (file)
@@ -1279,8 +1279,9 @@ int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event,
                    nla_put_u32(skb, RTA_FLOW, fi->fib_nh[0].nh_tclassid))
                        goto nla_put_failure;
 #endif
-               if (fi->fib_nh->nh_lwtstate)
-                       lwtunnel_fill_encap(skb, fi->fib_nh->nh_lwtstate);
+               if (fi->fib_nh->nh_lwtstate &&
+                   lwtunnel_fill_encap(skb, fi->fib_nh->nh_lwtstate) < 0)
+                       goto nla_put_failure;
        }
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
        if (fi->fib_nhs > 1) {
@@ -1316,8 +1317,10 @@ int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event,
                            nla_put_u32(skb, RTA_FLOW, nh->nh_tclassid))
                                goto nla_put_failure;
 #endif
-                       if (nh->nh_lwtstate)
-                               lwtunnel_fill_encap(skb, nh->nh_lwtstate);
+                       if (nh->nh_lwtstate &&
+                           lwtunnel_fill_encap(skb, nh->nh_lwtstate) < 0)
+                               goto nla_put_failure;
+
                        /* length of rtnetlink header + attributes */
                        rtnh->rtnh_len = nlmsg_get_pos(skb) - (void *) rtnh;
                } endfor_nexthops(fi);
index 0fcac8e7a2b2fb9fdb9f74bdcadf32bd177ceb39..709ffe67d1de1609be7d3e4a98d9314b01e5f265 100644 (file)
@@ -2472,7 +2472,7 @@ static int rt_fill_info(struct net *net,  __be32 dst, __be32 src, u32 table_id,
        r->rtm_dst_len  = 32;
        r->rtm_src_len  = 0;
        r->rtm_tos      = fl4->flowi4_tos;
-       r->rtm_table    = table_id;
+       r->rtm_table    = table_id < 256 ? table_id : RT_TABLE_COMPAT;
        if (nla_put_u32(skb, RTA_TABLE, table_id))
                goto nla_put_failure;
        r->rtm_type     = rt->rt_type;
index 4e777a3243f94457d9928e3967bb83947da563f6..f51919535ca763d54c25a48534256150de7b66a7 100644 (file)
@@ -113,7 +113,7 @@ static bool tcp_fastopen_cookie_gen(struct request_sock *req,
                struct tcp_fastopen_cookie tmp;
 
                if (__tcp_fastopen_cookie_gen(&ip6h->saddr, &tmp)) {
-                       struct in6_addr *buf = (struct in6_addr *) tmp.val;
+                       struct in6_addr *buf = &tmp.addr;
                        int i;
 
                        for (i = 0; i < 4; i++)
index 36d2921809428eb520256dffb39393ed023b7ec7..753d6d0860fb14c100ab8b20799782ab81602635 100644 (file)
@@ -1108,7 +1108,7 @@ route_lookup:
                                     t->parms.name);
                goto tx_err_dst_release;
        }
-       mtu = dst_mtu(dst) - psh_hlen;
+       mtu = dst_mtu(dst) - psh_hlen - t->tun_hlen;
        if (encap_limit >= 0) {
                max_headroom += 8;
                mtu -= 8;
@@ -1117,7 +1117,7 @@ route_lookup:
                mtu = IPV6_MIN_MTU;
        if (skb_dst(skb) && !t->parms.collect_md)
                skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
-       if (skb->len > mtu && !skb_is_gso(skb)) {
+       if (skb->len - t->tun_hlen > mtu && !skb_is_gso(skb)) {
                *pmtu = mtu;
                err = -EMSGSIZE;
                goto tx_err_dst_release;
index 14a3903f1c82d83d44c39befdfe827833d09b13c..7139fffd61b6f764a9d0ae02ed41365afa3ab55c 100644 (file)
@@ -81,7 +81,7 @@ static void mld_gq_timer_expire(unsigned long data);
 static void mld_ifc_timer_expire(unsigned long data);
 static void mld_ifc_event(struct inet6_dev *idev);
 static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *pmc);
-static void mld_del_delrec(struct inet6_dev *idev, const struct in6_addr *addr);
+static void mld_del_delrec(struct inet6_dev *idev, struct ifmcaddr6 *pmc);
 static void mld_clear_delrec(struct inet6_dev *idev);
 static bool mld_in_v1_mode(const struct inet6_dev *idev);
 static int sf_setstate(struct ifmcaddr6 *pmc);
@@ -692,9 +692,9 @@ static void igmp6_group_dropped(struct ifmcaddr6 *mc)
                        dev_mc_del(dev, buf);
        }
 
-       if (mc->mca_flags & MAF_NOREPORT)
-               goto done;
        spin_unlock_bh(&mc->mca_lock);
+       if (mc->mca_flags & MAF_NOREPORT)
+               return;
 
        if (!mc->idev->dead)
                igmp6_leave_group(mc);
@@ -702,8 +702,6 @@ static void igmp6_group_dropped(struct ifmcaddr6 *mc)
        spin_lock_bh(&mc->mca_lock);
        if (del_timer(&mc->mca_timer))
                atomic_dec(&mc->mca_refcnt);
-done:
-       ip6_mc_clear_src(mc);
        spin_unlock_bh(&mc->mca_lock);
 }
 
@@ -748,10 +746,11 @@ static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *im)
        spin_unlock_bh(&idev->mc_lock);
 }
 
-static void mld_del_delrec(struct inet6_dev *idev, const struct in6_addr *pmca)
+static void mld_del_delrec(struct inet6_dev *idev, struct ifmcaddr6 *im)
 {
        struct ifmcaddr6 *pmc, *pmc_prev;
-       struct ip6_sf_list *psf, *psf_next;
+       struct ip6_sf_list *psf;
+       struct in6_addr *pmca = &im->mca_addr;
 
        spin_lock_bh(&idev->mc_lock);
        pmc_prev = NULL;
@@ -768,14 +767,20 @@ static void mld_del_delrec(struct inet6_dev *idev, const struct in6_addr *pmca)
        }
        spin_unlock_bh(&idev->mc_lock);
 
+       spin_lock_bh(&im->mca_lock);
        if (pmc) {
-               for (psf = pmc->mca_tomb; psf; psf = psf_next) {
-                       psf_next = psf->sf_next;
-                       kfree(psf);
+               im->idev = pmc->idev;
+               im->mca_crcount = idev->mc_qrv;
+               im->mca_sfmode = pmc->mca_sfmode;
+               if (pmc->mca_sfmode == MCAST_INCLUDE) {
+                       im->mca_tomb = pmc->mca_tomb;
+                       im->mca_sources = pmc->mca_sources;
+                       for (psf = im->mca_sources; psf; psf = psf->sf_next)
+                               psf->sf_crcount = im->mca_crcount;
                }
                in6_dev_put(pmc->idev);
-               kfree(pmc);
        }
+       spin_unlock_bh(&im->mca_lock);
 }
 
 static void mld_clear_delrec(struct inet6_dev *idev)
@@ -904,7 +909,7 @@ int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr)
        mca_get(mc);
        write_unlock_bh(&idev->lock);
 
-       mld_del_delrec(idev, &mc->mca_addr);
+       mld_del_delrec(idev, mc);
        igmp6_group_added(mc);
        ma_put(mc);
        return 0;
@@ -927,6 +932,7 @@ int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr)
                                write_unlock_bh(&idev->lock);
 
                                igmp6_group_dropped(ma);
+                               ip6_mc_clear_src(ma);
 
                                ma_put(ma);
                                return 0;
@@ -2501,15 +2507,17 @@ void ipv6_mc_down(struct inet6_dev *idev)
        /* Withdraw multicast list */
 
        read_lock_bh(&idev->lock);
-       mld_ifc_stop_timer(idev);
-       mld_gq_stop_timer(idev);
-       mld_dad_stop_timer(idev);
 
        for (i = idev->mc_list; i; i = i->next)
                igmp6_group_dropped(i);
-       read_unlock_bh(&idev->lock);
 
-       mld_clear_delrec(idev);
+       /* Should stop timer after group drop. or we will
+        * start timer again in mld_ifc_event()
+        */
+       mld_ifc_stop_timer(idev);
+       mld_gq_stop_timer(idev);
+       mld_dad_stop_timer(idev);
+       read_unlock_bh(&idev->lock);
 }
 
 static void ipv6_mc_reset(struct inet6_dev *idev)
@@ -2531,8 +2539,10 @@ void ipv6_mc_up(struct inet6_dev *idev)
 
        read_lock_bh(&idev->lock);
        ipv6_mc_reset(idev);
-       for (i = idev->mc_list; i; i = i->next)
+       for (i = idev->mc_list; i; i = i->next) {
+               mld_del_delrec(idev, i);
                igmp6_group_added(i);
+       }
        read_unlock_bh(&idev->lock);
 }
 
@@ -2565,6 +2575,7 @@ void ipv6_mc_destroy_dev(struct inet6_dev *idev)
 
        /* Deactivate timers */
        ipv6_mc_down(idev);
+       mld_clear_delrec(idev);
 
        /* Delete all-nodes address. */
        /* We cannot call ipv6_dev_mc_dec() directly, our caller in
@@ -2579,11 +2590,9 @@ void ipv6_mc_destroy_dev(struct inet6_dev *idev)
        write_lock_bh(&idev->lock);
        while ((i = idev->mc_list) != NULL) {
                idev->mc_list = i->next;
-               write_unlock_bh(&idev->lock);
 
-               igmp6_group_dropped(i);
+               write_unlock_bh(&idev->lock);
                ma_put(i);
-
                write_lock_bh(&idev->lock);
        }
        write_unlock_bh(&idev->lock);
index ce5aaf448c541079e8e08b170d5d24d4f499d7d8..4f6b067c8753a541bc20d6d9f6f4c5009c8956cb 100644 (file)
@@ -3317,7 +3317,8 @@ static int rt6_fill_node(struct net *net,
        if (nla_put_u8(skb, RTA_PREF, IPV6_EXTRACT_PREF(rt->rt6i_flags)))
                goto nla_put_failure;
 
-       lwtunnel_fill_encap(skb, rt->dst.lwtstate);
+       if (lwtunnel_fill_encap(skb, rt->dst.lwtstate) < 0)
+               goto nla_put_failure;
 
        nlmsg_end(skb, nlh);
        return 0;
index ef1c8a46e7aceee45b2044d4b4338dc3aed88807..03a064803626890ade73073cc12735aec777f9e5 100644 (file)
@@ -400,7 +400,7 @@ static int seg6_hmac_init_algo(void)
                        *p_tfm = tfm;
                }
 
-               p_tfm = this_cpu_ptr(algo->tfms);
+               p_tfm = raw_cpu_ptr(algo->tfms);
                tfm = *p_tfm;
 
                shsize = sizeof(*shash) + crypto_shash_descsize(tfm);
index bbfca22c34aeec5c63e9494e672f959c5a06b380..1d60cb132835c9f9089510f035a1ca95e5b1e1a7 100644 (file)
@@ -265,7 +265,9 @@ int seg6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
        slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate);
 
 #ifdef CONFIG_DST_CACHE
+       preempt_disable();
        dst = dst_cache_get(&slwt->cache);
+       preempt_enable();
 #endif
 
        if (unlikely(!dst)) {
@@ -286,7 +288,9 @@ int seg6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
                }
 
 #ifdef CONFIG_DST_CACHE
+               preempt_disable();
                dst_cache_set_ip6(&slwt->cache, dst, &fl6.saddr);
+               preempt_enable();
 #endif
        }
 
index e75cbf6ecc26e4ec7bde777c385e001c0e49e371..a0d901d8992ea892bbb44890e08d6f782c68b4e3 100644 (file)
@@ -231,9 +231,6 @@ ieee80211_get_max_required_bw(struct ieee80211_sub_if_data *sdata)
                    !(sta->sdata->bss && sta->sdata->bss == sdata->bss))
                        continue;
 
-               if (!sta->uploaded || !test_sta_flag(sta, WLAN_STA_ASSOC))
-                       continue;
-
                max_bw = max(max_bw, ieee80211_get_sta_bw(&sta->sta));
        }
        rcu_read_unlock();
index 41497b670e2bde0e55a2a35f5fbbdb60148ddd54..d37ae7dc114b2c2eb5b8dc4773c6a688b047e0a2 100644 (file)
@@ -6,6 +6,7 @@
  * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
  * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
  * Copyright 2013-2014  Intel Mobile Communications GmbH
+ * Copyright (c) 2016        Intel Deutschland GmbH
  *
  * 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
@@ -1295,6 +1296,26 @@ static void ieee80211_iface_work(struct work_struct *work)
                } else if (ieee80211_is_action(mgmt->frame_control) &&
                           mgmt->u.action.category == WLAN_CATEGORY_VHT) {
                        switch (mgmt->u.action.u.vht_group_notif.action_code) {
+                       case WLAN_VHT_ACTION_OPMODE_NOTIF: {
+                               struct ieee80211_rx_status *status;
+                               enum nl80211_band band;
+                               u8 opmode;
+
+                               status = IEEE80211_SKB_RXCB(skb);
+                               band = status->band;
+                               opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode;
+
+                               mutex_lock(&local->sta_mtx);
+                               sta = sta_info_get_bss(sdata, mgmt->sa);
+
+                               if (sta)
+                                       ieee80211_vht_handle_opmode(sdata, sta,
+                                                                   opmode,
+                                                                   band);
+
+                               mutex_unlock(&local->sta_mtx);
+                               break;
+                       }
                        case WLAN_VHT_ACTION_GROUPID_MGMT:
                                ieee80211_process_mu_groups(sdata, mgmt);
                                break;
index 1822c77f2b1c3125ec1bc63fa6b7de085a26bbed..56fb47953b72420b3ceb4e3f5d27dc9c4d23928b 100644 (file)
@@ -913,12 +913,17 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
                supp_ht = supp_ht || sband->ht_cap.ht_supported;
                supp_vht = supp_vht || sband->vht_cap.vht_supported;
 
-               if (sband->ht_cap.ht_supported)
-                       local->rx_chains =
-                               max(ieee80211_mcs_to_chains(&sband->ht_cap.mcs),
-                                   local->rx_chains);
+               if (!sband->ht_cap.ht_supported)
+                       continue;
 
                /* TODO: consider VHT for RX chains, hopefully it's the same */
+               local->rx_chains =
+                       max(ieee80211_mcs_to_chains(&sband->ht_cap.mcs),
+                           local->rx_chains);
+
+               /* no need to mask, SM_PS_DISABLED has all bits set */
+               sband->ht_cap.cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
+                                    IEEE80211_HT_CAP_SM_PS_SHIFT;
        }
 
        /* if low-level driver supports AP, we also support VLAN */
index 206698bc93f406939bb5d883b6ab2f04bc1a3bed..9e2641d4558753b7bf746388a971ac337cef9349 100644 (file)
@@ -40,6 +40,8 @@ void rate_control_rate_init(struct sta_info *sta)
 
        ieee80211_sta_set_rx_nss(sta);
 
+       ieee80211_recalc_min_chandef(sta->sdata);
+
        if (!ref)
                return;
 
index 3e289a64ed4317a8a495cb7cac8197fb9ce10c3e..3090dd4342f6eee6f2d3bdba67493849622ac1a7 100644 (file)
@@ -2472,7 +2472,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
        if (!ifmsh->mshcfg.dot11MeshForwarding)
                goto out;
 
-       fwd_skb = skb_copy_expand(skb, local->tx_headroom, 0, GFP_ATOMIC);
+       fwd_skb = skb_copy_expand(skb, local->tx_headroom +
+                                      sdata->encrypt_headroom, 0, GFP_ATOMIC);
        if (!fwd_skb) {
                net_info_ratelimited("%s: failed to clone mesh frame\n",
                                    sdata->name);
@@ -2880,17 +2881,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
 
                switch (mgmt->u.action.u.vht_opmode_notif.action_code) {
                case WLAN_VHT_ACTION_OPMODE_NOTIF: {
-                       u8 opmode;
-
                        /* verify opmode is present */
                        if (len < IEEE80211_MIN_ACTION_SIZE + 2)
                                goto invalid;
-
-                       opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode;
-
-                       ieee80211_vht_handle_opmode(rx->sdata, rx->sta,
-                                                   opmode, status->band);
-                       goto handled;
+                       goto queue;
                }
                case WLAN_VHT_ACTION_GROUPID_MGMT: {
                        if (len < IEEE80211_MIN_ACTION_SIZE + 25)
@@ -3942,21 +3936,31 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
        u64_stats_update_end(&stats->syncp);
 
        if (fast_rx->internal_forward) {
-               struct sta_info *dsta = sta_info_get(rx->sdata, skb->data);
+               struct sk_buff *xmit_skb = NULL;
+               bool multicast = is_multicast_ether_addr(skb->data);
+
+               if (multicast) {
+                       xmit_skb = skb_copy(skb, GFP_ATOMIC);
+               } else if (sta_info_get(rx->sdata, skb->data)) {
+                       xmit_skb = skb;
+                       skb = NULL;
+               }
 
-               if (dsta) {
+               if (xmit_skb) {
                        /*
                         * Send to wireless media and increase priority by 256
                         * to keep the received priority instead of
                         * reclassifying the frame (see cfg80211_classify8021d).
                         */
-                       skb->priority += 256;
-                       skb->protocol = htons(ETH_P_802_3);
-                       skb_reset_network_header(skb);
-                       skb_reset_mac_header(skb);
-                       dev_queue_xmit(skb);
-                       return true;
+                       xmit_skb->priority += 256;
+                       xmit_skb->protocol = htons(ETH_P_802_3);
+                       skb_reset_network_header(xmit_skb);
+                       skb_reset_mac_header(xmit_skb);
+                       dev_queue_xmit(xmit_skb);
                }
+
+               if (!skb)
+                       return true;
        }
 
        /* deliver to local stack */
index b6cfcf038c11fa529e00da2eed70f6ff48426a37..50c309094c37ba5e73160613f6e316c0a6a161f2 100644 (file)
@@ -1501,8 +1501,8 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta,
 
                /* This will evaluate to 1, 3, 5 or 7. */
                for (ac = IEEE80211_AC_VO; ac < IEEE80211_NUM_ACS; ac++)
-                       if (ignored_acs & BIT(ac))
-                               continue;
+                       if (!(ignored_acs & ieee80211_ac_to_qos_mask[ac]))
+                               break;
                tid = 7 - 2 * ac;
 
                ieee80211_send_null_response(sta, tid, reason, true, false);
index 0d8b716e509edca48fbc65ceaf06e6b7d6a2c189..797e847cbc49a1a5f1a515f01aa68c0212aed997 100644 (file)
@@ -1243,7 +1243,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
 
 static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local,
                                          struct ieee80211_vif *vif,
-                                         struct ieee80211_sta *pubsta,
+                                         struct sta_info *sta,
                                          struct sk_buff *skb)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -1257,10 +1257,13 @@ static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local,
        if (!ieee80211_is_data(hdr->frame_control))
                return NULL;
 
-       if (pubsta) {
+       if (sta) {
                u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
 
-               txq = pubsta->txq[tid];
+               if (!sta->uploaded)
+                       return NULL;
+
+               txq = sta->sta.txq[tid];
        } else if (vif) {
                txq = vif->txq;
        }
@@ -1503,23 +1506,17 @@ static bool ieee80211_queue_skb(struct ieee80211_local *local,
        struct fq *fq = &local->fq;
        struct ieee80211_vif *vif;
        struct txq_info *txqi;
-       struct ieee80211_sta *pubsta;
 
        if (!local->ops->wake_tx_queue ||
            sdata->vif.type == NL80211_IFTYPE_MONITOR)
                return false;
 
-       if (sta && sta->uploaded)
-               pubsta = &sta->sta;
-       else
-               pubsta = NULL;
-
        if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
                sdata = container_of(sdata->bss,
                                     struct ieee80211_sub_if_data, u.ap);
 
        vif = &sdata->vif;
-       txqi = ieee80211_get_txq(local, vif, pubsta, skb);
+       txqi = ieee80211_get_txq(local, vif, sta, skb);
 
        if (!txqi)
                return false;
index 6832bf6ab69fe012ea4eeb3c02b79523083cdc58..43e45bb660bcde02af964a31a71efd64f07ba448 100644 (file)
@@ -527,8 +527,10 @@ void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
 
        u32 changed = __ieee80211_vht_handle_opmode(sdata, sta, opmode, band);
 
-       if (changed > 0)
+       if (changed > 0) {
+               ieee80211_recalc_min_chandef(sdata);
                rate_control_rate_update(local, sband, sta, changed);
+       }
 }
 
 void ieee80211_get_vht_mask_from_cap(__le16 vht_cap,
index 6b78bab27755b2758f3c8ecd5b9c6d61615af4b6..54253ea5976e694ba93a9145e575197fce9df69a 100644 (file)
@@ -514,7 +514,7 @@ static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
        int hooknum, nh_off, err = NF_ACCEPT;
 
        nh_off = skb_network_offset(skb);
-       skb_pull(skb, nh_off);
+       skb_pull_rcsum(skb, nh_off);
 
        /* See HOOK2MANIP(). */
        if (maniptype == NF_NAT_MANIP_SRC)
@@ -579,6 +579,7 @@ static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
        err = nf_nat_packet(ct, ctinfo, hooknum, skb);
 push:
        skb_push(skb, nh_off);
+       skb_postpush_rcsum(skb, skb->data, nh_off);
 
        return err;
 }
@@ -886,7 +887,7 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb,
 
        /* The conntrack module expects to be working at L3. */
        nh_ofs = skb_network_offset(skb);
-       skb_pull(skb, nh_ofs);
+       skb_pull_rcsum(skb, nh_ofs);
 
        if (key->ip.frag != OVS_FRAG_TYPE_NONE) {
                err = handle_fragments(net, key, info->zone.id, skb);
@@ -900,6 +901,7 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb,
                err = ovs_ct_lookup(net, key, info, skb);
 
        skb_push(skb, nh_ofs);
+       skb_postpush_rcsum(skb, skb->data, nh_ofs);
        if (err)
                kfree_skb(skb);
        return err;
index 2095c83ce7730d49550103a8efad943d28815617..e10456ef6f7a43c1b1a3c153012805015c51e9f5 100644 (file)
@@ -900,8 +900,6 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
                        goto err;
                }
                act->order = i;
-               if (event == RTM_GETACTION)
-                       act->tcfa_refcnt++;
                list_add_tail(&act->list, &actions);
        }
 
@@ -914,7 +912,8 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
                return ret;
        }
 err:
-       tcf_action_destroy(&actions, 0);
+       if (event != RTM_GETACTION)
+               tcf_action_destroy(&actions, 0);
        return ret;
 }
 
index 1c60317f01214ad77c17415bb2d7bc194b124615..520baa41cba3a8d24a659b67c5a5ed8a44129f37 100644 (file)
@@ -123,12 +123,11 @@ static int tcf_bpf_dump_ebpf_info(const struct tcf_bpf *prog,
            nla_put_string(skb, TCA_ACT_BPF_NAME, prog->bpf_name))
                return -EMSGSIZE;
 
-       nla = nla_reserve(skb, TCA_ACT_BPF_DIGEST,
-                         sizeof(prog->filter->digest));
+       nla = nla_reserve(skb, TCA_ACT_BPF_TAG, sizeof(prog->filter->tag));
        if (nla == NULL)
                return -EMSGSIZE;
 
-       memcpy(nla_data(nla), prog->filter->digest, nla_len(nla));
+       memcpy(nla_data(nla), prog->filter->tag, nla_len(nla));
 
        return 0;
 }
index adc776048d1a899f7955d0a92dd48b374178f3bb..d9c97018317dd7e26b6c99dfa83b8d6daeca6d19 100644 (file)
@@ -555,11 +555,11 @@ static int cls_bpf_dump_ebpf_info(const struct cls_bpf_prog *prog,
            nla_put_string(skb, TCA_BPF_NAME, prog->bpf_name))
                return -EMSGSIZE;
 
-       nla = nla_reserve(skb, TCA_BPF_DIGEST, sizeof(prog->filter->digest));
+       nla = nla_reserve(skb, TCA_BPF_TAG, sizeof(prog->filter->tag));
        if (nla == NULL)
                return -EMSGSIZE;
 
-       memcpy(nla_data(nla), prog->filter->digest, nla_len(nla));
+       memcpy(nla_data(nla), prog->filter->tag, nla_len(nla));
 
        return 0;
 }
index 886e9d381771ab8c05ed514a399a089c106b2282..1530825985221a1aeb5f77ee81f4251acdef9d96 100644 (file)
@@ -1489,7 +1489,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
        case RPC_GSS_PROC_DESTROY:
                if (gss_write_verf(rqstp, rsci->mechctx, gc->gc_seq))
                        goto auth_err;
-               rsci->h.expiry_time = get_seconds();
+               rsci->h.expiry_time = seconds_since_boot();
                set_bit(CACHE_NEGATIVE, &rsci->h.flags);
                if (resv->iov_len + 4 > PAGE_SIZE)
                        goto drop;
index 3bc1d61694cbbbf7a094a1849b747b65760550b2..9c9db55a0c1e1735e522e406797c4efb25930b07 100644 (file)
@@ -799,6 +799,8 @@ static int svc_handle_xprt(struct svc_rqst *rqstp, struct svc_xprt *xprt)
 
        if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
                dprintk("svc_recv: found XPT_CLOSE\n");
+               if (test_and_clear_bit(XPT_KILL_TEMP, &xprt->xpt_flags))
+                       xprt->xpt_ops->xpo_kill_temp_xprt(xprt);
                svc_delete_xprt(xprt);
                /* Leave XPT_BUSY set on the dead xprt: */
                goto out;
@@ -1020,9 +1022,11 @@ void svc_age_temp_xprts_now(struct svc_serv *serv, struct sockaddr *server_addr)
                le = to_be_closed.next;
                list_del_init(le);
                xprt = list_entry(le, struct svc_xprt, xpt_list);
-               dprintk("svc_age_temp_xprts_now: closing %p\n", xprt);
-               xprt->xpt_ops->xpo_kill_temp_xprt(xprt);
-               svc_close_xprt(xprt);
+               set_bit(XPT_CLOSE, &xprt->xpt_flags);
+               set_bit(XPT_KILL_TEMP, &xprt->xpt_flags);
+               dprintk("svc_age_temp_xprts_now: queuing xprt %p for closing\n",
+                               xprt);
+               svc_xprt_enqueue(xprt);
        }
 }
 EXPORT_SYMBOL_GPL(svc_age_temp_xprts_now);
index 57d35fbb1c28570b5c23f5e06974e8b902853846..172b537f8cfc942ef62574b74cff7ac5f421fba9 100644 (file)
@@ -347,8 +347,6 @@ int rdma_read_chunk_frmr(struct svcxprt_rdma *xprt,
        atomic_inc(&rdma_stat_read);
        return ret;
  err:
-       ib_dma_unmap_sg(xprt->sc_cm_id->device,
-                       frmr->sg, frmr->sg_nents, frmr->direction);
        svc_rdma_put_context(ctxt, 0);
        svc_rdma_put_frmr(xprt, frmr);
        return ret;
index 6b109a808d4c5f43677ff25bd5450d5e8c1dd920..02462d67d1914b6e4b20c4daf7a493b29049a2e4 100644 (file)
@@ -169,7 +169,7 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
 
        /* Send response, if necessary */
        if (respond && (mtyp == DSC_REQ_MSG)) {
-               rskb = tipc_buf_acquire(MAX_H_SIZE);
+               rskb = tipc_buf_acquire(MAX_H_SIZE, GFP_ATOMIC);
                if (!rskb)
                        return;
                tipc_disc_init_msg(net, rskb, DSC_RESP_MSG, bearer);
@@ -278,7 +278,7 @@ int tipc_disc_create(struct net *net, struct tipc_bearer *b,
        req = kmalloc(sizeof(*req), GFP_ATOMIC);
        if (!req)
                return -ENOMEM;
-       req->buf = tipc_buf_acquire(MAX_H_SIZE);
+       req->buf = tipc_buf_acquire(MAX_H_SIZE, GFP_ATOMIC);
        if (!req->buf) {
                kfree(req);
                return -ENOMEM;
index bda89bf9f4ff185f64c68c06d8b88a4385380c58..4e8647aef01c1d070751adc6a24c63769b66e599 100644 (file)
@@ -1395,7 +1395,7 @@ tnl:
                        msg_set_seqno(hdr, seqno++);
                pktlen = msg_size(hdr);
                msg_set_size(&tnlhdr, pktlen + INT_H_SIZE);
-               tnlskb = tipc_buf_acquire(pktlen + INT_H_SIZE);
+               tnlskb = tipc_buf_acquire(pktlen + INT_H_SIZE, GFP_ATOMIC);
                if (!tnlskb) {
                        pr_warn("%sunable to send packet\n", link_co_err);
                        return;
index a22be502f1bd06dc8ec23ab44e56d32f4c3dd469..ab02d07424764ad4b269b6ad560167f528454b80 100644 (file)
@@ -58,12 +58,12 @@ static unsigned int align(unsigned int i)
  * NOTE: Headroom is reserved to allow prepending of a data link header.
  *       There may also be unrequested tailroom present at the buffer's end.
  */
-struct sk_buff *tipc_buf_acquire(u32 size)
+struct sk_buff *tipc_buf_acquire(u32 size, gfp_t gfp)
 {
        struct sk_buff *skb;
        unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u;
 
-       skb = alloc_skb_fclone(buf_size, GFP_ATOMIC);
+       skb = alloc_skb_fclone(buf_size, gfp);
        if (skb) {
                skb_reserve(skb, BUF_HEADROOM);
                skb_put(skb, size);
@@ -95,7 +95,7 @@ struct sk_buff *tipc_msg_create(uint user, uint type,
        struct tipc_msg *msg;
        struct sk_buff *buf;
 
-       buf = tipc_buf_acquire(hdr_sz + data_sz);
+       buf = tipc_buf_acquire(hdr_sz + data_sz, GFP_ATOMIC);
        if (unlikely(!buf))
                return NULL;
 
@@ -261,7 +261,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
 
        /* No fragmentation needed? */
        if (likely(msz <= pktmax)) {
-               skb = tipc_buf_acquire(msz);
+               skb = tipc_buf_acquire(msz, GFP_KERNEL);
                if (unlikely(!skb))
                        return -ENOMEM;
                skb_orphan(skb);
@@ -282,7 +282,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
        msg_set_importance(&pkthdr, msg_importance(mhdr));
 
        /* Prepare first fragment */
-       skb = tipc_buf_acquire(pktmax);
+       skb = tipc_buf_acquire(pktmax, GFP_KERNEL);
        if (!skb)
                return -ENOMEM;
        skb_orphan(skb);
@@ -313,7 +313,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
                        pktsz = drem + INT_H_SIZE;
                else
                        pktsz = pktmax;
-               skb = tipc_buf_acquire(pktsz);
+               skb = tipc_buf_acquire(pktsz, GFP_KERNEL);
                if (!skb) {
                        rc = -ENOMEM;
                        goto error;
@@ -448,7 +448,7 @@ bool tipc_msg_make_bundle(struct sk_buff **skb,  struct tipc_msg *msg,
        if (msz > (max / 2))
                return false;
 
-       _skb = tipc_buf_acquire(max);
+       _skb = tipc_buf_acquire(max, GFP_ATOMIC);
        if (!_skb)
                return false;
 
@@ -496,7 +496,7 @@ bool tipc_msg_reverse(u32 own_node,  struct sk_buff **skb, int err)
 
        /* Never return SHORT header; expand by replacing buffer if necessary */
        if (msg_short(hdr)) {
-               *skb = tipc_buf_acquire(BASIC_H_SIZE + dlen);
+               *skb = tipc_buf_acquire(BASIC_H_SIZE + dlen, GFP_ATOMIC);
                if (!*skb)
                        goto exit;
                memcpy((*skb)->data + BASIC_H_SIZE, msg_data(hdr), dlen);
index 8d408612ffa490521e310b3c643f2407a6c822f3..2c3dc38abf9c25814c0d9e3c31711706f2bca664 100644 (file)
@@ -820,7 +820,7 @@ static inline bool msg_is_reset(struct tipc_msg *hdr)
        return (msg_user(hdr) == LINK_PROTOCOL) && (msg_type(hdr) == RESET_MSG);
 }
 
-struct sk_buff *tipc_buf_acquire(u32 size);
+struct sk_buff *tipc_buf_acquire(u32 size, gfp_t gfp);
 bool tipc_msg_validate(struct sk_buff *skb);
 bool tipc_msg_reverse(u32 own_addr, struct sk_buff **skb, int err);
 void tipc_msg_init(u32 own_addr, struct tipc_msg *m, u32 user, u32 type,
index c1cfd92de17aee30a310305707a70ecb87fd2548..23f8899e0f8c3d7bda50bc57801bcc63ceab448c 100644 (file)
@@ -69,7 +69,7 @@ static struct sk_buff *named_prepare_buf(struct net *net, u32 type, u32 size,
                                         u32 dest)
 {
        struct tipc_net *tn = net_generic(net, tipc_net_id);
-       struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE + size);
+       struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE + size, GFP_ATOMIC);
        struct tipc_msg *msg;
 
        if (buf != NULL) {
index ef5eff93a8b817dda5fa41bebf4fe4963663a9d6..5c1b267e22beefe7cfa83e3541783fab702a092a 100644 (file)
@@ -4615,6 +4615,15 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
                break;
        }
 
+       /*
+        * Older kernel versions ignored this attribute entirely, so don't
+        * reject attempts to update it but mark it as unused instead so the
+        * driver won't look at the data.
+        */
+       if (statype != CFG80211_STA_AP_CLIENT_UNASSOC &&
+           statype != CFG80211_STA_TDLS_PEER_SETUP)
+               params->opmode_notif_used = false;
+
        return 0;
 }
 EXPORT_SYMBOL(cfg80211_check_station_change);
@@ -4854,6 +4863,12 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
                params.local_pm = pm;
        }
 
+       if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
+               params.opmode_notif_used = true;
+               params.opmode_notif =
+                       nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
+       }
+
        /* Include parameters for TDLS peer (will check later) */
        err = nl80211_set_station_tdls(info, &params);
        if (err)
index 09f7fe7e5fd74c289586711263d99bd9e25b1c2c..d8014065d479f9b85d96ae3d09664b1b14894467 100644 (file)
@@ -4,7 +4,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
-#include <net/ethernet.h>
+#include <linux/if_ether.h>
 #include <net/if.h>
 #include <linux/if_packet.h>
 #include <arpa/inet.h>
index f4fa6af22def9fa9c01df1525c7a61b3aecb8cdd..ccca1e3480171501f01779ca88fc26305bff2491 100644 (file)
@@ -9,7 +9,6 @@
 #include <string.h>
 #include <fcntl.h>
 #include <poll.h>
-#include <sys/ioctl.h>
 #include <linux/perf_event.h>
 #include <linux/bpf.h>
 #include <errno.h>
index 3284bb14ae789bcb0513cba80e8ef0dd43e0812d..8aad81151d5068bacbc1e6d3c114248e9847bf84 100644 (file)
@@ -213,6 +213,9 @@ static int get_value(struct parse_opt_ctx_t *p,
                else
                        err = get_arg(p, opt, flags, (const char **)opt->value);
 
+               if (opt->set)
+                       *(bool *)opt->set = true;
+
                /* PARSE_OPT_NOEMPTY: Allow NULL but disallow empty string. */
                if (opt->flags & PARSE_OPT_NOEMPTY) {
                        const char *val = *(const char **)opt->value;
index 8866ac438b3441d9e82c739da41273e93466e48b..11c3be3bcce79598bd758d436270399f0f240842 100644 (file)
@@ -137,6 +137,11 @@ struct option {
        { .type = OPTION_STRING,  .short_name = (s), .long_name = (l), \
          .value = check_vtype(v, const char **), (a), .help = (h), \
          .flags = PARSE_OPT_OPTARG, .defval = (intptr_t)(d) }
+#define OPT_STRING_OPTARG_SET(s, l, v, os, a, h, d) \
+       { .type = OPTION_STRING, .short_name = (s), .long_name = (l), \
+         .value = check_vtype(v, const char **), (a), .help = (h), \
+         .flags = PARSE_OPT_OPTARG, .defval = (intptr_t)(d), \
+         .set = check_vtype(os, bool *)}
 #define OPT_STRING_NOEMPTY(s, l, v, a, h)   { .type = OPTION_STRING,  .short_name = (s), .long_name = (l), .value = check_vtype(v, const char **), (a), .help = (h), .flags = PARSE_OPT_NOEMPTY}
 #define OPT_DATE(s, l, v, h) \
        { .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = "time", .help = (h), .callback = parse_opt_approxidate_cb }
index f1ce6006525886169fa239bfaa5cabffa33e3c9f..ec30c2fcbac05c2bef0268ac9494c0c5b4254a23 100644 (file)
@@ -111,7 +111,7 @@ static int sched_switch_handler(struct trace_seq *s,
        trace_seq_printf(s, "%lld ", val);
 
        if (pevent_get_field_val(s, event, "prev_prio", record, &val, 0) == 0)
-               trace_seq_printf(s, "[%lld] ", val);
+               trace_seq_printf(s, "[%d] ", (int) val);
 
        if (pevent_get_field_val(s,  event, "prev_state", record, &val, 0) == 0)
                write_state(s, val);
@@ -129,7 +129,7 @@ static int sched_switch_handler(struct trace_seq *s,
        trace_seq_printf(s, "%lld", val);
 
        if (pevent_get_field_val(s, event, "next_prio", record, &val, 0) == 0)
-               trace_seq_printf(s, " [%lld]", val);
+               trace_seq_printf(s, " [%d]", (int) val);
 
        return 0;
 }
index 27fc3617c6a42066bf7a64bb2ace9961a350183b..5054d9147f0f03122f96338f96e9acd08cc36992 100644 (file)
@@ -430,6 +430,10 @@ that gets then processed, possibly via a perf script, to decide if that
 particular perf.data snapshot should be kept or not.
 
 Implies --timestamp-filename, --no-buildid and --no-buildid-cache.
+The reason for the latter two is to reduce the data file switching
+overhead. You can still switch them on with:
+
+  --switch-output --no-no-buildid  --no-no-buildid-cache
 
 --dry-run::
 Parse options then exit. --dry-run can be used to detect errors in cmdline
index 8fc24824705e0bfecd696bfc50a53ec4924cf9d7..8bb16aa9d661d0e5b8104adc0ef3d14a1fc296f9 100644 (file)
@@ -704,9 +704,9 @@ install-tests: all install-gtk
                $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \
                $(INSTALL) tests/attr/* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'
 
-install-bin: install-tools install-tests
+install-bin: install-tools install-tests install-traceevent-plugins
 
-install: install-bin try-install-man install-traceevent-plugins
+install: install-bin try-install-man
 
 install-python_ext:
        $(PYTHON_WORD) util/setup.py --quiet install --root='/$(DESTDIR_SQ)'
index 74d6a035133a96a7303287e130abe73af3fc4622..4ec10e9427d915a041e0510eaac2ded2daf9fc07 100644 (file)
@@ -1405,7 +1405,7 @@ static bool dry_run;
  * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
  * using pipes, etc.
  */
-struct option __record_options[] = {
+static struct option __record_options[] = {
        OPT_CALLBACK('e', "event", &record.evlist, "event",
                     "event selector. use 'perf list' to list available events",
                     parse_events_option),
@@ -1636,7 +1636,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
                 * overhead. Still generate buildid if they are required
                 * explicitly using
                 *
-                *  perf record --signal-trigger --no-no-buildid \
+                *  perf record --switch-output --no-no-buildid \
                 *              --no-no-buildid-cache
                 *
                 * Following code equals to:
index d53e706a6f1706d2d69caa93132521f55d89d072..5b134b0d1ff37e42a1b82b5973528c4003bb80f3 100644 (file)
@@ -209,6 +209,7 @@ struct perf_sched {
        u64             skipped_samples;
        const char      *time_str;
        struct perf_time_interval ptime;
+       struct perf_time_interval hist_time;
 };
 
 /* per thread run time data */
@@ -2460,6 +2461,11 @@ static int timehist_sched_change_event(struct perf_tool *tool,
                timehist_print_sample(sched, sample, &al, thread, t);
 
 out:
+       if (sched->hist_time.start == 0 && t >= ptime->start)
+               sched->hist_time.start = t;
+       if (ptime->end == 0 || t <= ptime->end)
+               sched->hist_time.end = t;
+
        if (tr) {
                /* time of this sched_switch event becomes last time task seen */
                tr->last_time = sample->time;
@@ -2624,6 +2630,7 @@ static void timehist_print_summary(struct perf_sched *sched,
        struct thread *t;
        struct thread_runtime *r;
        int i;
+       u64 hist_time = sched->hist_time.end - sched->hist_time.start;
 
        memset(&totals, 0, sizeof(totals));
 
@@ -2665,7 +2672,7 @@ static void timehist_print_summary(struct perf_sched *sched,
                        totals.sched_count += r->run_stats.n;
                        printf("    CPU %2d idle for ", i);
                        print_sched_time(r->total_run_time, 6);
-                       printf(" msec\n");
+                       printf(" msec  (%6.2f%%)\n", 100.0 * r->total_run_time / hist_time);
                } else
                        printf("    CPU %2d idle entire time window\n", i);
        }
@@ -2701,12 +2708,16 @@ static void timehist_print_summary(struct perf_sched *sched,
 
        printf("\n"
               "    Total number of unique tasks: %" PRIu64 "\n"
-              "Total number of context switches: %" PRIu64 "\n"
-              "           Total run time (msec): ",
+              "Total number of context switches: %" PRIu64 "\n",
               totals.task_count, totals.sched_count);
 
+       printf("           Total run time (msec): ");
        print_sched_time(totals.total_run_time, 2);
        printf("\n");
+
+       printf("    Total scheduling time (msec): ");
+       print_sched_time(hist_time, 2);
+       printf(" (x %d)\n", sched->max_cpu);
 }
 
 typedef int (*sched_handler)(struct perf_tool *tool,
index d281ae2b54e8fef7b85574a8b799dc33c21e9e44..6a6f44dd594bc4c6275694335ebaa02b22118982 100644 (file)
@@ -163,7 +163,7 @@ static struct map *kernel_get_module_map(const char *module)
 
        /* A file path -- this is an offline module */
        if (module && strchr(module, '/'))
-               return machine__findnew_module_map(host_machine, 0, module);
+               return dso__new_map(module);
 
        if (!module)
                module = "kernel";
@@ -173,6 +173,7 @@ static struct map *kernel_get_module_map(const char *module)
                if (strncmp(pos->dso->short_name + 1, module,
                            pos->dso->short_name_len - 2) == 0 &&
                    module[pos->dso->short_name_len - 2] == '\0') {
+                       map__get(pos);
                        return pos;
                }
        }
@@ -188,15 +189,6 @@ struct map *get_target_map(const char *target, bool user)
                return kernel_get_module_map(target);
 }
 
-static void put_target_map(struct map *map, bool user)
-{
-       if (map && user) {
-               /* Only the user map needs to be released */
-               map__put(map);
-       }
-}
-
-
 static int convert_exec_to_group(const char *exec, char **result)
 {
        char *ptr1, *ptr2, *exec_copy;
@@ -267,21 +259,6 @@ static bool kprobe_warn_out_range(const char *symbol, unsigned long address)
        return true;
 }
 
-/*
- * NOTE:
- * '.gnu.linkonce.this_module' section of kernel module elf directly
- * maps to 'struct module' from linux/module.h. This section contains
- * actual module name which will be used by kernel after loading it.
- * But, we cannot use 'struct module' here since linux/module.h is not
- * exposed to user-space. Offset of 'name' has remained same from long
- * time, so hardcoding it here.
- */
-#ifdef __LP64__
-#define MOD_NAME_OFFSET 24
-#else
-#define MOD_NAME_OFFSET 12
-#endif
-
 /*
  * @module can be module name of module file path. In case of path,
  * inspect elf and find out what is actual module name.
@@ -296,6 +273,7 @@ static char *find_module_name(const char *module)
        Elf_Data *data;
        Elf_Scn *sec;
        char *mod_name = NULL;
+       int name_offset;
 
        fd = open(module, O_RDONLY);
        if (fd < 0)
@@ -317,7 +295,21 @@ static char *find_module_name(const char *module)
        if (!data || !data->d_buf)
                goto ret_err;
 
-       mod_name = strdup((char *)data->d_buf + MOD_NAME_OFFSET);
+       /*
+        * NOTE:
+        * '.gnu.linkonce.this_module' section of kernel module elf directly
+        * maps to 'struct module' from linux/module.h. This section contains
+        * actual module name which will be used by kernel after loading it.
+        * But, we cannot use 'struct module' here since linux/module.h is not
+        * exposed to user-space. Offset of 'name' has remained same from long
+        * time, so hardcoding it here.
+        */
+       if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
+               name_offset = 12;
+       else    /* expect ELFCLASS64 by default */
+               name_offset = 24;
+
+       mod_name = strdup((char *)data->d_buf + name_offset);
 
 ret_err:
        elf_end(elf);
@@ -412,7 +404,7 @@ static int find_alternative_probe_point(struct debuginfo *dinfo,
        }
 
 out:
-       put_target_map(map, uprobes);
+       map__put(map);
        return ret;
 
 }
@@ -618,6 +610,67 @@ error:
        return ret ? : -ENOENT;
 }
 
+/* Adjust symbol name and address */
+static int post_process_probe_trace_point(struct probe_trace_point *tp,
+                                          struct map *map, unsigned long offs)
+{
+       struct symbol *sym;
+       u64 addr = tp->address + tp->offset - offs;
+
+       sym = map__find_symbol(map, addr);
+       if (!sym)
+               return -ENOENT;
+
+       if (strcmp(sym->name, tp->symbol)) {
+               /* If we have no realname, use symbol for it */
+               if (!tp->realname)
+                       tp->realname = tp->symbol;
+               else
+                       free(tp->symbol);
+               tp->symbol = strdup(sym->name);
+               if (!tp->symbol)
+                       return -ENOMEM;
+       }
+       tp->offset = addr - sym->start;
+       tp->address -= offs;
+
+       return 0;
+}
+
+/*
+ * Rename DWARF symbols to ELF symbols -- gcc sometimes optimizes functions
+ * and generate new symbols with suffixes such as .constprop.N or .isra.N
+ * etc. Since those symbols are not recorded in DWARF, we have to find
+ * correct generated symbols from offline ELF binary.
+ * For online kernel or uprobes we don't need this because those are
+ * rebased on _text, or already a section relative address.
+ */
+static int
+post_process_offline_probe_trace_events(struct probe_trace_event *tevs,
+                                       int ntevs, const char *pathname)
+{
+       struct map *map;
+       unsigned long stext = 0;
+       int i, ret = 0;
+
+       /* Prepare a map for offline binary */
+       map = dso__new_map(pathname);
+       if (!map || get_text_start_address(pathname, &stext) < 0) {
+               pr_warning("Failed to get ELF symbols for %s\n", pathname);
+               return -EINVAL;
+       }
+
+       for (i = 0; i < ntevs; i++) {
+               ret = post_process_probe_trace_point(&tevs[i].point,
+                                                    map, stext);
+               if (ret < 0)
+                       break;
+       }
+       map__put(map);
+
+       return ret;
+}
+
 static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs,
                                          int ntevs, const char *exec)
 {
@@ -645,18 +698,31 @@ static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs,
        return ret;
 }
 
-static int add_module_to_probe_trace_events(struct probe_trace_event *tevs,
-                                           int ntevs, const char *module)
+static int
+post_process_module_probe_trace_events(struct probe_trace_event *tevs,
+                                      int ntevs, const char *module,
+                                      struct debuginfo *dinfo)
 {
+       Dwarf_Addr text_offs = 0;
        int i, ret = 0;
        char *mod_name = NULL;
+       struct map *map;
 
        if (!module)
                return 0;
 
-       mod_name = find_module_name(module);
+       map = get_target_map(module, false);
+       if (!map || debuginfo__get_text_offset(dinfo, &text_offs, true) < 0) {
+               pr_warning("Failed to get ELF symbols for %s\n", module);
+               return -EINVAL;
+       }
 
+       mod_name = find_module_name(module);
        for (i = 0; i < ntevs; i++) {
+               ret = post_process_probe_trace_point(&tevs[i].point,
+                                               map, (unsigned long)text_offs);
+               if (ret < 0)
+                       break;
                tevs[i].point.module =
                        strdup(mod_name ? mod_name : module);
                if (!tevs[i].point.module) {
@@ -666,6 +732,8 @@ static int add_module_to_probe_trace_events(struct probe_trace_event *tevs,
        }
 
        free(mod_name);
+       map__put(map);
+
        return ret;
 }
 
@@ -679,7 +747,8 @@ post_process_kernel_probe_trace_events(struct probe_trace_event *tevs,
 
        /* Skip post process if the target is an offline kernel */
        if (symbol_conf.ignore_vmlinux_buildid)
-               return 0;
+               return post_process_offline_probe_trace_events(tevs, ntevs,
+                                               symbol_conf.vmlinux_name);
 
        reloc_sym = kernel_get_ref_reloc_sym();
        if (!reloc_sym) {
@@ -722,7 +791,7 @@ arch__post_process_probe_trace_events(struct perf_probe_event *pev __maybe_unuse
 static int post_process_probe_trace_events(struct perf_probe_event *pev,
                                           struct probe_trace_event *tevs,
                                           int ntevs, const char *module,
-                                          bool uprobe)
+                                          bool uprobe, struct debuginfo *dinfo)
 {
        int ret;
 
@@ -730,7 +799,8 @@ static int post_process_probe_trace_events(struct perf_probe_event *pev,
                ret = add_exec_to_probe_trace_events(tevs, ntevs, module);
        else if (module)
                /* Currently ref_reloc_sym based probe is not for drivers */
-               ret = add_module_to_probe_trace_events(tevs, ntevs, module);
+               ret = post_process_module_probe_trace_events(tevs, ntevs,
+                                                            module, dinfo);
        else
                ret = post_process_kernel_probe_trace_events(tevs, ntevs);
 
@@ -774,30 +844,27 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
                }
        }
 
-       debuginfo__delete(dinfo);
-
        if (ntevs > 0) {        /* Succeeded to find trace events */
                pr_debug("Found %d probe_trace_events.\n", ntevs);
                ret = post_process_probe_trace_events(pev, *tevs, ntevs,
-                                               pev->target, pev->uprobes);
+                                       pev->target, pev->uprobes, dinfo);
                if (ret < 0 || ret == ntevs) {
+                       pr_debug("Post processing failed or all events are skipped. (%d)\n", ret);
                        clear_probe_trace_events(*tevs, ntevs);
                        zfree(tevs);
+                       ntevs = 0;
                }
-               if (ret != ntevs)
-                       return ret < 0 ? ret : ntevs;
-               ntevs = 0;
-               /* Fall through */
        }
 
+       debuginfo__delete(dinfo);
+
        if (ntevs == 0) {       /* No error but failed to find probe point. */
                pr_warning("Probe point '%s' not found.\n",
                           synthesize_perf_probe_point(&pev->point));
                return -ENOENT;
-       }
-       /* Error path : ntevs < 0 */
-       pr_debug("An error occurred in debuginfo analysis (%d).\n", ntevs);
-       if (ntevs < 0) {
+       } else if (ntevs < 0) {
+               /* Error path : ntevs < 0 */
+               pr_debug("An error occurred in debuginfo analysis (%d).\n", ntevs);
                if (ntevs == -EBADF)
                        pr_warning("Warning: No dwarf info found in the vmlinux - "
                                "please rebuild kernel with CONFIG_DEBUG_INFO=y.\n");
@@ -2869,7 +2936,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
        }
 
 out:
-       put_target_map(map, pev->uprobes);
+       map__put(map);
        free(syms);
        return ret;
 
@@ -3362,10 +3429,7 @@ int show_available_funcs(const char *target, struct strfilter *_filter,
                return ret;
 
        /* Get a symbol map */
-       if (user)
-               map = dso__new_map(target);
-       else
-               map = kernel_get_module_map(target);
+       map = get_target_map(target, user);
        if (!map) {
                pr_err("Failed to get a map for %s\n", (target) ? : "kernel");
                return -EINVAL;
@@ -3397,9 +3461,7 @@ int show_available_funcs(const char *target, struct strfilter *_filter,
         }
 
 end:
-       if (user) {
-               map__put(map);
-       }
+       map__put(map);
        exit_probe_symbol_maps();
 
        return ret;
index df4debe564daabce2e739289b14360d49185bc6f..0d9d6e0803b88b6fe3909c0b8b83f24fa47580f6 100644 (file)
@@ -1501,7 +1501,8 @@ int debuginfo__find_available_vars_at(struct debuginfo *dbg,
 }
 
 /* For the kernel module, we need a special code to get a DIE */
-static int debuginfo__get_text_offset(struct debuginfo *dbg, Dwarf_Addr *offs)
+int debuginfo__get_text_offset(struct debuginfo *dbg, Dwarf_Addr *offs,
+                               bool adjust_offset)
 {
        int n, i;
        Elf32_Word shndx;
@@ -1530,6 +1531,8 @@ static int debuginfo__get_text_offset(struct debuginfo *dbg, Dwarf_Addr *offs)
                        if (!shdr)
                                return -ENOENT;
                        *offs = shdr->sh_addr;
+                       if (adjust_offset)
+                               *offs -= shdr->sh_offset;
                }
        }
        return 0;
@@ -1543,16 +1546,12 @@ int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
        Dwarf_Addr _addr = 0, baseaddr = 0;
        const char *fname = NULL, *func = NULL, *basefunc = NULL, *tmp;
        int baseline = 0, lineno = 0, ret = 0;
-       bool reloc = false;
 
-retry:
+       /* We always need to relocate the address for aranges */
+       if (debuginfo__get_text_offset(dbg, &baseaddr, false) == 0)
+               addr += baseaddr;
        /* Find cu die */
        if (!dwarf_addrdie(dbg->dbg, (Dwarf_Addr)addr, &cudie)) {
-               if (!reloc && debuginfo__get_text_offset(dbg, &baseaddr) == 0) {
-                       addr += baseaddr;
-                       reloc = true;
-                       goto retry;
-               }
                pr_warning("Failed to find debug information for address %lx\n",
                           addr);
                ret = -EINVAL;
index f1d8558f498e96771c13b3f42046a757e888bdf2..2956c51986529ee7481f922d488a449c0a7619a0 100644 (file)
@@ -46,6 +46,9 @@ int debuginfo__find_trace_events(struct debuginfo *dbg,
 int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
                                struct perf_probe_point *ppt);
 
+int debuginfo__get_text_offset(struct debuginfo *dbg, Dwarf_Addr *offs,
+                              bool adjust_offset);
+
 /* Find a line range */
 int debuginfo__find_line_range(struct debuginfo *dbg, struct line_range *lr);
 
index 99400b0e8f2a892dcfbfe2572758ef3eae73be59..adbc6c02c3aaac757028e6bbe1ae63cd11ee437a 100644 (file)
@@ -537,6 +537,12 @@ int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
                                break;
                } else {
                        int n = namesz + descsz;
+
+                       if (n > (int)sizeof(bf)) {
+                               n = sizeof(bf);
+                               pr_debug("%s: truncating reading of build id in sysfs file %s: n_namesz=%u, n_descsz=%u.\n",
+                                        __func__, filename, nhdr.n_namesz, nhdr.n_descsz);
+                       }
                        if (read(fd, bf, n) != n)
                                break;
                }