Merge branch 'stable-3.2' into pandora-3.2
authorGrazvydas Ignotas <notasas@gmail.com>
Sat, 16 Sep 2017 19:23:33 +0000 (22:23 +0300)
committerGrazvydas Ignotas <notasas@gmail.com>
Sat, 16 Sep 2017 19:23:33 +0000 (22:23 +0300)
150 files changed:
Makefile
arch/alpha/kernel/osf_sys.c
arch/mips/include/asm/kprobes.h
arch/mips/kernel/entry.S
arch/powerpc/include/asm/page.h
arch/powerpc/include/asm/qe.h
arch/powerpc/kernel/kprobes.c
arch/powerpc/kernel/setup_64.c
arch/x86/boot/boot.h
arch/x86/kvm/mmu.c
arch/x86/kvm/mmu.h
arch/x86/kvm/x86.c
arch/x86/mm/numa_32.c
arch/x86/um/ptrace_64.c
crypto/gcm.c
drivers/Makefile
drivers/ata/ahci.c
drivers/ata/libata-scsi.c
drivers/char/mem.c
drivers/dma/ep93xx_dma.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
drivers/i2c/busses/i2c-tiny-usb.c
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/verbs.c
drivers/input/serio/i8042-x86ia64io.h
drivers/media/dvb/dvb-usb/digitv.c
drivers/media/dvb/dvb-usb/dw2102.c
drivers/media/dvb/dvb-usb/ttusb2.c
drivers/media/rc/ir-raw.c
drivers/media/rc/mceusb.c
drivers/media/video/cx231xx/cx231xx-audio.c
drivers/media/video/cx231xx/cx231xx-cards.c
drivers/media/video/gspca/konica.c
drivers/media/video/ov2640.c
drivers/media/video/pvrusb2/pvrusb2-eeprom.c
drivers/media/video/usbvision/usbvision-video.c
drivers/media/video/videobuf2-core.c
drivers/media/video/zr364xx.c
drivers/net/ethernet/8390/ax88796.c
drivers/net/ethernet/ethoc.c
drivers/net/ethernet/freescale/ucc_geth.c
drivers/net/irda/irda-usb.c
drivers/net/phy/marvell.c
drivers/net/wireless/ath/ath9k/hif_usb.c
drivers/net/wireless/zd1211rw/zd_usb.c
drivers/of/fdt.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/proc.c
drivers/pci/quirks.c
drivers/power/pda_power.c
drivers/scsi/qla2xxx/qla_os.c
drivers/staging/gma500/psb_intel_lvds.c
drivers/staging/usbip/vhci_hcd.c
drivers/tty/serial/sh-sci.c
drivers/usb/class/cdc-acm.c
drivers/usb/core/devio.c
drivers/usb/core/driver.c
drivers/usb/core/file.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/gadget/dummy_hcd.c
drivers/usb/gadget/f_mass_storage.c
drivers/usb/host/r8a66597-hcd.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.h
drivers/usb/misc/iowarrior.c
drivers/usb/musb/tusb6010_omap.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/io_ti.c
drivers/usb/serial/ir-usb.c
drivers/usb/serial/mct_u232.c
drivers/usb/storage/ene_ub6250.c
drivers/uwb/i1480/dfu/usb.c
drivers/video/Kconfig
drivers/video/Makefile
drivers/watchdog/pcwd_usb.c
drivers/xen/biomerge.c
fs/autofs4/dev-ioctl.c
fs/cifs/cifssmb.c
fs/cifs/netmisc.c
fs/configfs/symlink.c
fs/ext4/extents.c
fs/ext4/inode.c
fs/partitions/check.c
fs/proc/array.c
fs/proc/base.c
fs/proc/namespaces.c
fs/timerfd.c
fs/ufs/inode.c
fs/ufs/super.c
fs/ufs/truncate.c
fs/ufs/util.h
include/linux/kprobes.h
include/linux/netfilter/nf_conntrack_common.h
include/linux/ptrace.h
include/linux/skbuff.h
include/linux/usb/ch11.h
include/net/xfrm.h
ipc/mqueue.c
kernel/events/core.c
kernel/futex.c
kernel/futex_compat.c
kernel/kprobes.c
kernel/padata.c
kernel/ptrace.c
kernel/signal.c
kernel/time/alarmtimer.c
kernel/trace/trace_kprobe.c
lib/cmdline.c
mm/mempolicy.c
mm/migrate.c
mm/page_cgroup.c
mm/process_vm_access.c
net/bluetooth/hci_sock.c
net/ceph/osdmap.c
net/core/dev.c
net/core/rtnetlink.c
net/core/skbuff.c
net/ipv4/af_inet.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_lp.c
net/ipv6/addrconf.c
net/ipv6/af_inet6.c
net/ipv6/exthdrs.c
net/ipv6/ip6_output.c
net/ipv6/ip6_tunnel.c
net/ipv6/xfrm6_mode_ro.c
net/ipv6/xfrm6_mode_transport.c
net/key/af_key.c
net/mac80211/rx.c
net/netfilter/nf_conntrack_netlink.c
net/packet/af_packet.c
net/wireless/util.c
net/xfrm/xfrm_policy.c
security/commoncap.c
security/keys/keyctl.c
security/selinux/hooks.c
sound/pci/hda/patch_sigmatel.c
sound/soc/soc-core.c
tools/perf/Documentation/perf-probe.txt
tools/perf/Documentation/perf-script-perl.txt
tools/perf/Documentation/perf-script-python.txt
tools/perf/util/scripting-engines/trace-event-python.c

index b8758cc..ec64e6f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 2
-SUBLEVEL = 91
+SUBLEVEL = 93
 EXTRAVERSION =
 NAME = Saber-toothed Squirrel
 
index b9abe5b..13a99b4 100644 (file)
@@ -1026,8 +1026,10 @@ SYSCALL_DEFINE4(osf_wait4, pid_t, pid, int __user *, ustatus, int, options,
        if (!access_ok(VERIFY_WRITE, ur, sizeof(*ur)))
                return -EFAULT;
 
-       err = 0;
-       err |= put_user(status, ustatus);
+       err = put_user(status, ustatus);
+       if (ret < 0)
+               return err ? err : ret;
+
        err |= __put_user(r.ru_utime.tv_sec, &ur->ru_utime.tv_sec);
        err |= __put_user(r.ru_utime.tv_usec, &ur->ru_utime.tv_usec);
        err |= __put_user(r.ru_stime.tv_sec, &ur->ru_stime.tv_sec);
index e6ea4d4..c271e27 100644 (file)
@@ -40,7 +40,8 @@ typedef union mips_instruction kprobe_opcode_t;
 
 #define flush_insn_slot(p)                                             \
 do {                                                                   \
-       flush_icache_range((unsigned long)p->addr,                      \
+       if (p->addr)                                                    \
+               flush_icache_range((unsigned long)p->addr,              \
                           (unsigned long)p->addr +                     \
                           (MAX_INSN_SIZE * sizeof(kprobe_opcode_t)));  \
 } while (0)
index 37acfa0..5fc7a64 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <asm/asm.h>
 #include <asm/asmmacro.h>
+#include <asm/irqflags.h>
 #include <asm/regdef.h>
 #include <asm/mipsregs.h>
 #include <asm/stackframe.h>
@@ -145,6 +146,7 @@ work_pending:
        andi    t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS
        beqz    t0, work_notifysig
 work_resched:
+       TRACE_IRQS_OFF
        jal     schedule
 
        local_irq_disable               # make sure need_resched and
@@ -172,6 +174,7 @@ syscall_exit_work:
        beqz    t0, work_pending        # trace bit set?
        local_irq_enable                # could let syscall_trace_leave()
                                        # call schedule() instead
+       TRACE_IRQS_ON
        move    a0, sp
        jal     syscall_trace_leave
        b       resume_userspace
index 5b0bde2..516fadd 100644 (file)
@@ -118,7 +118,19 @@ extern phys_addr_t kernstart_addr;
 
 #define virt_to_page(kaddr)    pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
+
+#ifdef CONFIG_PPC_BOOK3S_64
+/*
+ * On hash the vmalloc and other regions alias to the kernel region when passed
+ * through __pa(), which virt_to_pfn() uses. That means virt_addr_valid() can
+ * return true for some vmalloc addresses, which is incorrect. So explicitly
+ * check that the address is in the kernel region.
+ */
+#define virt_addr_valid(kaddr) (REGION_ID(kaddr) == KERNEL_REGION_ID && \
+                               pfn_valid(__pa(kaddr) >> PAGE_SHIFT))
+#else
 #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+#endif
 
 /*
  * On Book-E parts we need __va to parse the device tree and we can't
index 5e0b6d5..360abc6 100644 (file)
@@ -193,6 +193,7 @@ static inline int qe_alive_during_sleep(void)
 #define qe_muram_free cpm_muram_free
 #define qe_muram_addr cpm_muram_addr
 #define qe_muram_offset cpm_muram_offset
+#define qe_muram_dma cpm_muram_dma
 
 /* Structure that defines QE firmware binary files.
  *
index bc47352..fe3f4ef 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/module.h>
 #include <linux/kdebug.h>
 #include <linux/slab.h>
+#include <linux/ftrace.h>
 #include <asm/cacheflush.h>
 #include <asm/sstep.h>
 #include <asm/uaccess.h>
@@ -530,6 +531,15 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
        regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
 #endif
 
+       /*
+        * jprobes use jprobe_return() which skips the normal return
+        * path of the function, and this messes up the accounting of the
+        * function graph tracer.
+        *
+        * Pause function graph tracing while performing the jprobe function.
+        */
+       pause_graph_tracing();
+
        return 1;
 }
 
@@ -552,6 +562,8 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
         * saved regs...
         */
        memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs));
+       /* It's OK to start function graph tracing again */
+       unpause_graph_tracing();
        preempt_enable_no_resched();
        return 1;
 }
index 2c8890a..50c959b 100644 (file)
@@ -508,6 +508,23 @@ static void __init exc_lvl_early_init(void)
 #define exc_lvl_early_init()
 #endif
 
+/*
+ * Emergency stacks are used for a range of things, from asynchronous
+ * NMIs (system reset, machine check) to synchronous, process context.
+ * We set preempt_count to zero, even though that isn't necessarily correct. To
+ * get the right value we'd need to copy it from the previous thread_info, but
+ * doing that might fault causing more problems.
+ * TODO: what to do with accounting?
+ */
+static void emerg_stack_init_thread_info(struct thread_info *ti, int cpu)
+{
+       ti->task = NULL;
+       ti->cpu = cpu;
+       ti->preempt_count = 0;
+       ti->local_flags = 0;
+       ti->flags = 0;
+}
+
 /*
  * Stack space used when we detect a bad kernel stack pointer, and
  * early in SMP boots before relocation is enabled.
@@ -525,12 +542,20 @@ static void __init emergency_stack_init(void)
         * Since we use these as temporary stacks during secondary CPU
         * bringup, we need to get at them in real mode. This means they
         * must also be within the RMO region.
+        *
+        * The IRQ stacks allocated elsewhere in this file are zeroed and
+        * initialized in kernel/irq.c. These are initialized here in order
+        * to have emergency stacks available as early as possible.
         */
        limit = min(safe_stack_limit(), ppc64_rma_size);
 
        for_each_possible_cpu(i) {
                unsigned long sp;
+               struct thread_info *ti;
                sp  = memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit);
+               ti = __va(sp);
+               memset(ti, 0, THREAD_SIZE);
+               emerg_stack_init_thread_info(ti, i);
                sp += THREAD_SIZE;
                paca[i].emergency_sp = __va(sp);
        }
index c7093bd..790b53e 100644 (file)
@@ -16,7 +16,7 @@
 #ifndef BOOT_BOOT_H
 #define BOOT_BOOT_H
 
-#define STACK_SIZE     512     /* Minimum number of bytes for stack */
+#define STACK_SIZE     1024    /* Minimum number of bytes for stack */
 
 #ifndef __ASSEMBLY__
 
index 4a949c7..5b2bf2b 100644 (file)
@@ -3011,12 +3011,15 @@ static int kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn)
        return kvm_setup_async_pf(vcpu, gva, gfn, &arch);
 }
 
-static bool can_do_async_pf(struct kvm_vcpu *vcpu)
+bool kvm_can_do_async_pf(struct kvm_vcpu *vcpu)
 {
        if (unlikely(!irqchip_in_kernel(vcpu->kvm) ||
                     kvm_event_needs_reinjection(vcpu)))
                return false;
 
+       if (is_guest_mode(vcpu))
+               return false;
+
        return kvm_x86_ops->interrupt_allowed(vcpu);
 }
 
@@ -3032,7 +3035,7 @@ static bool try_async_pf(struct kvm_vcpu *vcpu, bool prefault, gfn_t gfn,
 
        put_page(pfn_to_page(*pfn));
 
-       if (!prefault && can_do_async_pf(vcpu)) {
+       if (!prefault && kvm_can_do_async_pf(vcpu)) {
                trace_kvm_try_async_get_page(gva, gfn);
                if (kvm_find_async_pf_gfn(vcpu, gfn)) {
                        trace_kvm_async_pf_doublefault(gva, gfn);
index e374db9..943198e 100644 (file)
@@ -52,6 +52,7 @@ int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]);
 void kvm_mmu_set_mmio_spte_mask(u64 mmio_mask);
 int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct);
 int kvm_init_shadow_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context);
+bool kvm_can_do_async_pf(struct kvm_vcpu *vcpu);
 
 static inline unsigned int kvm_mmu_available_pages(struct kvm *kvm)
 {
index d0284b4..c8c3c39 100644 (file)
@@ -4380,16 +4380,20 @@ emul_write:
 
 static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
 {
-       /* TODO: String I/O for in kernel device */
-       int r;
+       int r = 0, i;
 
-       if (vcpu->arch.pio.in)
-               r = kvm_io_bus_read(vcpu->kvm, KVM_PIO_BUS, vcpu->arch.pio.port,
-                                   vcpu->arch.pio.size, pd);
-       else
-               r = kvm_io_bus_write(vcpu->kvm, KVM_PIO_BUS,
-                                    vcpu->arch.pio.port, vcpu->arch.pio.size,
-                                    pd);
+       for (i = 0; i < vcpu->arch.pio.count; i++) {
+               if (vcpu->arch.pio.in)
+                       r = kvm_io_bus_read(vcpu->kvm, KVM_PIO_BUS, vcpu->arch.pio.port,
+                                           vcpu->arch.pio.size, pd);
+               else
+                       r = kvm_io_bus_write(vcpu->kvm, KVM_PIO_BUS,
+                                            vcpu->arch.pio.port, vcpu->arch.pio.size,
+                                            pd);
+               if (r)
+                       break;
+               pd += vcpu->arch.pio.size;
+       }
        return r;
 }
 
@@ -4403,6 +4407,8 @@ static int emulator_pio_in_emulated(struct x86_emulate_ctxt *ctxt,
        if (vcpu->arch.pio.count)
                goto data_avail;
 
+       memset(vcpu->arch.pio_data, 0, size * count);
+
        trace_kvm_pio(0, port, size, count);
 
        vcpu->arch.pio.port = port;
@@ -4605,8 +4611,12 @@ static bool emulator_get_segment(struct x86_emulate_ctxt *ctxt, u16 *selector,
        kvm_get_segment(emul_to_vcpu(ctxt), &var, seg);
        *selector = var.selector;
 
-       if (var.unusable)
+       if (var.unusable) {
+               memset(desc, 0, sizeof(*desc));
+               if (base3)
+                       *base3 = 0;
                return false;
+       }
 
        if (var.g)
                var.limit >>= 12;
@@ -5440,18 +5450,20 @@ int emulator_fix_hypercall(struct x86_emulate_ctxt *ctxt)
 static int move_to_next_stateful_cpuid_entry(struct kvm_vcpu *vcpu, int i)
 {
        struct kvm_cpuid_entry2 *e = &vcpu->arch.cpuid_entries[i];
-       int j, nent = vcpu->arch.cpuid_nent;
+       struct kvm_cpuid_entry2 *ej;
+       int j = i;
+       int nent = vcpu->arch.cpuid_nent;
 
        e->flags &= ~KVM_CPUID_FLAG_STATE_READ_NEXT;
        /* when no next entry is found, the current entry[i] is reselected */
-       for (j = i + 1; ; j = (j + 1) % nent) {
-               struct kvm_cpuid_entry2 *ej = &vcpu->arch.cpuid_entries[j];
-               if (ej->function == e->function) {
-                       ej->flags |= KVM_CPUID_FLAG_STATE_READ_NEXT;
-                       return j;
-               }
-       }
-       return 0; /* silence gcc, even though control never reaches here */
+       do {
+               j = (j + 1) % nent;
+               ej = &vcpu->arch.cpuid_entries[j];
+       } while (ej->function != e->function);
+
+       ej->flags |= KVM_CPUID_FLAG_STATE_READ_NEXT;
+
+       return j;
 }
 
 /* find an entry with matching function, matching index (if needed), and that
@@ -6923,8 +6935,7 @@ bool kvm_arch_can_inject_async_page_present(struct kvm_vcpu *vcpu)
        if (!(vcpu->arch.apf.msr_val & KVM_ASYNC_PF_ENABLED))
                return true;
        else
-               return !kvm_event_needs_reinjection(vcpu) &&
-                       kvm_x86_ops->interrupt_allowed(vcpu);
+               return kvm_can_do_async_pf(vcpu);
 }
 
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit);
index 3adebe7..07757f3 100644 (file)
@@ -261,5 +261,6 @@ void __init initmem_init(void)
        printk(KERN_DEBUG "High memory starts at vaddr %08lx\n",
                        (ulong) pfn_to_kaddr(highstart_pfn));
 
+       __vmalloc_start_set = true;
        setup_bootmem_allocator();
 }
index 3b52bf0..b0d25e6 100644 (file)
@@ -120,7 +120,7 @@ int poke_user(struct task_struct *child, long addr, long data)
        else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
                (addr <= offsetof(struct user, u_debugreg[7]))) {
                addr -= offsetof(struct user, u_debugreg[0]);
-               addr = addr >> 2;
+               addr = addr >> 3;
                if ((addr == 4) || (addr == 5))
                        return -EIO;
                child->thread.arch.debugregs[addr] = data;
index dd3bf30..9f74085 100644 (file)
@@ -140,10 +140,8 @@ static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key,
 
        err = crypto_ablkcipher_encrypt(&data->req);
        if (err == -EINPROGRESS || err == -EBUSY) {
-               err = wait_for_completion_interruptible(
-                       &data->result.completion);
-               if (!err)
-                       err = data->result.err;
+               wait_for_completion(&data->result.completion);
+               err = data->result.err;
        }
 
        if (err)
index 1b31421..3c7bd30 100644 (file)
@@ -73,6 +73,7 @@ obj-$(CONFIG_USB_OTG_UTILS)   += usb/
 obj-$(CONFIG_USB)              += usb/
 obj-$(CONFIG_PCI)              += usb/
 obj-$(CONFIG_USB_GADGET)       += usb/
+obj-$(CONFIG_OF)               += usb/
 obj-$(CONFIG_SERIO)            += input/serio/
 obj-$(CONFIG_GAMEPORT)         += input/gameport/
 obj-$(CONFIG_INPUT)            += input/
index baeee83..93ace9b 100644 (file)
@@ -1268,6 +1268,40 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host)
 {}
 #endif
 
+/*
+ * On the Acer Aspire Switch Alpha 12, sometimes all SATA ports are detected
+ * as DUMMY, or detected but eventually get a "link down" and never get up
+ * again. When this happens, CAP.NP may hold a value of 0x00 or 0x01, and the
+ * port_map may hold a value of 0x00.
+ *
+ * Overriding CAP.NP to 0x02 and the port_map to 0x7 will reveal all 3 ports
+ * and can significantly reduce the occurrence of the problem.
+ *
+ * https://bugzilla.kernel.org/show_bug.cgi?id=189471
+ */
+static void acer_sa5_271_workaround(struct ahci_host_priv *hpriv,
+                                   struct pci_dev *pdev)
+{
+       static const struct dmi_system_id sysids[] = {
+               {
+                       .ident = "Acer Switch Alpha 12",
+                       .matches = {
+                               DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                               DMI_MATCH(DMI_PRODUCT_NAME, "Switch SA5-271")
+                       },
+               },
+               { }
+       };
+
+       if (dmi_check_system(sysids)) {
+               dev_info(&pdev->dev, "enabling Acer Switch Alpha 12 workaround\n");
+               if ((hpriv->saved_cap & 0xC734FF00) == 0xC734FF00) {
+                       hpriv->port_map = 0x7;
+                       hpriv->cap = 0xC734FF02;
+               }
+       }
+}
+
 static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        unsigned int board_id = ent->driver_data;
@@ -1407,6 +1441,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                         "online status unreliable, applying workaround\n");
        }
 
+
+       /* Acer SA5-271 workaround modifies private_data */
+       acer_sa5_271_workaround(hpriv, pdev);
+
        /* CAP.NP sometimes indicate the index of the last enabled
         * port, at other times, that of the last possible port, so
         * determining the maximum port number requires looking at
index eeadf8f..01a019e 100644 (file)
@@ -3056,6 +3056,14 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
        if (unlikely(!dev->dma_mode))
                goto invalid_fld;
 
+       /*
+        * We only allow sending this command through the block layer,
+        * as it modifies the DATA OUT buffer, which would corrupt user
+        * memory for SG_IO commands.
+        */
+       if (unlikely(scmd->request->cmd_type != REQ_TYPE_FS))
+               goto invalid_fld;
+
        if (unlikely(scmd->cmd_len < 16))
                goto invalid_fld;
        scsi_16_lba_len(cdb, &block, &n_block);
index b1ac8d4..d783656 100644 (file)
@@ -322,6 +322,11 @@ static const struct vm_operations_struct mmap_mem_ops = {
 static int mmap_mem(struct file *file, struct vm_area_struct *vma)
 {
        size_t size = vma->vm_end - vma->vm_start;
+       phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
+
+       /* It's illegal to wrap around the end of the physical address space. */
+       if (offset + (phys_addr_t)size - 1 < offset)
+               return -EINVAL;
 
        if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
                return -EINVAL;
index b47e2b8..e1612b6 100644 (file)
@@ -300,6 +300,8 @@ static int m2p_hw_setup(struct ep93xx_dma_chan *edmac)
                | M2P_CONTROL_ENABLE;
        m2p_set_control(edmac, control);
 
+       edmac->buffer = 0;
+
        return 0;
 }
 
index 27999d9..c7b5428 100644 (file)
@@ -6995,9 +6995,9 @@ static void do_intel_finish_page_flip(struct drm_device *dev,
                          &obj->pending_flip.counter);
 
        wake_up(&dev_priv->pending_flip_queue);
-       schedule_work(&work->work);
-
        trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj);
+
+       schedule_work(&work->work);
 }
 
 void intel_finish_page_flip(struct drm_device *dev, int pipe)
index 87a677e..9ac606f 100644 (file)
@@ -3406,6 +3406,13 @@ void radeon_combios_asic_init(struct drm_device *dev)
            rdev->pdev->subsystem_vendor == 0x103c &&
            rdev->pdev->subsystem_device == 0x280a)
                return;
+       /* quirk for rs4xx Toshiba Sattellite L20-183 latop to make it resume
+        * - it hangs on resume inside the dynclk 1 table.
+        */
+       if (rdev->family == CHIP_RS400 &&
+           rdev->pdev->subsystem_vendor == 0x1179 &&
+           rdev->pdev->subsystem_device == 0xff31)
+               return;
 
        /* DYN CLK 1 */
        table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE);
index decca82..ea93583 100644 (file)
@@ -368,6 +368,8 @@ void *vmw_fifo_reserve(struct vmw_private *dev_priv, uint32_t bytes)
                                return fifo_state->static_buffer;
                        else {
                                fifo_state->dynamic_buffer = vmalloc(bytes);
+                               if (!fifo_state->dynamic_buffer)
+                                       goto out_err;
                                return fifo_state->dynamic_buffer;
                        }
                }
index d03b040..8c669d7 100644 (file)
@@ -159,22 +159,39 @@ static int usb_read(struct i2c_adapter *adapter, int cmd,
                    int value, int index, void *data, int len)
 {
        struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data;
+       void *dmadata = kmalloc(len, GFP_KERNEL);
+       int ret;
+
+       if (!dmadata)
+               return -ENOMEM;
 
        /* do control transfer */
-       return usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0),
+       ret = usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0),
                               cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE |
-                              USB_DIR_IN, value, index, data, len, 2000);
+                              USB_DIR_IN, value, index, dmadata, len, 2000);
+
+       memcpy(data, dmadata, len);
+       kfree(dmadata);
+       return ret;
 }
 
 static int usb_write(struct i2c_adapter *adapter, int cmd,
                     int value, int index, void *data, int len)
 {
        struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data;
+       void *dmadata = kmemdup(data, len, GFP_KERNEL);
+       int ret;
+
+       if (!dmadata)
+               return -ENOMEM;
 
        /* do control transfer */
-       return usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0),
+       ret = usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0),
                               cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
-                              value, index, data, len, 2000);
+                              value, index, dmadata, len, 2000);
+
+       kfree(dmadata);
+       return ret;
 }
 
 static void i2c_tiny_usb_free(struct i2c_tiny_usb *dev)
index 3be21aa..7f2254e 100644 (file)
@@ -2440,6 +2440,7 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
        struct ib_qp                 *qp;
        struct ib_uverbs_mcast_entry *mcast;
        int                           ret = -EINVAL;
+       bool                          found = false;
 
        if (copy_from_user(&cmd, buf, sizeof cmd))
                return -EFAULT;
@@ -2448,10 +2449,6 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
        if (!qp)
                return -EINVAL;
 
-       ret = ib_detach_mcast(qp, (union ib_gid *) cmd.gid, cmd.mlid);
-       if (ret)
-               goto out_put;
-
        obj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject);
 
        list_for_each_entry(mcast, &obj->mcast_list, list)
@@ -2459,9 +2456,17 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
                    !memcmp(cmd.gid, mcast->gid.raw, sizeof mcast->gid.raw)) {
                        list_del(&mcast->list);
                        kfree(mcast);
+                       found = true;
                        break;
                }
 
+       if (!found) {
+               ret = -EINVAL;
+               goto out_put;
+       }
+
+       ret = ib_detach_mcast(qp, (union ib_gid *)cmd.gid, cmd.mlid);
+
 out_put:
        put_qp_write(qp);
 
index 575b780..45a6744 100644 (file)
@@ -1185,7 +1185,9 @@ int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
 {
        if (!qp->device->attach_mcast)
                return -ENOSYS;
-       if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
+       if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD ||
+           lid < 0xC000 ||
+           lid == be16_to_cpu(IB_LID_PERMISSIVE))
                return -EINVAL;
 
        return qp->device->attach_mcast(qp, gid, lid);
@@ -1196,7 +1198,9 @@ int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
 {
        if (!qp->device->detach_mcast)
                return -ENOSYS;
-       if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
+       if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD ||
+           lid < 0xC000 ||
+           lid == be16_to_cpu(IB_LID_PERMISSIVE))
                return -EINVAL;
 
        return qp->device->detach_mcast(qp, gid, lid);
index 8941d8d..961e56b 100644 (file)
@@ -673,6 +673,13 @@ static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U574"),
                },
        },
+       {
+               /* Fujitsu UH554 laptop */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK UH544"),
+               },
+       },
        { }
 };
 
index f718411..67b2bd9 100644 (file)
@@ -30,6 +30,10 @@ static int digitv_ctrl_msg(struct dvb_usb_device *d,
 {
        int wo = (rbuf == NULL || rlen == 0); /* write-only */
        u8 sndbuf[7],rcvbuf[7];
+
+       if (wlen > 4 || rlen > 4)
+               return -EIO;
+
        memset(sndbuf,0,7); memset(rcvbuf,0,7);
 
        sndbuf[0] = cmd;
index f103ec1..e0b3d37 100644 (file)
@@ -28,6 +28,9 @@
 #include "stb6100.h"
 #include "stb6100_proc.h"
 
+/* Max transfer size done by I2C transfer functions */
+#define MAX_XFER_SIZE  64
+
 #ifndef USB_PID_DW2102
 #define USB_PID_DW2102 0x2102
 #endif
@@ -231,6 +234,20 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
 
        switch (num) {
        case 2:
+               if (msg[0].len != 1) {
+                       warn("i2c rd: len=%d is not 1!\n",
+                            msg[0].len);
+                       num = -EOPNOTSUPP;
+                       break;
+               }
+
+               if (2 + msg[1].len > sizeof(buf6)) {
+                       warn("i2c rd: len=%d is too big!\n",
+                            msg[1].len);
+                       num = -EOPNOTSUPP;
+                       break;
+               }
+
                /* read si2109 register by number */
                buf6[0] = msg[0].addr << 1;
                buf6[1] = msg[0].len;
@@ -246,6 +263,13 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
        case 1:
                switch (msg[0].addr) {
                case 0x68:
+                       if (2 + msg[0].len > sizeof(buf6)) {
+                               warn("i2c wr: len=%d is too big!\n",
+                                    msg[0].len);
+                               num = -EOPNOTSUPP;
+                               break;
+                       }
+
                        /* write to si2109 register */
                        buf6[0] = msg[0].addr << 1;
                        buf6[1] = msg[0].len;
@@ -287,7 +311,22 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
        case 2: {
                /* read */
                /* first write first register number */
-               u8 ibuf[msg[1].len + 2], obuf[3];
+               u8 ibuf[MAX_XFER_SIZE], obuf[3];
+
+               if (2 + msg[0].len != sizeof(obuf)) {
+                       warn("i2c rd: len=%d is not 1!\n",
+                            msg[0].len);
+                       ret = -EOPNOTSUPP;
+                       goto unlock;
+               }
+
+               if (2 + msg[1].len > sizeof(ibuf)) {
+                       warn("i2c rd: len=%d is too big!\n",
+                            msg[1].len);
+                       ret = -EOPNOTSUPP;
+                       goto unlock;
+               }
+
                obuf[0] = msg[0].addr << 1;
                obuf[1] = msg[0].len;
                obuf[2] = msg[0].buf[0];
@@ -304,7 +343,15 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
                switch (msg[0].addr) {
                case 0x68: {
                        /* write to register */
-                       u8 obuf[msg[0].len + 2];
+                       u8 obuf[MAX_XFER_SIZE];
+
+                       if (2 + msg[0].len > sizeof(obuf)) {
+                               warn("i2c wr: len=%d is too big!\n",
+                                    msg[1].len);
+                               ret = -EOPNOTSUPP;
+                               goto unlock;
+                       }
+
                        obuf[0] = msg[0].addr << 1;
                        obuf[1] = msg[0].len;
                        memcpy(obuf + 2, msg[0].buf, msg[0].len);
@@ -314,7 +361,15 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
                }
                case 0x61: {
                        /* write to tuner */
-                       u8 obuf[msg[0].len + 2];
+                       u8 obuf[MAX_XFER_SIZE];
+
+                       if (2 + msg[0].len > sizeof(obuf)) {
+                               warn("i2c wr: len=%d is too big!\n",
+                                    msg[1].len);
+                               ret = -EOPNOTSUPP;
+                               goto unlock;
+                       }
+
                        obuf[0] = msg[0].addr << 1;
                        obuf[1] = msg[0].len;
                        memcpy(obuf + 2, msg[0].buf, msg[0].len);
@@ -341,9 +396,11 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
 
                break;
        }
+       ret = num;
 
+unlock:
        mutex_unlock(&d->i2c_mutex);
-       return num;
+       return ret;
 }
 
 static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
@@ -381,7 +438,15 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
                default: {
                        if (msg[j].flags == I2C_M_RD) {
                                /* read registers */
-                               u8  ibuf[msg[j].len + 2];
+                               u8  ibuf[MAX_XFER_SIZE];
+
+                               if (2 + msg[j].len > sizeof(ibuf)) {
+                                       warn("i2c rd: len=%d is too big!\n",
+                                            msg[j].len);
+                                       ret = -EOPNOTSUPP;
+                                       goto unlock;
+                               }
+
                                ret = dw210x_op_rw(d->udev, 0xc3,
                                                (msg[j].addr << 1) + 1, 0,
                                                ibuf, msg[j].len + 2,
@@ -410,7 +475,15 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
                                } while (len > 0);
                        } else {
                                /* write registers */
-                               u8 obuf[msg[j].len + 2];
+                               u8 obuf[MAX_XFER_SIZE];
+
+                               if (2 + msg[j].len > sizeof(obuf)) {
+                                       warn("i2c wr: len=%d is too big!\n",
+                                            msg[j].len);
+                                       ret = -EOPNOTSUPP;
+                                       goto unlock;
+                               }
+
                                obuf[0] = msg[j].addr << 1;
                                obuf[1] = msg[j].len;
                                memcpy(obuf + 2, msg[j].buf, msg[j].len);
@@ -423,9 +496,11 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
                }
 
        }
+       ret = num;
 
+unlock:
        mutex_unlock(&d->i2c_mutex);
-       return num;
+       return ret;
 }
 
 static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
@@ -443,7 +518,20 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
        case 2: {
                /* read */
                /* first write first register number */
-               u8 ibuf[msg[1].len + 2], obuf[3];
+               u8 ibuf[MAX_XFER_SIZE], obuf[3];
+
+               if (2 + msg[0].len != sizeof(obuf)) {
+                       warn("i2c rd: len=%d is not 1!\n",
+                            msg[0].len);
+                       ret = -EOPNOTSUPP;
+                       goto unlock;
+               }
+               if (2 + msg[1].len > sizeof(ibuf)) {
+                       warn("i2c rd: len=%d is too big!\n",
+                            msg[1].len);
+                       ret = -EOPNOTSUPP;
+                       goto unlock;
+               }
                obuf[0] = msg[0].addr << 1;
                obuf[1] = msg[0].len;
                obuf[2] = msg[0].buf[0];
@@ -461,7 +549,14 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                case 0x60:
                case 0x0c: {
                        /* write to register */
-                       u8 obuf[msg[0].len + 2];
+                       u8 obuf[MAX_XFER_SIZE];
+
+                       if (2 + msg[0].len > sizeof(obuf)) {
+                               warn("i2c wr: len=%d is too big!\n",
+                                    msg[0].len);
+                               ret = -EOPNOTSUPP;
+                               goto unlock;
+                       }
                        obuf[0] = msg[0].addr << 1;
                        obuf[1] = msg[0].len;
                        memcpy(obuf + 2, msg[0].buf, msg[0].len);
@@ -486,9 +581,11 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                                msg[i].flags == 0 ? ">>>" : "<<<");
                debug_dump(msg[i].buf, msg[i].len, deb_xfer);
        }
+       ret = num;
 
+unlock:
        mutex_unlock(&d->i2c_mutex);
-       return num;
+       return ret;
 }
 
 static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
@@ -544,7 +641,15 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                default: {
                        if (msg[j].flags == I2C_M_RD) {
                                /* read registers */
-                               u8 ibuf[msg[j].len];
+                               u8 ibuf[MAX_XFER_SIZE];
+
+                               if (msg[j].len > sizeof(ibuf)) {
+                                       warn("i2c rd: len=%d is too big!\n",
+                                            msg[j].len);
+                                       ret = -EOPNOTSUPP;
+                                       goto unlock;
+                               }
+
                                ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
                                                ibuf, msg[j].len,
                                                DW210X_READ_MSG);
@@ -571,7 +676,15 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                                } while (len > 0);
                        } else if (j < (num - 1)) {
                                /* write register addr before read */
-                               u8 obuf[msg[j].len + 2];
+                               u8 obuf[MAX_XFER_SIZE];
+
+                               if (2 + msg[j].len > sizeof(obuf)) {
+                                       warn("i2c wr: len=%d is too big!\n",
+                                            msg[j].len);
+                                       ret = -EOPNOTSUPP;
+                                       goto unlock;
+                               }
+
                                obuf[0] = msg[j + 1].len;
                                obuf[1] = (msg[j].addr << 1);
                                memcpy(obuf + 2, msg[j].buf, msg[j].len);
@@ -583,7 +696,14 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                                break;
                        } else {
                                /* write registers */
-                               u8 obuf[msg[j].len + 2];
+                               u8 obuf[MAX_XFER_SIZE];
+
+                               if (2 + msg[j].len > sizeof(obuf)) {
+                                       warn("i2c wr: len=%d is too big!\n",
+                                            msg[j].len);
+                                       ret = -EOPNOTSUPP;
+                                       goto unlock;
+                               }
                                obuf[0] = msg[j].len + 1;
                                obuf[1] = (msg[j].addr << 1);
                                memcpy(obuf + 2, msg[j].buf, msg[j].len);
@@ -596,9 +716,11 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                }
                }
        }
+       ret = num;
 
+unlock:
        mutex_unlock(&d->i2c_mutex);
-       return num;
+       return ret;
 }
 
 static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
@@ -630,6 +752,13 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                        msg[0].buf[0] = ibuf[1];
                        break;
                default:
+                       if (3 + msg[0].len > sizeof(obuf)) {
+                               warn("i2c wr: len=%d is too big!\n",
+                                    msg[0].len);
+                               num = -EOPNOTSUPP;
+                               break;
+                       }
+
                        /* always i2c write*/
                        obuf[0] = 0x08;
                        obuf[1] = msg[0].addr;
@@ -645,6 +774,19 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                break;
        case 2:
                /* always i2c read */
+               if (4 + msg[0].len > sizeof(obuf)) {
+                       warn("i2c rd: len=%d is too big!\n",
+                            msg[0].len);
+                       num = -EOPNOTSUPP;
+                       break;
+               }
+               if (1 + msg[1].len > sizeof(obuf)) {
+                       warn("i2c rd: len=%d is too big!\n",
+                            msg[1].len);
+                       num = -EOPNOTSUPP;
+                       break;
+               }
+
                obuf[0] = 0x09;
                obuf[1] = msg[0].len;
                obuf[2] = msg[1].len;
index ea4eab8..9e56e7f 100644 (file)
@@ -75,10 +75,21 @@ static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd,
                u8 *wbuf, int wlen, u8 *rbuf, int rlen)
 {
        struct ttusb2_state *st = d->priv;
-       u8 s[wlen+4],r[64] = { 0 };
+       u8 *s, *r = NULL;
        int ret = 0;
 
-       memset(s,0,wlen+4);
+       if (4 + rlen > 64)
+               return -EIO;
+
+       s = kzalloc(wlen+4, GFP_KERNEL);
+       if (!s)
+               return -ENOMEM;
+
+       r = kzalloc(64, GFP_KERNEL);
+       if (!r) {
+               kfree(s);
+               return -ENOMEM;
+       }
 
        s[0] = 0xaa;
        s[1] = ++st->id;
@@ -94,12 +105,17 @@ static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd,
                r[2] != cmd ||
                (rlen > 0 && r[3] != rlen)) {
                warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]);
+               kfree(s);
+               kfree(r);
                return -EIO;
        }
 
        if (rlen > 0)
                memcpy(rbuf, &r[4], rlen);
 
+       kfree(s);
+       kfree(r);
+
        return 0;
 }
 
@@ -368,6 +384,22 @@ static int ttusb2_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
                write_read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
                read = msg[i].flags & I2C_M_RD;
 
+               if (3 + msg[i].len > sizeof(obuf)) {
+                       err("i2c wr len=%d too high", msg[i].len);
+                       break;
+               }
+               if (write_read) {
+                       if (3 + msg[i+1].len > sizeof(ibuf)) {
+                               err("i2c rd len=%d too high", msg[i+1].len);
+                               break;
+                       }
+               } else if (read) {
+                       if (3 + msg[i].len > sizeof(ibuf)) {
+                               err("i2c rd len=%d too high", msg[i].len);
+                               break;
+                       }
+               }
+
                obuf[0] = (msg[i].addr << 1) | (write_read | read);
                if (read)
                        obuf[1] = 0;
index 2e5cd31..3a5a5b6 100644 (file)
@@ -225,7 +225,7 @@ void ir_raw_event_handle(struct rc_dev *dev)
 {
        unsigned long flags;
 
-       if (!dev->raw)
+       if (!dev->raw || !dev->raw->thread)
                return;
 
        spin_lock_irqsave(&dev->raw->lock, flags);
@@ -252,6 +252,7 @@ int ir_raw_event_register(struct rc_dev *dev)
 {
        int rc;
        struct ir_raw_handler *handler;
+       struct task_struct *thread;
 
        if (!dev)
                return -EINVAL;
@@ -269,14 +270,16 @@ int ir_raw_event_register(struct rc_dev *dev)
                goto out;
 
        spin_lock_init(&dev->raw->lock);
-       dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw,
-                                      "rc%ld", dev->devno);
+       thread = kthread_run(ir_raw_event_thread, dev->raw, "rc%ld",
+                            dev->devno);
 
-       if (IS_ERR(dev->raw->thread)) {
-               rc = PTR_ERR(dev->raw->thread);
+       if (IS_ERR(thread)) {
+               rc = PTR_ERR(thread);
                goto out;
        }
 
+       dev->raw->thread = thread;
+
        mutex_lock(&ir_raw_handler_lock);
        list_add_tail(&dev->raw->list, &ir_raw_client_list);
        list_for_each_entry(handler, &ir_raw_handler_list, list)
index 60d3c1e..2fb6473 100644 (file)
@@ -1301,8 +1301,8 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
                                "found\n");
                }
        }
-       if (ep_in == NULL) {
-               mce_dbg(&intf->dev, "inbound and/or endpoint not found\n");
+       if (!ep_in || !ep_out) {
+               mce_dbg(&intf->dev, "required endpoints not found\n");
                return -ENODEV;
        }
 
index 30d13c1..2625ebc 100644 (file)
@@ -652,10 +652,8 @@ static int cx231xx_audio_init(struct cx231xx *dev)
 
        spin_lock_init(&adev->slock);
        err = snd_pcm_new(card, "Cx231xx Audio", 0, 0, 1, &pcm);
-       if (err < 0) {
-               snd_card_free(card);
-               return err;
-       }
+       if (err < 0)
+               goto err_free_card;
 
        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
                        &snd_cx231xx_pcm_capture);
@@ -670,10 +668,9 @@ static int cx231xx_audio_init(struct cx231xx *dev)
        INIT_WORK(&dev->wq_trigger, audio_trigger);
 
        err = snd_card_register(card);
-       if (err < 0) {
-               snd_card_free(card);
-               return err;
-       }
+       if (err < 0)
+               goto err_free_card;
+
        adev->sndcard = card;
        adev->udev = dev->udev;
 
@@ -683,6 +680,11 @@ static int cx231xx_audio_init(struct cx231xx *dev)
                                            hs_config_info[0].interface_info.
                                            audio_index + 1];
 
+       if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) {
+               err = -ENODEV;
+               goto err_free_card;
+       }
+
        adev->end_point_addr =
            le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
                        bEndpointAddress);
@@ -691,15 +693,21 @@ static int cx231xx_audio_init(struct cx231xx *dev)
        cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
                     adev->end_point_addr, adev->num_alt);
        adev->alt_max_pkt_size = kmalloc(32 * adev->num_alt, GFP_KERNEL);
-
-       if (adev->alt_max_pkt_size == NULL) {
+       if (!adev->alt_max_pkt_size) {
                cx231xx_errdev("out of memory!\n");
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto err_free_card;
        }
 
        for (i = 0; i < adev->num_alt; i++) {
-               u16 tmp =
-                   le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.
+               u16 tmp;
+
+               if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) {
+                       err = -ENODEV;
+                       goto err_free_pkt_size;
+               }
+
+               tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.
                                wMaxPacketSize);
                adev->alt_max_pkt_size[i] =
                    (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
@@ -708,6 +716,13 @@ static int cx231xx_audio_init(struct cx231xx *dev)
        }
 
        return 0;
+
+err_free_pkt_size:
+       kfree(adev->alt_max_pkt_size);
+err_free_card:
+       snd_card_free(card);
+
+       return err;
 }
 
 static int cx231xx_audio_fini(struct cx231xx *dev)
index 77d1064..21f23b6 100644 (file)
@@ -863,7 +863,6 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
 {
        struct cx231xx *dev = *devhandle;
        int retval = -ENOMEM;
-       int errCode;
        unsigned int maxh, maxw;
 
        dev->udev = udev;
@@ -899,8 +898,8 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
        /* Cx231xx pre card setup */
        cx231xx_pre_card_setup(dev);
 
-       errCode = cx231xx_config(dev);
-       if (errCode) {
+       retval = cx231xx_config(dev);
+       if (retval) {
                cx231xx_errdev("error configuring device\n");
                return -ENOMEM;
        }
@@ -909,12 +908,11 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
        dev->norm = dev->board.norm;
 
        /* register i2c bus */
-       errCode = cx231xx_dev_init(dev);
-       if (errCode < 0) {
-               cx231xx_dev_uninit(dev);
+       retval = cx231xx_dev_init(dev);
+       if (retval) {
                cx231xx_errdev("%s: cx231xx_i2c_register - errCode [%d]!\n",
-                              __func__, errCode);
-               return errCode;
+                              __func__, retval);
+               goto err_dev_init;
        }
 
        /* Do board specific init */
@@ -932,11 +930,11 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
        dev->interlaced = 0;
        dev->video_input = 0;
 
-       errCode = cx231xx_config(dev);
-       if (errCode < 0) {
+       retval = cx231xx_config(dev);
+       if (retval) {
                cx231xx_errdev("%s: cx231xx_config - errCode [%d]!\n",
-                              __func__, errCode);
-               return errCode;
+                              __func__, retval);
+               goto err_dev_init;
        }
 
        /* init video dma queues */
@@ -960,9 +958,9 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
        }
 
        retval = cx231xx_register_analog_devices(dev);
-       if (retval < 0) {
-               cx231xx_release_resources(dev);
-               return retval;
+       if (retval) {
+               cx231xx_release_analog_resources(dev);
+               goto err_analog;
        }
 
        cx231xx_ir_init(dev);
@@ -970,6 +968,11 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
        cx231xx_init_extension(dev);
 
        return 0;
+err_analog:
+       cx231xx_remove_from_devlist(dev);
+err_dev_init:
+       cx231xx_dev_uninit(dev);
+       return retval;
 }
 
 #if defined(CONFIG_MODULES) && defined(MODULE)
@@ -1019,7 +1022,6 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
        struct usb_interface *lif = NULL;
        struct usb_interface_assoc_descriptor *assoc_desc;
 
-       udev = usb_get_dev(interface_to_usbdev(interface));
        ifnum = interface->altsetting[0].desc.bInterfaceNumber;
 
        /*
@@ -1048,6 +1050,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
                return -ENOMEM;
        }
 
+       udev = usb_get_dev(interface_to_usbdev(interface));
+
        snprintf(dev->name, 29, "cx231xx #%d", nr);
        dev->devno = nr;
        dev->model = id->driver_info;
@@ -1126,10 +1130,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
        if (assoc_desc->bFirstInterface != ifnum) {
                cx231xx_err(DRIVER_NAME ": Not found "
                            "matching IAD interface\n");
-               cx231xx_devused &= ~(1 << nr);
-               kfree(dev);
-               dev = NULL;
-               return -ENODEV;
+               retval = -ENODEV;
+               goto err_if;
        }
 
        cx231xx_info("registering interface %d\n", ifnum);
@@ -1145,27 +1147,21 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
        retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
        if (retval) {
                cx231xx_errdev("v4l2_device_register failed\n");
-               cx231xx_devused &= ~(1 << nr);
-               kfree(dev);
-               dev = NULL;
-               return -EIO;
+               retval = -EIO;
+               goto err_v4l2;
        }
        /* allocate device struct */
        retval = cx231xx_init_dev(&dev, udev, nr);
-       if (retval) {
-               cx231xx_devused &= ~(1 << dev->devno);
-               v4l2_device_unregister(&dev->v4l2_dev);
-               kfree(dev);
-               dev = NULL;
-               usb_set_intfdata(lif, NULL);
-
-               return retval;
-       }
+       if (retval)
+               goto err_init;
 
        /* compute alternate max packet sizes for video */
        uif = udev->actconfig->interface[dev->current_pcb_config.
                       hs_config_info[0].interface_info.video_index + 1];
 
+       if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1)
+               return -ENODEV;
+
        dev->video_mode.end_point_addr = le16_to_cpu(uif->altsetting[0].
                        endpoint[isoc_pipe].desc.bEndpointAddress);
 
@@ -1178,16 +1174,17 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
 
        if (dev->video_mode.alt_max_pkt_size == NULL) {
                cx231xx_errdev("out of memory!\n");
-               cx231xx_devused &= ~(1 << nr);
-               v4l2_device_unregister(&dev->v4l2_dev);
-               kfree(dev);
-               dev = NULL;
-               return -ENOMEM;
+               retval = -ENOMEM;
+               goto err_video_alt;
        }
 
        for (i = 0; i < dev->video_mode.num_alt; i++) {
-               u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
-                               desc.wMaxPacketSize);
+               u16 tmp;
+
+               if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1)
+                       return -ENODEV;
+
+               tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize);
                dev->video_mode.alt_max_pkt_size[i] =
                    (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
                cx231xx_info("Alternate setting %i, max size= %i\n", i,
@@ -1199,6 +1196,9 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
                                       hs_config_info[0].interface_info.
                                       vanc_index + 1];
 
+       if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1)
+               return -ENODEV;
+
        dev->vbi_mode.end_point_addr =
            le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
                        bEndpointAddress);
@@ -1212,16 +1212,17 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
 
        if (dev->vbi_mode.alt_max_pkt_size == NULL) {
                cx231xx_errdev("out of memory!\n");
-               cx231xx_devused &= ~(1 << nr);
-               v4l2_device_unregister(&dev->v4l2_dev);
-               kfree(dev);
-               dev = NULL;
-               return -ENOMEM;
+               retval = -ENOMEM;
+               goto err_vbi_alt;
        }
 
        for (i = 0; i < dev->vbi_mode.num_alt; i++) {
-               u16 tmp =
-                   le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
+               u16 tmp;
+
+               if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1)
+                       return -ENODEV;
+
+               tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
                                desc.wMaxPacketSize);
                dev->vbi_mode.alt_max_pkt_size[i] =
                    (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
@@ -1234,6 +1235,9 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
                                       hs_config_info[0].interface_info.
                                       hanc_index + 1];
 
+       if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1)
+               return -ENODEV;
+
        dev->sliced_cc_mode.end_point_addr =
            le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
                        bEndpointAddress);
@@ -1247,15 +1251,17 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
 
        if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) {
                cx231xx_errdev("out of memory!\n");
-               cx231xx_devused &= ~(1 << nr);
-               v4l2_device_unregister(&dev->v4l2_dev);
-               kfree(dev);
-               dev = NULL;
-               return -ENOMEM;
+               retval = -ENOMEM;
+               goto err_sliced_cc_alt;
        }
 
        for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) {
-               u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
+               u16 tmp;
+
+               if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1)
+                       return -ENODEV;
+
+               tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
                                desc.wMaxPacketSize);
                dev->sliced_cc_mode.alt_max_pkt_size[i] =
                    (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
@@ -1270,6 +1276,11 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
                                               interface_info.
                                               ts1_index + 1];
 
+               if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) {
+                       retval = -ENODEV;
+                       goto err_video_alt;
+               }
+
                dev->ts1_mode.end_point_addr =
                    le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].
                                desc.bEndpointAddress);
@@ -1283,15 +1294,19 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
 
                if (dev->ts1_mode.alt_max_pkt_size == NULL) {
                        cx231xx_errdev("out of memory!\n");
-                       cx231xx_devused &= ~(1 << nr);
-                       v4l2_device_unregister(&dev->v4l2_dev);
-                       kfree(dev);
-                       dev = NULL;
-                       return -ENOMEM;
+                       retval = -ENOMEM;
+                       goto err_ts1_alt;
                }
 
                for (i = 0; i < dev->ts1_mode.num_alt; i++) {
-                       u16 tmp = le16_to_cpu(uif->altsetting[i].
+                       u16 tmp;
+
+                       if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) {
+                               retval = -ENODEV;
+                               goto err_video_alt;
+                       }
+
+                       tmp = le16_to_cpu(uif->altsetting[i].
                                                endpoint[isoc_pipe].desc.
                                                wMaxPacketSize);
                        dev->ts1_mode.alt_max_pkt_size[i] =
@@ -1314,6 +1329,29 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
        request_modules(dev);
 
        return 0;
+err_ts1_alt:
+       kfree(dev->sliced_cc_mode.alt_max_pkt_size);
+err_sliced_cc_alt:
+       kfree(dev->vbi_mode.alt_max_pkt_size);
+err_vbi_alt:
+       kfree(dev->video_mode.alt_max_pkt_size);
+err_video_alt:
+       /* cx231xx_uninit_dev: */
+       cx231xx_close_extension(dev);
+       cx231xx_ir_exit(dev);
+       cx231xx_release_analog_resources(dev);
+       cx231xx_417_unregister(dev);
+       cx231xx_remove_from_devlist(dev);
+       cx231xx_dev_uninit(dev);
+err_init:
+       v4l2_device_unregister(&dev->v4l2_dev);
+err_v4l2:
+       usb_set_intfdata(lif, NULL);
+err_if:
+       usb_put_dev(udev);
+       kfree(dev);
+       cx231xx_devused &= ~(1 << nr);
+       return retval;
 }
 
 /*
index f3f7fe0..9e0f5e2 100644 (file)
@@ -290,6 +290,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
                return -EIO;
        }
 
+       if (alt->desc.bNumEndpoints < 2)
+               return -ENODEV;
+
        packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
 
        reg_w(gspca_dev, sd->brightness, BRIGHTNESS_REG);
index b5247cb..ca721b7 100644 (file)
@@ -687,8 +687,10 @@ static int ov2640_s_ctrl(struct v4l2_ctrl *ctrl)
 
        switch (ctrl->id) {
        case V4L2_CID_VFLIP:
-               val = ctrl->val ? REG04_VFLIP_IMG : 0x00;
-               return ov2640_mask_set(client, REG04, REG04_VFLIP_IMG, val);
+               val = ctrl->val ? REG04_VFLIP_IMG | REG04_VREF_EN : 0x00;
+               return ov2640_mask_set(client, REG04,
+                                      REG04_VFLIP_IMG | REG04_VREF_EN, val);
+               /* NOTE: REG04_VREF_EN: 1 line shift / even/odd line swap */
        case V4L2_CID_HFLIP:
                val = ctrl->val ? REG04_HFLIP_IMG : 0x00;
                return ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val);
index 9515f3a..122815e 100644 (file)
@@ -123,15 +123,10 @@ int pvr2_eeprom_analyze(struct pvr2_hdw *hdw)
        memset(&tvdata,0,sizeof(tvdata));
 
        eeprom = pvr2_eeprom_fetch(hdw);
-       if (!eeprom) return -EINVAL;
-
-       {
-               struct i2c_client fake_client;
-               /* Newer version expects a useless client interface */
-               fake_client.addr = hdw->eeprom_addr;
-               fake_client.adapter = &hdw->i2c_adap;
-               tveeprom_hauppauge_analog(&fake_client,&tvdata,eeprom);
-       }
+       if (!eeprom)
+               return -EINVAL;
+
+       tveeprom_hauppauge_analog(NULL, &tvdata, eeprom);
 
        trace_eeprom("eeprom assumed v4l tveeprom module");
        trace_eeprom("eeprom direct call results:");
index 8f74081..b522f83 100644 (file)
@@ -1564,7 +1564,14 @@ static int __devinit usbvision_probe(struct usb_interface *intf,
        }
 
        for (i = 0; i < usbvision->num_alt; i++) {
-               u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc.
+               u16 tmp;
+
+               if (uif->altsetting[i].desc.bNumEndpoints < 2) {
+                       ret = -ENODEV;
+                       goto err_pkt;
+               }
+
+               tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc.
                                      wMaxPacketSize);
                usbvision->alt_max_pkt_size[i] =
                        (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
index 95a3f5e..92dfe23 100644 (file)
@@ -731,7 +731,7 @@ void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no)
 {
        struct vb2_queue *q = vb->vb2_queue;
 
-       if (plane_no > vb->num_planes)
+       if (plane_no >= vb->num_planes)
                return NULL;
 
        return call_memop(q, plane_no, vaddr, vb->planes[plane_no].mem_priv);
@@ -754,7 +754,7 @@ void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no)
 {
        struct vb2_queue *q = vb->vb2_queue;
 
-       if (plane_no > vb->num_planes)
+       if (plane_no >= vb->num_planes)
                return NULL;
 
        return call_memop(q, plane_no, cookie, vb->planes[plane_no].mem_priv);
index e78cf94..ed3f740 100644 (file)
@@ -611,6 +611,14 @@ static int zr364xx_read_video_callback(struct zr364xx_camera *cam,
        ptr = pdest = frm->lpvbits;
 
        if (frm->ulState == ZR364XX_READ_IDLE) {
+               if (purb->actual_length < 128) {
+                       /* header incomplete */
+                       dev_info(&cam->udev->dev,
+                                "%s: buffer (%d bytes) too small to hold jpeg header. Discarding.\n",
+                                __func__, purb->actual_length);
+                       return -EINVAL;
+               }
+
                frm->ulState = ZR364XX_READ_FRAME;
                frm->cur_size = 0;
 
index e9f8432..fdffd12 100644 (file)
@@ -769,13 +769,13 @@ static int ax_init_dev(struct net_device *dev)
 
        ret = ax_mii_init(dev);
        if (ret)
-               goto out_irq;
+               goto err_out;
 
        ax_NS8390_init(dev, 0);
 
        ret = register_netdev(dev);
        if (ret)
-               goto out_irq;
+               goto err_out;
 
        netdev_info(dev, "%dbit, irq %d, %lx, MAC: %pM\n",
                    ei_local->word16 ? 16 : 8, dev->irq, dev->base_addr,
@@ -783,9 +783,6 @@ static int ax_init_dev(struct net_device *dev)
 
        return 0;
 
- out_irq:
-       /* cleanup irq */
-       free_irq(dev->irq, dev);
  err_out:
        return ret;
 }
index b3b22f4..ba5c4a9 100644 (file)
@@ -703,6 +703,8 @@ static int ethoc_open(struct net_device *dev)
        if (ret)
                return ret;
 
+       napi_enable(&priv->napi);
+
        ethoc_init_ring(priv, dev->mem_start);
        ethoc_reset(priv);
 
@@ -715,7 +717,6 @@ static int ethoc_open(struct net_device *dev)
        }
 
        phy_start(priv->phy);
-       napi_enable(&priv->napi);
 
        if (netif_msg_ifup(priv)) {
                dev_info(&dev->dev, "I/O: %08lx Memory: %08lx-%08lx\n",
index b5dc027..5ed8f61 100644 (file)
@@ -2591,11 +2591,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                } else if (ugeth->ug_info->uf_info.bd_mem_part ==
                           MEM_PART_MURAM) {
                        out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base,
-                                (u32) immrbar_virt_to_phys(ugeth->
-                                                           p_tx_bd_ring[i]));
+                                (u32)qe_muram_dma(ugeth->p_tx_bd_ring[i]));
                        out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].
                                 last_bd_completed_address,
-                                (u32) immrbar_virt_to_phys(endOfRing));
+                                (u32)qe_muram_dma(endOfRing));
                }
        }
 
@@ -2856,8 +2855,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                } else if (ugeth->ug_info->uf_info.bd_mem_part ==
                           MEM_PART_MURAM) {
                        out_be32(&ugeth->p_rx_bd_qs_tbl[i].externalbdbaseptr,
-                                (u32) immrbar_virt_to_phys(ugeth->
-                                                           p_rx_bd_ring[i]));
+                                (u32)qe_muram_dma(ugeth->p_rx_bd_ring[i]));
                }
                /* rest of fields handled by QE */
        }
index d9267cb..6b4f49e 100644 (file)
@@ -1083,7 +1083,7 @@ static int stir421x_patch_device(struct irda_usb_cb *self)
          * are "42101001.sb" or "42101002.sb"
          */
         sprintf(stir421x_fw_name, "4210%4X.sb",
-                self->usbdev->descriptor.bcdDevice);
+               le16_to_cpu(self->usbdev->descriptor.bcdDevice));
         ret = request_firmware(&fw, stir421x_fw_name, &self->usbdev->dev);
         if (ret < 0)
                 return ret;
index e8b9c53..4915d10 100644 (file)
@@ -126,34 +126,6 @@ static int marvell_config_aneg(struct phy_device *phydev)
 {
        int err;
 
-       /* The Marvell PHY has an errata which requires
-        * that certain registers get written in order
-        * to restart autonegotiation */
-       err = phy_write(phydev, MII_BMCR, BMCR_RESET);
-
-       if (err < 0)
-               return err;
-
-       err = phy_write(phydev, 0x1d, 0x1f);
-       if (err < 0)
-               return err;
-
-       err = phy_write(phydev, 0x1e, 0x200c);
-       if (err < 0)
-               return err;
-
-       err = phy_write(phydev, 0x1d, 0x5);
-       if (err < 0)
-               return err;
-
-       err = phy_write(phydev, 0x1e, 0);
-       if (err < 0)
-               return err;
-
-       err = phy_write(phydev, 0x1e, 0x100);
-       if (err < 0)
-               return err;
-
        err = phy_write(phydev, MII_M1011_PHY_SCR,
                        MII_M1011_PHY_SCR_AUTO_CROSS);
        if (err < 0)
@@ -188,6 +160,42 @@ static int marvell_config_aneg(struct phy_device *phydev)
        return 0;
 }
 
+static int m88e1101_config_aneg(struct phy_device *phydev)
+{
+       int err;
+
+       /* This Marvell PHY has an errata which requires
+        * that certain registers get written in order
+        * to restart autonegotiation
+        */
+       err = phy_write(phydev, MII_BMCR, BMCR_RESET);
+
+       if (err < 0)
+               return err;
+
+       err = phy_write(phydev, 0x1d, 0x1f);
+       if (err < 0)
+               return err;
+
+       err = phy_write(phydev, 0x1e, 0x200c);
+       if (err < 0)
+               return err;
+
+       err = phy_write(phydev, 0x1d, 0x5);
+       if (err < 0)
+               return err;
+
+       err = phy_write(phydev, 0x1e, 0);
+       if (err < 0)
+               return err;
+
+       err = phy_write(phydev, 0x1e, 0x100);
+       if (err < 0)
+               return err;
+
+       return marvell_config_aneg(phydev);
+}
+
 #ifdef CONFIG_OF_MDIO
 /*
  * Set and/or override some configuration registers based on the
@@ -653,8 +661,6 @@ static int marvell_read_status(struct phy_device *phydev)
                if (adv < 0)
                        return adv;
 
-               lpa &= adv;
-
                if (status & MII_M1011_PHY_STATUS_FULLDUPLEX)
                        phydev->duplex = DUPLEX_FULL;
                else
@@ -724,7 +730,7 @@ static struct phy_driver marvell_drivers[] = {
                .name = "Marvell 88E1101",
                .features = PHY_GBIT_FEATURES,
                .flags = PHY_HAS_INTERRUPT,
-               .config_aneg = &marvell_config_aneg,
+               .config_aneg = &m88e1101_config_aneg,
                .read_status = &genphy_read_status,
                .ack_interrupt = &marvell_ack_interrupt,
                .config_intr = &marvell_config_intr,
index 77c8ded..5e267bf 100644 (file)
@@ -38,7 +38,10 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
        { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
        { USB_DEVICE(0x040D, 0x3801) }, /* VIA */
        { USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */
+       { USB_DEVICE(0x0cf3, 0xb002) }, /* Ubiquiti WifiStation */
        { USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */
+       { USB_DEVICE(0x0471, 0x209e) }, /* Philips (or NXP) PTA01 */
+       { USB_DEVICE(0x1eda, 0x2315) }, /* AirTies */
 
        { USB_DEVICE(0x0cf3, 0x7015),
          .driver_info = AR9287_USB },  /* Atheros */
@@ -53,6 +56,12 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
          .driver_info = AR9280_USB },  /* SMC Networks */
        { USB_DEVICE(0x0411, 0x017f),
          .driver_info = AR9280_USB },  /* Sony UWA-BR100 */
+       { USB_DEVICE(0x0411, 0x0197),
+         .driver_info = AR9280_USB },  /* Buffalo WLI-UV-AG300P */
+       { USB_DEVICE(0x04da, 0x3904),
+         .driver_info = AR9280_USB },
+       { USB_DEVICE(0x0930, 0x0a08),
+         .driver_info = AR9280_USB },  /* Toshiba WLM-20U2 and GN-1080 */
 
        { USB_DEVICE(0x0cf3, 0x20ff),
          .driver_info = STORAGE_DEVICE },
@@ -1095,6 +1104,9 @@ static int send_eject_command(struct usb_interface *interface)
        u8 bulk_out_ep;
        int r;
 
+       if (iface_desc->desc.bNumEndpoints < 2)
+               return -ENODEV;
+
        /* Find bulk out endpoint */
        for (r = 1; r >= 0; r--) {
                endpoint = &iface_desc->endpoint[r].desc;
index 785bdbe..a67d0b2 100644 (file)
@@ -1281,6 +1281,9 @@ static int eject_installer(struct usb_interface *intf)
        u8 bulk_out_ep;
        int r;
 
+       if (iface_desc->desc.bNumEndpoints < 2)
+               return -ENODEV;
+
        /* Find bulk out endpoint */
        for (r = 1; r >= 0; r--) {
                endpoint = &iface_desc->endpoint[r].desc;
index b77808c..29f121e 100644 (file)
@@ -388,6 +388,8 @@ static void __unflatten_device_tree(struct boot_param_header *blob,
        /* Allocate memory for the expanded device tree */
        mem = (unsigned long)
                dt_alloc(size + 4, __alignof__(struct device_node));
+       if (!mem)
+               return NULL;
 
        memset((void *)mem, 0, size);
 
index 82edc0f..ce4cbd1 100644 (file)
@@ -772,15 +772,19 @@ void pci_remove_legacy_files(struct pci_bus *b)
 int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma,
                  enum pci_mmap_api mmap_api)
 {
-       unsigned long nr, start, size, pci_start;
+       unsigned long nr, start, size;
+       resource_size_t pci_start = 0, pci_end;
 
        if (pci_resource_len(pdev, resno) == 0)
                return 0;
        nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
        start = vma->vm_pgoff;
        size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1;
-       pci_start = (mmap_api == PCI_MMAP_PROCFS) ?
-                       pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0;
+       if (mmap_api == PCI_MMAP_PROCFS) {
+               pci_resource_to_user(pdev, resno, &pdev->resource[resno],
+                                    &pci_start, &pci_end);
+               pci_start >>= PAGE_SHIFT;
+       }
        if (start >= pci_start && start < pci_start + size &&
                        start + nr <= pci_start + size)
                return 1;
index 6b72e4a..ff27772 100644 (file)
@@ -1478,8 +1478,8 @@ static void pci_pme_list_scan(struct work_struct *work)
                        }
                }
                if (!list_empty(&pci_pme_list))
-                       schedule_delayed_work(&pci_pme_work,
-                                             msecs_to_jiffies(PME_TIMEOUT));
+                       queue_delayed_work(system_freezable_wq, &pci_pme_work,
+                                          msecs_to_jiffies(PME_TIMEOUT));
        }
        mutex_unlock(&pci_pme_list_mutex);
 }
@@ -1528,8 +1528,9 @@ void pci_pme_active(struct pci_dev *dev, bool enable)
                        mutex_lock(&pci_pme_list_mutex);
                        list_add(&pme_dev->list, &pci_pme_list);
                        if (list_is_singular(&pci_pme_list))
-                               schedule_delayed_work(&pci_pme_work,
-                                                     msecs_to_jiffies(PME_TIMEOUT));
+                               queue_delayed_work(system_freezable_wq,
+                                                  &pci_pme_work,
+                                                  msecs_to_jiffies(PME_TIMEOUT));
                        mutex_unlock(&pci_pme_list_mutex);
                } else {
                        mutex_lock(&pci_pme_list_mutex);
index 27911b5..dab3219 100644 (file)
@@ -249,23 +249,35 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
        const struct proc_dir_entry *dp = PDE(inode);
        struct pci_dev *dev = dp->data;
        struct pci_filp_private *fpriv = file->private_data;
-       int i, ret;
+       int i, ret, write_combine = 0, res_bit;
 
        if (!capable(CAP_SYS_RAWIO))
                return -EPERM;
 
+       if (fpriv->mmap_state == pci_mmap_io)
+               res_bit = IORESOURCE_IO;
+       else
+               res_bit = IORESOURCE_MEM;
+
        /* Make sure the caller is mapping a real resource for this device */
        for (i = 0; i < PCI_ROM_RESOURCE; i++) {
-               if (pci_mmap_fits(dev, i, vma,  PCI_MMAP_PROCFS))
+               if (dev->resource[i].flags & res_bit &&
+                   pci_mmap_fits(dev, i, vma,  PCI_MMAP_PROCFS))
                        break;
        }
 
        if (i >= PCI_ROM_RESOURCE)
                return -ENODEV;
 
+       if (fpriv->mmap_state == pci_mmap_mem &&
+           fpriv->write_combine) {
+               if (dev->resource[i].flags & IORESOURCE_PREFETCH)
+                       write_combine = 1;
+               else
+                       return -EINVAL;
+       }
        ret = pci_mmap_page_range(dev, vma,
-                                 fpriv->mmap_state,
-                                 fpriv->write_combine);
+                                 fpriv->mmap_state, write_combine);
        if (ret < 0)
                return ret;
 
index 604ee35..ea6123f 100644 (file)
@@ -1733,6 +1733,29 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,     0x260a, quirk_intel_pcie_pm);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x260b, quirk_intel_pcie_pm);
 
 #ifdef CONFIG_X86_IO_APIC
+static int dmi_disable_ioapicreroute(const struct dmi_system_id *d)
+{
+       noioapicreroute = 1;
+       pr_info("%s detected: disable boot interrupt reroute\n", d->ident);
+
+       return 0;
+}
+
+static struct dmi_system_id boot_interrupt_dmi_table[] = {
+       /*
+        * Systems to exclude from boot interrupt reroute quirks
+        */
+       {
+               .callback = dmi_disable_ioapicreroute,
+               .ident = "ASUSTek Computer INC. M2N-LR",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek Computer INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "M2N-LR"),
+               },
+       },
+       {}
+};
+
 /*
  * Boot interrupts on some chipsets cannot be turned off. For these chipsets,
  * remap the original interrupt in the linux kernel to the boot interrupt, so
@@ -1741,6 +1764,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,      0x260b, quirk_intel_pcie_pm);
  */
 static void quirk_reroute_to_boot_interrupts_intel(struct pci_dev *dev)
 {
+       dmi_check_system(boot_interrupt_dmi_table);
        if (noioapicquirk || noioapicreroute)
                return;
 
index 69f8aa3..4873eaf 100644 (file)
@@ -33,9 +33,9 @@ static inline unsigned int get_irq_flags(struct resource *res)
 static struct device *dev;
 static struct pda_power_pdata *pdata;
 static struct resource *ac_irq, *usb_irq;
-static struct timer_list charger_timer;
-static struct timer_list supply_timer;
-static struct timer_list polling_timer;
+static struct delayed_work charger_work;
+static struct delayed_work polling_work;
+static struct delayed_work supply_work;
 static int polling;
 
 #ifdef CONFIG_USB_OTG_UTILS
@@ -144,7 +144,7 @@ static void update_charger(void)
        }
 }
 
-static void supply_timer_func(unsigned long unused)
+static void supply_work_func(struct work_struct *work)
 {
        if (ac_status == PDA_PSY_TO_CHANGE) {
                ac_status = new_ac_status;
@@ -165,11 +165,12 @@ static void psy_changed(void)
         * Okay, charger set. Now wait a bit before notifying supplicants,
         * charge power should stabilize.
         */
-       mod_timer(&supply_timer,
-                 jiffies + msecs_to_jiffies(pdata->wait_for_charger));
+       cancel_delayed_work(&supply_work);
+       schedule_delayed_work(&supply_work,
+                             msecs_to_jiffies(pdata->wait_for_charger));
 }
 
-static void charger_timer_func(unsigned long unused)
+static void charger_work_func(struct work_struct *work)
 {
        update_status();
        psy_changed();
@@ -188,13 +189,14 @@ static irqreturn_t power_changed_isr(int irq, void *power_supply)
         * Wait a bit before reading ac/usb line status and setting charger,
         * because ac/usb status readings may lag from irq.
         */
-       mod_timer(&charger_timer,
-                 jiffies + msecs_to_jiffies(pdata->wait_for_status));
+       cancel_delayed_work(&charger_work);
+       schedule_delayed_work(&charger_work,
+                             msecs_to_jiffies(pdata->wait_for_status));
 
        return IRQ_HANDLED;
 }
 
-static void polling_timer_func(unsigned long unused)
+static void polling_work_func(struct work_struct *work)
 {
        int changed = 0;
 
@@ -215,8 +217,9 @@ static void polling_timer_func(unsigned long unused)
        if (changed)
                psy_changed();
 
-       mod_timer(&polling_timer,
-                 jiffies + msecs_to_jiffies(pdata->polling_interval));
+       cancel_delayed_work(&polling_work);
+       schedule_delayed_work(&polling_work,
+                             msecs_to_jiffies(pdata->polling_interval));
 }
 
 #ifdef CONFIG_USB_OTG_UTILS
@@ -262,8 +265,8 @@ static int pda_power_probe(struct platform_device *pdev)
        if (!pdata->ac_max_uA)
                pdata->ac_max_uA = 500000;
 
-       setup_timer(&charger_timer, charger_timer_func, 0);
-       setup_timer(&supply_timer, supply_timer_func, 0);
+       INIT_DELAYED_WORK(&charger_work, charger_work_func);
+       INIT_DELAYED_WORK(&supply_work, supply_work_func);
 
        ac_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ac");
        usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb");
@@ -333,9 +336,10 @@ static int pda_power_probe(struct platform_device *pdev)
 
        if (polling) {
                dev_dbg(dev, "will poll for status\n");
-               setup_timer(&polling_timer, polling_timer_func, 0);
-               mod_timer(&polling_timer,
-                         jiffies + msecs_to_jiffies(pdata->polling_interval));
+               INIT_DELAYED_WORK(&polling_work, polling_work_func);
+               cancel_delayed_work(&polling_work);
+               schedule_delayed_work(&polling_work,
+                                     msecs_to_jiffies(pdata->polling_interval));
        }
 
        if (ac_irq || usb_irq)
@@ -376,9 +380,9 @@ static int pda_power_remove(struct platform_device *pdev)
                free_irq(ac_irq->start, &pda_psy_ac);
 
        if (polling)
-               del_timer_sync(&polling_timer);
-       del_timer_sync(&charger_timer);
-       del_timer_sync(&supply_timer);
+               cancel_delayed_work_sync(&polling_work);
+       cancel_delayed_work_sync(&charger_work);
+       cancel_delayed_work_sync(&supply_work);
 
        if (pdata->is_usb_online)
                power_supply_unregister(&pda_psy_usb);
index 82a5ca6..6cda887 100644 (file)
@@ -1999,10 +1999,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 
        if (mem_only) {
                if (pci_enable_device_mem(pdev))
-                       goto probe_out;
+                       return ret;
        } else {
                if (pci_enable_device(pdev))
-                       goto probe_out;
+                       return ret;
        }
 
        /* This may fail but that's ok */
@@ -2012,7 +2012,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        if (!ha) {
                ql_log_pci(ql_log_fatal, pdev, 0x0009,
                    "Unable to allocate memory for ha.\n");
-               goto probe_out;
+               goto disable_device;
        }
        ql_dbg_pci(ql_dbg_init, pdev, 0x000a,
            "Memory allocated for ha=%p.\n", ha);
@@ -2433,7 +2433,7 @@ probe_hw_failed:
        kfree(ha);
        ha = NULL;
 
-probe_out:
+disable_device:
        pci_disable_device(pdev);
        return ret;
 }
index 21022e1..8e2afbb 100644 (file)
@@ -792,20 +792,23 @@ void psb_intel_lvds_init(struct drm_device *dev,
                if (scan->type & DRM_MODE_TYPE_PREFERRED) {
                        mode_dev->panel_fixed_mode =
                            drm_mode_duplicate(dev, scan);
+                       DRM_DEBUG_KMS("Using mode from DDC\n");
                        goto out;       /* FIXME: check for quirks */
                }
        }
 
        /* Failed to get EDID, what about VBT? do we need this? */
-       if (mode_dev->vbt_mode)
+       if (dev_priv->lfp_lvds_vbt_mode) {
                mode_dev->panel_fixed_mode =
-                   drm_mode_duplicate(dev, mode_dev->vbt_mode);
+                       drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
 
-       if (!mode_dev->panel_fixed_mode)
-               if (dev_priv->lfp_lvds_vbt_mode)
-                       mode_dev->panel_fixed_mode =
-                               drm_mode_duplicate(dev,
-                                       dev_priv->lfp_lvds_vbt_mode);
+               if (mode_dev->panel_fixed_mode) {
+                       mode_dev->panel_fixed_mode->type |=
+                               DRM_MODE_TYPE_PREFERRED;
+                       DRM_DEBUG_KMS("Using mode from VBT\n");
+                       goto out;
+               }
+       }
 
        /*
         * If we didn't get EDID, try checking if the panel is already turned
@@ -822,6 +825,7 @@ void psb_intel_lvds_init(struct drm_device *dev,
                if (mode_dev->panel_fixed_mode) {
                        mode_dev->panel_fixed_mode->type |=
                            DRM_MODE_TYPE_PREFERRED;
+                       DRM_DEBUG_KMS("Using pre-programmed mode\n");
                        goto out;       /* FIXME: check for quirks */
                }
        }
index 2ee97e2..68f9af8 100644 (file)
@@ -248,14 +248,19 @@ done:
 /* See hub_configure in hub.c */
 static inline void hub_descriptor(struct usb_hub_descriptor *desc)
 {
+       int width;
+
        memset(desc, 0, sizeof(*desc));
        desc->bDescriptorType = 0x29;
-       desc->bDescLength = 9;
        desc->wHubCharacteristics = (__force __u16)
                (__constant_cpu_to_le16(0x0001));
+
        desc->bNbrPorts = VHCI_NPORTS;
-       desc->u.hs.DeviceRemovable[0] = 0xff;
-       desc->u.hs.DeviceRemovable[1] = 0xff;
+       BUILD_BUG_ON(VHCI_NPORTS > USB_MAXCHILDREN);
+       width = desc->bNbrPorts / 8 + 1;
+       desc->bDescLength = USB_DT_HUB_NONVAR_SIZE + 2 * width;
+       memset(&desc->u.hs.DeviceRemovable[0], 0, width);
+       memset(&desc->u.hs.DeviceRemovable[width], 0xff, width);
 }
 
 static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
index 07c0134..60f71ec 100644 (file)
@@ -1579,11 +1579,13 @@ static int sci_startup(struct uart_port *port)
 
        sci_port_enable(s);
 
+       sci_request_dma(port);
+
        ret = sci_request_irq(s);
-       if (unlikely(ret < 0))
+       if (unlikely(ret < 0)) {
+               sci_free_dma(port);
                return ret;
-
-       sci_request_dma(port);
+       }
 
        sci_start_tx(port);
        sci_start_rx(port);
@@ -1600,8 +1602,8 @@ static void sci_shutdown(struct uart_port *port)
        sci_stop_rx(port);
        sci_stop_tx(port);
 
-       sci_free_dma(port);
        sci_free_irq(s);
+       sci_free_dma(port);
 
        sci_port_disable(s);
 }
index 93249aa..210b533 100644 (file)
@@ -293,6 +293,12 @@ static void acm_ctrl_irq(struct urb *urb)
                break;
 
        case USB_CDC_NOTIFY_SERIAL_STATE:
+               if (le16_to_cpu(dr->wLength) != 2) {
+                       dev_dbg(&acm->control->dev,
+                               "%s - malformed serial state\n", __func__);
+                       break;
+               }
+
                tty = tty_port_tty_get(&acm->port);
                newctrl = get_unaligned_le16(data);
 
@@ -323,11 +329,10 @@ static void acm_ctrl_irq(struct urb *urb)
 
        default:
                dev_dbg(&acm->control->dev,
-                       "%s - unknown notification %d received: index %d "
-                       "len %d data0 %d data1 %d\n",
+                       "%s - unknown notification %d received: index %d len %d\n",
                        __func__,
-                       dr->bNotificationType, dr->wIndex,
-                       dr->wLength, data[0], data[1]);
+                       dr->bNotificationType, dr->wIndex, dr->wLength);
+
                break;
        }
 exit:
index 45d3007..6f34a26 100644 (file)
@@ -325,11 +325,11 @@ static void snoop_urb(struct usb_device *udev,
 
        if (userurb) {          /* Async */
                if (when == SUBMIT)
-                       dev_info(&udev->dev, "userurb %p, ep%d %s-%s, "
+                       dev_info(&udev->dev, "userurb %pK, ep%d %s-%s, "
                                        "length %u\n",
                                        userurb, ep, t, d, length);
                else
-                       dev_info(&udev->dev, "userurb %p, ep%d %s-%s, "
+                       dev_info(&udev->dev, "userurb %pK, ep%d %s-%s, "
                                        "actual_length %u status %d\n",
                                        userurb, ep, t, d, length,
                                        timeout_or_status);
index c595714..ad87f82 100644 (file)
@@ -1218,6 +1218,24 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
                 */
                if (udev->parent && !PMSG_IS_AUTO(msg))
                        status = 0;
+
+               /*
+                * If the device is inaccessible, don't try to resume
+                * suspended interfaces and just return the error.
+                */
+               if (status && status != -EBUSY) {
+                       int err;
+                       u16 devstat;
+
+                       err = usb_get_status(udev, USB_RECIP_DEVICE, 0,
+                                            &devstat);
+                       if (err) {
+                               dev_err(&udev->dev,
+                                       "Failed to suspend device, error %d\n",
+                                       status);
+                               goto done;
+                       }
+               }
        }
 
        /* If the suspend failed, resume interfaces that did get suspended */
@@ -1631,6 +1649,9 @@ static int autosuspend_check(struct usb_device *udev)
        int                     w, i;
        struct usb_interface    *intf;
 
+       if (udev->state == USB_STATE_NOTATTACHED)
+               return -ENODEV;
+
        /* Fail if autosuspend is disabled, or any interfaces are in use, or
         * any interface drivers require remote wakeup but it isn't available.
         */
index 99458c8..2062a15 100644 (file)
@@ -26,6 +26,7 @@
 #define MAX_USB_MINORS 256
 static const struct file_operations *usb_minors[MAX_USB_MINORS];
 static DECLARE_RWSEM(minor_rwsem);
+static DEFINE_MUTEX(init_usb_class_mutex);
 
 static int usb_open(struct inode * inode, struct file * file)
 {
@@ -116,8 +117,9 @@ static void release_usb_class(struct kref *kref)
 
 static void destroy_usb_class(void)
 {
-       if (usb_class)
-               kref_put(&usb_class->kref, release_usb_class);
+       mutex_lock(&init_usb_class_mutex);
+       kref_put(&usb_class->kref, release_usb_class);
+       mutex_unlock(&init_usb_class_mutex);
 }
 
 int usb_major_init(void)
@@ -179,7 +181,10 @@ int usb_register_dev(struct usb_interface *intf,
        if (intf->minor >= 0)
                return -EADDRINUSE;
 
+       mutex_lock(&init_usb_class_mutex);
        retval = init_usb_class();
+       mutex_unlock(&init_usb_class_mutex);
+
        if (retval)
                return retval;
 
index eb2c3bd..3cedf91 100644 (file)
@@ -1563,7 +1563,7 @@ int usb_hcd_unlink_urb (struct urb *urb, int status)
                if (retval == 0)
                        retval = -EINPROGRESS;
                else if (retval != -EIDRM && retval != -EBUSY)
-                       dev_dbg(&udev->dev, "hcd_unlink_urb %p fail %d\n",
+                       dev_dbg(&udev->dev, "hcd_unlink_urb %pK fail %d\n",
                                        urb, retval);
                usb_put_dev(udev);
        }
@@ -1645,7 +1645,7 @@ rescan:
                /* kick hcd */
                unlink1(hcd, urb, -ESHUTDOWN);
                dev_dbg (hcd->self.controller,
-                       "shutdown urb %p ep%d%s%s\n",
+                       "shutdown urb %pK ep%d%s%s\n",
                        urb, usb_endpoint_num(&ep->desc),
                        is_in ? "in" : "out",
                        ({      char *s;
index 676324a..7c59466 100644 (file)
@@ -177,7 +177,8 @@ static struct usb_hub *hdev_to_hub(struct usb_device *hdev)
 }
 
 /* USB 2.0 spec Section 11.24.4.5 */
-static int get_hub_descriptor(struct usb_device *hdev, void *data)
+static int get_hub_descriptor(struct usb_device *hdev,
+               struct usb_hub_descriptor *desc)
 {
        int i, ret, size;
        unsigned dtype;
@@ -193,10 +194,18 @@ static int get_hub_descriptor(struct usb_device *hdev, void *data)
        for (i = 0; i < 3; i++) {
                ret = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
                        USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB,
-                       dtype << 8, 0, data, size,
+                       dtype << 8, 0, desc, size,
                        USB_CTRL_GET_TIMEOUT);
-               if (ret >= (USB_DT_HUB_NONVAR_SIZE + 2))
+               if (hub_is_superspeed(hdev)) {
+                       if (ret == size)
+                               return ret;
+               } else if (ret >= USB_DT_HUB_NONVAR_SIZE + 2) {
+                       /* Make sure we have the DeviceRemovable field. */
+                       size = USB_DT_HUB_NONVAR_SIZE + desc->bNbrPorts / 8 + 1;
+                       if (ret < size)
+                               return -EMSGSIZE;
                        return ret;
+               }
        }
        return -EINVAL;
 }
@@ -884,6 +893,9 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
 
                portstatus = portchange = 0;
                status = hub_port_status(hub, port1, &portstatus, &portchange);
+               if (status)
+                       goto abort;
+
                if (udev || (portstatus & USB_PORT_STAT_CONNECTION))
                        dev_dbg(hub->intfdev,
                                        "port %d: status %04x change %04x\n",
@@ -1011,7 +1023,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
 
        /* Scan all ports that need attention */
        kick_khubd(hub);
-
+ abort:
        /* Allow autosuspend if it was suppressed */
        if (type <= HUB_INIT3)
                usb_autopm_put_interface_async(to_usb_interface(hub->intfdev));
@@ -1096,6 +1108,7 @@ static int hub_configure(struct usb_hub *hub,
        unsigned int pipe;
        int maxp, ret;
        char *message = "out of memory";
+       unsigned maxchild;
 
        hub->buffer = kmalloc(sizeof(*hub->buffer), GFP_KERNEL);
        if (!hub->buffer) {
@@ -1110,7 +1123,7 @@ static int hub_configure(struct usb_hub *hub,
        }
        mutex_init(&hub->status_mutex);
 
-       hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
+       hub->descriptor = kzalloc(sizeof(*hub->descriptor), GFP_KERNEL);
        if (!hub->descriptor) {
                ret = -ENOMEM;
                goto fail;
@@ -1118,13 +1131,19 @@ static int hub_configure(struct usb_hub *hub,
 
        /* Request the entire hub descriptor.
         * hub->descriptor can handle USB_MAXCHILDREN ports,
-        * but the hub can/will return fewer bytes here.
+        * but a (non-SS) hub can/will return fewer bytes here.
         */
        ret = get_hub_descriptor(hdev, hub->descriptor);
        if (ret < 0) {
                message = "can't read hub descriptor";
                goto fail;
-       } else if (hub->descriptor->bNbrPorts > USB_MAXCHILDREN) {
+       }
+
+       maxchild = USB_MAXCHILDREN;
+       if (hub_is_superspeed(hdev))
+               maxchild = min_t(unsigned, maxchild, USB_SS_MAXPORTS);
+
+       if (hub->descriptor->bNbrPorts > maxchild) {
                message = "hub has too many ports!";
                ret = -ENODEV;
                goto fail;
@@ -1778,6 +1797,12 @@ void usb_disconnect(struct usb_device **pdev)
        dev_info(&udev->dev, "USB disconnect, device number %d\n",
                        udev->devnum);
 
+       /*
+        * Ensure that the pm runtime code knows that the USB device
+        * is in the process of being disconnected.
+        */
+       pm_runtime_barrier(&udev->dev);
+
        usb_lock_device(udev);
 
        /* Free up all the children before we remove this device */
index 8e0a1bd..03a9222 100644 (file)
@@ -1770,7 +1770,7 @@ ss_hub_descriptor(struct usb_hub_descriptor *desc)
        desc->wHubCharacteristics = cpu_to_le16(0x0001);
        desc->bNbrPorts = 1;
        desc->u.ss.bHubHdrDecLat = 0x04; /* Worst case: 0.4 micro sec*/
-       desc->u.ss.DeviceRemovable = 0xffff;
+       desc->u.ss.DeviceRemovable = 0;
 }
 
 static inline void
@@ -1781,8 +1781,8 @@ hub_descriptor (struct usb_hub_descriptor *desc)
        desc->bDescLength = 9;
        desc->wHubCharacteristics = cpu_to_le16(0x0001);
        desc->bNbrPorts = 1;
-       desc->u.hs.DeviceRemovable[0] = 0xff;
-       desc->u.hs.DeviceRemovable[1] = 0xff;
+       desc->u.hs.DeviceRemovable[0] = 0;
+       desc->u.hs.DeviceRemovable[1] = 0xff;   /* PortPwrCtrlMask */
 }
 
 static int dummy_hub_control (
index 7dbbd1a..25b5ff6 100644 (file)
@@ -512,7 +512,11 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep)
 /* Caller must hold fsg->lock */
 static void wakeup_thread(struct fsg_common *common)
 {
-       smp_wmb();      /* ensure the write of bh->state is complete */
+       /*
+        * Ensure the reading of thread_wakeup_needed
+        * and the writing of bh->state are completed
+        */
+       smp_mb();
        /* Tell the main thread that something has happened */
        common->thread_wakeup_needed = 1;
        if (common->thread_task)
@@ -732,7 +736,12 @@ static int sleep_thread(struct fsg_common *common)
        }
        __set_current_state(TASK_RUNNING);
        common->thread_wakeup_needed = 0;
-       smp_rmb();      /* ensure the latest bh->state is visible */
+
+       /*
+        * Ensure the writing of thread_wakeup_needed
+        * and the reading of bh->state are completed
+        */
+       smp_mb();
        return rc;
 }
 
index e84ca19..fa5482c 100644 (file)
@@ -1274,7 +1274,7 @@ static void set_td_timer(struct r8a66597 *r8a66597, struct r8a66597_td *td)
                        time = 30;
                        break;
                default:
-                       time = 300;
+                       time = 50;
                        break;
                }
 
@@ -1790,6 +1790,7 @@ static void r8a66597_td_timer(unsigned long _r8a66597)
                pipe = td->pipe;
                pipe_stop(r8a66597, pipe);
 
+               /* Select a different address or endpoint */
                new_td = td;
                do {
                        list_move_tail(&new_td->queue,
@@ -1799,7 +1800,8 @@ static void r8a66597_td_timer(unsigned long _r8a66597)
                                new_td = td;
                                break;
                        }
-               } while (td != new_td && td->address == new_td->address);
+               } while (td != new_td && td->address == new_td->address &&
+                       td->pipe->info.epnum == new_td->pipe->info.epnum);
 
                start_transfer(r8a66597, new_td);
 
index 13bb316..d89b72c 100644 (file)
@@ -1036,6 +1036,35 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
        return 0;
 }
 
+/*
+ * Workaround for missing Cold Attach Status (CAS) if device re-plugged in S3.
+ * warm reset a USB3 device stuck in polling or compliance mode after resume.
+ * See Intel 100/c230 series PCH specification update Doc #332692-006 Errata #8
+ */
+static bool xhci_port_missing_cas_quirk(int port_index,
+                                            __le32 __iomem **port_array)
+{
+       u32 portsc;
+
+       portsc = readl(port_array[port_index]);
+
+       /* if any of these are set we are not stuck */
+       if (portsc & (PORT_CONNECT | PORT_CAS))
+               return false;
+
+       if (((portsc & PORT_PLS_MASK) != XDEV_POLLING) &&
+           ((portsc & PORT_PLS_MASK) != XDEV_COMP_MODE))
+               return false;
+
+       /* clear wakeup/change bits, and do a warm port reset */
+       portsc &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS);
+       portsc |= PORT_WR;
+       writel(portsc, port_array[port_index]);
+       /* flush write */
+       readl(port_array[port_index]);
+       return true;
+}
+
 int xhci_bus_resume(struct usb_hcd *hcd)
 {
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
@@ -1070,6 +1099,14 @@ int xhci_bus_resume(struct usb_hcd *hcd)
                int slot_id;
 
                temp = xhci_readl(xhci, port_array[port_index]);
+
+               /* warm reset CAS limited ports stuck in polling/compliance */
+               if ((xhci->quirks & XHCI_MISSING_CAS) &&
+                   (hcd->speed >= HCD_USB3) &&
+                   xhci_port_missing_cas_quirk(port_index, port_array)) {
+                       xhci_dbg(xhci, "reset stuck port %d\n", port_index);
+                       continue;
+               }
                if (DEV_SUPERSPEED(temp))
                        temp &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS);
                else
index 9a29152..841eb68 100644 (file)
@@ -1591,7 +1591,7 @@ static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags)
        if (!xhci->scratchpad)
                goto fail_sp;
 
-       xhci->scratchpad->sp_array = dma_alloc_coherent(dev,
+       xhci->scratchpad->sp_array = dma_zalloc_coherent(dev,
                                     num_sp * sizeof(u64),
                                     &xhci->scratchpad->sp_dma, flags);
        if (!xhci->scratchpad->sp_array)
@@ -2321,7 +2321,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
        val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) |
                (xhci->cmd_ring->first_seg->dma & (u64) ~CMD_RING_RSVD_BITS) |
                xhci->cmd_ring->cycle_state;
-       xhci_dbg(xhci, "// Setting command ring address to 0x%x\n", val);
+       xhci_dbg(xhci, "// Setting command ring address to 0x%016llx\n", val_64);
        xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring);
        xhci_dbg_cmd_ptrs(xhci);
 
index fce6355..423700b 100644 (file)
@@ -42,6 +42,8 @@
 #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI       0x9d2f
 #define PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI             0x0aa8
 #define PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI             0x1aa8
+#define PCI_DEVICE_ID_INTEL_APL_XHCI                   0x5aa8
+#define PCI_DEVICE_ID_INTEL_DNV_XHCI                   0x19d0
 
 static const char hcd_name[] = "xhci_hcd";
 
@@ -138,9 +140,17 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
                 pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI ||
                 pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
                 pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI ||
-                pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI)) {
+                pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI ||
+                pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI ||
+                pdev->device == PCI_DEVICE_ID_INTEL_DNV_XHCI)) {
                xhci->quirks |= XHCI_PME_STUCK_QUIRK;
        }
+       if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
+           (pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
+            pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI ||
+            pdev->device == PCI_DEVICE_ID_INTEL_DNV_XHCI))
+               xhci->quirks |= XHCI_MISSING_CAS;
+
        if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
                        pdev->device == PCI_DEVICE_ID_ASROCK_P67) {
                xhci->quirks |= XHCI_RESET_ON_RESUME;
@@ -149,6 +159,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
        }
        if (pdev->vendor == PCI_VENDOR_ID_VIA)
                xhci->quirks |= XHCI_RESET_ON_RESUME;
+
+       if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
+                       pdev->device == 0x1142)
+               xhci->quirks |= XHCI_TRUST_TX_LENGTH;
 }
 
 /*
index 35e1b84..74ed210 100644 (file)
@@ -2642,29 +2642,31 @@ static int xhci_handle_event(struct xhci_hcd *xhci)
 irqreturn_t xhci_irq(struct usb_hcd *hcd)
 {
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-       u32 status;
        union xhci_trb *trb;
-       u64 temp_64;
        union xhci_trb *event_ring_deq;
+       irqreturn_t ret = IRQ_NONE;
+       unsigned long flags;
        dma_addr_t deq;
+       u64 temp_64;
+       u32 status;
 
-       spin_lock(&xhci->lock);
+       spin_lock_irqsave(&xhci->lock, flags);
        trb = xhci->event_ring->dequeue;
        /* Check if the xHC generated the interrupt, or the irq is shared */
        status = xhci_readl(xhci, &xhci->op_regs->status);
-       if (status == 0xffffffff)
-               goto hw_died;
-
-       if (!(status & STS_EINT)) {
-               spin_unlock(&xhci->lock);
-               return IRQ_NONE;
+       if (status == 0xffffffff) {
+               ret = IRQ_HANDLED;
+               goto out;
        }
+
+       if (!(status & STS_EINT))
+               goto out;
+
        if (status & STS_FATAL) {
                xhci_warn(xhci, "WARNING: Host System Error\n");
                xhci_halt(xhci);
-hw_died:
-               spin_unlock(&xhci->lock);
-               return IRQ_HANDLED;
+               ret = IRQ_HANDLED;
+               goto out;
        }
 
        /*
@@ -2694,9 +2696,8 @@ hw_died:
                temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
                xhci_write_64(xhci, temp_64 | ERST_EHB,
                                &xhci->ir_set->erst_dequeue);
-               spin_unlock(&xhci->lock);
-
-               return IRQ_HANDLED;
+               ret = IRQ_HANDLED;
+               goto out;
        }
 
        event_ring_deq = xhci->event_ring->dequeue;
@@ -2721,10 +2722,12 @@ hw_died:
        /* Clear the event handler busy flag (RW1C); event ring is empty. */
        temp_64 |= ERST_EHB;
        xhci_write_64(xhci, temp_64, &xhci->ir_set->erst_dequeue);
+       ret = IRQ_HANDLED;
 
-       spin_unlock(&xhci->lock);
+out:
+       spin_unlock_irqrestore(&xhci->lock, flags);
 
-       return IRQ_HANDLED;
+       return ret;
 }
 
 irqreturn_t xhci_msi_irq(int irq, struct usb_hcd *hcd)
index 15f58d1..4453f2a 100644 (file)
@@ -280,6 +280,8 @@ struct xhci_op_regs {
 #define XDEV_U0                (0x0 << 5)
 #define XDEV_U2                (0x2 << 5)
 #define XDEV_U3                (0x3 << 5)
+#define XDEV_POLLING   (0x7 << 5)
+#define XDEV_COMP_MODE  (0xa << 5)
 #define XDEV_RESUME    (0xf << 5)
 /* true: port has power (see HCC_PPC) */
 #define PORT_POWER     (1 << 9)
@@ -1499,6 +1501,7 @@ struct xhci_hcd {
 #define XHCI_SLOW_SUSPEND      (1 << 17)
 #define XHCI_SPURIOUS_WAKEUP   (1 << 18)
 #define XHCI_PME_STUCK_QUIRK   (1 << 20)
+#define XHCI_MISSING_CAS       (1 << 24)
        unsigned int            num_active_eps;
        unsigned int            limit_active_eps;
        /* There are two roothubs to keep track of bus suspend info for */
index 878a346..097e4ef 100644 (file)
@@ -560,7 +560,7 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd,
                        info.revision = le16_to_cpu(dev->udev->descriptor.bcdDevice);
 
                        /* 0==UNKNOWN, 1==LOW(usb1.1) ,2=FULL(usb1.1), 3=HIGH(usb2.0) */
-                       info.speed = le16_to_cpu(dev->udev->speed);
+                       info.speed = dev->udev->speed;
                        info.if_num = dev->interface->cur_altsetting->desc.bInterfaceNumber;
                        info.report_size = dev->report_size;
 
index b67b4bc..659960b 100644 (file)
@@ -237,6 +237,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
        u32                             dma_remaining;
        int                             src_burst, dst_burst;
        u16                             csr;
+       u32                             psize;
        int                             ch;
        s8                              dmareq;
        s8                              sync_dev;
@@ -408,15 +409,19 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 
        if (chdat->tx) {
                /* Send transfer_packet_sz packets at a time */
-               musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
-                       chdat->transfer_packet_sz);
+               psize = musb_readl(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET);
+               psize &= ~0x7ff;
+               psize |= chdat->transfer_packet_sz;
+               musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET, psize);
 
                musb_writel(ep_conf, TUSB_EP_TX_OFFSET,
                        TUSB_EP_CONFIG_XFR_SIZE(chdat->transfer_len));
        } else {
                /* Receive transfer_packet_sz packets at a time */
-               musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
-                       chdat->transfer_packet_sz << 16);
+               psize = musb_readl(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET);
+               psize &= ~(0x7ff << 16);
+               psize |= (chdat->transfer_packet_sz << 16);
+               musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET, psize);
 
                musb_writel(ep_conf, TUSB_EP_RX_OFFSET,
                        TUSB_EP_CONFIG_XFR_SIZE(chdat->transfer_len));
index c298c7a..a42adab 100644 (file)
@@ -1543,9 +1543,9 @@ static int set_serial_info(struct tty_struct *tty,
                                        (new_serial.flags & ASYNC_FLAGS));
        priv->custom_divisor = new_serial.custom_divisor;
 
+check_and_exit:
        write_latency_timer(port);
 
-check_and_exit:
        if ((old_priv.flags & ASYNC_SPD_MASK) !=
             (priv->flags & ASYNC_SPD_MASK)) {
                if ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
index a417756..86c8efd 100644 (file)
@@ -2412,8 +2412,11 @@ static void change_port_settings(struct tty_struct *tty,
        if (!baud) {
                /* pick a default, any default... */
                baud = 9600;
-       } else
+       } else {
+               /* Avoid a zero divisor. */
+               baud = min(baud, 461550);
                tty_encode_baud_rate(tty, baud, baud);
+       }
 
        edge_port->baud_rate = baud;
        config->wBaudRate = (__u16)((461550L + baud/2) / baud);
index ccbce40..b0236ab 100644 (file)
@@ -236,6 +236,7 @@ static u8 ir_xbof_change(u8 xbof)
 static int ir_startup(struct usb_serial *serial)
 {
        struct usb_irda_cs_descriptor *irda_desc;
+       int rates;
 
        irda_desc = irda_usb_find_class_desc(serial->dev, 0);
        if (!irda_desc) {
@@ -244,17 +245,19 @@ static int ir_startup(struct usb_serial *serial)
                return -ENODEV;
        }
 
+       rates = le16_to_cpu(irda_desc->wBaudRate);
+
        dbg("%s - Baud rates supported:%s%s%s%s%s%s%s%s%s",
                __func__,
-               (irda_desc->wBaudRate & USB_IRDA_BR_2400) ? " 2400" : "",
-               (irda_desc->wBaudRate & USB_IRDA_BR_9600) ? " 9600" : "",
-               (irda_desc->wBaudRate & USB_IRDA_BR_19200) ? " 19200" : "",
-               (irda_desc->wBaudRate & USB_IRDA_BR_38400) ? " 38400" : "",
-               (irda_desc->wBaudRate & USB_IRDA_BR_57600) ? " 57600" : "",
-               (irda_desc->wBaudRate & USB_IRDA_BR_115200) ? " 115200" : "",
-               (irda_desc->wBaudRate & USB_IRDA_BR_576000) ? " 576000" : "",
-               (irda_desc->wBaudRate & USB_IRDA_BR_1152000) ? " 1152000" : "",
-               (irda_desc->wBaudRate & USB_IRDA_BR_4000000) ? " 4000000" : "");
+               (rates & USB_IRDA_BR_2400) ? " 2400" : "",
+               (rates & USB_IRDA_BR_9600) ? " 9600" : "",
+               (rates & USB_IRDA_BR_19200) ? " 19200" : "",
+               (rates & USB_IRDA_BR_38400) ? " 38400" : "",
+               (rates & USB_IRDA_BR_57600) ? " 57600" : "",
+               (rates & USB_IRDA_BR_115200) ? " 115200" : "",
+               (rates & USB_IRDA_BR_576000) ? " 576000" : "",
+               (rates & USB_IRDA_BR_1152000) ? " 1152000" : "",
+               (rates & USB_IRDA_BR_4000000) ? " 4000000" : "");
 
        switch (irda_desc->bmAdditionalBOFs) {
        case USB_IRDA_AB_48:
index 801c697..ed8694b 100644 (file)
@@ -251,7 +251,7 @@ static int mct_u232_set_baud_rate(struct tty_struct *tty,
                return -ENOMEM;
 
        divisor = mct_u232_calculate_baud_rate(serial, value, &speed);
-       put_unaligned_le32(cpu_to_le32(divisor), buf);
+       put_unaligned_le32(divisor, buf);
        rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
                                MCT_U232_SET_BAUD_RATE_REQUEST,
                                MCT_U232_SET_REQUEST_TYPE,
index 9fbe742..8f6fa2d 100644 (file)
@@ -431,6 +431,10 @@ struct ms_lib_ctrl {
 #define SD_BLOCK_LEN  9
 
 struct ene_ub6250_info {
+
+       /* I/O bounce buffer */
+       u8              *bbuf;
+
        /* for 6250 code */
        struct SD_STATUS        SD_Status;
        struct MS_STATUS        MS_Status;
@@ -478,8 +482,11 @@ static int ene_load_bincode(struct us_data *us, unsigned char flag);
 
 static void ene_ub6250_info_destructor(void *extra)
 {
+       struct ene_ub6250_info *info = (struct ene_ub6250_info *) extra;
+
        if (!extra)
                return;
+       kfree(info->bbuf);
 }
 
 static int ene_send_scsi_cmd(struct us_data *us, u8 fDir, void *buf, int use_sg)
@@ -843,8 +850,9 @@ static int ms_read_readpage(struct us_data *us, u32 PhyBlockAddr,
                u8 PageNum, u32 *PageBuf, struct ms_lib_type_extdat *ExtraDat)
 {
        struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+       struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+       u8 *bbuf = info->bbuf;
        int result;
-       u8 ExtBuf[4];
        u32 bn = PhyBlockAddr * 0x20 + PageNum;
 
        /* printk(KERN_INFO "MS --- MS_ReaderReadPage,
@@ -887,7 +895,7 @@ static int ms_read_readpage(struct us_data *us, u32 PhyBlockAddr,
        bcb->CDB[2]     = (unsigned char)(PhyBlockAddr>>16);
        bcb->CDB[6]     = 0x01;
 
-       result = ene_send_scsi_cmd(us, FDIR_READ, &ExtBuf, 0);
+       result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
        if (result != USB_STOR_XFER_GOOD)
                return USB_STOR_TRANSPORT_ERROR;
 
@@ -896,9 +904,9 @@ static int ms_read_readpage(struct us_data *us, u32 PhyBlockAddr,
        ExtraDat->status0  = 0x10;  /* Not yet,fireware support */
 
        ExtraDat->status1  = 0x00;  /* Not yet,fireware support */
-       ExtraDat->ovrflg   = ExtBuf[0];
-       ExtraDat->mngflg   = ExtBuf[1];
-       ExtraDat->logadr   = memstick_logaddr(ExtBuf[2], ExtBuf[3]);
+       ExtraDat->ovrflg   = bbuf[0];
+       ExtraDat->mngflg   = bbuf[1];
+       ExtraDat->logadr   = memstick_logaddr(bbuf[2], bbuf[3]);
 
        return USB_STOR_TRANSPORT_GOOD;
 }
@@ -1324,8 +1332,9 @@ static int ms_lib_read_extra(struct us_data *us, u32 PhyBlock,
                                u8 PageNum, struct ms_lib_type_extdat *ExtraDat)
 {
        struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+       struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+       u8 *bbuf = info->bbuf;
        int result;
-       u8 ExtBuf[4];
 
        /* printk("MS_LibReadExtra --- PhyBlock = %x, PageNum = %x\n", PhyBlock, PageNum); */
        memset(bcb, 0, sizeof(struct bulk_cb_wrap));
@@ -1340,7 +1349,7 @@ static int ms_lib_read_extra(struct us_data *us, u32 PhyBlock,
        bcb->CDB[2]     = (unsigned char)(PhyBlock>>16);
        bcb->CDB[6]     = 0x01;
 
-       result = ene_send_scsi_cmd(us, FDIR_READ, &ExtBuf, 0);
+       result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
        if (result != USB_STOR_XFER_GOOD)
                return USB_STOR_TRANSPORT_ERROR;
 
@@ -1348,9 +1357,9 @@ static int ms_lib_read_extra(struct us_data *us, u32 PhyBlock,
        ExtraDat->intr     = 0x80;  /* Not yet, waiting for fireware support */
        ExtraDat->status0  = 0x10;  /* Not yet, waiting for fireware support */
        ExtraDat->status1  = 0x00;  /* Not yet, waiting for fireware support */
-       ExtraDat->ovrflg   = ExtBuf[0];
-       ExtraDat->mngflg   = ExtBuf[1];
-       ExtraDat->logadr   = memstick_logaddr(ExtBuf[2], ExtBuf[3]);
+       ExtraDat->ovrflg   = bbuf[0];
+       ExtraDat->mngflg   = bbuf[1];
+       ExtraDat->logadr   = memstick_logaddr(bbuf[2], bbuf[3]);
 
        return USB_STOR_TRANSPORT_GOOD;
 }
@@ -1554,9 +1563,9 @@ static int ms_lib_scan_logicalblocknumber(struct us_data *us, u16 btBlk1st)
        u16 PhyBlock, newblk, i;
        u16 LogStart, LogEnde;
        struct ms_lib_type_extdat extdat;
-       u8 buf[0x200];
        u32 count = 0, index = 0;
        struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+       u8 *bbuf = info->bbuf;
 
        for (PhyBlock = 0; PhyBlock < info->MS_Lib.NumberOfPhyBlock;) {
                ms_lib_phy_to_log_range(PhyBlock, &LogStart, &LogEnde);
@@ -1570,14 +1579,16 @@ static int ms_lib_scan_logicalblocknumber(struct us_data *us, u16 btBlk1st)
                        }
 
                        if (count == PhyBlock) {
-                               ms_lib_read_extrablock(us, PhyBlock, 0, 0x80, &buf);
+                               ms_lib_read_extrablock(us, PhyBlock, 0, 0x80,
+                                               bbuf);
                                count += 0x80;
                        }
                        index = (PhyBlock % 0x80) * 4;
 
-                       extdat.ovrflg = buf[index];
-                       extdat.mngflg = buf[index+1];
-                       extdat.logadr = memstick_logaddr(buf[index+2], buf[index+3]);
+                       extdat.ovrflg = bbuf[index];
+                       extdat.mngflg = bbuf[index+1];
+                       extdat.logadr = memstick_logaddr(bbuf[index+2],
+                                       bbuf[index+3]);
 
                        if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK) {
                                ms_lib_setacquired_errorblock(us, PhyBlock);
@@ -2066,9 +2077,9 @@ static int ene_ms_init(struct us_data *us)
 {
        struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
        int result;
-       u8 buf[0x200];
        u16 MSP_BlockSize, MSP_UserAreaBlocks;
        struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+       u8 *bbuf = info->bbuf;
 
        printk(KERN_INFO "transport --- ENE_MSInit\n");
 
@@ -2087,13 +2098,13 @@ static int ene_ms_init(struct us_data *us)
        bcb->CDB[0]     = 0xF1;
        bcb->CDB[1]     = 0x01;
 
-       result = ene_send_scsi_cmd(us, FDIR_READ, &buf, 0);
+       result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
        if (result != USB_STOR_XFER_GOOD) {
                printk(KERN_ERR "Execution MS Init Code Fail !!\n");
                return USB_STOR_TRANSPORT_ERROR;
        }
        /* the same part to test ENE */
-       info->MS_Status = *(struct MS_STATUS *)&buf[0];
+       info->MS_Status = *(struct MS_STATUS *) bbuf;
 
        if (info->MS_Status.Insert && info->MS_Status.Ready) {
                printk(KERN_INFO "Insert     = %x\n", info->MS_Status.Insert);
@@ -2102,15 +2113,15 @@ static int ene_ms_init(struct us_data *us)
                printk(KERN_INFO "IsMSPHG    = %x\n", info->MS_Status.IsMSPHG);
                printk(KERN_INFO "WtP= %x\n", info->MS_Status.WtP);
                if (info->MS_Status.IsMSPro) {
-                       MSP_BlockSize      = (buf[6] << 8) | buf[7];
-                       MSP_UserAreaBlocks = (buf[10] << 8) | buf[11];
+                       MSP_BlockSize      = (bbuf[6] << 8) | bbuf[7];
+                       MSP_UserAreaBlocks = (bbuf[10] << 8) | bbuf[11];
                        info->MSP_TotalBlock = MSP_BlockSize * MSP_UserAreaBlocks;
                } else {
                        ms_card_init(us); /* Card is MS (to ms.c)*/
                }
                US_DEBUGP("MS Init Code OK !!\n");
        } else {
-               US_DEBUGP("MS Card Not Ready --- %x\n", buf[0]);
+               US_DEBUGP("MS Card Not Ready --- %x\n", bbuf[0]);
                return USB_STOR_TRANSPORT_ERROR;
        }
 
@@ -2120,9 +2131,9 @@ static int ene_ms_init(struct us_data *us)
 static int ene_sd_init(struct us_data *us)
 {
        int result;
-       u8  buf[0x200];
        struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
        struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+       u8 *bbuf = info->bbuf;
 
        US_DEBUGP("transport --- ENE_SDInit\n");
        /* SD Init Part-1 */
@@ -2156,15 +2167,15 @@ static int ene_sd_init(struct us_data *us)
        bcb->Flags              = 0x80;
        bcb->CDB[0]             = 0xF1;
 
-       result = ene_send_scsi_cmd(us, FDIR_READ, &buf, 0);
+       result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
        if (result != USB_STOR_XFER_GOOD) {
                US_DEBUGP("Execution SD Init Code Fail !!\n");
                return USB_STOR_TRANSPORT_ERROR;
        }
 
-       info->SD_Status =  *(struct SD_STATUS *)&buf[0];
+       info->SD_Status =  *(struct SD_STATUS *) bbuf;
        if (info->SD_Status.Insert && info->SD_Status.Ready) {
-               ene_get_card_status(us, (unsigned char *)&buf);
+               ene_get_card_status(us, bbuf);
                US_DEBUGP("Insert     = %x\n", info->SD_Status.Insert);
                US_DEBUGP("Ready      = %x\n", info->SD_Status.Ready);
                US_DEBUGP("IsMMC      = %x\n", info->SD_Status.IsMMC);
@@ -2172,7 +2183,7 @@ static int ene_sd_init(struct us_data *us)
                US_DEBUGP("HiSpeed    = %x\n", info->SD_Status.HiSpeed);
                US_DEBUGP("WtP        = %x\n", info->SD_Status.WtP);
        } else {
-               US_DEBUGP("SD Card Not Ready --- %x\n", buf[0]);
+               US_DEBUGP("SD Card Not Ready --- %x\n", bbuf[0]);
                return USB_STOR_TRANSPORT_ERROR;
        }
        return USB_STOR_TRANSPORT_GOOD;
@@ -2182,13 +2193,15 @@ static int ene_sd_init(struct us_data *us)
 static int ene_init(struct us_data *us)
 {
        int result;
-       u8  misc_reg03 = 0;
+       u8  misc_reg03;
        struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra);
+       u8 *bbuf = info->bbuf;
 
-       result = ene_get_card_type(us, REG_CARD_STATUS, &misc_reg03);
+       result = ene_get_card_type(us, REG_CARD_STATUS, bbuf);
        if (result != USB_STOR_XFER_GOOD)
                return USB_STOR_TRANSPORT_ERROR;
 
+       misc_reg03 = bbuf[0];
        if (misc_reg03 & 0x01) {
                if (!info->SD_Status.Ready) {
                        result = ene_sd_init(us);
@@ -2304,8 +2317,9 @@ static int ene_ub6250_probe(struct usb_interface *intf,
                         const struct usb_device_id *id)
 {
        int result;
-       u8  misc_reg03 = 0;
+       u8  misc_reg03;
        struct us_data *us;
+       struct ene_ub6250_info *info;
 
        result = usb_stor_probe1(&us, intf, id,
                   (id - ene_ub6250_usb_ids) + ene_ub6250_unusual_dev_list);
@@ -2313,11 +2327,16 @@ static int ene_ub6250_probe(struct usb_interface *intf,
                return result;
 
        /* FIXME: where should the code alloc extra buf ? */
-       if (!us->extra) {
-               us->extra = kzalloc(sizeof(struct ene_ub6250_info), GFP_KERNEL);
-               if (!us->extra)
-                       return -ENOMEM;
-               us->extra_destructor = ene_ub6250_info_destructor;
+       us->extra = kzalloc(sizeof(struct ene_ub6250_info), GFP_KERNEL);
+       if (!us->extra)
+               return -ENOMEM;
+       us->extra_destructor = ene_ub6250_info_destructor;
+
+       info = (struct ene_ub6250_info *)(us->extra);
+       info->bbuf = kmalloc(512, GFP_KERNEL);
+       if (!info->bbuf) {
+               kfree(us->extra);
+               return -ENOMEM;
        }
 
        us->transport_name = "ene_ub6250";
@@ -2329,12 +2348,13 @@ static int ene_ub6250_probe(struct usb_interface *intf,
                return result;
 
        /* probe card type */
-       result = ene_get_card_type(us, REG_CARD_STATUS, &misc_reg03);
+       result = ene_get_card_type(us, REG_CARD_STATUS, info->bbuf);
        if (result != USB_STOR_XFER_GOOD) {
                usb_stor_disconnect(intf);
                return USB_STOR_TRANSPORT_ERROR;
        }
 
+       misc_reg03 = info->bbuf[0];
        if (!(misc_reg03 & 0x01)) {
                pr_info("ums_eneub6250: The driver only supports SD/MS card. "
                        "To use SM card, please build driver/staging/keucr\n");
index b71291b..a0102f8 100644 (file)
@@ -341,6 +341,7 @@ error_submit_ep1:
 static
 int i1480_usb_probe(struct usb_interface *iface, const struct usb_device_id *id)
 {
+       struct usb_device *udev = interface_to_usbdev(iface);
        struct i1480_usb *i1480_usb;
        struct i1480 *i1480;
        struct device *dev = &iface->dev;
@@ -352,8 +353,8 @@ int i1480_usb_probe(struct usb_interface *iface, const struct usb_device_id *id)
                        iface->cur_altsetting->desc.bInterfaceNumber);
                goto error;
        }
-       if (iface->num_altsetting > 1
-           && interface_to_usbdev(iface)->descriptor.idProduct == 0xbabe) {
+       if (iface->num_altsetting > 1 &&
+                       le16_to_cpu(udev->descriptor.idProduct) == 0xbabe) {
                /* Need altsetting #1 [HW QUIRK] or EP1 won't work */
                result = usb_set_interface(interface_to_usbdev(iface), 0, 1);
                if (result < 0)
index d83e967..e6d0836 100644 (file)
@@ -683,8 +683,6 @@ config FB_STI
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select STI_CONSOLE
-       select VT
        default y
        ---help---
          STI refers to the HP "Standard Text Interface" which is a set of
index 9b9d8ff..7177a9d 100644 (file)
@@ -12,6 +12,7 @@ fb-y                              := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
 fb-objs                           := $(fb-y)
 
 obj-$(CONFIG_VT)                 += console/
+obj-$(CONFIG_FB_STI)             += console/
 obj-$(CONFIG_LOGO)               += logo/
 obj-y                            += backlight/ display/
 
index 748a74b..7da3298 100644 (file)
@@ -641,6 +641,9 @@ static int usb_pcwd_probe(struct usb_interface *interface,
                return -ENODEV;
        }
 
+       if (iface_desc->desc.bNumEndpoints < 1)
+               return -ENODEV;
+
        /* check out the endpoint: it has to be Interrupt & IN */
        endpoint = &iface_desc->endpoint[0].desc;
 
index ba6eda4..0d23e1f 100644 (file)
@@ -8,6 +8,5 @@ bool xen_biovec_phys_mergeable(const struct bio_vec *vec1,
        unsigned long mfn1 = pfn_to_mfn(page_to_pfn(vec1->bv_page));
        unsigned long mfn2 = pfn_to_mfn(page_to_pfn(vec2->bv_page));
 
-       return __BIOVEC_PHYS_MERGEABLE(vec1, vec2) &&
-               ((mfn1 == mfn2) || ((mfn1+1) == mfn2));
+       return mfn1 + PFN_DOWN(vec1->bv_offset + vec1->bv_len) == mfn2;
 }
index 0769e2e..ebedfb7 100644 (file)
@@ -345,7 +345,7 @@ static int autofs_dev_ioctl_fail(struct file *fp,
        int status;
 
        token = (autofs_wqt_t) param->fail.token;
-       status = param->fail.status ? param->fail.status : -ENOENT;
+       status = param->fail.status < 0 ? param->fail.status : -ENOENT;
        return autofs4_wait_release(sbi, token, status);
 }
 
index 555b576..c6b8cbc 100644 (file)
@@ -764,6 +764,9 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
        if (rc)
                return rc;
 
+       if (server->capabilities & CAP_UNICODE)
+               smb->hdr.Flags2 |= SMBFLG2_UNICODE;
+
        /* set up echo request */
        smb->hdr.Tid = 0xffff;
        smb->hdr.WordCount = 1;
index 73e47e8..3732f79 100644 (file)
@@ -974,10 +974,10 @@ struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
                cERROR(1, "illegal hours %d", st->Hours);
        days = sd->Day;
        month = sd->Month;
-       if ((days > 31) || (month > 12)) {
+       if (days < 1 || days > 31 || month < 1 || month > 12) {
                cERROR(1, "illegal date, month %d day: %d", month, days);
-               if (month > 12)
-                       month = 12;
+               days = clamp(days, 1, 31);
+               month = clamp(month, 1, 12);
        }
        month -= 1;
        days += total_days_of_prev_months[month];
index 0f3eb41..5ffc3f6 100644 (file)
@@ -83,14 +83,13 @@ static int create_link(struct config_item *parent_item,
        ret = -ENOMEM;
        sl = kmalloc(sizeof(struct configfs_symlink), GFP_KERNEL);
        if (sl) {
-               sl->sl_target = config_item_get(item);
                spin_lock(&configfs_dirent_lock);
                if (target_sd->s_type & CONFIGFS_USET_DROPPING) {
                        spin_unlock(&configfs_dirent_lock);
-                       config_item_put(item);
                        kfree(sl);
                        return -ENOENT;
                }
+               sl->sl_target = config_item_get(item);
                list_add(&sl->sl_list, &target_sd->s_links);
                spin_unlock(&configfs_dirent_lock);
                ret = configfs_create_link(sl, parent_item->ci_dentry,
index bb40a70..aa54e82 100644 (file)
@@ -5023,6 +5023,8 @@ out:
        ext4_orphan_del(handle, inode);
        inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
        ext4_mark_inode_dirty(handle, inode);
+       if (err >= 0)
+               ext4_update_inode_fsync_trans(handle, inode, 1);
        ext4_journal_stop(handle);
        return err;
 }
index f881e34..fde77a7 100644 (file)
@@ -1344,7 +1344,6 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
        int ret = 0, err, nr_pages, i;
        struct inode *inode = mpd->inode;
        struct address_space *mapping = inode->i_mapping;
-       loff_t size = i_size_read(inode);
        unsigned int len, block_start;
        struct buffer_head *bh, *page_bufs = NULL;
        int journal_data = ext4_should_journal_data(inode);
@@ -1370,6 +1369,7 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
                for (i = 0; i < nr_pages; i++) {
                        int commit_write = 0, skip_page = 0;
                        struct page *page = pvec.pages[i];
+                       loff_t size = i_size_read(inode);
 
                        index = page->index;
                        if (index > end)
@@ -1443,11 +1443,31 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
                        if (skip_page)
                                goto skip_page;
 
+                       clear_page_dirty_for_io(page);
+                       /*
+                        * We have to be very careful here!  Nothing protects
+                        * writeback path against i_size changes and the page
+                        * can be writeably mapped into page tables. So an
+                        * application can be growing i_size and writing data
+                        * through mmap while writeback runs.
+                        * clear_page_dirty_for_io() write-protects our page in
+                        * page tables and the page cannot get written to again
+                        * until we release page lock. So only after
+                        * clear_page_dirty_for_io() we are safe to sample
+                        * i_size for ext4_bio_write_page() to zero-out tail of
+                        * the written page. We rely on the barrier provided by
+                        * TestClearPageDirty in clear_page_dirty_for_io() to
+                        * make sure i_size is really sampled only after page
+                        * tables are updated.
+                        */
+                       if (size != i_size_read(inode)) {
+                               set_page_dirty(page);
+                               goto skip_page;
+                       }
+
                        if (commit_write)
                                /* mark the buffer_heads as dirty & uptodate */
                                block_commit_write(page, 0, len);
-
-                       clear_page_dirty_for_io(page);
                        /*
                         * Delalloc doesn't support data journalling,
                         * but eventually maybe we'll lift this
@@ -4637,8 +4657,9 @@ static int ext4_expand_extra_isize(struct inode *inode,
        /* No extended attributes present */
        if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR) ||
            header->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC)) {
-               memset((void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE, 0,
-                       new_extra_isize);
+               memset((void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE +
+                      EXT4_I(inode)->i_extra_isize, 0,
+                      new_extra_isize - EXT4_I(inode)->i_extra_isize);
                EXT4_I(inode)->i_extra_isize = new_extra_isize;
                return 0;
        }
index 18c58e5..66897c9 100644 (file)
@@ -457,8 +457,10 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
 
        if (info) {
                struct partition_meta_info *pinfo = alloc_part_info(disk);
-               if (!pinfo)
+               if (!pinfo) {
+                       err = -ENOMEM;
                        goto out_free_stats;
+               }
                memcpy(pinfo, info, sizeof(*info));
                p->info = pinfo;
        }
index 439b5a1..b83dcbb 100644 (file)
@@ -380,7 +380,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
 
        state = *get_task_state(task);
        vsize = eip = esp = 0;
-       permitted = ptrace_may_access(task, PTRACE_MODE_READ);
+       permitted = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
        mm = get_task_mm(task);
        if (mm) {
                vsize = task_vsize(mm);
index f0a3ea3..51be1ce 100644 (file)
@@ -216,7 +216,7 @@ static struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
 
 struct mm_struct *mm_for_maps(struct task_struct *task)
 {
-       return mm_access(task, PTRACE_MODE_READ);
+       return mm_access(task, PTRACE_MODE_READ_FSCREDS);
 }
 
 static int proc_pid_cmdline(struct task_struct *task, char * buffer)
@@ -288,7 +288,7 @@ static int proc_pid_wchan(struct task_struct *task, char *buffer)
        wchan = get_wchan(task);
 
        if (lookup_symbol_name(wchan, symname) < 0)
-               if (!ptrace_may_access(task, PTRACE_MODE_READ))
+               if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
                        return 0;
                else
                        return sprintf(buffer, "%lu", wchan);
@@ -302,7 +302,7 @@ static int lock_trace(struct task_struct *task)
        int err = mutex_lock_killable(&task->signal->cred_guard_mutex);
        if (err)
                return err;
-       if (!ptrace_may_access(task, PTRACE_MODE_ATTACH)) {
+       if (!ptrace_may_access(task, PTRACE_MODE_ATTACH_FSCREDS)) {
                mutex_unlock(&task->signal->cred_guard_mutex);
                return -EPERM;
        }
@@ -544,7 +544,7 @@ static int proc_fd_access_allowed(struct inode *inode)
         */
        task = get_proc_task(inode);
        if (task) {
-               allowed = ptrace_may_access(task, PTRACE_MODE_READ);
+               allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
                put_task_struct(task);
        }
        return allowed;
@@ -769,7 +769,7 @@ static int mem_open(struct inode* inode, struct file* file)
        if (!task)
                return -ESRCH;
 
-       mm = mm_access(task, PTRACE_MODE_ATTACH);
+       mm = mm_access(task, PTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS);
        put_task_struct(task);
 
        if (IS_ERR(mm))
@@ -2627,7 +2627,7 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
        if (result)
                return result;
 
-       if (!ptrace_may_access(task, PTRACE_MODE_READ)) {
+       if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
                result = -EACCES;
                goto out_unlock;
        }
index d6c078e..50de28b 100644 (file)
@@ -91,7 +91,7 @@ static int proc_ns_dir_readdir(struct file *filp, void *dirent,
                goto out_no_task;
 
        ret = -EPERM;
-       if (!ptrace_may_access(task, PTRACE_MODE_READ))
+       if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
                goto out;
 
        ret = 0;
@@ -154,7 +154,7 @@ static struct dentry *proc_ns_dir_lookup(struct inode *dir,
                goto out_no_task;
 
        error = ERR_PTR(-EPERM);
-       if (!ptrace_may_access(task, PTRACE_MODE_READ))
+       if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
                goto out;
 
        last = &ns_entries[ARRAY_SIZE(ns_entries) - 1];
index 113208c..b2c7dd7 100644 (file)
@@ -34,6 +34,7 @@ struct timerfd_ctx {
        int clockid;
        struct rcu_head rcu;
        struct list_head clist;
+       spinlock_t cancel_lock;
        bool might_cancel;
 };
 
@@ -86,7 +87,7 @@ void timerfd_clock_was_set(void)
        rcu_read_unlock();
 }
 
-static void timerfd_remove_cancel(struct timerfd_ctx *ctx)
+static void __timerfd_remove_cancel(struct timerfd_ctx *ctx)
 {
        if (ctx->might_cancel) {
                ctx->might_cancel = false;
@@ -96,6 +97,13 @@ static void timerfd_remove_cancel(struct timerfd_ctx *ctx)
        }
 }
 
+static void timerfd_remove_cancel(struct timerfd_ctx *ctx)
+{
+       spin_lock(&ctx->cancel_lock);
+       __timerfd_remove_cancel(ctx);
+       spin_unlock(&ctx->cancel_lock);
+}
+
 static bool timerfd_canceled(struct timerfd_ctx *ctx)
 {
        if (!ctx->might_cancel || ctx->moffs.tv64 != KTIME_MAX)
@@ -106,6 +114,7 @@ static bool timerfd_canceled(struct timerfd_ctx *ctx)
 
 static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags)
 {
+       spin_lock(&ctx->cancel_lock);
        if (ctx->clockid == CLOCK_REALTIME && (flags & TFD_TIMER_ABSTIME) &&
            (flags & TFD_TIMER_CANCEL_ON_SET)) {
                if (!ctx->might_cancel) {
@@ -114,9 +123,10 @@ static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags)
                        list_add_rcu(&ctx->clist, &cancel_list);
                        spin_unlock(&cancel_lock);
                }
-       } else if (ctx->might_cancel) {
-               timerfd_remove_cancel(ctx);
+       } else {
+               __timerfd_remove_cancel(ctx);
        }
+       spin_unlock(&ctx->cancel_lock);
 }
 
 static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx)
@@ -268,6 +278,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
                return -ENOMEM;
 
        init_waitqueue_head(&ctx->wqh);
+       spin_lock_init(&ctx->cancel_lock);
        ctx->clockid = clockid;
        hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS);
        ctx->moffs = ktime_get_monotonic_offset();
index 879b134..56947d3 100644 (file)
@@ -890,7 +890,10 @@ void ufs_evict_inode(struct inode * inode)
                ufs_update_inode(inode, IS_SYNC(inode));
                old_i_size = inode->i_size;
                inode->i_size = 0;
-               if (inode->i_blocks && ufs_truncate(inode, old_i_size))
+               if (inode->i_blocks &&
+                   (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+                    S_ISLNK(inode->i_mode)) &&
+                   ufs_truncate(inode, old_i_size))
                        ufs_warning(inode->i_sb, __func__, "ufs_truncate failed\n");
                unlock_ufs(inode->i_sb);
        }
index 3915ade..c7090f5 100644 (file)
@@ -695,6 +695,23 @@ static void ufs_put_super_internal(struct super_block *sb)
        UFSD("EXIT\n");
 }
 
+static u64 ufs_max_bytes(struct super_block *sb)
+{
+       struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
+       int bits = uspi->s_apbshift;
+       u64 res;
+
+       if (bits > 21)
+               res = ~0ULL;
+       else
+               res = UFS_NDADDR + (1LL << bits) + (1LL << (2*bits)) +
+                       (1LL << (3*bits));
+
+       if (res >= (MAX_LFS_FILESIZE >> uspi->s_bshift))
+               return MAX_LFS_FILESIZE;
+       return res << uspi->s_bshift;
+}
+
 static int ufs_fill_super(struct super_block *sb, void *data, int silent)
 {
        struct ufs_sb_info * sbi;
@@ -1157,6 +1174,7 @@ magic_found:
                            "fast symlink size (%u)\n", uspi->s_maxsymlinklen);
                uspi->s_maxsymlinklen = maxsymlen;
        }
+       sb->s_maxbytes = ufs_max_bytes(sb);
 
        inode = ufs_iget(sb, UFS_ROOTINO);
        if (IS_ERR(inode)) {
index 92cde99..93bc59c 100644 (file)
@@ -451,12 +451,6 @@ int ufs_truncate(struct inode *inode, loff_t old_i_size)
             inode->i_ino, (unsigned long long)i_size_read(inode),
             (unsigned long long)old_i_size);
 
-       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
-             S_ISLNK(inode->i_mode)))
-               return -EINVAL;
-       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
-               return -EPERM;
-
        err = ufs_alloc_lastblock(inode);
 
        if (err) {
index 9541759..3f9463f 100644 (file)
@@ -473,15 +473,19 @@ static inline unsigned _ubh_find_last_zero_bit_(
 static inline int _ubh_isblockset_(struct ufs_sb_private_info * uspi,
        struct ufs_buffer_head * ubh, unsigned begin, unsigned block)
 {
+       u8 mask;
        switch (uspi->s_fpb) {
        case 8:
                return (*ubh_get_addr (ubh, begin + block) == 0xff);
        case 4:
-               return (*ubh_get_addr (ubh, begin + (block >> 1)) == (0x0f << ((block & 0x01) << 2)));
+               mask = 0x0f << ((block & 0x01) << 2);
+               return (*ubh_get_addr (ubh, begin + (block >> 1)) & mask) == mask;
        case 2:
-               return (*ubh_get_addr (ubh, begin + (block >> 2)) == (0x03 << ((block & 0x03) << 1)));
+               mask = 0x03 << ((block & 0x03) << 1);
+               return (*ubh_get_addr (ubh, begin + (block >> 2)) & mask) == mask;
        case 1:
-               return (*ubh_get_addr (ubh, begin + (block >> 3)) == (0x01 << (block & 0x07)));
+               mask = 0x01 << (block & 0x07);
+               return (*ubh_get_addr (ubh, begin + (block >> 3)) & mask) == mask;
        }
        return 0;       
 }
index dce6e4d..8e44d73 100644 (file)
@@ -292,7 +292,9 @@ extern int proc_kprobes_optimization_handler(struct ctl_table *table,
                                             int write, void __user *buffer,
                                             size_t *length, loff_t *ppos);
 #endif
-
+extern void wait_for_kprobe_optimizer(void);
+#else
+static inline void wait_for_kprobe_optimizer(void) { }
 #endif /* CONFIG_OPTPROBES */
 
 /* Get the kprobe at this addr (if any) - called with preemption disabled */
index 0d3dd66..95b615a 100644 (file)
@@ -83,6 +83,15 @@ enum ip_conntrack_status {
        /* Conntrack is a fake untracked entry */
        IPS_UNTRACKED_BIT = 12,
        IPS_UNTRACKED = (1 << IPS_UNTRACKED_BIT),
+
+       /* Be careful here, modifying these bits can make things messy,
+        * so don't let users modify them directly.
+        */
+       IPS_UNCHANGEABLE_MASK = (IPS_NAT_DONE_MASK | IPS_NAT_MASK |
+                                IPS_EXPECTED | IPS_CONFIRMED | IPS_DYING |
+                                IPS_SEQ_ADJUST | IPS_TEMPLATE),
+
+       __IPS_MAX_BIT = 13,
 };
 
 /* Connection tracking event types */
index e49240b..9531936 100644 (file)
@@ -130,9 +130,31 @@ extern void __ptrace_unlink(struct task_struct *child);
 extern void exit_ptrace(struct task_struct *tracer);
 #define PTRACE_MODE_READ   1
 #define PTRACE_MODE_ATTACH 2
+#define PTRACE_MODE_FSCREDS 0x08
+#define PTRACE_MODE_REALCREDS 0x10
+
+/* shorthands for READ/ATTACH and FSCREDS/REALCREDS combinations */
+#define PTRACE_MODE_READ_FSCREDS (PTRACE_MODE_READ | PTRACE_MODE_FSCREDS)
+#define PTRACE_MODE_READ_REALCREDS (PTRACE_MODE_READ | PTRACE_MODE_REALCREDS)
+#define PTRACE_MODE_ATTACH_FSCREDS (PTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS)
+#define PTRACE_MODE_ATTACH_REALCREDS (PTRACE_MODE_ATTACH | PTRACE_MODE_REALCREDS)
+
 /* Returns 0 on success, -errno on denial. */
 extern int __ptrace_may_access(struct task_struct *task, unsigned int mode);
-/* Returns true on success, false on denial. */
+/**
+ * ptrace_may_access - check whether the caller is permitted to access
+ * a target task.
+ * @task: target task
+ * @mode: selects type of access and caller credentials
+ *
+ * Returns true on success, false on denial.
+ *
+ * One of the flags PTRACE_MODE_FSCREDS and PTRACE_MODE_REALCREDS must
+ * be set in @mode to specify whether the access was requested through
+ * a filesystem syscall (should use effective capabilities and fsuid
+ * of the caller) or through an explicit syscall such as
+ * process_vm_writev or ptrace (and should use the real credentials).
+ */
 extern bool ptrace_may_access(struct task_struct *task, unsigned int mode);
 
 static inline int ptrace_reparented(struct task_struct *child)
index 2af31eb..42e067b 100644 (file)
@@ -534,6 +534,7 @@ static inline struct rtable *skb_rtable(const struct sk_buff *skb)
 }
 
 extern void kfree_skb(struct sk_buff *skb);
+extern void kfree_skb_list(struct sk_buff *segs);
 extern void consume_skb(struct sk_buff *skb);
 extern void           __kfree_skb(struct sk_buff *skb);
 extern struct sk_buff *__alloc_skb(unsigned int size,
index 1eb735b..5c62734 100644 (file)
@@ -11,6 +11,9 @@
 
 #include <linux/types.h>       /* __u8 etc */
 
+/* See USB 3.1 spec Table 10-5 */
+#define USB_SS_MAXPORTS                15
+
 /*
  * Hub request types
  */
index 921f627..9e5f337 100644 (file)
@@ -925,10 +925,6 @@ struct xfrm_dst {
        struct flow_cache_object flo;
        struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
        int num_pols, num_xfrms;
-#ifdef CONFIG_XFRM_SUB_POLICY
-       struct flowi *origin;
-       struct xfrm_selector *partner;
-#endif
        u32 xfrm_genid;
        u32 policy_genid;
        u32 route_mtu_cached;
@@ -944,12 +940,6 @@ static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
        dst_release(xdst->route);
        if (likely(xdst->u.dst.xfrm))
                xfrm_state_put(xdst->u.dst.xfrm);
-#ifdef CONFIG_XFRM_SUB_POLICY
-       kfree(xdst->origin);
-       xdst->origin = NULL;
-       kfree(xdst->partner);
-       xdst->partner = NULL;
-#endif
 }
 #endif
 
index 5b4293d..081a2d7 100644 (file)
@@ -1095,8 +1095,10 @@ retry:
 
                        timeo = MAX_SCHEDULE_TIMEOUT;
                        ret = netlink_attachskb(sock, nc, &timeo, NULL);
-                       if (ret == 1)
+                       if (ret == 1) {
+                               sock = NULL;
                                goto retry;
+                       }
                        if (ret) {
                                sock = NULL;
                                nc = NULL;
index cd4f88a..bc94278 100644 (file)
@@ -3004,7 +3004,7 @@ find_lively_task_by_vpid(pid_t vpid)
 
        /* Reuse ptrace permission checks for now. */
        err = -EACCES;
-       if (!ptrace_may_access(task, PTRACE_MODE_READ))
+       if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS))
                goto errout;
 
        return task;
index bbd3601..3854e75 100644 (file)
@@ -2627,7 +2627,7 @@ SYSCALL_DEFINE3(get_robust_list, int, pid,
        }
 
        ret = -EPERM;
-       if (!ptrace_may_access(p, PTRACE_MODE_READ))
+       if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS))
                goto err_unlock;
 
        head = p->robust_list;
index a9642d5..e07b64b 100644 (file)
@@ -154,7 +154,7 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
        }
 
        ret = -EPERM;
-       if (!ptrace_may_access(p, PTRACE_MODE_READ))
+       if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS))
                goto err_unlock;
 
        head = p->compat_robust_list;
index bc90b87..a4f561a 100644 (file)
@@ -598,7 +598,7 @@ static __kprobes void kprobe_optimizer(struct work_struct *work)
 }
 
 /* Wait for completing optimization and unoptimization */
-static __kprobes void wait_for_kprobe_optimizer(void)
+__kprobes void wait_for_kprobe_optimizer(void)
 {
        if (delayed_work_pending(&optimizing_work))
                wait_for_completion(&optimizer_comp);
index b452599..0f4bd70 100644 (file)
@@ -369,7 +369,7 @@ static int padata_setup_cpumasks(struct parallel_data *pd,
 
        cpumask_and(pd->cpumask.pcpu, pcpumask, cpu_active_mask);
        if (!alloc_cpumask_var(&pd->cpumask.cbcpu, GFP_KERNEL)) {
-               free_cpumask_var(pd->cpumask.cbcpu);
+               free_cpumask_var(pd->cpumask.pcpu);
                return -ENOMEM;
        }
 
index fd3909b..b50cded 100644 (file)
@@ -220,6 +220,14 @@ int ptrace_check_attach(struct task_struct *child, bool ignore_state)
 int __ptrace_may_access(struct task_struct *task, unsigned int mode)
 {
        const struct cred *cred = current_cred(), *tcred;
+       int dumpable = 0;
+       uid_t caller_uid;
+       gid_t caller_gid;
+
+       if (!(mode & PTRACE_MODE_FSCREDS) == !(mode & PTRACE_MODE_REALCREDS)) {
+               WARN(1, "denying ptrace access check without PTRACE_MODE_*CREDS\n");
+               return -EPERM;
+       }
 
        /* May we inspect the given task?
         * This check is used both for attaching with ptrace
@@ -229,19 +237,34 @@ int __ptrace_may_access(struct task_struct *task, unsigned int mode)
         * because setting up the necessary parent/child relationship
         * or halting the specified task is impossible.
         */
-       int dumpable = 0;
+
        /* Don't let security modules deny introspection */
        if (same_thread_group(task, current))
                return 0;
        rcu_read_lock();
+       if (mode & PTRACE_MODE_FSCREDS) {
+               caller_uid = cred->fsuid;
+               caller_gid = cred->fsgid;
+       } else {
+               /*
+                * Using the euid would make more sense here, but something
+                * in userland might rely on the old behavior, and this
+                * shouldn't be a security problem since
+                * PTRACE_MODE_REALCREDS implies that the caller explicitly
+                * used a syscall that requests access to another process
+                * (and not a filesystem syscall to procfs).
+                */
+               caller_uid = cred->uid;
+               caller_gid = cred->gid;
+       }
        tcred = __task_cred(task);
        if (cred->user->user_ns == tcred->user->user_ns &&
-           (cred->uid == tcred->euid &&
-            cred->uid == tcred->suid &&
-            cred->uid == tcred->uid  &&
-            cred->gid == tcred->egid &&
-            cred->gid == tcred->sgid &&
-            cred->gid == tcred->gid))
+           (caller_uid == tcred->euid &&
+            caller_uid == tcred->suid &&
+            caller_uid == tcred->uid  &&
+            caller_gid == tcred->egid &&
+            caller_gid == tcred->sgid &&
+            caller_gid == tcred->gid))
                goto ok;
        if (ns_capable(tcred->user->user_ns, CAP_SYS_PTRACE))
                goto ok;
@@ -308,7 +331,7 @@ static int ptrace_attach(struct task_struct *task, long request,
                goto out;
 
        task_lock(task);
-       retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH);
+       retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH_REALCREDS);
        task_unlock(task);
        if (retval)
                goto unlock_creds;
index 6c4cc94..82a3d92 100644 (file)
@@ -535,7 +535,8 @@ unblock_all_signals(void)
        spin_unlock_irqrestore(&current->sighand->siglock, flags);
 }
 
-static void collect_signal(int sig, struct sigpending *list, siginfo_t *info)
+static void collect_signal(int sig, struct sigpending *list, siginfo_t *info,
+                          bool *resched_timer)
 {
        struct sigqueue *q, *first = NULL;
 
@@ -557,6 +558,12 @@ static void collect_signal(int sig, struct sigpending *list, siginfo_t *info)
 still_pending:
                list_del_init(&first->list);
                copy_siginfo(info, &first->info);
+
+               *resched_timer =
+                       (first->flags & SIGQUEUE_PREALLOC) &&
+                       (info->si_code == SI_TIMER) &&
+                       (info->si_sys_private);
+
                __sigqueue_free(first);
        } else {
                /*
@@ -573,7 +580,7 @@ still_pending:
 }
 
 static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
-                       siginfo_t *info)
+                       siginfo_t *info, bool *resched_timer)
 {
        int sig = next_signal(pending, mask);
 
@@ -587,7 +594,7 @@ static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
                        }
                }
 
-               collect_signal(sig, pending, info);
+               collect_signal(sig, pending, info, resched_timer);
        }
 
        return sig;
@@ -601,15 +608,16 @@ static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
  */
 int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
 {
+       bool resched_timer = false;
        int signr;
 
        /* We only dequeue private signals from ourselves, we don't let
         * signalfd steal them
         */
-       signr = __dequeue_signal(&tsk->pending, mask, info);
+       signr = __dequeue_signal(&tsk->pending, mask, info, &resched_timer);
        if (!signr) {
                signr = __dequeue_signal(&tsk->signal->shared_pending,
-                                        mask, info);
+                                        mask, info, &resched_timer);
                /*
                 * itimer signal ?
                 *
@@ -654,7 +662,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
                 */
                current->jobctl |= JOBCTL_STOP_DEQUEUED;
        }
-       if ((info->si_code & __SI_MASK) == __SI_TIMER && info->si_sys_private) {
+       if (resched_timer) {
                /*
                 * Release the siglock to ensure proper locking order
                 * of timer locks outside of siglocks.  Note, we leave
index 7eaf162..c82900c 100644 (file)
@@ -419,7 +419,7 @@ u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval)
                overrun++;
        }
 
-       alarm->node.expires = ktime_add(alarm->node.expires, interval);
+       alarm->node.expires = ktime_add_safe(alarm->node.expires, interval);
        return overrun;
 }
 
@@ -598,13 +598,21 @@ static int alarm_timer_set(struct k_itimer *timr, int flags,
 
        /* start the timer */
        timr->it.alarm.interval = timespec_to_ktime(new_setting->it_interval);
+
+       /*
+        * Rate limit to the tick as a hot fix to prevent DOS. Will be
+        * mopped up later.
+        */
+       if (ktime_to_ns(timr->it.alarm.interval) < TICK_NSEC)
+               timr->it.alarm.interval = ktime_set(1, 0);
+
        exp = timespec_to_ktime(new_setting->it_value);
        /* Convert (if necessary) to absolute time */
        if (flags != TIMER_ABSTIME) {
                ktime_t now;
 
                now = alarm_bases[timr->it.alarm.alarmtimer.type].gettime();
-               exp = ktime_add(now, exp);
+               exp = ktime_add_safe(now, exp);
        }
 
        alarm_start(&timr->it.alarm.alarmtimer, exp);
index 00d527c..2ec1a38 100644 (file)
@@ -1225,24 +1225,21 @@ static int create_trace_probe(int argc, char **argv)
                pr_info("Probe point is not specified.\n");
                return -EINVAL;
        }
-       if (isdigit(argv[1][0])) {
+
+       /* try to parse an address. if that fails, try to read the
+        * input as a symbol. */
+       if (!strict_strtoul(argv[1], 0, (unsigned long *)&addr)) {
                if (is_return) {
                        pr_info("Return probe point must be a symbol.\n");
                        return -EINVAL;
                }
-               /* an address specified */
-               ret = strict_strtoul(&argv[1][0], 0, (unsigned long *)&addr);
-               if (ret) {
-                       pr_info("Failed to parse address.\n");
-                       return ret;
-               }
        } else {
                /* a symbol specified */
                symbol = argv[1];
                /* TODO: support .init module functions */
                ret = split_symbol_offset(symbol, &offset);
                if (ret) {
-                       pr_info("Failed to parse symbol.\n");
+                       pr_info("Failed to parse either an address or a symbol.\n");
                        return ret;
                }
                if (offset && is_return) {
@@ -2109,6 +2106,11 @@ static __init int kprobe_trace_self_tests_init(void)
 
 end:
        release_all_trace_probes();
+       /*
+        * Wait for the optimizer work to finish. Otherwise it might fiddle
+        * with probes in already freed __init text.
+        */
+       wait_for_kprobe_optimizer();
        if (warn)
                pr_cont("NG: Some tests are failed. Please check them.\n");
        else
index f5f3ad8..82c466f 100644 (file)
  *     the values[M, M+1, ..., N] into the ints array in get_options.
  */
 
-static int get_range(char **str, int *pint)
+static int get_range(char **str, int *pint, int n)
 {
        int x, inc_counter, upper_range;
 
        (*str)++;
        upper_range = simple_strtol((*str), NULL, 0);
        inc_counter = upper_range - *pint;
-       for (x = *pint; x < upper_range; x++)
+       for (x = *pint; n && x < upper_range; x++, n--)
                *pint++ = x;
        return inc_counter;
 }
@@ -95,7 +95,7 @@ char *get_options(const char *str, int nints, int *ints)
                        break;
                if (res == 3) {
                        int range_nums;
-                       range_nums = get_range((char **)&str, ints + i);
+                       range_nums = get_range((char **)&str, ints + i, nints - i);
                        if (range_nums < 0)
                                break;
                        /*
index c555935..c8e4ebe 100644 (file)
@@ -1334,12 +1334,9 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pid, unsigned long, maxnode,
                err = -ESRCH;
                goto out;
        }
-       mm = get_task_mm(task);
-       rcu_read_unlock();
+       get_task_struct(task);
 
        err = -EINVAL;
-       if (!mm)
-               goto out;
 
        /*
         * Check if this process has the right to modify the specified
@@ -1347,14 +1344,13 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pid, unsigned long, maxnode,
         * capabilities, superuser privileges or the same
         * userid as the target process.
         */
-       rcu_read_lock();
        tcred = __task_cred(task);
        if (cred->euid != tcred->suid && cred->euid != tcred->uid &&
            cred->uid  != tcred->suid && cred->uid  != tcred->uid &&
            !capable(CAP_SYS_NICE)) {
                rcu_read_unlock();
                err = -EPERM;
-               goto out;
+               goto out_put;
        }
        rcu_read_unlock();
 
@@ -1362,26 +1358,39 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pid, unsigned long, maxnode,
        /* Is the user allowed to access the target nodes? */
        if (!nodes_subset(*new, task_nodes) && !capable(CAP_SYS_NICE)) {
                err = -EPERM;
-               goto out;
+               goto out_put;
        }
 
        if (!nodes_subset(*new, node_states[N_HIGH_MEMORY])) {
                err = -EINVAL;
-               goto out;
+               goto out_put;
        }
 
        err = security_task_movememory(task);
        if (err)
+               goto out_put;
+
+       mm = get_task_mm(task);
+       put_task_struct(task);
+
+       if (!mm) {
+               err = -EINVAL;
                goto out;
+       }
 
        err = do_migrate_pages(mm, old, new,
                capable(CAP_SYS_NICE) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE);
+
+       mmput(mm);
 out:
-       if (mm)
-               mmput(mm);
        NODEMASK_SCRATCH_FREE(scratch);
 
        return err;
+
+out_put:
+       put_task_struct(task);
+       goto out;
+
 }
 
 
index f2d86f2..3f95bab 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/syscalls.h>
 #include <linux/hugetlb.h>
 #include <linux/gfp.h>
+#include <linux/ptrace.h>
 
 #include <asm/tlbflush.h>
 
@@ -1198,20 +1199,17 @@ set_status:
  * Migrate an array of page address onto an array of nodes and fill
  * the corresponding array of status.
  */
-static int do_pages_move(struct mm_struct *mm, struct task_struct *task,
+static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
                         unsigned long nr_pages,
                         const void __user * __user *pages,
                         const int __user *nodes,
                         int __user *status, int flags)
 {
        struct page_to_node *pm;
-       nodemask_t task_nodes;
        unsigned long chunk_nr_pages;
        unsigned long chunk_start;
        int err;
 
-       task_nodes = cpuset_mems_allowed(task);
-
        err = -ENOMEM;
        pm = (struct page_to_node *)__get_free_page(GFP_KERNEL);
        if (!pm)
@@ -1369,10 +1367,10 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
                const int __user *, nodes,
                int __user *, status, int, flags)
 {
-       const struct cred *cred = current_cred(), *tcred;
        struct task_struct *task;
        struct mm_struct *mm;
        int err;
+       nodemask_t task_nodes;
 
        /* Check flags */
        if (flags & ~(MPOL_MF_MOVE|MPOL_MF_MOVE_ALL))
@@ -1388,23 +1386,13 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
                rcu_read_unlock();
                return -ESRCH;
        }
-       mm = get_task_mm(task);
-       rcu_read_unlock();
-
-       if (!mm)
-               return -EINVAL;
+       get_task_struct(task);
 
        /*
         * Check if this process has the right to modify the specified
-        * process. The right exists if the process has administrative
-        * capabilities, superuser privileges or the same
-        * userid as the target process.
+        * process. Use the regular "ptrace_may_access()" checks.
         */
-       rcu_read_lock();
-       tcred = __task_cred(task);
-       if (cred->euid != tcred->suid && cred->euid != tcred->uid &&
-           cred->uid  != tcred->suid && cred->uid  != tcred->uid &&
-           !capable(CAP_SYS_NICE)) {
+       if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) {
                rcu_read_unlock();
                err = -EPERM;
                goto out;
@@ -1415,16 +1403,25 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
        if (err)
                goto out;
 
-       if (nodes) {
-               err = do_pages_move(mm, task, nr_pages, pages, nodes, status,
-                                   flags);
-       } else {
+       task_nodes = cpuset_mems_allowed(task);
+       mm = get_task_mm(task);
+       put_task_struct(task);
+
+       if (!mm)
+               return -EINVAL;
+
+       if (nodes)
+               err = do_pages_move(mm, task_nodes, nr_pages, pages,
+                                   nodes, status, flags);
+       else
                err = do_pages_stat(mm, nr_pages, pages, status);
-       }
 
-out:
        mmput(mm);
        return err;
+
+out:
+       put_task_struct(task);
+       return err;
 }
 
 /*
index 6f4ef53..c7a7e01 100644 (file)
@@ -399,6 +399,9 @@ static int swap_cgroup_prepare(int type)
                if (!page)
                        goto not_enough_page;
                ctrl->map[idx] = page;
+
+               if (!(idx % SWAP_CLUSTER_MAX))
+                       cond_resched();
        }
        return 0;
 not_enough_page:
index 70e814a..88c35c9 100644 (file)
@@ -299,7 +299,7 @@ static ssize_t process_vm_rw_core(pid_t pid, const struct iovec *lvec,
        }
 
        task_lock(task);
-       if (__ptrace_may_access(task, PTRACE_MODE_ATTACH)) {
+       if (__ptrace_may_access(task, PTRACE_MODE_ATTACH_REALCREDS)) {
                task_unlock(task);
                rc = -EPERM;
                goto put_task_struct;
index bb78c75..0f3ba24 100644 (file)
@@ -477,7 +477,8 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
        if (msg->msg_flags & MSG_OOB)
                return -EOPNOTSUPP;
 
-       if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
+       if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE|
+                              MSG_CMSG_COMPAT))
                return -EINVAL;
 
        if (len < 4 || len > HCI_MAX_FRAME_SIZE)
index bb38a3c..e31529d 100644 (file)
@@ -268,6 +268,7 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
                u32 yes;
                struct crush_rule *r;
 
+               err = -EINVAL;
                ceph_decode_32_safe(p, end, yes, bad);
                if (!yes) {
                        dout("crush_decode NO rule %d off %x %p to %p\n",
index 164958d..bb7a0cc 100644 (file)
@@ -5942,7 +5942,7 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
        } else {
                netdev_stats_to_stats64(storage, &dev->stats);
        }
-       storage->rx_dropped += atomic_long_read(&dev->rx_dropped);
+       storage->rx_dropped += (unsigned long)atomic_long_read(&dev->rx_dropped);
        return storage;
 }
 EXPORT_SYMBOL(dev_get_stats);
index 684b573..f2007b3 100644 (file)
@@ -791,6 +791,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
               + nla_total_size(4) /* IFLA_MASTER */
               + nla_total_size(1) /* IFLA_OPERSTATE */
               + nla_total_size(1) /* IFLA_LINKMODE */
+              + nla_total_size(4) /* IFLA_GROUP */
               + nla_total_size(ext_filter_mask
                                & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */
               + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */
@@ -1142,6 +1143,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
        [IFLA_PORT_SELF]        = { .type = NLA_NESTED },
        [IFLA_AF_SPEC]          = { .type = NLA_NESTED },
        [IFLA_EXT_MASK]         = { .type = NLA_U32 },
+       [IFLA_GROUP]            = { .type = NLA_U32 },
 };
 EXPORT_SYMBOL(ifla_policy);
 
index b30d9c2..847b314 100644 (file)
@@ -277,15 +277,8 @@ EXPORT_SYMBOL(dev_alloc_skb);
 
 static void skb_drop_list(struct sk_buff **listp)
 {
-       struct sk_buff *list = *listp;
-
+       kfree_skb_list(*listp);
        *listp = NULL;
-
-       do {
-               struct sk_buff *this = list;
-               list = list->next;
-               kfree_skb(this);
-       } while (list);
 }
 
 static inline void skb_drop_fraglist(struct sk_buff *skb)
@@ -436,6 +429,17 @@ void kfree_skb(struct sk_buff *skb)
 }
 EXPORT_SYMBOL(kfree_skb);
 
+void kfree_skb_list(struct sk_buff *segs)
+{
+       while (segs) {
+               struct sk_buff *next = segs->next;
+
+               kfree_skb(segs);
+               segs = next;
+       }
+}
+EXPORT_SYMBOL(kfree_skb_list);
+
 /**
  *     consume_skb - free an skbuff
  *     @skb: buffer to free
index e2ab968..19dcfe5 100644 (file)
@@ -1032,7 +1032,7 @@ static struct inet_protosw inetsw_array[] =
                .type =       SOCK_DGRAM,
                .protocol =   IPPROTO_ICMP,
                .prot =       &ping_prot,
-               .ops =        &inet_dgram_ops,
+               .ops =        &inet_sockraw_ops,
                .no_check =   UDP_CSUM_DEFAULT,
                .flags =      INET_PROTOSW_REUSE,
        },
index 80a9a97..9d0a94b 100644 (file)
@@ -2106,6 +2106,10 @@ int tcp_disconnect(struct sock *sk, int flags)
        tcp_set_ca_state(sk, TCP_CA_Open);
        tcp_clear_retrans(tp);
        inet_csk_delack_init(sk);
+       /* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0
+        * issue in __tcp_select_window()
+        */
+       icsk->icsk_ack.rcv_mss = TCP_MIN_MSS;
        tcp_init_send_head(sk);
        memset(&tp->rx_opt, 0, sizeof(tp->rx_opt));
        __sk_dst_reset(sk);
index eb7a8fb..73a4355 100644 (file)
@@ -1303,13 +1303,14 @@ static int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb,
                 */
                if (pkt_len > mss) {
                        unsigned int new_len = (pkt_len / mss) * mss;
-                       if (!in_sack && new_len < pkt_len) {
+                       if (!in_sack && new_len < pkt_len)
                                new_len += mss;
-                               if (new_len >= skb->len)
-                                       return 0;
-                       }
                        pkt_len = new_len;
                }
+
+               if (pkt_len >= skb->len && !in_sack)
+                       return 0;
+
                err = tcp_fragment(sk, skb, pkt_len, mss);
                if (err < 0)
                        return err;
@@ -3424,7 +3425,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
                        int delta;
 
                        /* Non-retransmitted hole got filled? That's reordering */
-                       if (reord < prior_fackets)
+                       if (reord < prior_fackets && reord <= tp->fackets_out)
                                tcp_update_reordering(sk, tp->fackets_out - reord, 0);
 
                        delta = tcp_is_fack(tp) ? pkts_acked :
index 72f7218..8d24d0b 100644 (file)
@@ -264,13 +264,15 @@ static void tcp_lp_pkts_acked(struct sock *sk, u32 num_acked, s32 rtt_us)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct lp *lp = inet_csk_ca(sk);
+       u32 delta;
 
        if (rtt_us > 0)
                tcp_lp_rtt_sample(sk, rtt_us);
 
        /* calc inference */
-       if (tcp_time_stamp > tp->rx_opt.rcv_tsecr)
-               lp->inference = 3 * (tcp_time_stamp - tp->rx_opt.rcv_tsecr);
+       delta = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
+       if ((s32)delta > 0)
+               lp->inference = 3 * delta;
 
        /* test if within inference */
        if (lp->last_drop && (tcp_time_stamp - lp->last_drop < lp->inference))
index 9a851d1..cb1de47 100644 (file)
@@ -2633,6 +2633,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
 {
        struct net_device *dev = (struct net_device *) data;
        struct inet6_dev *idev = __in6_dev_get(dev);
+       struct net *net = dev_net(dev);
        int run_pending = 0;
        int err;
 
@@ -2733,7 +2734,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
                         * IPV6_MIN_MTU stop IPv6 on this interface.
                         */
                        if (dev->mtu < IPV6_MIN_MTU)
-                               addrconf_ifdown(dev, 1);
+                               addrconf_ifdown(dev, dev != net->loopback_dev);
                }
                break;
 
@@ -2754,6 +2755,8 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
                 * MTU falled under IPV6_MIN_MTU.
                 * Stop IPv6 on this interface.
                 */
+               addrconf_ifdown(dev, dev != net->loopback_dev);
+               break;
 
        case NETDEV_DOWN:
        case NETDEV_UNREGISTER:
index b0e4fb8..7039068 100644 (file)
@@ -824,8 +824,10 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, u32 features)
                                           sizeof(*ipv6h));
                if (proto == IPPROTO_UDP) {
                        int err = ip6_find_1stfragopt(skb, &prevhdr);
-                       if (err < 0)
+                       if (err < 0) {
+                               kfree_skb_list(segs);
                                return ERR_PTR(err);
+                       }
                        fptr = (struct frag_hdr *)(skb_network_header(skb) +
                                err);
                        fptr->frag_off = htons(offset);
index ef7b872..2129fed 100644 (file)
@@ -723,13 +723,13 @@ void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
                ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
 }
 
-EXPORT_SYMBOL(ipv6_push_nfrag_opts);
 
 void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto)
 {
        if (opt->dst1opt)
                ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst1opt);
 }
+EXPORT_SYMBOL(ipv6_push_frag_opts);
 
 struct ipv6_txoptions *
 ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
index dd8aca8..a2a0852 100644 (file)
@@ -561,13 +561,14 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
 
 int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
 {
-       u16 offset = sizeof(struct ipv6hdr);
+       unsigned int offset = sizeof(struct ipv6hdr);
        unsigned int packet_len = skb->tail - skb->network_header;
        int found_rhdr = 0;
        *nexthdr = &ipv6_hdr(skb)->nexthdr;
 
        while (offset <= packet_len) {
                struct ipv6_opt_hdr *exthdr;
+               unsigned int len;
 
                switch (**nexthdr) {
 
@@ -593,7 +594,10 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
 
                exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
                                                 offset);
-               offset += ipv6_optlen(exthdr);
+               len = ipv6_optlen(exthdr);
+               if (len + offset >= IPV6_MAXPLEN)
+                       return -EINVAL;
+               offset += len;
                *nexthdr = &exthdr->nexthdr;
        }
 
index 08e4edc..2b4b4e3 100644 (file)
@@ -818,7 +818,7 @@ static void init_tel_txopt(struct ipv6_tel_txoption *opt, __u8 encap_limit)
        opt->dst_opt[5] = IPV6_TLV_PADN;
        opt->dst_opt[6] = 1;
 
-       opt->ops.dst0opt = (struct ipv6_opt_hdr *) opt->dst_opt;
+       opt->ops.dst1opt = (struct ipv6_opt_hdr *) opt->dst_opt;
        opt->ops.opt_nflen = 8;
 }
 
@@ -989,7 +989,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
        proto = fl6->flowi6_proto;
        if (encap_limit >= 0) {
                init_tel_txopt(&opt, encap_limit);
-               ipv6_push_nfrag_opts(skb, &opt.ops, &proto, NULL);
+               ipv6_push_frag_opts(skb, &opt.ops, &proto);
        }
        skb_push(skb, sizeof(struct ipv6hdr));
        skb_reset_network_header(skb);
index 63d5d49..bc75be1 100644 (file)
@@ -48,6 +48,8 @@ static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb)
        iph = ipv6_hdr(skb);
 
        hdr_len = x->type->hdr_offset(x, skb, &prevhdr);
+       if (hdr_len < 0)
+               return hdr_len;
        skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data);
        skb_set_network_header(skb, -x->props.header_len);
        skb->transport_header = skb->network_header + hdr_len;
index 4e34410..1d3bbe6 100644 (file)
@@ -28,6 +28,8 @@ static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb)
        iph = ipv6_hdr(skb);
 
        hdr_len = x->type->hdr_offset(x, skb, &prevhdr);
+       if (hdr_len < 0)
+               return hdr_len;
        skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data);
        skb_set_network_header(skb, -x->props.header_len);
        skb->transport_header = skb->network_header + hdr_len;
index 1b19d6a..35fc5ba 100644 (file)
@@ -1152,6 +1152,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
                        goto out;
        }
 
+       err = -ENOBUFS;
        key = ext_hdrs[SADB_EXT_KEY_AUTH - 1];
        if (sa->sadb_sa_auth) {
                int keysize = 0;
@@ -1163,8 +1164,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
                if (key)
                        keysize = (key->sadb_key_bits + 7) / 8;
                x->aalg = kmalloc(sizeof(*x->aalg) + keysize, GFP_KERNEL);
-               if (!x->aalg)
+               if (!x->aalg) {
+                       err = -ENOMEM;
                        goto out;
+               }
                strcpy(x->aalg->alg_name, a->name);
                x->aalg->alg_key_len = 0;
                if (key) {
@@ -1183,8 +1186,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
                                goto out;
                        }
                        x->calg = kmalloc(sizeof(*x->calg), GFP_KERNEL);
-                       if (!x->calg)
+                       if (!x->calg) {
+                               err = -ENOMEM;
                                goto out;
+                       }
                        strcpy(x->calg->alg_name, a->name);
                        x->props.calgo = sa->sadb_sa_encrypt;
                } else {
@@ -1198,8 +1203,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
                        if (key)
                                keysize = (key->sadb_key_bits + 7) / 8;
                        x->ealg = kmalloc(sizeof(*x->ealg) + keysize, GFP_KERNEL);
-                       if (!x->ealg)
+                       if (!x->ealg) {
+                               err = -ENOMEM;
                                goto out;
+                       }
                        strcpy(x->ealg->alg_name, a->name);
                        x->ealg->alg_key_len = 0;
                        if (key) {
@@ -1247,8 +1254,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
                struct xfrm_encap_tmpl *natt;
 
                x->encap = kmalloc(sizeof(*x->encap), GFP_KERNEL);
-               if (!x->encap)
+               if (!x->encap) {
+                       err = -ENOMEM;
                        goto out;
+               }
 
                natt = x->encap;
                n_type = ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1];
@@ -3230,7 +3239,7 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt,
                p += pol->sadb_x_policy_len*8;
                sec_ctx = (struct sadb_x_sec_ctx *)p;
                if (len < pol->sadb_x_policy_len*8 +
-                   sec_ctx->sadb_x_sec_len) {
+                   sec_ctx->sadb_x_sec_len*8) {
                        *dir = -EINVAL;
                        goto out;
                }
index 96c34c1..0cfb95a 100644 (file)
@@ -1959,7 +1959,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
                if (is_multicast_ether_addr(hdr->addr1)) {
                        mpp_addr = hdr->addr3;
                        proxied_addr = mesh_hdr->eaddr1;
-               } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) {
+               } else if ((mesh_hdr->flags & MESH_FLAGS_AE) ==
+                           MESH_FLAGS_AE_A5_A6) {
                        /* has_a4 already checked in ieee80211_rx_mesh_check */
                        mpp_addr = hdr->addr4;
                        proxied_addr = mesh_hdr->eaddr2;
index 782cdcd..93bb8ae 100644 (file)
@@ -731,8 +731,13 @@ restart:
        }
 out:
        spin_unlock_bh(&nf_conntrack_lock);
-       if (last)
+       if (last) {
+               /* nf ct hash resize happened, now clear the leftover. */
+               if ((struct nf_conn *)cb->args[1] == last)
+                       cb->args[1] = 0;
+
                nf_ct_put(last);
+       }
 
        return skb->len;
 }
@@ -1053,6 +1058,24 @@ ctnetlink_parse_nat_setup(struct nf_conn *ct,
 }
 #endif
 
+static void
+__ctnetlink_change_status(struct nf_conn *ct, unsigned long on,
+                         unsigned long off)
+{
+       unsigned int bit;
+
+       /* Ignore these unchangable bits */
+       on &= ~IPS_UNCHANGEABLE_MASK;
+       off &= ~IPS_UNCHANGEABLE_MASK;
+
+       for (bit = 0; bit < __IPS_MAX_BIT; bit++) {
+               if (on & (1 << bit))
+                       set_bit(bit, &ct->status);
+               else if (off & (1 << bit))
+                       clear_bit(bit, &ct->status);
+       }
+}
+
 static int
 ctnetlink_change_status(struct nf_conn *ct, const struct nlattr * const cda[])
 {
@@ -1072,10 +1095,7 @@ ctnetlink_change_status(struct nf_conn *ct, const struct nlattr * const cda[])
                /* ASSURED bit can only be set */
                return -EBUSY;
 
-       /* Be careful here, modifying NAT bits can screw up things,
-        * so don't let users modify them directly if they don't pass
-        * nf_nat_range. */
-       ct->status |= status & ~(IPS_NAT_DONE_MASK | IPS_NAT_MASK);
+       __ctnetlink_change_status(ct, status, 0);
        return 0;
 }
 
@@ -1258,7 +1278,7 @@ ctnetlink_change_nat_seq_adj(struct nf_conn *ct,
                if (ret < 0)
                        return ret;
 
-               ct->status |= IPS_SEQ_ADJUST;
+               set_bit(IPS_SEQ_ADJUST_BIT, &ct->status);
        }
 
        if (cda[CTA_NAT_SEQ_ADJ_REPLY]) {
@@ -1267,7 +1287,7 @@ ctnetlink_change_nat_seq_adj(struct nf_conn *ct,
                if (ret < 0)
                        return ret;
 
-               ct->status |= IPS_SEQ_ADJUST;
+               set_bit(IPS_SEQ_ADJUST_BIT, &ct->status);
        }
 
        return 0;
index e961773..57b5add 100644 (file)
@@ -3132,14 +3132,19 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
 
                if (optlen != sizeof(val))
                        return -EINVAL;
-               if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
-                       return -EBUSY;
                if (copy_from_user(&val, optval, sizeof(val)))
                        return -EFAULT;
                if (val > INT_MAX)
                        return -EINVAL;
-               po->tp_reserve = val;
-               return 0;
+               lock_sock(sk);
+               if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
+                       ret = -EBUSY;
+               } else {
+                       po->tp_reserve = val;
+                       ret = 0;
+               }
+               release_sock(sk);
+               return ret;
        }
        case PACKET_LOSS:
        {
index 5fba039..870c52d 100644 (file)
@@ -360,12 +360,15 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
                if (iftype == NL80211_IFTYPE_MESH_POINT) {
                        struct ieee80211s_hdr *meshdr =
                                (struct ieee80211s_hdr *) (skb->data + hdrlen);
+                       u8 mesh_flags;
+
                        /* make sure meshdr->flags is on the linear part */
                        if (!pskb_may_pull(skb, hdrlen + 1))
                                return -1;
-                       if (meshdr->flags & MESH_FLAGS_AE_A4)
+                       mesh_flags = meshdr->flags & MESH_FLAGS_AE;
+                       if (mesh_flags == MESH_FLAGS_AE_A4)
                                return -1;
-                       if (meshdr->flags & MESH_FLAGS_AE_A5_A6) {
+                       if (mesh_flags == MESH_FLAGS_AE_A5_A6) {
                                skb_copy_bits(skb, hdrlen +
                                        offsetof(struct ieee80211s_hdr, eaddr1),
                                        dst, ETH_ALEN);
@@ -386,12 +389,15 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
                if (iftype == NL80211_IFTYPE_MESH_POINT) {
                        struct ieee80211s_hdr *meshdr =
                                (struct ieee80211s_hdr *) (skb->data + hdrlen);
+                       u8 mesh_flags;
+
                        /* make sure meshdr->flags is on the linear part */
                        if (!pskb_may_pull(skb, hdrlen + 1))
                                return -1;
-                       if (meshdr->flags & MESH_FLAGS_AE_A5_A6)
+                       mesh_flags = meshdr->flags & MESH_FLAGS_AE;
+                       if (mesh_flags == MESH_FLAGS_AE_A5_A6)
                                return -1;
-                       if (meshdr->flags & MESH_FLAGS_AE_A4)
+                       if (mesh_flags == MESH_FLAGS_AE_A4)
                                skb_copy_bits(skb, hdrlen +
                                        offsetof(struct ieee80211s_hdr, eaddr1),
                                        src, ETH_ALEN);
index 113d20e..3ca14dc 100644 (file)
@@ -1530,41 +1530,6 @@ free_dst:
        goto out;
 }
 
-static int inline
-xfrm_dst_alloc_copy(void **target, const void *src, int size)
-{
-       if (!*target) {
-               *target = kmalloc(size, GFP_ATOMIC);
-               if (!*target)
-                       return -ENOMEM;
-       }
-       memcpy(*target, src, size);
-       return 0;
-}
-
-static int inline
-xfrm_dst_update_parent(struct dst_entry *dst, const struct xfrm_selector *sel)
-{
-#ifdef CONFIG_XFRM_SUB_POLICY
-       struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
-       return xfrm_dst_alloc_copy((void **)&(xdst->partner),
-                                  sel, sizeof(*sel));
-#else
-       return 0;
-#endif
-}
-
-static int inline
-xfrm_dst_update_origin(struct dst_entry *dst, const struct flowi *fl)
-{
-#ifdef CONFIG_XFRM_SUB_POLICY
-       struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
-       return xfrm_dst_alloc_copy((void **)&(xdst->origin), fl, sizeof(*fl));
-#else
-       return 0;
-#endif
-}
-
 static int xfrm_expand_policies(const struct flowi *fl, u16 family,
                                struct xfrm_policy **pols,
                                int *num_pols, int *num_xfrms)
@@ -1636,16 +1601,6 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,
 
        xdst = (struct xfrm_dst *)dst;
        xdst->num_xfrms = err;
-       if (num_pols > 1)
-               err = xfrm_dst_update_parent(dst, &pols[1]->selector);
-       else
-               err = xfrm_dst_update_origin(dst, fl);
-       if (unlikely(err)) {
-               dst_free(dst);
-               XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
-               return ERR_PTR(err);
-       }
-
        xdst->num_pols = num_pols;
        memcpy(xdst->pols, pols, sizeof(struct xfrm_policy*) * num_pols);
        xdst->policy_genid = atomic_read(&pols[0]->genid);
@@ -2942,9 +2897,15 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
        struct xfrm_state *x_new[XFRM_MAX_DEPTH];
        struct xfrm_migrate *mp;
 
+       /* Stage 0 - sanity checks */
        if ((err = xfrm_migrate_check(m, num_migrate)) < 0)
                goto out;
 
+       if (dir >= XFRM_POLICY_MAX) {
+               err = -EINVAL;
+               goto out;
+       }
+
        /* Stage 1 - find policy */
        if ((pol = xfrm_migrate_policy_find(sel, dir, type)) == NULL) {
                err = -ENOENT;
index f90d82f..7790e48 100644 (file)
@@ -141,12 +141,17 @@ int cap_ptrace_access_check(struct task_struct *child, unsigned int mode)
 {
        int ret = 0;
        const struct cred *cred, *child_cred;
+       const kernel_cap_t *caller_caps;
 
        rcu_read_lock();
        cred = current_cred();
        child_cred = __task_cred(child);
+       if (mode & PTRACE_MODE_FSCREDS)
+               caller_caps = &cred->cap_effective;
+       else
+               caller_caps = &cred->cap_permitted;
        if (cred->user->user_ns == child_cred->user->user_ns &&
-           cap_issubset(child_cred->cap_permitted, cred->cap_permitted))
+           cap_issubset(child_cred->cap_permitted, *caller_caps))
                goto out;
        if (ns_capable(child_cred->user->user_ns, CAP_SYS_PTRACE))
                goto out;
index b9073eb..4152533 100644 (file)
@@ -85,7 +85,7 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type,
        payload = NULL;
 
        vm = false;
-       if (_payload) {
+       if (plen) {
                ret = -ENOMEM;
                payload = kmalloc(plen, GFP_KERNEL);
                if (!payload) {
@@ -319,7 +319,7 @@ long keyctl_update_key(key_serial_t id,
 
        /* pull the payload in if one was supplied */
        payload = NULL;
-       if (_payload) {
+       if (plen) {
                ret = -ENOMEM;
                payload = kmalloc(plen, GFP_KERNEL);
                if (!payload)
index c279f2f..4c6a347 100644 (file)
@@ -911,10 +911,8 @@ static int selinux_parse_opts_str(char *options,
                goto out_err;
 
        opts->mnt_opts_flags = kcalloc(NUM_SEL_MNT_OPTS, sizeof(int), GFP_ATOMIC);
-       if (!opts->mnt_opts_flags) {
-               kfree(opts->mnt_opts);
+       if (!opts->mnt_opts_flags)
                goto out_err;
-       }
 
        if (fscontext) {
                opts->mnt_opts[num_mnt_opts] = fscontext;
@@ -937,6 +935,7 @@ static int selinux_parse_opts_str(char *options,
        return 0;
 
 out_err:
+       security_free_mnt_opts(opts);
        kfree(context);
        kfree(defcontext);
        kfree(fscontext);
index 9b89822..e6f93b9 100644 (file)
@@ -1448,6 +1448,8 @@ static const struct snd_pci_quirk stac9200_cfg_tbl[] = {
                      "Dell Inspiron 1501", STAC_9200_DELL_M26),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
                      "unknown Dell", STAC_9200_DELL_M26),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0201,
+                     "Dell Latitude D430", STAC_9200_DELL_M22),
        /* Panasonic */
        SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC),
        /* Gateway machines needs EAPD to be set on resume */
index a25fa63..ff8dd8b 100644 (file)
@@ -1574,6 +1574,9 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card)
                flush_delayed_work_sync(&rtd->delayed_work);
        }
 
+       /* free the ALSA card at first; this syncs with pending operations */
+       snd_card_free(card->snd_card);
+
        /* remove auxiliary devices */
        for (i = 0; i < card->num_aux_devs; i++)
                soc_remove_aux_dev(card, i);
@@ -1590,9 +1593,7 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card)
        snd_soc_dapm_free(&card->dapm);
 
        kfree(card->rtd);
-       snd_card_free(card->snd_card);
        return 0;
-
 }
 
 /* removes a socdev */
index 2780d9c..df12548 100644 (file)
@@ -170,9 +170,13 @@ Add a probe on schedule() function 12th line with recording cpu local variable:
  or
  ./perf probe --add='schedule:12 cpu'
 
- this will add one or more probes which has the name start with "schedule".
+Add one or more probes which has the name start with "schedule".
 
- Add probes on lines in schedule() function which calls update_rq_clock().
+ ./perf probe schedule*
+ or
+ ./perf probe --add='schedule*'
+
+Add probes on lines in schedule() function which calls update_rq_clock().
 
  ./perf probe 'schedule;update_rq_clock*'
  or
index 3152cca..2bdf2b6 100644 (file)
@@ -39,7 +39,7 @@ EVENT HANDLERS
 When perf script is invoked using a trace script, a user-defined
 'handler function' is called for each event in the trace.  If there's
 no handler function defined for a given event type, the event is
-ignored (or passed to a 'trace_handled' function, see below) and the
+ignored (or passed to a 'trace_unhandled' function, see below) and the
 next event is processed.
 
 Most of the event's field values are passed as arguments to the
index 4710220..282b0e2 100644 (file)
@@ -149,10 +149,8 @@ def raw_syscalls__sys_enter(event_name, context, common_cpu,
                print "id=%d, args=%s\n" % \
                (id, args),
 
-def trace_unhandled(event_name, context, common_cpu, common_secs, common_nsecs,
-               common_pid, common_comm):
-               print_header(event_name, common_cpu, common_secs, common_nsecs,
-               common_pid, common_comm)
+def trace_unhandled(event_name, context, event_fields_dict):
+               print ' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())])
 
 def print_header(event_name, cpu, secs, nsecs, pid, comm):
        print "%-20s %5u %05u.%09u %8u %-20s " % \
@@ -321,7 +319,7 @@ So those are the essential steps in writing and running a script.  The
 process can be generalized to any tracepoint or set of tracepoints
 you're interested in - basically find the tracepoint(s) you're
 interested in by looking at the list of available events shown by
-'perf list' and/or look in /sys/kernel/debug/tracing events for
+'perf list' and/or look in /sys/kernel/debug/tracing/events/ for
 detailed event and field info, record the corresponding trace data
 using 'perf record', passing it the list of interesting events,
 generate a skeleton script using 'perf script -g python' and modify the
@@ -334,7 +332,7 @@ right place, you can have your script listed alongside the other
 scripts listed by the 'perf script -l' command e.g.:
 
 ----
-root@tropicana:~# perf script -l
+# perf script -l
 List of available trace scripts:
   workqueue-stats                      workqueue stats (ins/exe/create/destroy)
   wakeup-latency                       system-wide min/max/avg wakeup latency
@@ -384,8 +382,6 @@ source tree:
 
 ----
 # ls -al kernel-source/tools/perf/scripts/python
-
-root@tropicana:/home/trz/src/tip# ls -al tools/perf/scripts/python
 total 32
 drwxr-xr-x 4 trz trz 4096 2010-01-26 22:30 .
 drwxr-xr-x 4 trz trz 4096 2010-01-26 22:29 ..
@@ -400,7 +396,7 @@ otherwise your script won't show up at run-time), 'perf script -l'
 should show a new entry for your script:
 
 ----
-root@tropicana:~# perf script -l
+# perf script -l
 List of available trace scripts:
   workqueue-stats                      workqueue stats (ins/exe/create/destroy)
   wakeup-latency                       system-wide min/max/avg wakeup latency
@@ -439,7 +435,7 @@ EVENT HANDLERS
 When perf script is invoked using a trace script, a user-defined
 'handler function' is called for each event in the trace.  If there's
 no handler function defined for a given event type, the event is
-ignored (or passed to a 'trace_handled' function, see below) and the
+ignored (or passed to a 'trace_unhandled' function, see below) and the
 next event is processed.
 
 Most of the event's field values are passed as arguments to the
@@ -534,7 +530,7 @@ can implement a set of optional functions:
 gives scripts a chance to do setup tasks:
 
 ----
-def trace_begin:
+def trace_begin():
     pass
 ----
 
@@ -543,7 +539,7 @@ def trace_begin:
  as display results:
 
 ----
-def trace_end:
+def trace_end():
     pass
 ----
 
@@ -552,8 +548,7 @@ def trace_end:
  of common arguments are passed into it:
 
 ----
-def trace_unhandled(event_name, context, common_cpu, common_secs,
-        common_nsecs, common_pid, common_comm):
+def trace_unhandled(event_name, context, event_fields_dict):
     pass
 ----
 
index 6ccf70e..8173636 100644 (file)
@@ -465,7 +465,7 @@ static int python_generate_script(const char *outfile)
        fprintf(ofp, "# be retrieved using Python functions of the form "
                "common_*(context).\n");
 
-       fprintf(ofp, "# See the perf-trace-python Documentation for the list "
+       fprintf(ofp, "# See the perf-script-python Documentation for the list "
                "of available functions.\n\n");
 
        fprintf(ofp, "import os\n");