Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 10 Oct 2013 18:33:48 +0000 (11:33 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 10 Oct 2013 18:33:48 +0000 (11:33 -0700)
Pull kvm fixes from Paolo Bonzini:
 "Fixes for 3.12-rc5: two old PPC bugs and one new (3.12-rc2) x86 bug"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  kvm: ppc: booke: check range page invalidation progress on page setup
  KVM: PPC: Book3S HV: Fix typo in saving DSCR
  KVM: nVMX: fix shadow on EPT

124 files changed:
MAINTAINERS
Makefile
arch/arm64/Kconfig.debug
arch/arm64/configs/defconfig
arch/arm64/include/asm/uaccess.h
arch/arm64/kernel/fpsimd.c
arch/arm64/mm/tlb.S
arch/mips/alchemy/board-mtx1.c
arch/mips/mm/c-r4k.c
arch/powerpc/kernel/irq.c
arch/s390/kernel/crash_dump.c
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/kprobes.c
arch/tile/include/asm/atomic.h
arch/tile/include/asm/atomic_32.h
arch/tile/include/asm/cmpxchg.h
arch/tile/include/asm/percpu.h
arch/tile/kernel/hardwall.c
arch/tile/kernel/intvec_32.S
arch/tile/kernel/intvec_64.S
arch/tile/kernel/stack.c
arch/tile/lib/atomic_32.c
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/sysfb_simplefb.c
arch/x86/pci/mmconfig-shared.c
drivers/acpi/scan.c
drivers/cpufreq/cpufreq-cpu0.c
drivers/cpufreq/intel_pstate.c
drivers/cpufreq/spear-cpufreq.c
drivers/dma/Kconfig
drivers/dma/edma.c
drivers/dma/imx-dma.c
drivers/gpio/gpio-omap.c
drivers/hid/Kconfig
drivers/hid/hid-core.c
drivers/hid/hid-holtek-mouse.c
drivers/hid/hid-ids.h
drivers/hid/hid-roccat-kone.c
drivers/hid/hid-roccat-koneplus.c
drivers/hid/hid-roccat-kovaplus.c
drivers/hid/hid-roccat-pyra.c
drivers/hid/hid-wiimote-modules.c
drivers/hid/hid-wiimote.h
drivers/hid/hidraw.c
drivers/hid/uhid.c
drivers/iio/amplifiers/ad8366.c
drivers/iio/industrialio-core.c
drivers/iio/magnetometer/st_magn_core.c
drivers/infiniband/ulp/srpt/ib_srpt.c
drivers/iommu/arm-smmu.c
drivers/mtd/devices/m25p80.c
drivers/mtd/nand/nand_base.c
drivers/s390/char/sclp_cmd.c
drivers/s390/char/tty3270.c
drivers/spi/spi-atmel.c
drivers/spi/spi-clps711x.c
drivers/spi/spi-fsl-dspi.c
drivers/spi/spi-mpc512x-psc.c
drivers/spi/spi-pxa2xx.c
drivers/spi/spi-s3c64xx.c
drivers/spi/spi-sh-hspi.c
drivers/staging/comedi/drivers/ni_65xx.c
drivers/target/iscsi/iscsi_target.c
drivers/target/iscsi/iscsi_target_nego.c
drivers/target/iscsi/iscsi_target_util.c
drivers/target/target_core_sbc.c
drivers/target/target_core_transport.c
drivers/target/target_core_xcopy.c
drivers/tty/hvc/hvc_xen.c
drivers/tty/n_tty.c
drivers/usb/chipidea/ci_hdrc_pci.c
drivers/usb/gadget/f_fs.c
drivers/usb/gadget/pxa25x_udc.c
drivers/usb/gadget/s3c-hsotg.c
drivers/usb/musb/musb_dsps.c
drivers/usb/musb/musb_gadget.c
drivers/usb/phy/phy-gpio-vbus-usb.c
drivers/usb/serial/option.c
drivers/vhost/scsi.c
fs/btrfs/async-thread.c
fs/btrfs/async-thread.h
fs/btrfs/dev-replace.c
fs/btrfs/extent_io.c
fs/btrfs/transaction.c
fs/btrfs/volumes.c
fs/cifs/cifsfs.h
fs/cifs/cifsglob.h
fs/cifs/cifspdu.h
fs/cifs/cifssmb.c
fs/cifs/file.c
fs/cifs/fscache.c
fs/cifs/fscache.h
fs/cifs/inode.c
fs/cifs/readdir.c
fs/cifs/sess.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/xfs/xfs_dir2_block.c
fs/xfs/xfs_dir2_format.h
fs/xfs/xfs_dir2_readdir.c
fs/xfs/xfs_dir2_sf.c
fs/xfs/xfs_dquot.c
fs/xfs/xfs_log_recover.c
include/linux/intel-iommu.h
include/linux/miscdevice.h
include/linux/perf_event.h
kernel/events/core.c
kernel/power/snapshot.c
kernel/power/user.c
kernel/softirq.c
net/sysctl_net.c
security/selinux/avc.c
security/selinux/hooks.c
security/selinux/include/avc.h
tools/perf/Makefile
tools/perf/builtin-stat.c
tools/perf/config/feature-tests.mak
tools/perf/util/dwarf-aux.c
tools/perf/util/dwarf-aux.h
tools/perf/util/header.c
tools/perf/util/probe-finder.c
tools/perf/util/session.c

index 5678de3..8a0cbf3 100644 (file)
@@ -4476,6 +4476,13 @@ L:       linux-serial@vger.kernel.org
 S:     Maintained
 F:     drivers/tty/serial/ioc3_serial.c
 
+IOMMU DRIVERS
+M:     Joerg Roedel <joro@8bytes.org>
+L:     iommu@lists.linux-foundation.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
+S:     Maintained
+F:     drivers/iommu/
+
 IP MASQUERADING
 M:     Juanjo Ciarlante <jjciarla@raiz.uncu.edu.ar>
 S:     Maintained
index 2ae108d..9de9aba 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 12
 SUBLEVEL = 0
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc4
 NAME = One Giant Leap for Frogkind
 
 # *DOCUMENTATION*
index 1a6bfe9..835c559 100644 (file)
@@ -6,13 +6,6 @@ config FRAME_POINTER
        bool
        default y
 
-config DEBUG_STACK_USAGE
-       bool "Enable stack utilization instrumentation"
-       depends on DEBUG_KERNEL
-       help
-         Enables the display of the minimum amount of free stack which each
-         task has ever had available in the sysrq-T output.
-
 config EARLY_PRINTK
        bool "Early printk support"
        default y
index 5b3e832..31c81e9 100644 (file)
@@ -42,7 +42,7 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
-# CONFIG_BLK_DEV is not set
+CONFIG_BLK_DEV=y
 CONFIG_SCSI=y
 # CONFIG_SCSI_PROC_FS is not set
 CONFIG_BLK_DEV_SD=y
@@ -72,6 +72,7 @@ CONFIG_LOGO=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
 CONFIG_FUSE_FS=y
@@ -90,3 +91,5 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_FTRACE is not set
 CONFIG_ATOMIC64_SELFTEST=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_VIRTIO_BLK=y
index edb3d5c..7ecc2b2 100644 (file)
@@ -166,9 +166,10 @@ do {                                                                       \
 
 #define get_user(x, ptr)                                               \
 ({                                                                     \
+       __typeof__(*(ptr)) __user *__p = (ptr);                         \
        might_fault();                                                  \
-       access_ok(VERIFY_READ, (ptr), sizeof(*(ptr))) ?                 \
-               __get_user((x), (ptr)) :                                \
+       access_ok(VERIFY_READ, __p, sizeof(*__p)) ?                     \
+               __get_user((x), __p) :                                  \
                ((x) = 0, -EFAULT);                                     \
 })
 
@@ -227,9 +228,10 @@ do {                                                                       \
 
 #define put_user(x, ptr)                                               \
 ({                                                                     \
+       __typeof__(*(ptr)) __user *__p = (ptr);                         \
        might_fault();                                                  \
-       access_ok(VERIFY_WRITE, (ptr), sizeof(*(ptr))) ?                \
-               __put_user((x), (ptr)) :                                \
+       access_ok(VERIFY_WRITE, __p, sizeof(*__p)) ?                    \
+               __put_user((x), __p) :                                  \
                -EFAULT;                                                \
 })
 
index 1f2e4d5..bb785d2 100644 (file)
@@ -80,8 +80,10 @@ void fpsimd_thread_switch(struct task_struct *next)
 
 void fpsimd_flush_thread(void)
 {
+       preempt_disable();
        memset(&current->thread.fpsimd_state, 0, sizeof(struct fpsimd_state));
        fpsimd_load_state(&current->thread.fpsimd_state);
+       preempt_enable();
 }
 
 #ifdef CONFIG_KERNEL_MODE_NEON
index 8ae80a1..19da91e 100644 (file)
@@ -35,7 +35,7 @@
  */
 ENTRY(__cpu_flush_user_tlb_range)
        vma_vm_mm x3, x2                        // get vma->vm_mm
-       mmid    x3, x3                          // get vm_mm->context.id
+       mmid    w3, x3                          // get vm_mm->context.id
        dsb     sy
        lsr     x0, x0, #12                     // align address
        lsr     x1, x1, #12
index 4a9baa9..9969dba 100644 (file)
@@ -276,7 +276,7 @@ static struct platform_device mtx1_pci_host = {
        .resource       = alchemy_pci_host_res,
 };
 
-static struct __initdata platform_device * mtx1_devs[] = {
+static struct platform_device *mtx1_devs[] __initdata = {
        &mtx1_pci_host,
        &mtx1_gpio_leds,
        &mtx1_wdt,
index 627883b..bc6f96f 100644 (file)
@@ -609,6 +609,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
                        r4k_blast_scache();
                else
                        blast_scache_range(addr, addr + size);
+               preempt_enable();
                __sync();
                return;
        }
@@ -650,6 +651,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
                         */
                        blast_inv_scache_range(addr, addr + size);
                }
+               preempt_enable();
                __sync();
                return;
        }
index 57d286a..c7cb8c2 100644 (file)
@@ -495,14 +495,15 @@ void __do_irq(struct pt_regs *regs)
 void do_IRQ(struct pt_regs *regs)
 {
        struct pt_regs *old_regs = set_irq_regs(regs);
-       struct thread_info *curtp, *irqtp;
+       struct thread_info *curtp, *irqtp, *sirqtp;
 
        /* Switch to the irq stack to handle this */
        curtp = current_thread_info();
        irqtp = hardirq_ctx[raw_smp_processor_id()];
+       sirqtp = softirq_ctx[raw_smp_processor_id()];
 
        /* Already there ? */
-       if (unlikely(curtp == irqtp)) {
+       if (unlikely(curtp == irqtp || curtp == sirqtp)) {
                __do_irq(regs);
                set_irq_regs(old_regs);
                return;
index c84f33d..7dd2172 100644 (file)
@@ -40,28 +40,26 @@ static inline void *load_real_addr(void *addr)
 }
 
 /*
- * Copy up to one page to vmalloc or real memory
+ * Copy real to virtual or real memory
  */
-static ssize_t copy_page_real(void *buf, void *src, size_t csize)
+static int copy_from_realmem(void *dest, void *src, size_t count)
 {
-       size_t size;
+       unsigned long size;
+       int rc;
 
-       if (is_vmalloc_addr(buf)) {
-               BUG_ON(csize >= PAGE_SIZE);
-               /* If buf is not page aligned, copy first part */
-               size = min(roundup(__pa(buf), PAGE_SIZE) - __pa(buf), csize);
-               if (size) {
-                       if (memcpy_real(load_real_addr(buf), src, size))
-                               return -EFAULT;
-                       buf += size;
-                       src += size;
-               }
-               /* Copy second part */
-               size = csize - size;
-               return (size) ? memcpy_real(load_real_addr(buf), src, size) : 0;
-       } else {
-               return memcpy_real(buf, src, csize);
-       }
+       if (!count)
+               return 0;
+       if (!is_vmalloc_or_module_addr(dest))
+               return memcpy_real(dest, src, count);
+       do {
+               size = min(count, PAGE_SIZE - (__pa(dest) & ~PAGE_MASK));
+               if (memcpy_real(load_real_addr(dest), src, size))
+                       return -EFAULT;
+               count -= size;
+               dest += size;
+               src += size;
+       } while (count);
+       return 0;
 }
 
 /*
@@ -114,7 +112,7 @@ static ssize_t copy_oldmem_page_kdump(char *buf, size_t csize,
                rc = copy_to_user_real((void __force __user *) buf,
                                       (void *) src, csize);
        else
-               rc = copy_page_real(buf, (void *) src, csize);
+               rc = copy_from_realmem(buf, (void *) src, csize);
        return (rc == 0) ? rc : csize;
 }
 
@@ -210,7 +208,7 @@ int copy_from_oldmem(void *dest, void *src, size_t count)
        if (OLDMEM_BASE) {
                if ((unsigned long) src < OLDMEM_SIZE) {
                        copied = min(count, OLDMEM_SIZE - (unsigned long) src);
-                       rc = memcpy_real(dest, src + OLDMEM_BASE, copied);
+                       rc = copy_from_realmem(dest, src + OLDMEM_BASE, copied);
                        if (rc)
                                return rc;
                }
@@ -223,7 +221,7 @@ int copy_from_oldmem(void *dest, void *src, size_t count)
                                return rc;
                }
        }
-       return memcpy_real(dest + copied, src + copied, count - copied);
+       return copy_from_realmem(dest + copied, src + copied, count - copied);
 }
 
 /*
index cc30d1f..0dc2b6d 100644 (file)
@@ -266,6 +266,7 @@ sysc_sigpending:
        tm      __TI_flags+3(%r12),_TIF_SYSCALL
        jno     sysc_return
        lm      %r2,%r7,__PT_R2(%r11)   # load svc arguments
+       l       %r10,__TI_sysc_table(%r12)      # 31 bit system call table
        xr      %r8,%r8                 # svc 0 returns -ENOSYS
        clc     __PT_INT_CODE+2(2,%r11),BASED(.Lnr_syscalls+2)
        jnl     sysc_nr_ok              # invalid svc number -> do svc 0
index 2b2188b..e5b43c9 100644 (file)
@@ -297,6 +297,7 @@ sysc_sigpending:
        tm      __TI_flags+7(%r12),_TIF_SYSCALL
        jno     sysc_return
        lmg     %r2,%r7,__PT_R2(%r11)   # load svc arguments
+       lg      %r10,__TI_sysc_table(%r12)      # address of system call table
        lghi    %r8,0                   # svc 0 returns -ENOSYS
        llgh    %r1,__PT_INT_CODE+2(%r11)       # load new svc number
        cghi    %r1,NR_syscalls
index 0ce9fb2..d86e64e 100644 (file)
@@ -67,6 +67,11 @@ static int __kprobes is_prohibited_opcode(kprobe_opcode_t *insn)
        case 0xac:      /* stnsm */
        case 0xad:      /* stosm */
                return -EINVAL;
+       case 0xc6:
+               switch (insn[0] & 0x0f) {
+               case 0x00: /* exrl   */
+                       return -EINVAL;
+               }
        }
        switch (insn[0]) {
        case 0x0101:    /* pr    */
@@ -180,7 +185,6 @@ static int __kprobes is_insn_relative_long(kprobe_opcode_t *insn)
                break;
        case 0xc6:
                switch (insn[0] & 0x0f) {
-               case 0x00: /* exrl   */
                case 0x02: /* pfdrl  */
                case 0x04: /* cghrl  */
                case 0x05: /* chrl   */
index d385eaa..7097984 100644 (file)
@@ -166,7 +166,7 @@ static inline int atomic_cmpxchg(atomic_t *v, int o, int n)
  *
  * Atomically sets @v to @i and returns old @v
  */
-static inline u64 atomic64_xchg(atomic64_t *v, u64 n)
+static inline long long atomic64_xchg(atomic64_t *v, long long n)
 {
        return xchg64(&v->counter, n);
 }
@@ -180,7 +180,8 @@ static inline u64 atomic64_xchg(atomic64_t *v, u64 n)
  * Atomically checks if @v holds @o and replaces it with @n if so.
  * Returns the old value at @v.
  */
-static inline u64 atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n)
+static inline long long atomic64_cmpxchg(atomic64_t *v, long long o,
+                                       long long n)
 {
        return cmpxchg64(&v->counter, o, n);
 }
index 0d0395b..1ad4a1f 100644 (file)
@@ -80,7 +80,7 @@ static inline void atomic_set(atomic_t *v, int n)
 /* A 64bit atomic type */
 
 typedef struct {
-       u64 __aligned(8) counter;
+       long long counter;
 } atomic64_t;
 
 #define ATOMIC64_INIT(val) { (val) }
@@ -91,14 +91,14 @@ typedef struct {
  *
  * Atomically reads the value of @v.
  */
-static inline u64 atomic64_read(const atomic64_t *v)
+static inline long long atomic64_read(const atomic64_t *v)
 {
        /*
         * Requires an atomic op to read both 32-bit parts consistently.
         * Casting away const is safe since the atomic support routines
         * do not write to memory if the value has not been modified.
         */
-       return _atomic64_xchg_add((u64 *)&v->counter, 0);
+       return _atomic64_xchg_add((long long *)&v->counter, 0);
 }
 
 /**
@@ -108,7 +108,7 @@ static inline u64 atomic64_read(const atomic64_t *v)
  *
  * Atomically adds @i to @v.
  */
-static inline void atomic64_add(u64 i, atomic64_t *v)
+static inline void atomic64_add(long long i, atomic64_t *v)
 {
        _atomic64_xchg_add(&v->counter, i);
 }
@@ -120,7 +120,7 @@ static inline void atomic64_add(u64 i, atomic64_t *v)
  *
  * Atomically adds @i to @v and returns @i + @v
  */
-static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
+static inline long long atomic64_add_return(long long i, atomic64_t *v)
 {
        smp_mb();  /* barrier for proper semantics */
        return _atomic64_xchg_add(&v->counter, i) + i;
@@ -135,7 +135,8 @@ static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
  * Atomically adds @a to @v, so long as @v was not already @u.
  * Returns non-zero if @v was not @u, and zero otherwise.
  */
-static inline u64 atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
+static inline long long atomic64_add_unless(atomic64_t *v, long long a,
+                                       long long u)
 {
        smp_mb();  /* barrier for proper semantics */
        return _atomic64_xchg_add_unless(&v->counter, a, u) != u;
@@ -151,7 +152,7 @@ static inline u64 atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
  * atomic64_set() can't be just a raw store, since it would be lost if it
  * fell between the load and store of one of the other atomic ops.
  */
-static inline void atomic64_set(atomic64_t *v, u64 n)
+static inline void atomic64_set(atomic64_t *v, long long n)
 {
        _atomic64_xchg(&v->counter, n);
 }
@@ -236,11 +237,13 @@ extern struct __get_user __atomic_xchg_add_unless(volatile int *p,
 extern struct __get_user __atomic_or(volatile int *p, int *lock, int n);
 extern struct __get_user __atomic_andn(volatile int *p, int *lock, int n);
 extern struct __get_user __atomic_xor(volatile int *p, int *lock, int n);
-extern u64 __atomic64_cmpxchg(volatile u64 *p, int *lock, u64 o, u64 n);
-extern u64 __atomic64_xchg(volatile u64 *p, int *lock, u64 n);
-extern u64 __atomic64_xchg_add(volatile u64 *p, int *lock, u64 n);
-extern u64 __atomic64_xchg_add_unless(volatile u64 *p,
-                                     int *lock, u64 o, u64 n);
+extern long long __atomic64_cmpxchg(volatile long long *p, int *lock,
+                                       long long o, long long n);
+extern long long __atomic64_xchg(volatile long long *p, int *lock, long long n);
+extern long long __atomic64_xchg_add(volatile long long *p, int *lock,
+                                       long long n);
+extern long long __atomic64_xchg_add_unless(volatile long long *p,
+                                       int *lock, long long o, long long n);
 
 /* Return failure from the atomic wrappers. */
 struct __get_user __atomic_bad_address(int __user *addr);
index 4001d5e..0ccda3c 100644 (file)
@@ -35,10 +35,10 @@ int _atomic_xchg(int *ptr, int n);
 int _atomic_xchg_add(int *v, int i);
 int _atomic_xchg_add_unless(int *v, int a, int u);
 int _atomic_cmpxchg(int *ptr, int o, int n);
-u64 _atomic64_xchg(u64 *v, u64 n);
-u64 _atomic64_xchg_add(u64 *v, u64 i);
-u64 _atomic64_xchg_add_unless(u64 *v, u64 a, u64 u);
-u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n);
+long long _atomic64_xchg(long long *v, long long n);
+long long _atomic64_xchg_add(long long *v, long long i);
+long long _atomic64_xchg_add_unless(long long *v, long long a, long long u);
+long long _atomic64_cmpxchg(long long *v, long long o, long long n);
 
 #define xchg(ptr, n)                                                   \
        ({                                                              \
@@ -53,7 +53,8 @@ u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n);
                if (sizeof(*(ptr)) != 4)                                \
                        __cmpxchg_called_with_bad_pointer();            \
                smp_mb();                                               \
-               (typeof(*(ptr)))_atomic_cmpxchg((int *)ptr, (int)o, (int)n); \
+               (typeof(*(ptr)))_atomic_cmpxchg((int *)ptr, (int)o,     \
+                                               (int)n);                \
        })
 
 #define xchg64(ptr, n)                                                 \
@@ -61,7 +62,8 @@ u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n);
                if (sizeof(*(ptr)) != 8)                                \
                        __xchg_called_with_bad_pointer();               \
                smp_mb();                                               \
-               (typeof(*(ptr)))_atomic64_xchg((u64 *)(ptr), (u64)(n)); \
+               (typeof(*(ptr)))_atomic64_xchg((long long *)(ptr),      \
+                                               (long long)(n));        \
        })
 
 #define cmpxchg64(ptr, o, n)                                           \
@@ -69,7 +71,8 @@ u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n);
                if (sizeof(*(ptr)) != 8)                                \
                        __cmpxchg_called_with_bad_pointer();            \
                smp_mb();                                               \
-               (typeof(*(ptr)))_atomic64_cmpxchg((u64 *)ptr, (u64)o, (u64)n); \
+               (typeof(*(ptr)))_atomic64_cmpxchg((long long *)ptr,     \
+                                       (long long)o, (long long)n);    \
        })
 
 #else
@@ -81,10 +84,11 @@ u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n);
                switch (sizeof(*(ptr))) {                               \
                case 4:                                                 \
                        __x = (typeof(__x))(unsigned long)              \
-                               __insn_exch4((ptr), (u32)(unsigned long)(n)); \
+                               __insn_exch4((ptr),                     \
+                                       (u32)(unsigned long)(n));       \
                        break;                                          \
                case 8:                                                 \
-                       __x = (typeof(__x))                     \
+                       __x = (typeof(__x))                             \
                                __insn_exch((ptr), (unsigned long)(n)); \
                        break;                                          \
                default:                                                \
@@ -103,10 +107,12 @@ u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n);
                switch (sizeof(*(ptr))) {                               \
                case 4:                                                 \
                        __x = (typeof(__x))(unsigned long)              \
-                               __insn_cmpexch4((ptr), (u32)(unsigned long)(n)); \
+                               __insn_cmpexch4((ptr),                  \
+                                       (u32)(unsigned long)(n));       \
                        break;                                          \
                case 8:                                                 \
-                       __x = (typeof(__x))__insn_cmpexch((ptr), (u64)(n)); \
+                       __x = (typeof(__x))__insn_cmpexch((ptr),        \
+                                               (long long)(n));        \
                        break;                                          \
                default:                                                \
                        __cmpxchg_called_with_bad_pointer();            \
index 63294f5..4f7ae39 100644 (file)
 #ifndef _ASM_TILE_PERCPU_H
 #define _ASM_TILE_PERCPU_H
 
-register unsigned long __my_cpu_offset __asm__("tp");
-#define __my_cpu_offset __my_cpu_offset
-#define set_my_cpu_offset(tp) (__my_cpu_offset = (tp))
+register unsigned long my_cpu_offset_reg asm("tp");
+
+#ifdef CONFIG_PREEMPT
+/*
+ * For full preemption, we can't just use the register variable
+ * directly, since we need barrier() to hazard against it, causing the
+ * compiler to reload anything computed from a previous "tp" value.
+ * But we also don't want to use volatile asm, since we'd like the
+ * compiler to be able to cache the value across multiple percpu reads.
+ * So we use a fake stack read as a hazard against barrier().
+ * The 'U' constraint is like 'm' but disallows postincrement.
+ */
+static inline unsigned long __my_cpu_offset(void)
+{
+       unsigned long tp;
+       register unsigned long *sp asm("sp");
+       asm("move %0, tp" : "=r" (tp) : "U" (*sp));
+       return tp;
+}
+#define __my_cpu_offset __my_cpu_offset()
+#else
+/*
+ * We don't need to hazard against barrier() since "tp" doesn't ever
+ * change with PREEMPT_NONE, and with PREEMPT_VOLUNTARY it only
+ * changes at function call points, at which we are already re-reading
+ * the value of "tp" due to "my_cpu_offset_reg" being a global variable.
+ */
+#define __my_cpu_offset my_cpu_offset_reg
+#endif
+
+#define set_my_cpu_offset(tp) (my_cpu_offset_reg = (tp))
 
 #include <asm-generic/percpu.h>
 
index df27a1f..531f4c3 100644 (file)
@@ -66,7 +66,7 @@ static struct hardwall_type hardwall_types[] = {
                0,
                "udn",
                LIST_HEAD_INIT(hardwall_types[HARDWALL_UDN].list),
-               __SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_UDN].lock),
+               __SPIN_LOCK_UNLOCKED(hardwall_types[HARDWALL_UDN].lock),
                NULL
        },
 #ifndef __tilepro__
@@ -77,7 +77,7 @@ static struct hardwall_type hardwall_types[] = {
                1,  /* disabled pending hypervisor support */
                "idn",
                LIST_HEAD_INIT(hardwall_types[HARDWALL_IDN].list),
-               __SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_IDN].lock),
+               __SPIN_LOCK_UNLOCKED(hardwall_types[HARDWALL_IDN].lock),
                NULL
        },
        {  /* access to user-space IPI */
@@ -87,7 +87,7 @@ static struct hardwall_type hardwall_types[] = {
                0,
                "ipi",
                LIST_HEAD_INIT(hardwall_types[HARDWALL_IPI].list),
-               __SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_IPI].lock),
+               __SPIN_LOCK_UNLOCKED(hardwall_types[HARDWALL_IPI].lock),
                NULL
        },
 #endif
index 088d5c1..2cbe6d5 100644 (file)
@@ -815,6 +815,9 @@ STD_ENTRY(interrupt_return)
        }
        bzt     r28, 1f
        bnz     r29, 1f
+       /* Disable interrupts explicitly for preemption. */
+       IRQ_DISABLE(r20,r21)
+       TRACE_IRQS_OFF
        jal     preempt_schedule_irq
        FEEDBACK_REENTER(interrupt_return)
 1:
index ec755d3..b8fc497 100644 (file)
@@ -841,6 +841,9 @@ STD_ENTRY(interrupt_return)
        }
        beqzt   r28, 1f
        bnez    r29, 1f
+       /* Disable interrupts explicitly for preemption. */
+       IRQ_DISABLE(r20,r21)
+       TRACE_IRQS_OFF
        jal     preempt_schedule_irq
        FEEDBACK_REENTER(interrupt_return)
 1:
index 362284a..c93977a 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/mmzone.h>
 #include <linux/dcache.h>
 #include <linux/fs.h>
+#include <linux/string.h>
 #include <asm/backtrace.h>
 #include <asm/page.h>
 #include <asm/ucontext.h>
@@ -332,21 +333,18 @@ static void describe_addr(struct KBacktraceIterator *kbt,
        }
 
        if (vma->vm_file) {
-               char *s;
                p = d_path(&vma->vm_file->f_path, buf, bufsize);
                if (IS_ERR(p))
                        p = "?";
-               s = strrchr(p, '/');
-               if (s)
-                       p = s+1;
+               name = kbasename(p);
        } else {
-               p = "anon";
+               name = "anon";
        }
 
        /* Generate a string description of the vma info. */
-       namelen = strlen(p);
+       namelen = strlen(name);
        remaining = (bufsize - 1) - namelen;
-       memmove(buf, p, namelen);
+       memmove(buf, name, namelen);
        snprintf(buf + namelen, remaining, "[%lx+%lx] ",
                 vma->vm_start, vma->vm_end - vma->vm_start);
 }
index 759efa3..c89b211 100644 (file)
@@ -107,19 +107,19 @@ unsigned long _atomic_xor(volatile unsigned long *p, unsigned long mask)
 EXPORT_SYMBOL(_atomic_xor);
 
 
-u64 _atomic64_xchg(u64 *v, u64 n)
+long long _atomic64_xchg(long long *v, long long n)
 {
        return __atomic64_xchg(v, __atomic_setup(v), n);
 }
 EXPORT_SYMBOL(_atomic64_xchg);
 
-u64 _atomic64_xchg_add(u64 *v, u64 i)
+long long _atomic64_xchg_add(long long *v, long long i)
 {
        return __atomic64_xchg_add(v, __atomic_setup(v), i);
 }
 EXPORT_SYMBOL(_atomic64_xchg_add);
 
-u64 _atomic64_xchg_add_unless(u64 *v, u64 a, u64 u)
+long long _atomic64_xchg_add_unless(long long *v, long long a, long long u)
 {
        /*
         * Note: argument order is switched here since it is easier
@@ -130,7 +130,7 @@ u64 _atomic64_xchg_add_unless(u64 *v, u64 a, u64 u)
 }
 EXPORT_SYMBOL(_atomic64_xchg_add_unless);
 
-u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n)
+long long _atomic64_cmpxchg(long long *v, long long o, long long n)
 {
        return __atomic64_cmpxchg(v, __atomic_setup(v), o, n);
 }
index 897783b..9d84491 100644 (file)
@@ -1888,10 +1888,7 @@ void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now)
        userpg->cap_user_rdpmc = x86_pmu.attr_rdpmc;
        userpg->pmc_width = x86_pmu.cntval_bits;
 
-       if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
-               return;
-
-       if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
+       if (!sched_clock_stable)
                return;
 
        userpg->cap_user_time = 1;
@@ -1899,10 +1896,8 @@ void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now)
        userpg->time_shift = CYC2NS_SCALE_FACTOR;
        userpg->time_offset = this_cpu_read(cyc2ns_offset) - now;
 
-       if (sched_clock_stable && !check_tsc_disabled()) {
-               userpg->cap_user_time_zero = 1;
-               userpg->time_zero = this_cpu_read(cyc2ns_offset);
-       }
+       userpg->cap_user_time_zero = 1;
+       userpg->time_zero = this_cpu_read(cyc2ns_offset);
 }
 
 /*
index 22513e9..86179d4 100644 (file)
@@ -72,14 +72,14 @@ __init int create_simplefb(const struct screen_info *si,
         * the part that is occupied by the framebuffer */
        len = mode->height * mode->stride;
        len = PAGE_ALIGN(len);
-       if (len > si->lfb_size << 16) {
+       if (len > (u64)si->lfb_size << 16) {
                printk(KERN_WARNING "sysfb: VRAM smaller than advertised\n");
                return -EINVAL;
        }
 
        /* setup IORESOURCE_MEM as framebuffer memory */
        memset(&res, 0, sizeof(res));
-       res.flags = IORESOURCE_MEM;
+       res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
        res.name = simplefb_resname;
        res.start = si->lfb_base;
        res.end = si->lfb_base + len - 1;
index 5596c7b..082e881 100644 (file)
@@ -700,7 +700,7 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
        if (!(pci_probe & PCI_PROBE_MMCONF) || pci_mmcfg_arch_init_failed)
                return -ENODEV;
 
-       if (start > end || !addr)
+       if (start > end)
                return -EINVAL;
 
        mutex_lock(&pci_mmcfg_lock);
@@ -716,6 +716,11 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
                return -EEXIST;
        }
 
+       if (!addr) {
+               mutex_unlock(&pci_mmcfg_lock);
+               return -EINVAL;
+       }
+
        rc = -EBUSY;
        cfg = pci_mmconfig_alloc(seg, start, end, addr);
        if (cfg == NULL) {
index 611ce90..407ad13 100644 (file)
@@ -968,7 +968,7 @@ int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
        }
        return 0;
 }
-EXPORT_SYMBOL_GPL(acpi_bus_get_device);
+EXPORT_SYMBOL(acpi_bus_get_device);
 
 int acpi_device_add(struct acpi_device *device,
                    void (*release)(struct device *))
index 78c49d8..c522a95 100644 (file)
@@ -229,7 +229,7 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
        if (of_property_read_u32(np, "clock-latency", &transition_latency))
                transition_latency = CPUFREQ_ETERNAL;
 
-       if (cpu_reg) {
+       if (!IS_ERR(cpu_reg)) {
                struct opp *opp;
                unsigned long min_uV, max_uV;
                int i;
index 9733f29..32b3479 100644 (file)
@@ -394,7 +394,10 @@ static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
        trace_cpu_frequency(pstate * 100000, cpu->cpu);
 
        cpu->pstate.current_pstate = pstate;
-       wrmsrl(MSR_IA32_PERF_CTL, pstate << 8);
+       if (limits.no_turbo)
+               wrmsrl(MSR_IA32_PERF_CTL, BIT(32) | (pstate << 8));
+       else
+               wrmsrl(MSR_IA32_PERF_CTL, pstate << 8);
 
 }
 
index 19e364f..3f41816 100644 (file)
@@ -113,7 +113,7 @@ static int spear_cpufreq_target(struct cpufreq_policy *policy,
                unsigned int target_freq, unsigned int relation)
 {
        struct cpufreq_freqs freqs;
-       unsigned long newfreq;
+       long newfreq;
        struct clk *srcclk;
        int index, ret, mult = 1;
 
index 526ec77..f238cfd 100644 (file)
@@ -198,6 +198,7 @@ config TI_EDMA
        depends on ARCH_DAVINCI || ARCH_OMAP
        select DMA_ENGINE
        select DMA_VIRTUAL_CHANNELS
+       select TI_PRIV_EDMA
        default n
        help
          Enable support for the TI EDMA controller. This DMA
index ff50ff4..098a8da 100644 (file)
@@ -749,6 +749,6 @@ static void __exit edma_exit(void)
 }
 module_exit(edma_exit);
 
-MODULE_AUTHOR("Matt Porter <mporter@ti.com>");
+MODULE_AUTHOR("Matt Porter <matt.porter@linaro.org>");
 MODULE_DESCRIPTION("TI EDMA DMA engine driver");
 MODULE_LICENSE("GPL v2");
index 78f8ca5..55852c0 100644 (file)
@@ -437,17 +437,18 @@ static void dma_irq_handle_channel(struct imxdma_channel *imxdmac)
        struct imxdma_engine *imxdma = imxdmac->imxdma;
        int chno = imxdmac->channel;
        struct imxdma_desc *desc;
+       unsigned long flags;
 
-       spin_lock(&imxdma->lock);
+       spin_lock_irqsave(&imxdma->lock, flags);
        if (list_empty(&imxdmac->ld_active)) {
-               spin_unlock(&imxdma->lock);
+               spin_unlock_irqrestore(&imxdma->lock, flags);
                goto out;
        }
 
        desc = list_first_entry(&imxdmac->ld_active,
                                struct imxdma_desc,
                                node);
-       spin_unlock(&imxdma->lock);
+       spin_unlock_irqrestore(&imxdma->lock, flags);
 
        if (desc->sg) {
                u32 tmp;
@@ -519,7 +520,6 @@ static int imxdma_xfer_desc(struct imxdma_desc *d)
 {
        struct imxdma_channel *imxdmac = to_imxdma_chan(d->desc.chan);
        struct imxdma_engine *imxdma = imxdmac->imxdma;
-       unsigned long flags;
        int slot = -1;
        int i;
 
@@ -527,7 +527,6 @@ static int imxdma_xfer_desc(struct imxdma_desc *d)
        switch (d->type) {
        case IMXDMA_DESC_INTERLEAVED:
                /* Try to get a free 2D slot */
-               spin_lock_irqsave(&imxdma->lock, flags);
                for (i = 0; i < IMX_DMA_2D_SLOTS; i++) {
                        if ((imxdma->slots_2d[i].count > 0) &&
                        ((imxdma->slots_2d[i].xsr != d->x) ||
@@ -537,10 +536,8 @@ static int imxdma_xfer_desc(struct imxdma_desc *d)
                        slot = i;
                        break;
                }
-               if (slot < 0) {
-                       spin_unlock_irqrestore(&imxdma->lock, flags);
+               if (slot < 0)
                        return -EBUSY;
-               }
 
                imxdma->slots_2d[slot].xsr = d->x;
                imxdma->slots_2d[slot].ysr = d->y;
@@ -549,7 +546,6 @@ static int imxdma_xfer_desc(struct imxdma_desc *d)
 
                imxdmac->slot_2d = slot;
                imxdmac->enabled_2d = true;
-               spin_unlock_irqrestore(&imxdma->lock, flags);
 
                if (slot == IMX_DMA_2D_SLOT_A) {
                        d->config_mem &= ~CCR_MSEL_B;
@@ -625,18 +621,17 @@ static void imxdma_tasklet(unsigned long data)
        struct imxdma_channel *imxdmac = (void *)data;
        struct imxdma_engine *imxdma = imxdmac->imxdma;
        struct imxdma_desc *desc;
+       unsigned long flags;
 
-       spin_lock(&imxdma->lock);
+       spin_lock_irqsave(&imxdma->lock, flags);
 
        if (list_empty(&imxdmac->ld_active)) {
                /* Someone might have called terminate all */
-               goto out;
+               spin_unlock_irqrestore(&imxdma->lock, flags);
+               return;
        }
        desc = list_first_entry(&imxdmac->ld_active, struct imxdma_desc, node);
 
-       if (desc->desc.callback)
-               desc->desc.callback(desc->desc.callback_param);
-
        /* If we are dealing with a cyclic descriptor, keep it on ld_active
         * and dont mark the descriptor as complete.
         * Only in non-cyclic cases it would be marked as complete
@@ -663,7 +658,11 @@ static void imxdma_tasklet(unsigned long data)
                                 __func__, imxdmac->channel);
        }
 out:
-       spin_unlock(&imxdma->lock);
+       spin_unlock_irqrestore(&imxdma->lock, flags);
+
+       if (desc->desc.callback)
+               desc->desc.callback(desc->desc.callback_param);
+
 }
 
 static int imxdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
@@ -883,7 +882,7 @@ static struct dma_async_tx_descriptor *imxdma_prep_dma_cyclic(
        kfree(imxdmac->sg_list);
 
        imxdmac->sg_list = kcalloc(periods + 1,
-                       sizeof(struct scatterlist), GFP_KERNEL);
+                       sizeof(struct scatterlist), GFP_ATOMIC);
        if (!imxdmac->sg_list)
                return NULL;
 
index 0ff4355..89675f8 100644 (file)
@@ -63,6 +63,7 @@ struct gpio_bank {
        struct gpio_chip chip;
        struct clk *dbck;
        u32 mod_usage;
+       u32 irq_usage;
        u32 dbck_enable_mask;
        bool dbck_enabled;
        struct device *dev;
@@ -86,6 +87,9 @@ struct gpio_bank {
 #define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio))
 #define GPIO_MOD_CTRL_BIT      BIT(0)
 
+#define BANK_USED(bank) (bank->mod_usage || bank->irq_usage)
+#define LINE_USED(line, offset) (line & (1 << offset))
+
 static int irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq)
 {
        return bank->chip.base + gpio_irq;
@@ -420,15 +424,69 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio,
        return 0;
 }
 
+static void _enable_gpio_module(struct gpio_bank *bank, unsigned offset)
+{
+       if (bank->regs->pinctrl) {
+               void __iomem *reg = bank->base + bank->regs->pinctrl;
+
+               /* Claim the pin for MPU */
+               __raw_writel(__raw_readl(reg) | (1 << offset), reg);
+       }
+
+       if (bank->regs->ctrl && !BANK_USED(bank)) {
+               void __iomem *reg = bank->base + bank->regs->ctrl;
+               u32 ctrl;
+
+               ctrl = __raw_readl(reg);
+               /* Module is enabled, clocks are not gated */
+               ctrl &= ~GPIO_MOD_CTRL_BIT;
+               __raw_writel(ctrl, reg);
+               bank->context.ctrl = ctrl;
+       }
+}
+
+static void _disable_gpio_module(struct gpio_bank *bank, unsigned offset)
+{
+       void __iomem *base = bank->base;
+
+       if (bank->regs->wkup_en &&
+           !LINE_USED(bank->mod_usage, offset) &&
+           !LINE_USED(bank->irq_usage, offset)) {
+               /* Disable wake-up during idle for dynamic tick */
+               _gpio_rmw(base, bank->regs->wkup_en, 1 << offset, 0);
+               bank->context.wake_en =
+                       __raw_readl(bank->base + bank->regs->wkup_en);
+       }
+
+       if (bank->regs->ctrl && !BANK_USED(bank)) {
+               void __iomem *reg = bank->base + bank->regs->ctrl;
+               u32 ctrl;
+
+               ctrl = __raw_readl(reg);
+               /* Module is disabled, clocks are gated */
+               ctrl |= GPIO_MOD_CTRL_BIT;
+               __raw_writel(ctrl, reg);
+               bank->context.ctrl = ctrl;
+       }
+}
+
+static int gpio_is_input(struct gpio_bank *bank, int mask)
+{
+       void __iomem *reg = bank->base + bank->regs->direction;
+
+       return __raw_readl(reg) & mask;
+}
+
 static int gpio_irq_type(struct irq_data *d, unsigned type)
 {
        struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
        unsigned gpio = 0;
        int retval;
        unsigned long flags;
+       unsigned offset;
 
-       if (WARN_ON(!bank->mod_usage))
-               return -EINVAL;
+       if (!BANK_USED(bank))
+               pm_runtime_get_sync(bank->dev);
 
 #ifdef CONFIG_ARCH_OMAP1
        if (d->irq > IH_MPUIO_BASE)
@@ -446,7 +504,17 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
                return -EINVAL;
 
        spin_lock_irqsave(&bank->lock, flags);
-       retval = _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), type);
+       offset = GPIO_INDEX(bank, gpio);
+       retval = _set_gpio_triggering(bank, offset, type);
+       if (!LINE_USED(bank->mod_usage, offset)) {
+               _enable_gpio_module(bank, offset);
+               _set_gpio_direction(bank, offset, 1);
+       } else if (!gpio_is_input(bank, 1 << offset)) {
+               spin_unlock_irqrestore(&bank->lock, flags);
+               return -EINVAL;
+       }
+
+       bank->irq_usage |= 1 << GPIO_INDEX(bank, gpio);
        spin_unlock_irqrestore(&bank->lock, flags);
 
        if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
@@ -603,35 +671,19 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
         * If this is the first gpio_request for the bank,
         * enable the bank module.
         */
-       if (!bank->mod_usage)
+       if (!BANK_USED(bank))
                pm_runtime_get_sync(bank->dev);
 
        spin_lock_irqsave(&bank->lock, flags);
        /* Set trigger to none. You need to enable the desired trigger with
-        * request_irq() or set_irq_type().
+        * request_irq() or set_irq_type(). Only do this if the IRQ line has
+        * not already been requested.
         */
-       _set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
-
-       if (bank->regs->pinctrl) {
-               void __iomem *reg = bank->base + bank->regs->pinctrl;
-
-               /* Claim the pin for MPU */
-               __raw_writel(__raw_readl(reg) | (1 << offset), reg);
-       }
-
-       if (bank->regs->ctrl && !bank->mod_usage) {
-               void __iomem *reg = bank->base + bank->regs->ctrl;
-               u32 ctrl;
-
-               ctrl = __raw_readl(reg);
-               /* Module is enabled, clocks are not gated */
-               ctrl &= ~GPIO_MOD_CTRL_BIT;
-               __raw_writel(ctrl, reg);
-               bank->context.ctrl = ctrl;
+       if (!LINE_USED(bank->irq_usage, offset)) {
+               _set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
+               _enable_gpio_module(bank, offset);
        }
-
        bank->mod_usage |= 1 << offset;
-
        spin_unlock_irqrestore(&bank->lock, flags);
 
        return 0;
@@ -640,31 +692,11 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
 static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
 {
        struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
-       void __iomem *base = bank->base;
        unsigned long flags;
 
        spin_lock_irqsave(&bank->lock, flags);
-
-       if (bank->regs->wkup_en) {
-               /* Disable wake-up during idle for dynamic tick */
-               _gpio_rmw(base, bank->regs->wkup_en, 1 << offset, 0);
-               bank->context.wake_en =
-                       __raw_readl(bank->base + bank->regs->wkup_en);
-       }
-
        bank->mod_usage &= ~(1 << offset);
-
-       if (bank->regs->ctrl && !bank->mod_usage) {
-               void __iomem *reg = bank->base + bank->regs->ctrl;
-               u32 ctrl;
-
-               ctrl = __raw_readl(reg);
-               /* Module is disabled, clocks are gated */
-               ctrl |= GPIO_MOD_CTRL_BIT;
-               __raw_writel(ctrl, reg);
-               bank->context.ctrl = ctrl;
-       }
-
+       _disable_gpio_module(bank, offset);
        _reset_gpio(bank, bank->chip.base + offset);
        spin_unlock_irqrestore(&bank->lock, flags);
 
@@ -672,7 +704,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
         * If this is the last gpio to be freed in the bank,
         * disable the bank module.
         */
-       if (!bank->mod_usage)
+       if (!BANK_USED(bank))
                pm_runtime_put(bank->dev);
 }
 
@@ -762,10 +794,20 @@ static void gpio_irq_shutdown(struct irq_data *d)
        struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
        unsigned int gpio = irq_to_gpio(bank, d->hwirq);
        unsigned long flags;
+       unsigned offset = GPIO_INDEX(bank, gpio);
 
        spin_lock_irqsave(&bank->lock, flags);
+       bank->irq_usage &= ~(1 << offset);
+       _disable_gpio_module(bank, offset);
        _reset_gpio(bank, gpio);
        spin_unlock_irqrestore(&bank->lock, flags);
+
+       /*
+        * If this is the last IRQ to be freed in the bank,
+        * disable the bank module.
+        */
+       if (!BANK_USED(bank))
+               pm_runtime_put(bank->dev);
 }
 
 static void gpio_ack_irq(struct irq_data *d)
@@ -897,13 +939,6 @@ static int gpio_input(struct gpio_chip *chip, unsigned offset)
        return 0;
 }
 
-static int gpio_is_input(struct gpio_bank *bank, int mask)
-{
-       void __iomem *reg = bank->base + bank->regs->direction;
-
-       return __raw_readl(reg) & mask;
-}
-
 static int gpio_get(struct gpio_chip *chip, unsigned offset)
 {
        struct gpio_bank *bank;
@@ -922,13 +957,22 @@ static int gpio_output(struct gpio_chip *chip, unsigned offset, int value)
 {
        struct gpio_bank *bank;
        unsigned long flags;
+       int retval = 0;
 
        bank = container_of(chip, struct gpio_bank, chip);
        spin_lock_irqsave(&bank->lock, flags);
+
+       if (LINE_USED(bank->irq_usage, offset)) {
+                       retval = -EINVAL;
+                       goto exit;
+       }
+
        bank->set_dataout(bank, offset, value);
        _set_gpio_direction(bank, offset, 0);
+
+exit:
        spin_unlock_irqrestore(&bank->lock, flags);
-       return 0;
+       return retval;
 }
 
 static int gpio_debounce(struct gpio_chip *chip, unsigned offset,
@@ -1400,7 +1444,7 @@ void omap2_gpio_prepare_for_idle(int pwr_mode)
        struct gpio_bank *bank;
 
        list_for_each_entry(bank, &omap_gpio_list, node) {
-               if (!bank->mod_usage || !bank->loses_context)
+               if (!BANK_USED(bank) || !bank->loses_context)
                        continue;
 
                bank->power_mode = pwr_mode;
@@ -1414,7 +1458,7 @@ void omap2_gpio_resume_after_idle(void)
        struct gpio_bank *bank;
 
        list_for_each_entry(bank, &omap_gpio_list, node) {
-               if (!bank->mod_usage || !bank->loses_context)
+               if (!BANK_USED(bank) || !bank->loses_context)
                        continue;
 
                pm_runtime_get_sync(bank->dev);
index 71b70e3..c91d547 100644 (file)
@@ -241,6 +241,7 @@ config HID_HOLTEK
          - Sharkoon Drakonia / Perixx MX-2000 gaming mice
          - Tracer Sniper TRM-503 / NOVA Gaming Slider X200 /
            Zalman ZM-GM1
+         - SHARKOON DarkGlider Gaming mouse
 
 config HOLTEK_FF
        bool "Holtek On Line Grip force feedback support"
index b8470b1..5a8c011 100644 (file)
@@ -1715,6 +1715,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) },
        { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) },
        { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) },
        { HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
index 7e6db3c..e696566 100644 (file)
@@ -27,6 +27,7 @@
  * - USB ID 04d9:a067, sold as Sharkoon Drakonia and Perixx MX-2000
  * - USB ID 04d9:a04a, sold as Tracer Sniper TRM-503, NOVA Gaming Slider X200
  *   and Zalman ZM-GM1
+ * - USB ID 04d9:a081, sold as SHARKOON DarkGlider Gaming mouse
  */
 
 static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
@@ -46,6 +47,7 @@ static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
                        }
                        break;
                case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A:
+               case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081:
                        if (*rsize >= 113 && rdesc[106] == 0xff && rdesc[107] == 0x7f
                                        && rdesc[111] == 0xff && rdesc[112] == 0x7f) {
                                hid_info(hdev, "Fixing up report descriptor\n");
@@ -63,6 +65,8 @@ static const struct hid_device_id holtek_mouse_devices[] = {
                        USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) },
        { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT,
                        USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT,
+                       USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) },
        { }
 };
 MODULE_DEVICE_TABLE(hid, holtek_mouse_devices);
index e60e8d5..9cbc7ab 100644 (file)
 #define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD      0xa055
 #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067    0xa067
 #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A    0xa04a
+#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081    0xa081
 
 #define USB_VENDOR_ID_IMATION          0x0718
 #define USB_DEVICE_ID_DISC_STAKKA      0xd000
index 602c188..6101816 100644 (file)
@@ -382,7 +382,7 @@ static ssize_t kone_sysfs_write_profilex(struct file *fp,
 }
 #define PROFILE_ATTR(number)                                   \
 static struct bin_attribute bin_attr_profile##number = {       \
-       .attr = { .name = "profile##number", .mode = 0660 },    \
+       .attr = { .name = "profile" #number, .mode = 0660 },    \
        .size = sizeof(struct kone_profile),                    \
        .read = kone_sysfs_read_profilex,                       \
        .write = kone_sysfs_write_profilex,                     \
index 5ddf605..5e99fcd 100644 (file)
@@ -229,13 +229,13 @@ static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp,
 
 #define PROFILE_ATTR(number)                                           \
 static struct bin_attribute bin_attr_profile##number##_settings = {    \
-       .attr = { .name = "profile##number##_settings", .mode = 0440 }, \
+       .attr = { .name = "profile" #number "_settings", .mode = 0440 },        \
        .size = KONEPLUS_SIZE_PROFILE_SETTINGS,                         \
        .read = koneplus_sysfs_read_profilex_settings,                  \
        .private = &profile_numbers[number-1],                          \
 };                                                                     \
 static struct bin_attribute bin_attr_profile##number##_buttons = {     \
-       .attr = { .name = "profile##number##_buttons", .mode = 0440 },  \
+       .attr = { .name = "profile" #number "_buttons", .mode = 0440 }, \
        .size = KONEPLUS_SIZE_PROFILE_BUTTONS,                          \
        .read = koneplus_sysfs_read_profilex_buttons,                   \
        .private = &profile_numbers[number-1],                          \
index 515bc03..0c8e1ef 100644 (file)
@@ -257,13 +257,13 @@ static ssize_t kovaplus_sysfs_read_profilex_buttons(struct file *fp,
 
 #define PROFILE_ATTR(number)                                           \
 static struct bin_attribute bin_attr_profile##number##_settings = {    \
-       .attr = { .name = "profile##number##_settings", .mode = 0440 }, \
+       .attr = { .name = "profile" #number "_settings", .mode = 0440 },        \
        .size = KOVAPLUS_SIZE_PROFILE_SETTINGS,                         \
        .read = kovaplus_sysfs_read_profilex_settings,                  \
        .private = &profile_numbers[number-1],                          \
 };                                                                     \
 static struct bin_attribute bin_attr_profile##number##_buttons = {     \
-       .attr = { .name = "profile##number##_buttons", .mode = 0440 },  \
+       .attr = { .name = "profile" #number "_buttons", .mode = 0440 }, \
        .size = KOVAPLUS_SIZE_PROFILE_BUTTONS,                          \
        .read = kovaplus_sysfs_read_profilex_buttons,                   \
        .private = &profile_numbers[number-1],                          \
index 5a6dbbe..1a07e07 100644 (file)
@@ -225,13 +225,13 @@ static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp,
 
 #define PROFILE_ATTR(number)                                           \
 static struct bin_attribute bin_attr_profile##number##_settings = {    \
-       .attr = { .name = "profile##number##_settings", .mode = 0440 }, \
+       .attr = { .name = "profile" #number "_settings", .mode = 0440 },        \
        .size = PYRA_SIZE_PROFILE_SETTINGS,                             \
        .read = pyra_sysfs_read_profilex_settings,                      \
        .private = &profile_numbers[number-1],                          \
 };                                                                     \
 static struct bin_attribute bin_attr_profile##number##_buttons = {     \
-       .attr = { .name = "profile##number##_buttons", .mode = 0440 },  \
+       .attr = { .name = "profile" #number "_buttons", .mode = 0440 }, \
        .size = PYRA_SIZE_PROFILE_BUTTONS,                              \
        .read = pyra_sysfs_read_profilex_buttons,                       \
        .private = &profile_numbers[number-1],                          \
index 2e7d644..71adf9e 100644 (file)
@@ -119,12 +119,22 @@ static const struct wiimod_ops wiimod_keys = {
  * the rumble motor, this flag shouldn't be set.
  */
 
+/* used by wiimod_rumble and wiipro_rumble */
+static void wiimod_rumble_worker(struct work_struct *work)
+{
+       struct wiimote_data *wdata = container_of(work, struct wiimote_data,
+                                                 rumble_worker);
+
+       spin_lock_irq(&wdata->state.lock);
+       wiiproto_req_rumble(wdata, wdata->state.cache_rumble);
+       spin_unlock_irq(&wdata->state.lock);
+}
+
 static int wiimod_rumble_play(struct input_dev *dev, void *data,
                              struct ff_effect *eff)
 {
        struct wiimote_data *wdata = input_get_drvdata(dev);
        __u8 value;
-       unsigned long flags;
 
        /*
         * The wiimote supports only a single rumble motor so if any magnitude
@@ -137,9 +147,10 @@ static int wiimod_rumble_play(struct input_dev *dev, void *data,
        else
                value = 0;
 
-       spin_lock_irqsave(&wdata->state.lock, flags);
-       wiiproto_req_rumble(wdata, value);
-       spin_unlock_irqrestore(&wdata->state.lock, flags);
+       /* Locking state.lock here might deadlock with input_event() calls.
+        * schedule_work acts as barrier. Merging multiple changes is fine. */
+       wdata->state.cache_rumble = value;
+       schedule_work(&wdata->rumble_worker);
 
        return 0;
 }
@@ -147,6 +158,8 @@ static int wiimod_rumble_play(struct input_dev *dev, void *data,
 static int wiimod_rumble_probe(const struct wiimod_ops *ops,
                               struct wiimote_data *wdata)
 {
+       INIT_WORK(&wdata->rumble_worker, wiimod_rumble_worker);
+
        set_bit(FF_RUMBLE, wdata->input->ffbit);
        if (input_ff_create_memless(wdata->input, NULL, wiimod_rumble_play))
                return -ENOMEM;
@@ -159,6 +172,8 @@ static void wiimod_rumble_remove(const struct wiimod_ops *ops,
 {
        unsigned long flags;
 
+       cancel_work_sync(&wdata->rumble_worker);
+
        spin_lock_irqsave(&wdata->state.lock, flags);
        wiiproto_req_rumble(wdata, 0);
        spin_unlock_irqrestore(&wdata->state.lock, flags);
@@ -1731,7 +1746,6 @@ static int wiimod_pro_play(struct input_dev *dev, void *data,
 {
        struct wiimote_data *wdata = input_get_drvdata(dev);
        __u8 value;
-       unsigned long flags;
 
        /*
         * The wiimote supports only a single rumble motor so if any magnitude
@@ -1744,9 +1758,10 @@ static int wiimod_pro_play(struct input_dev *dev, void *data,
        else
                value = 0;
 
-       spin_lock_irqsave(&wdata->state.lock, flags);
-       wiiproto_req_rumble(wdata, value);
-       spin_unlock_irqrestore(&wdata->state.lock, flags);
+       /* Locking state.lock here might deadlock with input_event() calls.
+        * schedule_work acts as barrier. Merging multiple changes is fine. */
+       wdata->state.cache_rumble = value;
+       schedule_work(&wdata->rumble_worker);
 
        return 0;
 }
@@ -1756,6 +1771,8 @@ static int wiimod_pro_probe(const struct wiimod_ops *ops,
 {
        int ret, i;
 
+       INIT_WORK(&wdata->rumble_worker, wiimod_rumble_worker);
+
        wdata->extension.input = input_allocate_device();
        if (!wdata->extension.input)
                return -ENOMEM;
@@ -1817,12 +1834,13 @@ static void wiimod_pro_remove(const struct wiimod_ops *ops,
        if (!wdata->extension.input)
                return;
 
+       input_unregister_device(wdata->extension.input);
+       wdata->extension.input = NULL;
+       cancel_work_sync(&wdata->rumble_worker);
+
        spin_lock_irqsave(&wdata->state.lock, flags);
        wiiproto_req_rumble(wdata, 0);
        spin_unlock_irqrestore(&wdata->state.lock, flags);
-
-       input_unregister_device(wdata->extension.input);
-       wdata->extension.input = NULL;
 }
 
 static const struct wiimod_ops wiimod_pro = {
index f1474f3..75db0c4 100644 (file)
@@ -133,13 +133,15 @@ struct wiimote_state {
        __u8 *cmd_read_buf;
        __u8 cmd_read_size;
 
-       /* calibration data */
+       /* calibration/cache data */
        __u16 calib_bboard[4][3];
+       __u8 cache_rumble;
 };
 
 struct wiimote_data {
        struct hid_device *hdev;
        struct input_dev *input;
+       struct work_struct rumble_worker;
        struct led_classdev *leds[4];
        struct input_dev *accel;
        struct input_dev *ir;
index 8918dd1..6a6dd5c 100644 (file)
@@ -308,18 +308,25 @@ static int hidraw_fasync(int fd, struct file *file, int on)
 static void drop_ref(struct hidraw *hidraw, int exists_bit)
 {
        if (exists_bit) {
-               hid_hw_close(hidraw->hid);
                hidraw->exist = 0;
-               if (hidraw->open)
+               if (hidraw->open) {
+                       hid_hw_close(hidraw->hid);
                        wake_up_interruptible(&hidraw->wait);
+               }
        } else {
                --hidraw->open;
        }
-
-       if (!hidraw->open && !hidraw->exist) {
-               device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
-               hidraw_table[hidraw->minor] = NULL;
-               kfree(hidraw);
+       if (!hidraw->open) {
+               if (!hidraw->exist) {
+                       device_destroy(hidraw_class,
+                                       MKDEV(hidraw_major, hidraw->minor));
+                       hidraw_table[hidraw->minor] = NULL;
+                       kfree(hidraw);
+               } else {
+                       /* close device for last reader */
+                       hid_hw_power(hidraw->hid, PM_HINT_NORMAL);
+                       hid_hw_close(hidraw->hid);
+               }
        }
 }
 
index 5bf2fb7..93b00d7 100644 (file)
@@ -615,7 +615,7 @@ static const struct file_operations uhid_fops = {
 
 static struct miscdevice uhid_misc = {
        .fops           = &uhid_fops,
-       .minor          = MISC_DYNAMIC_MINOR,
+       .minor          = UHID_MINOR,
        .name           = UHID_NAME,
 };
 
@@ -634,4 +634,5 @@ module_exit(uhid_exit);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>");
 MODULE_DESCRIPTION("User-space I/O driver support for HID subsystem");
+MODULE_ALIAS_MISCDEV(UHID_MINOR);
 MODULE_ALIAS("devname:" UHID_NAME);
index d0a79a4..ba6f6a9 100644 (file)
@@ -185,10 +185,8 @@ static int ad8366_remove(struct spi_device *spi)
 
        iio_device_unregister(indio_dev);
 
-       if (!IS_ERR(reg)) {
+       if (!IS_ERR(reg))
                regulator_disable(reg);
-               regulator_put(reg);
-       }
 
        return 0;
 }
index 8e84cd5..f95c697 100644 (file)
@@ -852,7 +852,6 @@ static void iio_dev_release(struct device *device)
                iio_device_unregister_trigger_consumer(indio_dev);
        iio_device_unregister_eventset(indio_dev);
        iio_device_unregister_sysfs(indio_dev);
-       iio_device_unregister_debugfs(indio_dev);
 
        ida_simple_remove(&iio_ida, indio_dev->id);
        kfree(indio_dev);
@@ -1087,6 +1086,7 @@ void iio_device_unregister(struct iio_dev *indio_dev)
 
        if (indio_dev->chrdev.dev)
                cdev_del(&indio_dev->chrdev);
+       iio_device_unregister_debugfs(indio_dev);
 
        iio_disable_all_buffers(indio_dev);
 
index e8d2849..cab3bc7 100644 (file)
@@ -29,9 +29,9 @@
 #define ST_MAGN_NUMBER_DATA_CHANNELS           3
 
 /* DEFAULT VALUE FOR SENSORS */
-#define ST_MAGN_DEFAULT_OUT_X_L_ADDR           0X04
-#define ST_MAGN_DEFAULT_OUT_Y_L_ADDR           0X08
-#define ST_MAGN_DEFAULT_OUT_Z_L_ADDR           0X06
+#define ST_MAGN_DEFAULT_OUT_X_H_ADDR           0X03
+#define ST_MAGN_DEFAULT_OUT_Y_H_ADDR           0X07
+#define ST_MAGN_DEFAULT_OUT_Z_H_ADDR           0X05
 
 /* FULLSCALE */
 #define ST_MAGN_FS_AVL_1300MG                  1300
 static const struct iio_chan_spec st_magn_16bit_channels[] = {
        ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
-                       ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
-                       ST_MAGN_DEFAULT_OUT_X_L_ADDR),
+                       ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_BE, 16, 16,
+                       ST_MAGN_DEFAULT_OUT_X_H_ADDR),
        ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
-                       ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
-                       ST_MAGN_DEFAULT_OUT_Y_L_ADDR),
+                       ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_BE, 16, 16,
+                       ST_MAGN_DEFAULT_OUT_Y_H_ADDR),
        ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
-                       ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
-                       ST_MAGN_DEFAULT_OUT_Z_L_ADDR),
+                       ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_BE, 16, 16,
+                       ST_MAGN_DEFAULT_OUT_Z_H_ADDR),
        IIO_CHAN_SOFT_TIMESTAMP(3)
 };
 
index 653ac6b..6c923c7 100644 (file)
@@ -1588,7 +1588,7 @@ static int srpt_build_tskmgmt_rsp(struct srpt_rdma_ch *ch,
        int resp_data_len;
        int resp_len;
 
-       resp_data_len = (rsp_code == SRP_TSK_MGMT_SUCCESS) ? 0 : 4;
+       resp_data_len = 4;
        resp_len = sizeof(*srp_rsp) + resp_data_len;
 
        srp_rsp = ioctx->ioctx.buf;
@@ -1600,11 +1600,9 @@ static int srpt_build_tskmgmt_rsp(struct srpt_rdma_ch *ch,
                                    + atomic_xchg(&ch->req_lim_delta, 0));
        srp_rsp->tag = tag;
 
-       if (rsp_code != SRP_TSK_MGMT_SUCCESS) {
-               srp_rsp->flags |= SRP_RSP_FLAG_RSPVALID;
-               srp_rsp->resp_data_len = cpu_to_be32(resp_data_len);
-               srp_rsp->data[3] = rsp_code;
-       }
+       srp_rsp->flags |= SRP_RSP_FLAG_RSPVALID;
+       srp_rsp->resp_data_len = cpu_to_be32(resp_data_len);
+       srp_rsp->data[3] = rsp_code;
 
        return resp_len;
 }
@@ -2358,6 +2356,8 @@ static void srpt_release_channel_work(struct work_struct *w)
        transport_deregister_session(se_sess);
        ch->sess = NULL;
 
+       ib_destroy_cm_id(ch->cm_id);
+
        srpt_destroy_ch_ib(ch);
 
        srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_ring,
@@ -2368,8 +2368,6 @@ static void srpt_release_channel_work(struct work_struct *w)
        list_del(&ch->list);
        spin_unlock_irq(&sdev->spinlock);
 
-       ib_destroy_cm_id(ch->cm_id);
-
        if (ch->release_done)
                complete(ch->release_done);
 
index f417e89..181c9ba 100644 (file)
@@ -377,6 +377,7 @@ struct arm_smmu_cfg {
        u32                             cbar;
        pgd_t                           *pgd;
 };
+#define INVALID_IRPTNDX                        0xff
 
 #define ARM_SMMU_CB_ASID(cfg)          ((cfg)->cbndx)
 #define ARM_SMMU_CB_VMID(cfg)          ((cfg)->cbndx + 1)
@@ -840,7 +841,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
        if (IS_ERR_VALUE(ret)) {
                dev_err(smmu->dev, "failed to request context IRQ %d (%u)\n",
                        root_cfg->irptndx, irq);
-               root_cfg->irptndx = -1;
+               root_cfg->irptndx = INVALID_IRPTNDX;
                goto out_free_context;
        }
 
@@ -869,7 +870,7 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain)
        writel_relaxed(0, cb_base + ARM_SMMU_CB_SCTLR);
        arm_smmu_tlb_inv_context(root_cfg);
 
-       if (root_cfg->irptndx != -1) {
+       if (root_cfg->irptndx != INVALID_IRPTNDX) {
                irq = smmu->irqs[smmu->num_global_irqs + root_cfg->irptndx];
                free_irq(irq, domain);
        }
@@ -1857,8 +1858,6 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
                goto out_put_parent;
        }
 
-       arm_smmu_device_reset(smmu);
-
        for (i = 0; i < smmu->num_global_irqs; ++i) {
                err = request_irq(smmu->irqs[i],
                                  arm_smmu_global_fault,
@@ -1876,6 +1875,8 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
        spin_lock(&arm_smmu_devices_lock);
        list_add(&smmu->list, &arm_smmu_devices);
        spin_unlock(&arm_smmu_devices_lock);
+
+       arm_smmu_device_reset(smmu);
        return 0;
 
 out_free_irqs:
@@ -1966,10 +1967,10 @@ static int __init arm_smmu_init(void)
                return ret;
 
        /* Oh, for a proper bus abstraction */
-       if (!iommu_present(&platform_bus_type));
+       if (!iommu_present(&platform_bus_type))
                bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
 
-       if (!iommu_present(&amba_bustype));
+       if (!iommu_present(&amba_bustype))
                bus_set_iommu(&amba_bustype, &arm_smmu_ops);
 
        return 0;
index 26b14f9..6bc9618 100644 (file)
@@ -168,12 +168,25 @@ static inline int write_disable(struct m25p *flash)
  */
 static inline int set_4byte(struct m25p *flash, u32 jedec_id, int enable)
 {
+       int status;
+       bool need_wren = false;
+
        switch (JEDEC_MFR(jedec_id)) {
-       case CFI_MFR_MACRONIX:
        case CFI_MFR_ST: /* Micron, actually */
+               /* Some Micron need WREN command; all will accept it */
+               need_wren = true;
+       case CFI_MFR_MACRONIX:
        case 0xEF /* winbond */:
+               if (need_wren)
+                       write_enable(flash);
+
                flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B;
-               return spi_write(flash->spi, flash->command, 1);
+               status = spi_write(flash->spi, flash->command, 1);
+
+               if (need_wren)
+                       write_disable(flash);
+
+               return status;
        default:
                /* Spansion style */
                flash->command[0] = OPCODE_BRWR;
index 7ed4841..d340b2f 100644 (file)
@@ -2869,10 +2869,8 @@ static int nand_flash_detect_ext_param_page(struct mtd_info *mtd,
 
        len = le16_to_cpu(p->ext_param_page_length) * 16;
        ep = kmalloc(len, GFP_KERNEL);
-       if (!ep) {
-               ret = -ENOMEM;
-               goto ext_out;
-       }
+       if (!ep)
+               return -ENOMEM;
 
        /* Send our own NAND_CMD_PARAM. */
        chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
@@ -2920,7 +2918,7 @@ static int nand_flash_detect_ext_param_page(struct mtd_info *mtd,
        }
 
        pr_info("ONFI extended param page detected.\n");
-       return 0;
+       ret = 0;
 
 ext_out:
        kfree(ep);
index 8cd34bf..77df9cb 100644 (file)
@@ -145,9 +145,11 @@ bool __init sclp_has_linemode(void)
 
        if (sccb->header.response_code != 0x20)
                return 0;
-       if (sccb->sclp_send_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK))
-               return 1;
-       return 0;
+       if (!(sccb->sclp_send_mask & (EVTYP_OPCMD_MASK | EVTYP_PMSGCMD_MASK)))
+               return 0;
+       if (!(sccb->sclp_receive_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK)))
+               return 0;
+       return 1;
 }
 
 bool __init sclp_has_vt220(void)
index a0f47c8..3f4ca4e 100644 (file)
@@ -810,7 +810,7 @@ static void tty3270_resize_work(struct work_struct *work)
        struct winsize ws;
 
        screen = tty3270_alloc_screen(tp->n_rows, tp->n_cols);
-       if (!screen)
+       if (IS_ERR(screen))
                return;
        /* Switch to new output size */
        spin_lock_bh(&tp->view.lock);
index fd7cc56..d4ac60b 100644 (file)
@@ -1583,7 +1583,7 @@ static int atmel_spi_probe(struct platform_device *pdev)
        /* Initialize the hardware */
        ret = clk_prepare_enable(clk);
        if (ret)
-               goto out_unmap_regs;
+               goto out_free_irq;
        spi_writel(as, CR, SPI_BIT(SWRST));
        spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
        if (as->caps.has_wdrbt) {
@@ -1614,6 +1614,7 @@ out_free_dma:
        spi_writel(as, CR, SPI_BIT(SWRST));
        spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
        clk_disable_unprepare(clk);
+out_free_irq:
        free_irq(irq, master);
 out_unmap_regs:
        iounmap(as->regs);
index 5655acf..6416798 100644 (file)
@@ -226,7 +226,6 @@ static int spi_clps711x_probe(struct platform_device *pdev)
                               dev_name(&pdev->dev), hw);
        if (ret) {
                dev_err(&pdev->dev, "Can't request IRQ\n");
-               clk_put(hw->spi_clk);
                goto clk_out;
        }
 
@@ -247,7 +246,6 @@ err_out:
                        gpio_free(hw->chipselect[i]);
 
        spi_master_put(master);
-       kfree(master);
 
        return ret;
 }
@@ -263,7 +261,6 @@ static int spi_clps711x_remove(struct platform_device *pdev)
                        gpio_free(hw->chipselect[i]);
 
        spi_unregister_master(master);
-       kfree(master);
 
        return 0;
 }
index 6cd07d1..4e44575 100644 (file)
@@ -476,15 +476,9 @@ static int dspi_probe(struct platform_device *pdev)
        master->bus_num = bus_num;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "can't get platform resource\n");
-               ret = -EINVAL;
-               goto out_master_put;
-       }
-
        dspi->base = devm_ioremap_resource(&pdev->dev, res);
-       if (!dspi->base) {
-               ret = -EINVAL;
+       if (IS_ERR(dspi->base)) {
+               ret = PTR_ERR(dspi->base);
                goto out_master_put;
        }
 
index dbc5e99..6adf4e3 100644 (file)
@@ -522,8 +522,10 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
        psc_num = master->bus_num;
        snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num);
        clk = devm_clk_get(dev, clk_name);
-       if (IS_ERR(clk))
+       if (IS_ERR(clk)) {
+               ret = PTR_ERR(clk);
                goto free_irq;
+       }
        ret = clk_prepare_enable(clk);
        if (ret)
                goto free_irq;
index 2eb06ee..c1a5067 100644 (file)
@@ -546,8 +546,17 @@ static irqreturn_t ssp_int(int irq, void *dev_id)
        if (pm_runtime_suspended(&drv_data->pdev->dev))
                return IRQ_NONE;
 
-       sccr1_reg = read_SSCR1(reg);
+       /*
+        * If the device is not yet in RPM suspended state and we get an
+        * interrupt that is meant for another device, check if status bits
+        * are all set to one. That means that the device is already
+        * powered off.
+        */
        status = read_SSSR(reg);
+       if (status == ~0)
+               return IRQ_NONE;
+
+       sccr1_reg = read_SSCR1(reg);
 
        /* Ignore possible writes if we don't need to write */
        if (!(sccr1_reg & SSCR1_TIE))
index 512b889..a80376d 100644 (file)
@@ -1428,6 +1428,8 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
               S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN,
               sdd->regs + S3C64XX_SPI_INT_EN);
 
+       pm_runtime_enable(&pdev->dev);
+
        if (spi_register_master(master)) {
                dev_err(&pdev->dev, "cannot register SPI master\n");
                ret = -EBUSY;
@@ -1440,8 +1442,6 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
                                        mem_res,
                                        sdd->rx_dma.dmach, sdd->tx_dma.dmach);
 
-       pm_runtime_enable(&pdev->dev);
-
        return 0;
 
 err3:
index 0b68cb5..e488a90 100644 (file)
@@ -296,6 +296,8 @@ static int hspi_probe(struct platform_device *pdev)
                goto error1;
        }
 
+       pm_runtime_enable(&pdev->dev);
+
        master->num_chipselect  = 1;
        master->bus_num         = pdev->id;
        master->setup           = hspi_setup;
@@ -309,8 +311,6 @@ static int hspi_probe(struct platform_device *pdev)
                goto error1;
        }
 
-       pm_runtime_enable(&pdev->dev);
-
        return 0;
 
  error1:
index 3ba4c57..853f62b 100644 (file)
@@ -369,28 +369,23 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
 {
        const struct ni_65xx_board *board = comedi_board(dev);
        struct ni_65xx_private *devpriv = dev->private;
-       unsigned base_bitfield_channel;
-       const unsigned max_ports_per_bitfield = 5;
+       int base_bitfield_channel;
        unsigned read_bits = 0;
-       unsigned j;
+       int last_port_offset = ni_65xx_port_by_channel(s->n_chan - 1);
+       int port_offset;
 
        base_bitfield_channel = CR_CHAN(insn->chanspec);
-       for (j = 0; j < max_ports_per_bitfield; ++j) {
-               const unsigned port_offset =
-                       ni_65xx_port_by_channel(base_bitfield_channel) + j;
-               const unsigned port =
-                       sprivate(s)->base_port + port_offset;
-               unsigned base_port_channel;
+       for (port_offset = ni_65xx_port_by_channel(base_bitfield_channel);
+            port_offset <= last_port_offset; port_offset++) {
+               unsigned port = sprivate(s)->base_port + port_offset;
+               int base_port_channel = port_offset * ni_65xx_channels_per_port;
                unsigned port_mask, port_data, port_read_bits;
-               int bitshift;
-               if (port >= ni_65xx_total_num_ports(board))
+               int bitshift = base_port_channel - base_bitfield_channel;
+
+               if (bitshift >= 32)
                        break;
-               base_port_channel = port_offset * ni_65xx_channels_per_port;
                port_mask = data[0];
                port_data = data[1];
-               bitshift = base_port_channel - base_bitfield_channel;
-               if (bitshift >= 32 || bitshift <= -32)
-                       break;
                if (bitshift > 0) {
                        port_mask >>= bitshift;
                        port_data >>= bitshift;
index 35b61f7..38e44b9 100644 (file)
@@ -753,7 +753,8 @@ static void iscsit_unmap_iovec(struct iscsi_cmd *cmd)
 
 static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn)
 {
-       struct iscsi_cmd *cmd;
+       LIST_HEAD(ack_list);
+       struct iscsi_cmd *cmd, *cmd_p;
 
        conn->exp_statsn = exp_statsn;
 
@@ -761,19 +762,23 @@ static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn)
                return;
 
        spin_lock_bh(&conn->cmd_lock);
-       list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) {
+       list_for_each_entry_safe(cmd, cmd_p, &conn->conn_cmd_list, i_conn_node) {
                spin_lock(&cmd->istate_lock);
                if ((cmd->i_state == ISTATE_SENT_STATUS) &&
                    iscsi_sna_lt(cmd->stat_sn, exp_statsn)) {
                        cmd->i_state = ISTATE_REMOVE;
                        spin_unlock(&cmd->istate_lock);
-                       iscsit_add_cmd_to_immediate_queue(cmd, conn,
-                                               cmd->i_state);
+                       list_move_tail(&cmd->i_conn_node, &ack_list);
                        continue;
                }
                spin_unlock(&cmd->istate_lock);
        }
        spin_unlock_bh(&conn->cmd_lock);
+
+       list_for_each_entry_safe(cmd, cmd_p, &ack_list, i_conn_node) {
+               list_del(&cmd->i_conn_node);
+               iscsit_free_cmd(cmd, false);
+       }
 }
 
 static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd)
index 14d1aed..ef6d836 100644 (file)
@@ -1192,7 +1192,7 @@ get_target:
         */
 alloc_tags:
        tag_num = max_t(u32, ISCSIT_MIN_TAGS, queue_depth);
-       tag_num += ISCSIT_EXTRA_TAGS;
+       tag_num += (tag_num / 2) + ISCSIT_EXTRA_TAGS;
        tag_size = sizeof(struct iscsi_cmd) + conn->conn_transport->priv_size;
 
        ret = transport_alloc_session_tags(sess->se_sess, tag_num, tag_size);
index f2de28e..b0cac0c 100644 (file)
@@ -736,7 +736,7 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown)
                 * Fallthrough
                 */
        case ISCSI_OP_SCSI_TMFUNC:
-               rc = transport_generic_free_cmd(&cmd->se_cmd, 1);
+               rc = transport_generic_free_cmd(&cmd->se_cmd, shutdown);
                if (!rc && shutdown && se_cmd && se_cmd->se_sess) {
                        __iscsit_free_cmd(cmd, true, shutdown);
                        target_put_sess_cmd(se_cmd->se_sess, se_cmd);
@@ -752,7 +752,7 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown)
                        se_cmd = &cmd->se_cmd;
                        __iscsit_free_cmd(cmd, true, shutdown);
 
-                       rc = transport_generic_free_cmd(&cmd->se_cmd, 1);
+                       rc = transport_generic_free_cmd(&cmd->se_cmd, shutdown);
                        if (!rc && shutdown && se_cmd->se_sess) {
                                __iscsit_free_cmd(cmd, true, shutdown);
                                target_put_sess_cmd(se_cmd->se_sess, se_cmd);
index 6c17295..4714c6f 100644 (file)
@@ -349,7 +349,16 @@ static sense_reason_t compare_and_write_post(struct se_cmd *cmd)
 {
        struct se_device *dev = cmd->se_dev;
 
-       cmd->se_cmd_flags |= SCF_COMPARE_AND_WRITE_POST;
+       /*
+        * Only set SCF_COMPARE_AND_WRITE_POST to force a response fall-through
+        * within target_complete_ok_work() if the command was successfully
+        * sent to the backend driver.
+        */
+       spin_lock_irq(&cmd->t_state_lock);
+       if ((cmd->transport_state & CMD_T_SENT) && !cmd->scsi_status)
+               cmd->se_cmd_flags |= SCF_COMPARE_AND_WRITE_POST;
+       spin_unlock_irq(&cmd->t_state_lock);
+
        /*
         * Unlock ->caw_sem originally obtained during sbc_compare_and_write()
         * before the original READ I/O submission.
@@ -363,7 +372,7 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd)
 {
        struct se_device *dev = cmd->se_dev;
        struct scatterlist *write_sg = NULL, *sg;
-       unsigned char *buf, *addr;
+       unsigned char *buf = NULL, *addr;
        struct sg_mapping_iter m;
        unsigned int offset = 0, len;
        unsigned int nlbas = cmd->t_task_nolb;
@@ -378,6 +387,15 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd)
         */
        if (!cmd->t_data_sg || !cmd->t_bidi_data_sg)
                return TCM_NO_SENSE;
+       /*
+        * Immediately exit + release dev->caw_sem if command has already
+        * been failed with a non-zero SCSI status.
+        */
+       if (cmd->scsi_status) {
+               pr_err("compare_and_write_callback: non zero scsi_status:"
+                       " 0x%02x\n", cmd->scsi_status);
+               goto out;
+       }
 
        buf = kzalloc(cmd->data_length, GFP_KERNEL);
        if (!buf) {
@@ -508,6 +526,12 @@ sbc_compare_and_write(struct se_cmd *cmd)
                cmd->transport_complete_callback = NULL;
                return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
        }
+       /*
+        * Reset cmd->data_length to individual block_size in order to not
+        * confuse backend drivers that depend on this value matching the
+        * size of the I/O being submitted.
+        */
+       cmd->data_length = cmd->t_task_nolb * dev->dev_attrib.block_size;
 
        ret = cmd->execute_rw(cmd, cmd->t_bidi_data_sg, cmd->t_bidi_data_nents,
                              DMA_FROM_DEVICE);
index 84747cc..81e945e 100644 (file)
@@ -236,17 +236,24 @@ int transport_alloc_session_tags(struct se_session *se_sess,
 {
        int rc;
 
-       se_sess->sess_cmd_map = kzalloc(tag_num * tag_size, GFP_KERNEL);
+       se_sess->sess_cmd_map = kzalloc(tag_num * tag_size,
+                                       GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT);
        if (!se_sess->sess_cmd_map) {
-               pr_err("Unable to allocate se_sess->sess_cmd_map\n");
-               return -ENOMEM;
+               se_sess->sess_cmd_map = vzalloc(tag_num * tag_size);
+               if (!se_sess->sess_cmd_map) {
+                       pr_err("Unable to allocate se_sess->sess_cmd_map\n");
+                       return -ENOMEM;
+               }
        }
 
        rc = percpu_ida_init(&se_sess->sess_tag_pool, tag_num);
        if (rc < 0) {
                pr_err("Unable to init se_sess->sess_tag_pool,"
                        " tag_num: %u\n", tag_num);
-               kfree(se_sess->sess_cmd_map);
+               if (is_vmalloc_addr(se_sess->sess_cmd_map))
+                       vfree(se_sess->sess_cmd_map);
+               else
+                       kfree(se_sess->sess_cmd_map);
                se_sess->sess_cmd_map = NULL;
                return -ENOMEM;
        }
@@ -412,7 +419,10 @@ void transport_free_session(struct se_session *se_sess)
 {
        if (se_sess->sess_cmd_map) {
                percpu_ida_destroy(&se_sess->sess_tag_pool);
-               kfree(se_sess->sess_cmd_map);
+               if (is_vmalloc_addr(se_sess->sess_cmd_map))
+                       vfree(se_sess->sess_cmd_map);
+               else
+                       kfree(se_sess->sess_cmd_map);
        }
        kmem_cache_free(se_sess_cache, se_sess);
 }
index 4d22e7d..3da4fd1 100644 (file)
@@ -298,8 +298,8 @@ static int target_xcopy_parse_segdesc_02(struct se_cmd *se_cmd, struct xcopy_op
                (unsigned long long)xop->dst_lba);
 
        if (dc != 0) {
-               xop->dbl = (desc[29] << 16) & 0xff;
-               xop->dbl |= (desc[30] << 8) & 0xff;
+               xop->dbl = (desc[29] & 0xff) << 16;
+               xop->dbl |= (desc[30] & 0xff) << 8;
                xop->dbl |= desc[31] & 0xff;
 
                pr_debug("XCOPY seg desc 0x02: DC=1 w/ dbl: %u\n", xop->dbl);
index e61c36c..c193af6 100644 (file)
@@ -636,6 +636,7 @@ struct console xenboot_console = {
        .name           = "xenboot",
        .write          = xenboot_write_console,
        .flags          = CON_PRINTBUFFER | CON_BOOT | CON_ANYTIME,
+       .index          = -1,
 };
 #endif /* CONFIG_EARLY_PRINTK */
 
index 01bf5eb..7a744b6 100644 (file)
@@ -2183,28 +2183,34 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
 
                if (!input_available_p(tty, 0)) {
                        if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
-                               retval = -EIO;
-                               break;
-                       }
-                       if (tty_hung_up_p(file))
-                               break;
-                       if (!timeout)
-                               break;
-                       if (file->f_flags & O_NONBLOCK) {
-                               retval = -EAGAIN;
-                               break;
-                       }
-                       if (signal_pending(current)) {
-                               retval = -ERESTARTSYS;
-                               break;
-                       }
-                       n_tty_set_room(tty);
-                       up_read(&tty->termios_rwsem);
+                               up_read(&tty->termios_rwsem);
+                               tty_flush_to_ldisc(tty);
+                               down_read(&tty->termios_rwsem);
+                               if (!input_available_p(tty, 0)) {
+                                       retval = -EIO;
+                                       break;
+                               }
+                       } else {
+                               if (tty_hung_up_p(file))
+                                       break;
+                               if (!timeout)
+                                       break;
+                               if (file->f_flags & O_NONBLOCK) {
+                                       retval = -EAGAIN;
+                                       break;
+                               }
+                               if (signal_pending(current)) {
+                                       retval = -ERESTARTSYS;
+                                       break;
+                               }
+                               n_tty_set_room(tty);
+                               up_read(&tty->termios_rwsem);
 
-                       timeout = schedule_timeout(timeout);
+                               timeout = schedule_timeout(timeout);
 
-                       down_read(&tty->termios_rwsem);
-                       continue;
+                               down_read(&tty->termios_rwsem);
+                               continue;
+                       }
                }
                __set_current_state(TASK_RUNNING);
 
index 042320a..d514332 100644 (file)
@@ -129,7 +129,12 @@ static DEFINE_PCI_DEVICE_TABLE(ci_hdrc_pci_id_table) = {
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0829),
                .driver_data = (kernel_ulong_t)&penwell_pci_platdata,
        },
-       { 0, 0, 0, 0, 0, 0, 0 /* end: all zeroes */ }
+       {
+               /* Intel Clovertrail */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe006),
+               .driver_data = (kernel_ulong_t)&penwell_pci_platdata,
+       },
+       { 0 } /* end: all zeroes */
 };
 MODULE_DEVICE_TABLE(pci, ci_hdrc_pci_id_table);
 
index 0658908..44cf775 100644 (file)
@@ -2256,6 +2256,8 @@ static int ffs_func_bind(struct usb_configuration *c,
                                   data->raw_descs + ret,
                                   (sizeof data->raw_descs) - ret,
                                   __ffs_func_bind_do_descs, func);
+               if (unlikely(ret < 0))
+                       goto error;
        }
 
        /*
index cc92074..0ac6064 100644 (file)
@@ -2054,7 +2054,7 @@ static struct pxa25x_udc memory = {
 /*
  *     probe - binds to the platform device
  */
-static int __init pxa25x_udc_probe(struct platform_device *pdev)
+static int pxa25x_udc_probe(struct platform_device *pdev)
 {
        struct pxa25x_udc *dev = &memory;
        int retval, irq;
@@ -2203,7 +2203,7 @@ static void pxa25x_udc_shutdown(struct platform_device *_dev)
        pullup_off();
 }
 
-static int __exit pxa25x_udc_remove(struct platform_device *pdev)
+static int pxa25x_udc_remove(struct platform_device *pdev)
 {
        struct pxa25x_udc *dev = platform_get_drvdata(pdev);
 
@@ -2294,7 +2294,8 @@ static int pxa25x_udc_resume(struct platform_device *dev)
 
 static struct platform_driver udc_driver = {
        .shutdown       = pxa25x_udc_shutdown,
-       .remove         = __exit_p(pxa25x_udc_remove),
+       .probe          = pxa25x_udc_probe,
+       .remove         = pxa25x_udc_remove,
        .suspend        = pxa25x_udc_suspend,
        .resume         = pxa25x_udc_resume,
        .driver         = {
@@ -2303,7 +2304,7 @@ static struct platform_driver udc_driver = {
        },
 };
 
-module_platform_driver_probe(udc_driver, pxa25x_udc_probe);
+module_platform_driver(udc_driver);
 
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_AUTHOR("Frank Becker, Robert Schwebel, David Brownell");
index 6bddf1a..a8a99e4 100644 (file)
@@ -543,7 +543,7 @@ static int s3c_hsotg_write_fifo(struct s3c_hsotg *hsotg,
         * FIFO, requests of >512 cause the endpoint to get stuck with a
         * fragment of the end of the transfer in it.
         */
-       if (can_write > 512)
+       if (can_write > 512 && !periodic)
                can_write = 512;
 
        /*
index 4047cbb..bd4138d 100644 (file)
@@ -535,6 +535,9 @@ static int dsps_probe(struct platform_device *pdev)
        struct dsps_glue *glue;
        int ret;
 
+       if (!strcmp(pdev->name, "musb-hdrc"))
+               return -ENODEV;
+
        match = of_match_node(musb_dsps_of_match, pdev->dev.of_node);
        if (!match) {
                dev_err(&pdev->dev, "fail to get matching of_match struct\n");
index 9a08679..b19ed21 100644 (file)
@@ -1790,6 +1790,10 @@ int musb_gadget_setup(struct musb *musb)
        musb->g.max_speed = USB_SPEED_HIGH;
        musb->g.speed = USB_SPEED_UNKNOWN;
 
+       MUSB_DEV_MODE(musb);
+       musb->xceiv->otg->default_a = 0;
+       musb->xceiv->state = OTG_STATE_B_IDLE;
+
        /* this "gadget" abstracts/virtualizes the controller */
        musb->g.name = musb_driver_name;
        musb->g.is_otg = 1;
@@ -1849,7 +1853,6 @@ static int musb_gadget_start(struct usb_gadget *g,
        musb->gadget_driver = driver;
 
        spin_lock_irqsave(&musb->lock, flags);
-       musb->is_active = 1;
 
        otg_set_peripheral(otg, &musb->g);
        musb->xceiv->state = OTG_STATE_B_IDLE;
index b2f29c9..02799a5 100644 (file)
@@ -241,7 +241,7 @@ static int gpio_vbus_set_suspend(struct usb_phy *phy, int suspend)
 
 /* platform driver interface */
 
-static int __init gpio_vbus_probe(struct platform_device *pdev)
+static int gpio_vbus_probe(struct platform_device *pdev)
 {
        struct gpio_vbus_mach_info *pdata = dev_get_platdata(&pdev->dev);
        struct gpio_vbus_data *gpio_vbus;
@@ -349,7 +349,7 @@ err_gpio:
        return err;
 }
 
-static int __exit gpio_vbus_remove(struct platform_device *pdev)
+static int gpio_vbus_remove(struct platform_device *pdev)
 {
        struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev);
        struct gpio_vbus_mach_info *pdata = dev_get_platdata(&pdev->dev);
@@ -398,8 +398,6 @@ static const struct dev_pm_ops gpio_vbus_dev_pm_ops = {
 };
 #endif
 
-/* NOTE:  the gpio-vbus device may *NOT* be hotplugged */
-
 MODULE_ALIAS("platform:gpio-vbus");
 
 static struct platform_driver gpio_vbus_driver = {
@@ -410,10 +408,11 @@ static struct platform_driver gpio_vbus_driver = {
                .pm = &gpio_vbus_dev_pm_ops,
 #endif
        },
-       .remove  = __exit_p(gpio_vbus_remove),
+       .probe          = gpio_vbus_probe,
+       .remove         = gpio_vbus_remove,
 };
 
-module_platform_driver_probe(gpio_vbus_driver, gpio_vbus_probe);
+module_platform_driver(gpio_vbus_driver);
 
 MODULE_DESCRIPTION("simple GPIO controlled OTG transceiver driver");
 MODULE_AUTHOR("Philipp Zabel");
index 1cf6f12..80a7104 100644 (file)
@@ -81,6 +81,7 @@ static void option_instat_callback(struct urb *urb);
 
 #define HUAWEI_VENDOR_ID                       0x12D1
 #define HUAWEI_PRODUCT_E173                    0x140C
+#define HUAWEI_PRODUCT_E1750                   0x1406
 #define HUAWEI_PRODUCT_K4505                   0x1464
 #define HUAWEI_PRODUCT_K3765                   0x1465
 #define HUAWEI_PRODUCT_K4605                   0x14C6
@@ -567,6 +568,8 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff),
                .driver_info = (kernel_ulong_t) &net_intf1_blacklist },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1750, 0xff, 0xff, 0xff),
+               .driver_info = (kernel_ulong_t) &net_intf2_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1441, USB_CLASS_COMM, 0x02, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1442, USB_CLASS_COMM, 0x02, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff),
index 592b316..ce5221f 100644 (file)
@@ -728,7 +728,12 @@ vhost_scsi_get_tag(struct vhost_virtqueue *vq,
        }
        se_sess = tv_nexus->tvn_se_sess;
 
-       tag = percpu_ida_alloc(&se_sess->sess_tag_pool, GFP_KERNEL);
+       tag = percpu_ida_alloc(&se_sess->sess_tag_pool, GFP_ATOMIC);
+       if (tag < 0) {
+               pr_err("Unable to obtain tag for tcm_vhost_cmd\n");
+               return ERR_PTR(-ENOMEM);
+       }
+
        cmd = &((struct tcm_vhost_cmd *)se_sess->sess_cmd_map)[tag];
        sg = cmd->tvc_sgl;
        pages = cmd->tvc_upages;
index 58b7d14..08cc08f 100644 (file)
@@ -107,7 +107,8 @@ static void check_idle_worker(struct btrfs_worker_thread *worker)
                worker->idle = 1;
 
                /* the list may be empty if the worker is just starting */
-               if (!list_empty(&worker->worker_list)) {
+               if (!list_empty(&worker->worker_list) &&
+                   !worker->workers->stopping) {
                        list_move(&worker->worker_list,
                                 &worker->workers->idle_list);
                }
@@ -127,7 +128,8 @@ static void check_busy_worker(struct btrfs_worker_thread *worker)
                spin_lock_irqsave(&worker->workers->lock, flags);
                worker->idle = 0;
 
-               if (!list_empty(&worker->worker_list)) {
+               if (!list_empty(&worker->worker_list) &&
+                   !worker->workers->stopping) {
                        list_move_tail(&worker->worker_list,
                                      &worker->workers->worker_list);
                }
@@ -412,6 +414,7 @@ void btrfs_stop_workers(struct btrfs_workers *workers)
        int can_stop;
 
        spin_lock_irq(&workers->lock);
+       workers->stopping = 1;
        list_splice_init(&workers->idle_list, &workers->worker_list);
        while (!list_empty(&workers->worker_list)) {
                cur = workers->worker_list.next;
@@ -455,6 +458,7 @@ void btrfs_init_workers(struct btrfs_workers *workers, char *name, int max,
        workers->ordered = 0;
        workers->atomic_start_pending = 0;
        workers->atomic_worker_start = async_helper;
+       workers->stopping = 0;
 }
 
 /*
@@ -480,15 +484,19 @@ static int __btrfs_start_workers(struct btrfs_workers *workers)
        atomic_set(&worker->num_pending, 0);
        atomic_set(&worker->refs, 1);
        worker->workers = workers;
-       worker->task = kthread_run(worker_loop, worker,
-                                  "btrfs-%s-%d", workers->name,
-                                  workers->num_workers + 1);
+       worker->task = kthread_create(worker_loop, worker,
+                                     "btrfs-%s-%d", workers->name,
+                                     workers->num_workers + 1);
        if (IS_ERR(worker->task)) {
                ret = PTR_ERR(worker->task);
-               kfree(worker);
                goto fail;
        }
+
        spin_lock_irq(&workers->lock);
+       if (workers->stopping) {
+               spin_unlock_irq(&workers->lock);
+               goto fail_kthread;
+       }
        list_add_tail(&worker->worker_list, &workers->idle_list);
        worker->idle = 1;
        workers->num_workers++;
@@ -496,8 +504,13 @@ static int __btrfs_start_workers(struct btrfs_workers *workers)
        WARN_ON(workers->num_workers_starting < 0);
        spin_unlock_irq(&workers->lock);
 
+       wake_up_process(worker->task);
        return 0;
+
+fail_kthread:
+       kthread_stop(worker->task);
 fail:
+       kfree(worker);
        spin_lock_irq(&workers->lock);
        workers->num_workers_starting--;
        spin_unlock_irq(&workers->lock);
index 063698b..1f26792 100644 (file)
@@ -107,6 +107,8 @@ struct btrfs_workers {
 
        /* extra name for this worker, used for current->name */
        char *name;
+
+       int stopping;
 };
 
 void btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work);
index 7068168..9efb94e 100644 (file)
@@ -535,10 +535,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
        list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list);
 
        btrfs_rm_dev_replace_srcdev(fs_info, src_device);
-       if (src_device->bdev) {
-               /* zero out the old super */
-               btrfs_scratch_superblock(src_device);
-       }
+
        /*
         * this is again a consistent state where no dev_replace procedure
         * is running, the target device is part of the filesystem, the
index c09a40d..22bda32 100644 (file)
@@ -145,8 +145,16 @@ int __init extent_io_init(void)
                                     offsetof(struct btrfs_io_bio, bio));
        if (!btrfs_bioset)
                goto free_buffer_cache;
+
+       if (bioset_integrity_create(btrfs_bioset, BIO_POOL_SIZE))
+               goto free_bioset;
+
        return 0;
 
+free_bioset:
+       bioset_free(btrfs_bioset);
+       btrfs_bioset = NULL;
+
 free_buffer_cache:
        kmem_cache_destroy(extent_buffer_cache);
        extent_buffer_cache = NULL;
@@ -1614,7 +1622,7 @@ again:
                *start = delalloc_start;
                *end = delalloc_end;
                free_extent_state(cached_state);
-               return found;
+               return 0;
        }
 
        /*
index e7a9535..8c81bdc 100644 (file)
@@ -1838,11 +1838,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
        assert_qgroups_uptodate(trans);
        update_super_roots(root);
 
-       if (!root->fs_info->log_root_recovering) {
-               btrfs_set_super_log_root(root->fs_info->super_copy, 0);
-               btrfs_set_super_log_root_level(root->fs_info->super_copy, 0);
-       }
-
+       btrfs_set_super_log_root(root->fs_info->super_copy, 0);
+       btrfs_set_super_log_root_level(root->fs_info->super_copy, 0);
        memcpy(root->fs_info->super_for_commit, root->fs_info->super_copy,
               sizeof(*root->fs_info->super_copy));
 
index a106458..043b215 100644 (file)
@@ -1716,6 +1716,7 @@ void btrfs_rm_dev_replace_srcdev(struct btrfs_fs_info *fs_info,
                                 struct btrfs_device *srcdev)
 {
        WARN_ON(!mutex_is_locked(&fs_info->fs_devices->device_list_mutex));
+
        list_del_rcu(&srcdev->dev_list);
        list_del_rcu(&srcdev->dev_alloc_list);
        fs_info->fs_devices->num_devices--;
@@ -1725,9 +1726,13 @@ void btrfs_rm_dev_replace_srcdev(struct btrfs_fs_info *fs_info,
        }
        if (srcdev->can_discard)
                fs_info->fs_devices->num_can_discard--;
-       if (srcdev->bdev)
+       if (srcdev->bdev) {
                fs_info->fs_devices->open_devices--;
 
+               /* zero out the old super */
+               btrfs_scratch_superblock(srcdev);
+       }
+
        call_rcu(&srcdev->rcu, free_device);
 }
 
index ea723a5..6d0b072 100644 (file)
@@ -132,5 +132,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
 extern const struct export_operations cifs_export_ops;
 #endif /* CONFIG_CIFS_NFSD_EXPORT */
 
-#define CIFS_VERSION   "2.01"
+#define CIFS_VERSION   "2.02"
 #endif                         /* _CIFSFS_H */
index cfa14c8..52b6f6c 100644 (file)
@@ -547,9 +547,6 @@ struct TCP_Server_Info {
        unsigned int max_rw;    /* maxRw specifies the maximum */
        /* message size the server can send or receive for */
        /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */
-       unsigned int max_vcs;   /* maximum number of smb sessions, at least
-                                  those that can be specified uniquely with
-                                  vcnumbers */
        unsigned int capabilities; /* selective disabling of caps by smb sess */
        int timeAdj;  /* Adjust for difference in server time zone in sec */
        __u64 CurrentMid;         /* multiplex id - rotating counter */
@@ -715,7 +712,6 @@ struct cifs_ses {
        enum statusEnum status;
        unsigned overrideSecFlg;  /* if non-zero override global sec flags */
        __u16 ipc_tid;          /* special tid for connection to IPC share */
-       __u16 vcnum;
        char *serverOS;         /* name of operating system underlying server */
        char *serverNOS;        /* name of network operating system of server */
        char *serverDomain;     /* security realm of server */
@@ -1272,6 +1268,7 @@ struct dfs_info3_param {
 #define CIFS_FATTR_DELETE_PENDING      0x2
 #define CIFS_FATTR_NEED_REVAL          0x4
 #define CIFS_FATTR_INO_COLLISION       0x8
+#define CIFS_FATTR_UNKNOWN_NLINK       0x10
 
 struct cifs_fattr {
        u32             cf_flags;
index 948676d..a630475 100644 (file)
@@ -2652,26 +2652,7 @@ typedef struct file_xattr_info {
 } __attribute__((packed)) FILE_XATTR_INFO; /* extended attribute info
                                              level 0x205 */
 
-
-/* flags for chattr command */
-#define EXT_SECURE_DELETE              0x00000001 /* EXT3_SECRM_FL */
-#define EXT_ENABLE_UNDELETE            0x00000002 /* EXT3_UNRM_FL */
-/* Reserved for compress file 0x4 */
-#define EXT_SYNCHRONOUS                        0x00000008 /* EXT3_SYNC_FL */
-#define EXT_IMMUTABLE_FL               0x00000010 /* EXT3_IMMUTABLE_FL */
-#define EXT_OPEN_APPEND_ONLY           0x00000020 /* EXT3_APPEND_FL */
-#define EXT_DO_NOT_BACKUP              0x00000040 /* EXT3_NODUMP_FL */
-#define EXT_NO_UPDATE_ATIME            0x00000080 /* EXT3_NOATIME_FL */
-/* 0x100 through 0x800 reserved for compression flags and are GET-ONLY */
-#define EXT_HASH_TREE_INDEXED_DIR      0x00001000 /* GET-ONLY EXT3_INDEX_FL */
-/* 0x2000 reserved for IMAGIC_FL */
-#define EXT_JOURNAL_THIS_FILE  0x00004000 /* GET-ONLY EXT3_JOURNAL_DATA_FL */
-/* 0x8000 reserved for EXT3_NOTAIL_FL */
-#define EXT_SYNCHRONOUS_DIR            0x00010000 /* EXT3_DIRSYNC_FL */
-#define EXT_TOPDIR                     0x00020000 /* EXT3_TOPDIR_FL */
-
-#define EXT_SET_MASK                   0x000300FF
-#define EXT_GET_MASK                   0x0003DFFF
+/* flags for lsattr and chflags commands removed arein uapi/linux/fs.h */
 
 typedef struct file_chattr_info {
        __le64  mask; /* list of all possible attribute bits */
index a3d74fe..4baf359 100644 (file)
@@ -463,7 +463,6 @@ decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
                               cifs_max_pending);
        set_credits(server, server->maxReq);
        server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
-       server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs);
        /* even though we do not use raw we might as well set this
        accurately, in case we ever find a need for it */
        if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
index eb955b5..7ddddf2 100644 (file)
@@ -3254,6 +3254,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
        /*
         * Reads as many pages as possible from fscache. Returns -ENOBUFS
         * immediately if the cookie is negative
+        *
+        * After this point, every page in the list might have PG_fscache set,
+        * so we will need to clean that up off of every page we don't use.
         */
        rc = cifs_readpages_from_fscache(mapping->host, mapping, page_list,
                                         &num_pages);
@@ -3376,6 +3379,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                kref_put(&rdata->refcount, cifs_readdata_release);
        }
 
+       /* Any pages that have been shown to fscache but didn't get added to
+        * the pagecache must be uncached before they get returned to the
+        * allocator.
+        */
+       cifs_fscache_readpages_cancel(mapping->host, page_list);
        return rc;
 }
 
index 2f4bc5a..b3258f3 100644 (file)
@@ -223,6 +223,13 @@ void __cifs_readpage_to_fscache(struct inode *inode, struct page *page)
                fscache_uncache_page(CIFS_I(inode)->fscache, page);
 }
 
+void __cifs_fscache_readpages_cancel(struct inode *inode, struct list_head *pages)
+{
+       cifs_dbg(FYI, "%s: (fsc: %p, i: %p)\n",
+                __func__, CIFS_I(inode)->fscache, inode);
+       fscache_readpages_cancel(CIFS_I(inode)->fscache, pages);
+}
+
 void __cifs_fscache_invalidate_page(struct page *page, struct inode *inode)
 {
        struct cifsInodeInfo *cifsi = CIFS_I(inode);
index 6353932..24794b6 100644 (file)
@@ -54,6 +54,7 @@ extern int __cifs_readpages_from_fscache(struct inode *,
                                         struct address_space *,
                                         struct list_head *,
                                         unsigned *);
+extern void __cifs_fscache_readpages_cancel(struct inode *, struct list_head *);
 
 extern void __cifs_readpage_to_fscache(struct inode *, struct page *);
 
@@ -91,6 +92,13 @@ static inline void cifs_readpage_to_fscache(struct inode *inode,
                __cifs_readpage_to_fscache(inode, page);
 }
 
+static inline void cifs_fscache_readpages_cancel(struct inode *inode,
+                                                struct list_head *pages)
+{
+       if (CIFS_I(inode)->fscache)
+               return __cifs_fscache_readpages_cancel(inode, pages);
+}
+
 #else /* CONFIG_CIFS_FSCACHE */
 static inline int cifs_fscache_register(void) { return 0; }
 static inline void cifs_fscache_unregister(void) {}
@@ -131,6 +139,11 @@ static inline int cifs_readpages_from_fscache(struct inode *inode,
 static inline void cifs_readpage_to_fscache(struct inode *inode,
                        struct page *page) {}
 
+static inline void cifs_fscache_readpages_cancel(struct inode *inode,
+                                                struct list_head *pages)
+{
+}
+
 #endif /* CONFIG_CIFS_FSCACHE */
 
 #endif /* _CIFS_FSCACHE_H */
index f9ff9c1..867b7cd 100644 (file)
@@ -120,6 +120,33 @@ cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
        cifs_i->invalid_mapping = true;
 }
 
+/*
+ * copy nlink to the inode, unless it wasn't provided.  Provide
+ * sane values if we don't have an existing one and none was provided
+ */
+static void
+cifs_nlink_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
+{
+       /*
+        * if we're in a situation where we can't trust what we
+        * got from the server (readdir, some non-unix cases)
+        * fake reasonable values
+        */
+       if (fattr->cf_flags & CIFS_FATTR_UNKNOWN_NLINK) {
+               /* only provide fake values on a new inode */
+               if (inode->i_state & I_NEW) {
+                       if (fattr->cf_cifsattrs & ATTR_DIRECTORY)
+                               set_nlink(inode, 2);
+                       else
+                               set_nlink(inode, 1);
+               }
+               return;
+       }
+
+       /* we trust the server, so update it */
+       set_nlink(inode, fattr->cf_nlink);
+}
+
 /* populate an inode with info from a cifs_fattr struct */
 void
 cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
@@ -134,7 +161,7 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
        inode->i_mtime = fattr->cf_mtime;
        inode->i_ctime = fattr->cf_ctime;
        inode->i_rdev = fattr->cf_rdev;
-       set_nlink(inode, fattr->cf_nlink);
+       cifs_nlink_fattr_to_inode(inode, fattr);
        inode->i_uid = fattr->cf_uid;
        inode->i_gid = fattr->cf_gid;
 
@@ -541,6 +568,7 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
        fattr->cf_bytes = le64_to_cpu(info->AllocationSize);
        fattr->cf_createtime = le64_to_cpu(info->CreationTime);
 
+       fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks);
        if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
                fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
                fattr->cf_dtype = DT_DIR;
@@ -548,7 +576,8 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
                 * Server can return wrong NumberOfLinks value for directories
                 * when Unix extensions are disabled - fake it.
                 */
-               fattr->cf_nlink = 2;
+               if (!tcon->unix_ext)
+                       fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK;
        } else if (fattr->cf_cifsattrs & ATTR_REPARSE) {
                fattr->cf_mode = S_IFLNK;
                fattr->cf_dtype = DT_LNK;
@@ -561,11 +590,15 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
                if (fattr->cf_cifsattrs & ATTR_READONLY)
                        fattr->cf_mode &= ~(S_IWUGO);
 
-               fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks);
-               if (fattr->cf_nlink < 1) {
-                       cifs_dbg(1, "replacing bogus file nlink value %u\n",
+               /*
+                * Don't accept zero nlink from non-unix servers unless
+                * delete is pending.  Instead mark it as unknown.
+                */
+               if ((fattr->cf_nlink < 1) && !tcon->unix_ext &&
+                   !info->DeletePending) {
+                       cifs_dbg(1, "bogus file nlink value %u\n",
                                fattr->cf_nlink);
-                       fattr->cf_nlink = 1;
+                       fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK;
                }
        }
 
index 42ef03b..53a75f3 100644 (file)
@@ -180,6 +180,9 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
                fattr->cf_dtype = DT_REG;
        }
 
+       /* non-unix readdir doesn't provide nlink */
+       fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK;
+
        if (fattr->cf_cifsattrs & ATTR_READONLY)
                fattr->cf_mode &= ~S_IWUGO;
 
index 5f99b7f..352358d 100644 (file)
 #include <linux/slab.h>
 #include "cifs_spnego.h"
 
-/*
- * Checks if this is the first smb session to be reconnected after
- * the socket has been reestablished (so we know whether to use vc 0).
- * Called while holding the cifs_tcp_ses_lock, so do not block
- */
-static bool is_first_ses_reconnect(struct cifs_ses *ses)
-{
-       struct list_head *tmp;
-       struct cifs_ses *tmp_ses;
-
-       list_for_each(tmp, &ses->server->smb_ses_list) {
-               tmp_ses = list_entry(tmp, struct cifs_ses,
-                                    smb_ses_list);
-               if (tmp_ses->need_reconnect == false)
-                       return false;
-       }
-       /* could not find a session that was already connected,
-          this must be the first one we are reconnecting */
-       return true;
-}
-
-/*
- *     vc number 0 is treated specially by some servers, and should be the
- *      first one we request.  After that we can use vcnumbers up to maxvcs,
- *     one for each smb session (some Windows versions set maxvcs incorrectly
- *     so maxvc=1 can be ignored).  If we have too many vcs, we can reuse
- *     any vc but zero (some servers reset the connection on vcnum zero)
- *
- */
-static __le16 get_next_vcnum(struct cifs_ses *ses)
-{
-       __u16 vcnum = 0;
-       struct list_head *tmp;
-       struct cifs_ses *tmp_ses;
-       __u16 max_vcs = ses->server->max_vcs;
-       __u16 i;
-       int free_vc_found = 0;
-
-       /* Quoting the MS-SMB specification: "Windows-based SMB servers set this
-       field to one but do not enforce this limit, which allows an SMB client
-       to establish more virtual circuits than allowed by this value ... but
-       other server implementations can enforce this limit." */
-       if (max_vcs < 2)
-               max_vcs = 0xFFFF;
-
-       spin_lock(&cifs_tcp_ses_lock);
-       if ((ses->need_reconnect) && is_first_ses_reconnect(ses))
-                       goto get_vc_num_exit;  /* vcnum will be zero */
-       for (i = ses->server->srv_count - 1; i < max_vcs; i++) {
-               if (i == 0) /* this is the only connection, use vc 0 */
-                       break;
-
-               free_vc_found = 1;
-
-               list_for_each(tmp, &ses->server->smb_ses_list) {
-                       tmp_ses = list_entry(tmp, struct cifs_ses,
-                                            smb_ses_list);
-                       if (tmp_ses->vcnum == i) {
-                               free_vc_found = 0;
-                               break; /* found duplicate, try next vcnum */
-                       }
-               }
-               if (free_vc_found)
-                       break; /* we found a vcnumber that will work - use it */
-       }
-
-       if (i == 0)
-               vcnum = 0; /* for most common case, ie if one smb session, use
-                             vc zero.  Also for case when no free vcnum, zero
-                             is safest to send (some clients only send zero) */
-       else if (free_vc_found == 0)
-               vcnum = 1;  /* we can not reuse vc=0 safely, since some servers
-                               reset all uids on that, but 1 is ok. */
-       else
-               vcnum = i;
-       ses->vcnum = vcnum;
-get_vc_num_exit:
-       spin_unlock(&cifs_tcp_ses_lock);
-
-       return cpu_to_le16(vcnum);
-}
-
 static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB)
 {
        __u32 capabilities = 0;
@@ -128,7 +46,7 @@ static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB)
                                        CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4,
                                        USHRT_MAX));
        pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
-       pSMB->req.VcNumber = get_next_vcnum(ses);
+       pSMB->req.VcNumber = __constant_cpu_to_le16(1);
 
        /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
 
index 62b43b5..b7989f2 100644 (file)
@@ -182,6 +182,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
        struct inode *inode;
        struct dentry *parent;
        struct fuse_conn *fc;
+       struct fuse_inode *fi;
        int ret;
 
        inode = ACCESS_ONCE(entry->d_inode);
@@ -228,7 +229,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
                if (!err && !outarg.nodeid)
                        err = -ENOENT;
                if (!err) {
-                       struct fuse_inode *fi = get_fuse_inode(inode);
+                       fi = get_fuse_inode(inode);
                        if (outarg.nodeid != get_node_id(inode)) {
                                fuse_queue_forget(fc, forget, outarg.nodeid, 1);
                                goto invalid;
@@ -246,8 +247,11 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
                                       attr_version);
                fuse_change_entry_timeout(entry, &outarg);
        } else if (inode) {
-               fc = get_fuse_conn(inode);
-               if (fc->readdirplus_auto) {
+               fi = get_fuse_inode(inode);
+               if (flags & LOOKUP_RCU) {
+                       if (test_bit(FUSE_I_INIT_RDPLUS, &fi->state))
+                               return -ECHILD;
+               } else if (test_and_clear_bit(FUSE_I_INIT_RDPLUS, &fi->state)) {
                        parent = dget_parent(entry);
                        fuse_advise_use_readdirplus(parent->d_inode);
                        dput(parent);
@@ -259,7 +263,8 @@ out:
 
 invalid:
        ret = 0;
-       if (check_submounts_and_drop(entry) != 0)
+
+       if (!(flags & LOOKUP_RCU) && check_submounts_and_drop(entry) != 0)
                ret = 1;
        goto out;
 }
@@ -1063,6 +1068,8 @@ static int fuse_access(struct inode *inode, int mask)
        struct fuse_access_in inarg;
        int err;
 
+       BUG_ON(mask & MAY_NOT_BLOCK);
+
        if (fc->no_access)
                return 0;
 
@@ -1150,9 +1157,6 @@ static int fuse_permission(struct inode *inode, int mask)
                   noticed immediately, only after the attribute
                   timeout has expired */
        } else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
-               if (mask & MAY_NOT_BLOCK)
-                       return -ECHILD;
-
                err = fuse_access(inode, mask);
        } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
                if (!(inode->i_mode & S_IXUGO)) {
@@ -1291,6 +1295,8 @@ static int fuse_direntplus_link(struct file *file,
        }
 
 found:
+       if (fc->readdirplus_auto)
+               set_bit(FUSE_I_INIT_RDPLUS, &get_fuse_inode(inode)->state);
        fuse_change_entry_timeout(dentry, o);
 
        err = 0;
index d409dea..4598345 100644 (file)
@@ -2467,6 +2467,7 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
 {
        struct fuse_file *ff = file->private_data;
        struct inode *inode = file->f_inode;
+       struct fuse_inode *fi = get_fuse_inode(inode);
        struct fuse_conn *fc = ff->fc;
        struct fuse_req *req;
        struct fuse_fallocate_in inarg = {
@@ -2484,10 +2485,20 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
 
        if (lock_inode) {
                mutex_lock(&inode->i_mutex);
-               if (mode & FALLOC_FL_PUNCH_HOLE)
-                       fuse_set_nowrite(inode);
+               if (mode & FALLOC_FL_PUNCH_HOLE) {
+                       loff_t endbyte = offset + length - 1;
+                       err = filemap_write_and_wait_range(inode->i_mapping,
+                                                          offset, endbyte);
+                       if (err)
+                               goto out;
+
+                       fuse_sync_writes(inode);
+               }
        }
 
+       if (!(mode & FALLOC_FL_KEEP_SIZE))
+               set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
+
        req = fuse_get_req_nopages(fc);
        if (IS_ERR(req)) {
                err = PTR_ERR(req);
@@ -2520,11 +2531,11 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
        fuse_invalidate_attr(inode);
 
 out:
-       if (lock_inode) {
-               if (mode & FALLOC_FL_PUNCH_HOLE)
-                       fuse_release_nowrite(inode);
+       if (!(mode & FALLOC_FL_KEEP_SIZE))
+               clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
+
+       if (lock_inode)
                mutex_unlock(&inode->i_mutex);
-       }
 
        return err;
 }
index 5ced199..5b9e6f3 100644 (file)
@@ -115,6 +115,8 @@ struct fuse_inode {
 enum {
        /** Advise readdirplus  */
        FUSE_I_ADVISE_RDPLUS,
+       /** Initialized with readdirplus */
+       FUSE_I_INIT_RDPLUS,
        /** An operation changing file size is in progress  */
        FUSE_I_SIZE_UNSTABLE,
 };
index 0957aa9..12dad18 100644 (file)
@@ -1158,7 +1158,7 @@ xfs_dir2_sf_to_block(
        /*
         * Create entry for .
         */
-       dep = xfs_dir3_data_dot_entry_p(hdr);
+       dep = xfs_dir3_data_dot_entry_p(mp, hdr);
        dep->inumber = cpu_to_be64(dp->i_ino);
        dep->namelen = 1;
        dep->name[0] = '.';
@@ -1172,7 +1172,7 @@ xfs_dir2_sf_to_block(
        /*
         * Create entry for ..
         */
-       dep = xfs_dir3_data_dotdot_entry_p(hdr);
+       dep = xfs_dir3_data_dotdot_entry_p(mp, hdr);
        dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp));
        dep->namelen = 2;
        dep->name[0] = dep->name[1] = '.';
@@ -1183,7 +1183,7 @@ xfs_dir2_sf_to_block(
        blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot);
        blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp,
                                (char *)dep - (char *)hdr));
-       offset = xfs_dir3_data_first_offset(hdr);
+       offset = xfs_dir3_data_first_offset(mp);
        /*
         * Loop over existing entries, stuff them in.
         */
index a0961a6..9cf6738 100644 (file)
@@ -497,69 +497,58 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
 /*
  * Offsets of . and .. in data space (always block 0)
  *
- * The macros are used for shortform directories as they have no headers to read
- * the magic number out of. Shortform directories need to know the size of the
- * data block header because the sfe embeds the block offset of the entry into
- * it so that it doesn't change when format conversion occurs. Bad Things Happen
- * if we don't follow this rule.
- *
  * XXX: there is scope for significant optimisation of the logic here. Right
  * now we are checking for "dir3 format" over and over again. Ideally we should
  * only do it once for each operation.
  */
-#define        XFS_DIR3_DATA_DOT_OFFSET(mp)    \
-       xfs_dir3_data_hdr_size(xfs_sb_version_hascrc(&(mp)->m_sb))
-#define        XFS_DIR3_DATA_DOTDOT_OFFSET(mp) \
-       (XFS_DIR3_DATA_DOT_OFFSET(mp) + xfs_dir3_data_entsize(mp, 1))
-#define        XFS_DIR3_DATA_FIRST_OFFSET(mp)          \
-       (XFS_DIR3_DATA_DOTDOT_OFFSET(mp) + xfs_dir3_data_entsize(mp, 2))
-
 static inline xfs_dir2_data_aoff_t
-xfs_dir3_data_dot_offset(struct xfs_dir2_data_hdr *hdr)
+xfs_dir3_data_dot_offset(struct xfs_mount *mp)
 {
-       return xfs_dir3_data_entry_offset(hdr);
+       return xfs_dir3_data_hdr_size(xfs_sb_version_hascrc(&mp->m_sb));
 }
 
 static inline xfs_dir2_data_aoff_t
-xfs_dir3_data_dotdot_offset(struct xfs_dir2_data_hdr *hdr)
+xfs_dir3_data_dotdot_offset(struct xfs_mount *mp)
 {
-       bool dir3 = hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
-                   hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC);
-       return xfs_dir3_data_dot_offset(hdr) +
-               __xfs_dir3_data_entsize(dir3, 1);
+       return xfs_dir3_data_dot_offset(mp) +
+               xfs_dir3_data_entsize(mp, 1);
 }
 
 static inline xfs_dir2_data_aoff_t
-xfs_dir3_data_first_offset(struct xfs_dir2_data_hdr *hdr)
+xfs_dir3_data_first_offset(struct xfs_mount *mp)
 {
-       bool dir3 = hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
-                   hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC);
-       return xfs_dir3_data_dotdot_offset(hdr) +
-               __xfs_dir3_data_entsize(dir3, 2);
+       return xfs_dir3_data_dotdot_offset(mp) +
+               xfs_dir3_data_entsize(mp, 2);
 }
 
 /*
  * location of . and .. in data space (always block 0)
  */
 static inline struct xfs_dir2_data_entry *
-xfs_dir3_data_dot_entry_p(struct xfs_dir2_data_hdr *hdr)
+xfs_dir3_data_dot_entry_p(
+       struct xfs_mount        *mp,
+       struct xfs_dir2_data_hdr *hdr)
 {
        return (struct xfs_dir2_data_entry *)
-               ((char *)hdr + xfs_dir3_data_dot_offset(hdr));
+               ((char *)hdr + xfs_dir3_data_dot_offset(mp));
 }
 
 static inline struct xfs_dir2_data_entry *
-xfs_dir3_data_dotdot_entry_p(struct xfs_dir2_data_hdr *hdr)
+xfs_dir3_data_dotdot_entry_p(
+       struct xfs_mount        *mp,
+       struct xfs_dir2_data_hdr *hdr)
 {
        return (struct xfs_dir2_data_entry *)
-               ((char *)hdr + xfs_dir3_data_dotdot_offset(hdr));
+               ((char *)hdr + xfs_dir3_data_dotdot_offset(mp));
 }
 
 static inline struct xfs_dir2_data_entry *
-xfs_dir3_data_first_entry_p(struct xfs_dir2_data_hdr *hdr)
+xfs_dir3_data_first_entry_p(
+       struct xfs_mount        *mp,
+       struct xfs_dir2_data_hdr *hdr)
 {
        return (struct xfs_dir2_data_entry *)
-               ((char *)hdr + xfs_dir3_data_first_offset(hdr));
+               ((char *)hdr + xfs_dir3_data_first_offset(mp));
 }
 
 /*
index 8993ec1..8f84153 100644 (file)
@@ -119,9 +119,9 @@ xfs_dir2_sf_getdents(
         * mp->m_dirdatablk.
         */
        dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
-                                            XFS_DIR3_DATA_DOT_OFFSET(mp));
+                                            xfs_dir3_data_dot_offset(mp));
        dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
-                                               XFS_DIR3_DATA_DOTDOT_OFFSET(mp));
+                                               xfs_dir3_data_dotdot_offset(mp));
 
        /*
         * Put . entry unless we're starting past it.
index bb6e284..3ef6d40 100644 (file)
@@ -557,7 +557,7 @@ xfs_dir2_sf_addname_hard(
         * to insert the new entry.
         * If it's going to end up at the end then oldsfep will point there.
         */
-       for (offset = XFS_DIR3_DATA_FIRST_OFFSET(mp),
+       for (offset = xfs_dir3_data_first_offset(mp),
              oldsfep = xfs_dir2_sf_firstentry(oldsfp),
              add_datasize = xfs_dir3_data_entsize(mp, args->namelen),
              eof = (char *)oldsfep == &buf[old_isize];
@@ -640,7 +640,7 @@ xfs_dir2_sf_addname_pick(
 
        sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
        size = xfs_dir3_data_entsize(mp, args->namelen);
-       offset = XFS_DIR3_DATA_FIRST_OFFSET(mp);
+       offset = xfs_dir3_data_first_offset(mp);
        sfep = xfs_dir2_sf_firstentry(sfp);
        holefit = 0;
        /*
@@ -713,7 +713,7 @@ xfs_dir2_sf_check(
        mp = dp->i_mount;
 
        sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
-       offset = XFS_DIR3_DATA_FIRST_OFFSET(mp);
+       offset = xfs_dir3_data_first_offset(mp);
        ino = xfs_dir2_sf_get_parent_ino(sfp);
        i8count = ino > XFS_DIR2_MAX_SHORT_INUM;
 
index 71520e6..1ee776d 100644 (file)
@@ -64,7 +64,8 @@ int xfs_dqerror_mod = 33;
 struct kmem_zone               *xfs_qm_dqtrxzone;
 static struct kmem_zone                *xfs_qm_dqzone;
 
-static struct lock_class_key xfs_dquot_other_class;
+static struct lock_class_key xfs_dquot_group_class;
+static struct lock_class_key xfs_dquot_project_class;
 
 /*
  * This is called to free all the memory associated with a dquot
@@ -703,8 +704,20 @@ xfs_qm_dqread(
         * Make sure group quotas have a different lock class than user
         * quotas.
         */
-       if (!(type & XFS_DQ_USER))
-               lockdep_set_class(&dqp->q_qlock, &xfs_dquot_other_class);
+       switch (type) {
+       case XFS_DQ_USER:
+               /* uses the default lock class */
+               break;
+       case XFS_DQ_GROUP:
+               lockdep_set_class(&dqp->q_qlock, &xfs_dquot_group_class);
+               break;
+       case XFS_DQ_PROJ:
+               lockdep_set_class(&dqp->q_qlock, &xfs_dquot_project_class);
+               break;
+       default:
+               ASSERT(0);
+               break;
+       }
 
        XFS_STATS_INC(xs_qm_dquot);
 
index cc17987..3979749 100644 (file)
@@ -1585,6 +1585,7 @@ xlog_recover_add_to_trans(
                "bad number of regions (%d) in inode log format",
                                  in_f->ilf_size);
                        ASSERT(0);
+                       kmem_free(ptr);
                        return XFS_ERROR(EIO);
                }
 
index 78e2ada..d380c5e 100644 (file)
@@ -55,7 +55,7 @@
 #define DMAR_IQT_REG   0x88    /* Invalidation queue tail register */
 #define DMAR_IQ_SHIFT  4       /* Invalidation queue head/tail shift */
 #define DMAR_IQA_REG   0x90    /* Invalidation queue addr register */
-#define DMAR_ICS_REG   0x98    /* Invalidation complete status register */
+#define DMAR_ICS_REG   0x9c    /* Invalidation complete status register */
 #define DMAR_IRTA_REG  0xb8    /* Interrupt remapping table addr register */
 
 #define OFFSET_STRIDE          (9)
index 09c2300..cb35835 100644 (file)
@@ -45,6 +45,7 @@
 #define MAPPER_CTRL_MINOR      236
 #define LOOP_CTRL_MINOR                237
 #define VHOST_NET_MINOR                238
+#define UHID_MINOR             239
 #define MISC_DYNAMIC_MINOR     255
 
 struct device;
index 866e85c..c8ba627 100644 (file)
@@ -294,9 +294,31 @@ struct ring_buffer;
  */
 struct perf_event {
 #ifdef CONFIG_PERF_EVENTS
-       struct list_head                group_entry;
+       /*
+        * entry onto perf_event_context::event_list;
+        *   modifications require ctx->lock
+        *   RCU safe iterations.
+        */
        struct list_head                event_entry;
+
+       /*
+        * XXX: group_entry and sibling_list should be mutually exclusive;
+        * either you're a sibling on a group, or you're the group leader.
+        * Rework the code to always use the same list element.
+        *
+        * Locked for modification by both ctx->mutex and ctx->lock; holding
+        * either sufficies for read.
+        */
+       struct list_head                group_entry;
        struct list_head                sibling_list;
+
+       /*
+        * We need storage to track the entries in perf_pmu_migrate_context; we
+        * cannot use the event_entry because of RCU and we want to keep the
+        * group in tact which avoids us using the other two entries.
+        */
+       struct list_head                migrate_entry;
+
        struct hlist_node               hlist_entry;
        int                             nr_siblings;
        int                             group_flags;
index cb4238e..d49a9d2 100644 (file)
@@ -7234,15 +7234,15 @@ void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu)
                perf_remove_from_context(event);
                unaccount_event_cpu(event, src_cpu);
                put_ctx(src_ctx);
-               list_add(&event->event_entry, &events);
+               list_add(&event->migrate_entry, &events);
        }
        mutex_unlock(&src_ctx->mutex);
 
        synchronize_rcu();
 
        mutex_lock(&dst_ctx->mutex);
-       list_for_each_entry_safe(event, tmp, &events, event_entry) {
-               list_del(&event->event_entry);
+       list_for_each_entry_safe(event, tmp, &events, migrate_entry) {
+               list_del(&event->migrate_entry);
                if (event->state >= PERF_EVENT_STATE_OFF)
                        event->state = PERF_EVENT_STATE_INACTIVE;
                account_event_cpu(event, dst_cpu);
index 358a146..98c3b34 100644 (file)
@@ -743,7 +743,10 @@ int create_basic_memory_bitmaps(void)
        struct memory_bitmap *bm1, *bm2;
        int error = 0;
 
-       BUG_ON(forbidden_pages_map || free_pages_map);
+       if (forbidden_pages_map && free_pages_map)
+               return 0;
+       else
+               BUG_ON(forbidden_pages_map || free_pages_map);
 
        bm1 = kzalloc(sizeof(struct memory_bitmap), GFP_KERNEL);
        if (!bm1)
index 72e8f4f..957f061 100644 (file)
@@ -39,6 +39,7 @@ static struct snapshot_data {
        char frozen;
        char ready;
        char platform_support;
+       bool free_bitmaps;
 } snapshot_state;
 
 atomic_t snapshot_device_available = ATOMIC_INIT(1);
@@ -82,6 +83,10 @@ static int snapshot_open(struct inode *inode, struct file *filp)
                data->swap = -1;
                data->mode = O_WRONLY;
                error = pm_notifier_call_chain(PM_RESTORE_PREPARE);
+               if (!error) {
+                       error = create_basic_memory_bitmaps();
+                       data->free_bitmaps = !error;
+               }
                if (error)
                        pm_notifier_call_chain(PM_POST_RESTORE);
        }
@@ -111,6 +116,8 @@ static int snapshot_release(struct inode *inode, struct file *filp)
                pm_restore_gfp_mask();
                free_basic_memory_bitmaps();
                thaw_processes();
+       } else if (data->free_bitmaps) {
+               free_basic_memory_bitmaps();
        }
        pm_notifier_call_chain(data->mode == O_RDONLY ?
                        PM_POST_HIBERNATION : PM_POST_RESTORE);
@@ -231,6 +238,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
                        break;
                pm_restore_gfp_mask();
                free_basic_memory_bitmaps();
+               data->free_bitmaps = false;
                thaw_processes();
                data->frozen = 0;
                break;
index 53cc09c..d7d498d 100644 (file)
@@ -328,10 +328,19 @@ void irq_enter(void)
 
 static inline void invoke_softirq(void)
 {
-       if (!force_irqthreads)
-               __do_softirq();
-       else
+       if (!force_irqthreads) {
+               /*
+                * We can safely execute softirq on the current stack if
+                * it is the irq stack, because it should be near empty
+                * at this stage. But we have no way to know if the arch
+                * calls irq_exit() on the irq stack. So call softirq
+                * in its own stack to prevent from any overrun on top
+                * of a potentially deep task stack.
+                */
+               do_softirq();
+       } else {
                wakeup_softirqd();
+       }
 }
 
 static inline void tick_irq_exit(void)
index 9bc6db0..e7000be 100644 (file)
@@ -47,12 +47,12 @@ static int net_ctl_permissions(struct ctl_table_header *head,
 
        /* Allow network administrator to have same access as root. */
        if (ns_capable(net->user_ns, CAP_NET_ADMIN) ||
-           uid_eq(root_uid, current_uid())) {
+           uid_eq(root_uid, current_euid())) {
                int mode = (table->mode >> 6) & 7;
                return (mode << 6) | (mode << 3) | mode;
        }
        /* Allow netns root group to have the same access as the root group */
-       if (gid_eq(root_gid, current_gid())) {
+       if (in_egroup_p(root_gid)) {
                int mode = (table->mode >> 3) & 7;
                return (mode << 3) | mode;
        }
index dad36a6..fc3e662 100644 (file)
@@ -746,7 +746,6 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid,
  * @tclass: target security class
  * @requested: requested permissions, interpreted based on @tclass
  * @auditdata: auxiliary audit data
- * @flags: VFS walk flags
  *
  * Check the AVC to determine whether the @requested permissions are granted
  * for the SID pair (@ssid, @tsid), interpreting the permissions
@@ -756,17 +755,15 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid,
  * permissions are granted, -%EACCES if any permissions are denied, or
  * another -errno upon other errors.
  */
-int avc_has_perm_flags(u32 ssid, u32 tsid, u16 tclass,
-                      u32 requested, struct common_audit_data *auditdata,
-                      unsigned flags)
+int avc_has_perm(u32 ssid, u32 tsid, u16 tclass,
+                u32 requested, struct common_audit_data *auditdata)
 {
        struct av_decision avd;
        int rc, rc2;
 
        rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd);
 
-       rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata,
-                       flags);
+       rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata);
        if (rc2)
                return rc2;
        return rc;
index a5091ec..5b52310 100644 (file)
@@ -1502,7 +1502,7 @@ static int cred_has_capability(const struct cred *cred,
 
        rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd);
        if (audit == SECURITY_CAP_AUDIT) {
-               int rc2 = avc_audit(sid, sid, sclass, av, &avd, rc, &ad, 0);
+               int rc2 = avc_audit(sid, sid, sclass, av, &avd, rc, &ad);
                if (rc2)
                        return rc2;
        }
@@ -1525,8 +1525,7 @@ static int task_has_system(struct task_struct *tsk,
 static int inode_has_perm(const struct cred *cred,
                          struct inode *inode,
                          u32 perms,
-                         struct common_audit_data *adp,
-                         unsigned flags)
+                         struct common_audit_data *adp)
 {
        struct inode_security_struct *isec;
        u32 sid;
@@ -1539,7 +1538,7 @@ static int inode_has_perm(const struct cred *cred,
        sid = cred_sid(cred);
        isec = inode->i_security;
 
-       return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
+       return avc_has_perm(sid, isec->sid, isec->sclass, perms, adp);
 }
 
 /* Same as inode_has_perm, but pass explicit audit data containing
@@ -1554,7 +1553,7 @@ static inline int dentry_has_perm(const struct cred *cred,
 
        ad.type = LSM_AUDIT_DATA_DENTRY;
        ad.u.dentry = dentry;
-       return inode_has_perm(cred, inode, av, &ad, 0);
+       return inode_has_perm(cred, inode, av, &ad);
 }
 
 /* Same as inode_has_perm, but pass explicit audit data containing
@@ -1569,7 +1568,7 @@ static inline int path_has_perm(const struct cred *cred,
 
        ad.type = LSM_AUDIT_DATA_PATH;
        ad.u.path = *path;
-       return inode_has_perm(cred, inode, av, &ad, 0);
+       return inode_has_perm(cred, inode, av, &ad);
 }
 
 /* Same as path_has_perm, but uses the inode from the file struct. */
@@ -1581,7 +1580,7 @@ static inline int file_path_has_perm(const struct cred *cred,
 
        ad.type = LSM_AUDIT_DATA_PATH;
        ad.u.path = file->f_path;
-       return inode_has_perm(cred, file_inode(file), av, &ad, 0);
+       return inode_has_perm(cred, file_inode(file), av, &ad);
 }
 
 /* Check whether a task can use an open file descriptor to
@@ -1617,7 +1616,7 @@ static int file_has_perm(const struct cred *cred,
        /* av is zero if only checking access to the descriptor. */
        rc = 0;
        if (av)
-               rc = inode_has_perm(cred, inode, av, &ad, 0);
+               rc = inode_has_perm(cred, inode, av, &ad);
 
 out:
        return rc;
index 92d0ab5..f53ee3c 100644 (file)
@@ -130,7 +130,7 @@ static inline int avc_audit(u32 ssid, u32 tsid,
                            u16 tclass, u32 requested,
                            struct av_decision *avd,
                            int result,
-                           struct common_audit_data *a, unsigned flags)
+                           struct common_audit_data *a)
 {
        u32 audited, denied;
        audited = avc_audit_required(requested, avd, result, 0, &denied);
@@ -138,7 +138,7 @@ static inline int avc_audit(u32 ssid, u32 tsid,
                return 0;
        return slow_avc_audit(ssid, tsid, tclass,
                              requested, audited, denied,
-                             a, flags);
+                             a, 0);
 }
 
 #define AVC_STRICT 1 /* Ignore permissive mode. */
@@ -147,17 +147,9 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
                         unsigned flags,
                         struct av_decision *avd);
 
-int avc_has_perm_flags(u32 ssid, u32 tsid,
-                      u16 tclass, u32 requested,
-                      struct common_audit_data *auditdata,
-                      unsigned);
-
-static inline int avc_has_perm(u32 ssid, u32 tsid,
-                              u16 tclass, u32 requested,
-                              struct common_audit_data *auditdata)
-{
-       return avc_has_perm_flags(ssid, tsid, tclass, requested, auditdata, 0);
-}
+int avc_has_perm(u32 ssid, u32 tsid,
+                u16 tclass, u32 requested,
+                struct common_audit_data *auditdata);
 
 u32 avc_policy_seqno(void);
 
index 3a0ff7f..64c043b 100644 (file)
@@ -770,6 +770,7 @@ check: $(OUTPUT)common-cmds.h
 install-bin: all
        $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
        $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'
+       $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
        $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
 ifndef NO_LIBPERL
        $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
index f686d5f..5098f14 100644 (file)
@@ -457,6 +457,7 @@ static int __run_perf_stat(int argc, const char **argv)
                        perror("failed to prepare workload");
                        return -1;
                }
+               child_pid = evsel_list->workload.pid;
        }
 
        if (group)
index d5a8dd4..f793057 100644 (file)
@@ -219,7 +219,7 @@ define SOURCE_LIBAUDIT
 
 int main(void)
 {
-       printf(\"error message: %s\n\", audit_errno_to_name(0));
+       printf(\"error message: %s\", audit_errno_to_name(0));
        return audit_open();
 }
 endef
index e23bde1..7defd77 100644 (file)
@@ -426,7 +426,7 @@ static int __die_search_func_cb(Dwarf_Die *fn_die, void *data)
  * @die_mem: a buffer for result DIE
  *
  * Search a non-inlined function DIE which includes @addr. Stores the
- * DIE to @die_mem and returns it if found. Returns NULl if failed.
+ * DIE to @die_mem and returns it if found. Returns NULL if failed.
  */
 Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
                                    Dwarf_Die *die_mem)
@@ -454,15 +454,32 @@ static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data)
 }
 
 /**
+ * die_find_top_inlinefunc - Search the top inlined function at given address
+ * @sp_die: a subprogram DIE which including @addr
+ * @addr: target address
+ * @die_mem: a buffer for result DIE
+ *
+ * Search an inlined function DIE which includes @addr. Stores the
+ * DIE to @die_mem and returns it if found. Returns NULL if failed.
+ * Even if several inlined functions are expanded recursively, this
+ * doesn't trace it down, and returns the topmost one.
+ */
+Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
+                                  Dwarf_Die *die_mem)
+{
+       return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem);
+}
+
+/**
  * die_find_inlinefunc - Search an inlined function at given address
- * @cu_die: a CU DIE which including @addr
+ * @sp_die: a subprogram DIE which including @addr
  * @addr: target address
  * @die_mem: a buffer for result DIE
  *
  * Search an inlined function DIE which includes @addr. Stores the
- * DIE to @die_mem and returns it if found. Returns NULl if failed.
+ * DIE to @die_mem and returns it if found. Returns NULL if failed.
  * If several inlined functions are expanded recursively, this trace
- * it and returns deepest one.
+ * it down and returns deepest one.
  */
 Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
                               Dwarf_Die *die_mem)
index 8658d41..b4fe90c 100644 (file)
@@ -79,7 +79,11 @@ extern Dwarf_Die *die_find_child(Dwarf_Die *rt_die,
 extern Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
                                    Dwarf_Die *die_mem);
 
-/* Search an inlined function including given address */
+/* Search the top inlined function including given address */
+extern Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
+                                         Dwarf_Die *die_mem);
+
+/* Search the deepest inlined function including given address */
 extern Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
                                      Dwarf_Die *die_mem);
 
index ce69901..c3e5a3b 100644 (file)
@@ -2768,6 +2768,18 @@ int perf_session__read_header(struct perf_session *session)
        if (perf_file_header__read(&f_header, header, fd) < 0)
                return -EINVAL;
 
+       /*
+        * Sanity check that perf.data was written cleanly; data size is
+        * initialized to 0 and updated only if the on_exit function is run.
+        * If data size is still 0 then the file contains only partial
+        * information.  Just warn user and process it as much as it can.
+        */
+       if (f_header.data.size == 0) {
+               pr_warning("WARNING: The %s file's data size field is 0 which is unexpected.\n"
+                          "Was the 'perf record' command properly terminated?\n",
+                          session->filename);
+       }
+
        nr_attrs = f_header.attrs.size / f_header.attr_size;
        lseek(fd, f_header.attrs.offset, SEEK_SET);
 
index 371476c..c09e0a9 100644 (file)
@@ -1327,8 +1327,8 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr,
                                struct perf_probe_point *ppt)
 {
        Dwarf_Die cudie, spdie, indie;
-       Dwarf_Addr _addr, baseaddr;
-       const char *fname = NULL, *func = NULL, *tmp;
+       Dwarf_Addr _addr = 0, baseaddr = 0;
+       const char *fname = NULL, *func = NULL, *basefunc = NULL, *tmp;
        int baseline = 0, lineno = 0, ret = 0;
 
        /* Adjust address with bias */
@@ -1349,27 +1349,36 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr,
        /* Find a corresponding function (name, baseline and baseaddr) */
        if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) {
                /* Get function entry information */
-               tmp = dwarf_diename(&spdie);
-               if (!tmp ||
+               func = basefunc = dwarf_diename(&spdie);
+               if (!func ||
                    dwarf_entrypc(&spdie, &baseaddr) != 0 ||
-                   dwarf_decl_line(&spdie, &baseline) != 0)
+                   dwarf_decl_line(&spdie, &baseline) != 0) {
+                       lineno = 0;
                        goto post;
-               func = tmp;
+               }
 
-               if (addr == (unsigned long)baseaddr)
+               if (addr == (unsigned long)baseaddr) {
                        /* Function entry - Relative line number is 0 */
                        lineno = baseline;
-               else if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr,
-                                            &indie)) {
+                       fname = dwarf_decl_file(&spdie);
+                       goto post;
+               }
+
+               /* Track down the inline functions step by step */
+               while (die_find_top_inlinefunc(&spdie, (Dwarf_Addr)addr,
+                                               &indie)) {
+                       /* There is an inline function */
                        if (dwarf_entrypc(&indie, &_addr) == 0 &&
-                           _addr == addr)
+                           _addr == addr) {
                                /*
                                 * addr is at an inline function entry.
                                 * In this case, lineno should be the call-site
-                                * line number.
+                                * line number. (overwrite lineinfo)
                                 */
                                lineno = die_get_call_lineno(&indie);
-                       else {
+                               fname = die_get_call_file(&indie);
+                               break;
+                       } else {
                                /*
                                 * addr is in an inline function body.
                                 * Since lineno points one of the lines
@@ -1377,19 +1386,27 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr,
                                 * be the entry line of the inline function.
                                 */
                                tmp = dwarf_diename(&indie);
-                               if (tmp &&
-                                   dwarf_decl_line(&spdie, &baseline) == 0)
-                                       func = tmp;
+                               if (!tmp ||
+                                   dwarf_decl_line(&indie, &baseline) != 0)
+                                       break;
+                               func = tmp;
+                               spdie = indie;
                        }
                }
+               /* Verify the lineno and baseline are in a same file */
+               tmp = dwarf_decl_file(&spdie);
+               if (!tmp || strcmp(tmp, fname) != 0)
+                       lineno = 0;
        }
 
 post:
        /* Make a relative line number or an offset */
        if (lineno)
                ppt->line = lineno - baseline;
-       else if (func)
+       else if (basefunc) {
                ppt->offset = addr - (unsigned long)baseaddr;
+               func = basefunc;
+       }
 
        /* Duplicate strings */
        if (func) {
index 70ffa41..568b750 100644 (file)
@@ -256,6 +256,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
                tool->sample = process_event_sample_stub;
        if (tool->mmap == NULL)
                tool->mmap = process_event_stub;
+       if (tool->mmap2 == NULL)
+               tool->mmap2 = process_event_stub;
        if (tool->comm == NULL)
                tool->comm = process_event_stub;
        if (tool->fork == NULL)
@@ -1310,7 +1312,7 @@ int __perf_session__process_events(struct perf_session *session,
        file_offset = page_offset;
        head = data_offset - page_offset;
 
-       if (data_offset + data_size < file_size)
+       if (data_size && (data_offset + data_size < file_size))
                file_size = data_offset + data_size;
 
        progress_next = file_size / 16;