Merge branch 'samsung-fixes-4' of git://github.com/kgene/linux-samsung
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 23 Oct 2011 07:44:40 +0000 (10:44 +0300)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 23 Oct 2011 07:44:40 +0000 (10:44 +0300)
* 'samsung-fixes-4' of git://github.com/kgene/linux-samsung:
  ARM: S3C24XX: Fix s3c24xx build errors if !CONFIG_PM
  ARM: S5P: fix offset calculation on gpio-interrupt

46 files changed:
MAINTAINERS
arch/sparc/include/asm/pgtsrmmu.h
arch/sparc/kernel/pci.c
arch/sparc/kernel/signal32.c
arch/sparc/kernel/signal_32.c
arch/sparc/kernel/signal_64.c
arch/sparc/mm/leon_mm.c
crypto/ghash-generic.c
drivers/gpu/drm/radeon/atom.c
drivers/gpu/drm/radeon/atom.h
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/ttm/ttm_bo_util.c
drivers/hwmon/w83627ehf.c
drivers/media/video/v4l2-dev.c
drivers/net/bonding/bond_main.c
drivers/net/netconsole.c
drivers/net/pptp.c
drivers/net/r8169.c
drivers/net/smsc911x.c
drivers/net/tg3.c
include/net/ip_vs.h
include/net/udplite.h
kernel/posix-cpu-timers.c
mm/migrate.c
net/bluetooth/l2cap_sock.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/sco.c
net/bridge/br_if.c
net/bridge/br_netlink.c
net/bridge/br_private.h
net/core/fib_rules.c
net/ipv4/tcp_minisocks.c
net/l2tp/l2tp_core.c
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/ipvs/ip_vs_sync.c
net/netfilter/nf_conntrack_proto_gre.c
net/x25/af_x25.c
net/x25/x25_dev.c
net/x25/x25_facilities.c
net/x25/x25_in.c
net/x25/x25_link.c
net/x25/x25_subr.c
security/security.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_conexant.c

index 5483e0c..b3bc88d 100644 (file)
@@ -2460,7 +2460,7 @@ S:        Supported
 F:     drivers/infiniband/hw/ehca/
 
 EHEA (IBM pSeries eHEA 10Gb ethernet adapter) DRIVER
-M:     Breno Leitao <leitao@linux.vnet.ibm.com>
+M:     Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/ehea/
index 1407c07..f6ae2b2 100644 (file)
@@ -280,7 +280,7 @@ static inline unsigned long srmmu_hwprobe(unsigned long vaddr)
        return retval;
 }
 #else
-#define srmmu_hwprobe(addr) (srmmu_swprobe(addr, 0) & SRMMU_PTE_PMASK)
+#define srmmu_hwprobe(addr) srmmu_swprobe(addr, 0)
 #endif
 
 static inline int
index 1e94f94..8aa0d44 100644 (file)
@@ -230,7 +230,8 @@ static void pci_parse_of_addrs(struct platform_device *op,
                        res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
                } else if (i == dev->rom_base_reg) {
                        res = &dev->resource[PCI_ROM_RESOURCE];
-                       flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
+                       flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE
+                             | IORESOURCE_SIZEALIGN;
                } else {
                        printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
                        continue;
index 1ba95af..2caa556 100644 (file)
@@ -273,10 +273,7 @@ void do_sigreturn32(struct pt_regs *regs)
                case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32);
        }
        sigdelsetmask(&set, ~_BLOCKABLE);
-       spin_lock_irq(&current->sighand->siglock);
-       current->blocked = set;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       set_current_blocked(&set);
        return;
 
 segv:
@@ -377,10 +374,7 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
                case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
        }
        sigdelsetmask(&set, ~_BLOCKABLE);
-       spin_lock_irq(&current->sighand->siglock);
-       current->blocked = set;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       set_current_blocked(&set);
        return;
 segv:
        force_sig(SIGSEGV, current);
@@ -782,6 +776,7 @@ static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka,
                                  siginfo_t *info,
                                  sigset_t *oldset, struct pt_regs *regs)
 {
+       sigset_t blocked;
        int err;
 
        if (ka->sa.sa_flags & SA_SIGINFO)
@@ -792,12 +787,10 @@ static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka,
        if (err)
                return err;
 
-       spin_lock_irq(&current->sighand->siglock);
-       sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+       sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
        if (!(ka->sa.sa_flags & SA_NOMASK))
-               sigaddset(&current->blocked,signr);
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+               sigaddset(&blocked, signr);
+       set_current_blocked(&blocked);
 
        tracehook_signal_handler(signr, info, ka, regs, 0);
 
@@ -881,7 +874,7 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
         */
        if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
                current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
-               sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+               set_current_blocked(&current->saved_sigmask);
        }
 }
 
index 04ede8f..8ce247a 100644 (file)
@@ -62,12 +62,13 @@ struct rt_signal_frame {
 
 static int _sigpause_common(old_sigset_t set)
 {
-       set &= _BLOCKABLE;
-       spin_lock_irq(&current->sighand->siglock);
+       sigset_t blocked;
+
        current->saved_sigmask = current->blocked;
-       siginitset(&current->blocked, set);
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+
+       set &= _BLOCKABLE;
+       siginitset(&blocked, set);
+       set_current_blocked(&blocked);
 
        current->state = TASK_INTERRUPTIBLE;
        schedule();
@@ -139,10 +140,7 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
                goto segv_and_exit;
 
        sigdelsetmask(&set, ~_BLOCKABLE);
-       spin_lock_irq(&current->sighand->siglock);
-       current->blocked = set;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       set_current_blocked(&set);
        return;
 
 segv_and_exit:
@@ -209,10 +207,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
        }
 
        sigdelsetmask(&set, ~_BLOCKABLE);
-       spin_lock_irq(&current->sighand->siglock);
-       current->blocked = set;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       set_current_blocked(&set);
        return;
 segv:
        force_sig(SIGSEGV, current);
@@ -470,6 +465,7 @@ static inline int
 handle_signal(unsigned long signr, struct k_sigaction *ka,
              siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
 {
+       sigset_t blocked;
        int err;
 
        if (ka->sa.sa_flags & SA_SIGINFO)
@@ -480,12 +476,10 @@ handle_signal(unsigned long signr, struct k_sigaction *ka,
        if (err)
                return err;
 
-       spin_lock_irq(&current->sighand->siglock);
-       sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+       sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
        if (!(ka->sa.sa_flags & SA_NOMASK))
-               sigaddset(&current->blocked, signr);
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+               sigaddset(&blocked, signr);
+       set_current_blocked(&blocked);
 
        tracehook_signal_handler(signr, info, ka, regs, 0);
 
@@ -581,7 +575,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
         */
        if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
                clear_thread_flag(TIF_RESTORE_SIGMASK);
-               sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+               set_current_blocked(&current->saved_sigmask);
        }
 }
 
index 47509df..a2b8159 100644 (file)
@@ -70,10 +70,7 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
                                goto do_sigsegv;
                }
                sigdelsetmask(&set, ~_BLOCKABLE);
-               spin_lock_irq(&current->sighand->siglock);
-               current->blocked = set;
-               recalc_sigpending();
-               spin_unlock_irq(&current->sighand->siglock);
+               set_current_blocked(&set);
        }
        if (test_thread_flag(TIF_32BIT)) {
                pc &= 0xffffffff;
@@ -242,12 +239,13 @@ struct rt_signal_frame {
 
 static long _sigpause_common(old_sigset_t set)
 {
-       set &= _BLOCKABLE;
-       spin_lock_irq(&current->sighand->siglock);
+       sigset_t blocked;
+
        current->saved_sigmask = current->blocked;
-       siginitset(&current->blocked, set);
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+
+       set &= _BLOCKABLE;
+       siginitset(&blocked, set);
+       set_current_blocked(&blocked);
 
        current->state = TASK_INTERRUPTIBLE;
        schedule();
@@ -327,10 +325,7 @@ void do_rt_sigreturn(struct pt_regs *regs)
        pt_regs_clear_syscall(regs);
 
        sigdelsetmask(&set, ~_BLOCKABLE);
-       spin_lock_irq(&current->sighand->siglock);
-       current->blocked = set;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       set_current_blocked(&set);
        return;
 segv:
        force_sig(SIGSEGV, current);
@@ -484,18 +479,17 @@ static inline int handle_signal(unsigned long signr, struct k_sigaction *ka,
                                siginfo_t *info,
                                sigset_t *oldset, struct pt_regs *regs)
 {
+       sigset_t blocked;
        int err;
 
        err = setup_rt_frame(ka, regs, signr, oldset,
                             (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
        if (err)
                return err;
-       spin_lock_irq(&current->sighand->siglock);
-       sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+       sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
        if (!(ka->sa.sa_flags & SA_NOMASK))
-               sigaddset(&current->blocked,signr);
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+               sigaddset(&blocked, signr);
+       set_current_blocked(&blocked);
 
        tracehook_signal_handler(signr, info, ka, regs, 0);
 
@@ -601,7 +595,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
         */
        if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
                current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
-               sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+               set_current_blocked(&current->saved_sigmask);
        }
 }
 
index e485a68..13c2169 100644 (file)
@@ -162,7 +162,7 @@ ready:
                printk(KERN_INFO "swprobe: padde %x\n", paddr_calc);
        if (paddr)
                *paddr = paddr_calc;
-       return paddrbase;
+       return pte;
 }
 
 void leon_flush_icache_all(void)
index be44256..7835b8f 100644 (file)
@@ -67,6 +67,9 @@ static int ghash_update(struct shash_desc *desc,
        struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
        u8 *dst = dctx->buffer;
 
+       if (!ctx->gf128)
+               return -ENOKEY;
+
        if (dctx->bytes) {
                int n = min(srclen, dctx->bytes);
                u8 *pos = dst + (GHASH_BLOCK_SIZE - dctx->bytes);
@@ -119,6 +122,9 @@ static int ghash_final(struct shash_desc *desc, u8 *dst)
        struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
        u8 *buf = dctx->buffer;
 
+       if (!ctx->gf128)
+               return -ENOKEY;
+
        ghash_flush(ctx, dctx);
        memcpy(dst, buf, GHASH_BLOCK_SIZE);
 
index e88c644..14cc88a 100644 (file)
@@ -277,7 +277,12 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr,
        case ATOM_ARG_FB:
                idx = U8(*ptr);
                (*ptr)++;
-               val = gctx->scratch[((gctx->fb_base + idx) / 4)];
+               if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) {
+                       DRM_ERROR("ATOM: fb read beyond scratch region: %d vs. %d\n",
+                                 gctx->fb_base + (idx * 4), gctx->scratch_size_bytes);
+                       val = 0;
+               } else
+                       val = gctx->scratch[(gctx->fb_base / 4) + idx];
                if (print)
                        DEBUG("FB[0x%02X]", idx);
                break;
@@ -531,7 +536,11 @@ static void atom_put_dst(atom_exec_context *ctx, int arg, uint8_t attr,
        case ATOM_ARG_FB:
                idx = U8(*ptr);
                (*ptr)++;
-               gctx->scratch[((gctx->fb_base + idx) / 4)] = val;
+               if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) {
+                       DRM_ERROR("ATOM: fb write beyond scratch region: %d vs. %d\n",
+                                 gctx->fb_base + (idx * 4), gctx->scratch_size_bytes);
+               } else
+                       gctx->scratch[(gctx->fb_base / 4) + idx] = val;
                DEBUG("FB[0x%02X]", idx);
                break;
        case ATOM_ARG_PLL:
@@ -1370,11 +1379,13 @@ int atom_allocate_fb_scratch(struct atom_context *ctx)
 
                usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
        }
+       ctx->scratch_size_bytes = 0;
        if (usage_bytes == 0)
                usage_bytes = 20 * 1024;
        /* allocate some scratch memory */
        ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL);
        if (!ctx->scratch)
                return -ENOMEM;
+       ctx->scratch_size_bytes = usage_bytes;
        return 0;
 }
index a589a55..93cfe20 100644 (file)
@@ -137,6 +137,7 @@ struct atom_context {
        int cs_equal, cs_above;
        int io_mode;
        uint32_t *scratch;
+       int scratch_size_bytes;
 };
 
 extern int atom_debug;
index c742944..a515b2a 100644 (file)
@@ -466,7 +466,7 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc,
                        return;
                }
                args.v2.ucEnable = enable;
-               if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK))
+               if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK) || ASIC_IS_DCE41(rdev))
                        args.v2.ucEnable = ATOM_DISABLE;
        } else if (ASIC_IS_DCE3(rdev)) {
                args.v1.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
index 8a171b2..eb3f6dc 100644 (file)
@@ -1638,7 +1638,17 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
                        break;
                case 2:
                        args.v2.ucCRTC = radeon_crtc->crtc_id;
-                       args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder);
+                       if (radeon_encoder_is_dp_bridge(encoder)) {
+                               struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+
+                               if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
+                                       args.v2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;
+                               else if (connector->connector_type == DRM_MODE_CONNECTOR_VGA)
+                                       args.v2.ucEncodeMode = ATOM_ENCODER_MODE_CRT;
+                               else
+                                       args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder);
+                       } else
+                               args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder);
                        switch (radeon_encoder->encoder_id) {
                        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
                        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
@@ -1756,10 +1766,15 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)
        if (ASIC_IS_DCE4(rdev)) {
                dig = radeon_encoder->enc_priv;
                if (ASIC_IS_DCE41(rdev)) {
-                       if (dig->linkb)
-                               return 1;
-                       else
-                               return 0;
+                       /* ontario follows DCE4 */
+                       if (rdev->family == CHIP_PALM) {
+                               if (dig->linkb)
+                                       return 1;
+                               else
+                                       return 0;
+                       } else
+                               /* llano follows DCE3.2 */
+                               return radeon_crtc->crtc_id;
                } else {
                        switch (radeon_encoder->encoder_id) {
                        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
index ae3c6f5..082fcae 100644 (file)
@@ -321,7 +321,7 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
        struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type];
        struct ttm_tt *ttm = bo->ttm;
        struct ttm_mem_reg *old_mem = &bo->mem;
-       struct ttm_mem_reg old_copy;
+       struct ttm_mem_reg old_copy = *old_mem;
        void *old_iomap;
        void *new_iomap;
        int ret;
index 7b0260d..36d7f27 100644 (file)
@@ -390,7 +390,7 @@ temp_from_reg(u16 reg, s16 regval)
 {
        if (is_word_sized(reg))
                return LM75_TEMP_FROM_REG(regval);
-       return regval * 1000;
+       return ((s8)regval) * 1000;
 }
 
 static inline u16
@@ -398,7 +398,8 @@ temp_to_reg(u16 reg, long temp)
 {
        if (is_word_sized(reg))
                return LM75_TEMP_TO_REG(temp);
-       return DIV_ROUND_CLOSEST(SENSORS_LIMIT(temp, -127000, 128000), 1000);
+       return (s8)DIV_ROUND_CLOSEST(SENSORS_LIMIT(temp, -127000, 128000),
+                                    1000);
 }
 
 /* Some of analog inputs have internal scaling (2x), 8mV is ADC LSB */
index d721565..a5c9ed1 100644 (file)
@@ -181,7 +181,7 @@ static void v4l2_device_release(struct device *cd)
         * TODO: In the long run all drivers that use v4l2_device should use the
         * v4l2_device release callback. This check will then be unnecessary.
         */
-       if (v4l2_dev->release == NULL)
+       if (v4l2_dev && v4l2_dev->release == NULL)
                v4l2_dev = NULL;
 
        /* Release video_device and perform other
index 6d79b78..de3d351 100644 (file)
@@ -1435,6 +1435,8 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
        struct sk_buff *skb = *pskb;
        struct slave *slave;
        struct bonding *bond;
+       void (*recv_probe)(struct sk_buff *, struct bonding *,
+                               struct slave *);
 
        skb = skb_share_check(skb, GFP_ATOMIC);
        if (unlikely(!skb))
@@ -1448,11 +1450,12 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
        if (bond->params.arp_interval)
                slave->dev->last_rx = jiffies;
 
-       if (bond->recv_probe) {
+       recv_probe = ACCESS_ONCE(bond->recv_probe);
+       if (recv_probe) {
                struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
 
                if (likely(nskb)) {
-                       bond->recv_probe(nskb, bond, slave);
+                       recv_probe(nskb, bond, slave);
                        dev_kfree_skb(nskb);
                }
        }
index ed2a397..e888202 100644 (file)
@@ -307,6 +307,11 @@ static ssize_t store_enabled(struct netconsole_target *nt,
                return err;
        if (enabled < 0 || enabled > 1)
                return -EINVAL;
+       if (enabled == nt->enabled) {
+               printk(KERN_INFO "netconsole: network logging has already %s\n",
+                               nt->enabled ? "started" : "stopped");
+               return -EINVAL;
+       }
 
        if (enabled) {  /* 1 */
 
index eae542a..89f829f 100644 (file)
@@ -285,8 +285,10 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
        ip_send_check(iph);
 
        ip_local_out(skb);
+       return 1;
 
 tx_error:
+       kfree_skb(skb);
        return 1;
 }
 
@@ -305,11 +307,18 @@ static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb)
        }
 
        header = (struct pptp_gre_header *)(skb->data);
+       headersize  = sizeof(*header);
 
        /* test if acknowledgement present */
        if (PPTP_GRE_IS_A(header->ver)) {
-               __u32 ack = (PPTP_GRE_IS_S(header->flags)) ?
-                               header->ack : header->seq; /* ack in different place if S = 0 */
+               __u32 ack;
+
+               if (!pskb_may_pull(skb, headersize))
+                       goto drop;
+               header = (struct pptp_gre_header *)(skb->data);
+
+               /* ack in different place if S = 0 */
+               ack = PPTP_GRE_IS_S(header->flags) ? header->ack : header->seq;
 
                ack = ntohl(ack);
 
@@ -318,21 +327,18 @@ static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb)
                /* also handle sequence number wrap-around  */
                if (WRAPPED(ack, opt->ack_recv))
                        opt->ack_recv = ack;
+       } else {
+               headersize -= sizeof(header->ack);
        }
-
        /* test if payload present */
        if (!PPTP_GRE_IS_S(header->flags))
                goto drop;
 
-       headersize  = sizeof(*header);
        payload_len = ntohs(header->payload_len);
        seq         = ntohl(header->seq);
 
-       /* no ack present? */
-       if (!PPTP_GRE_IS_A(header->ver))
-               headersize -= sizeof(header->ack);
        /* check for incomplete packet (length smaller than expected) */
-       if (skb->len - headersize < payload_len)
+       if (!pskb_may_pull(skb, headersize + payload_len))
                goto drop;
 
        payload = skb->data + headersize;
index c236670..6d657ca 100644 (file)
@@ -2859,7 +2859,7 @@ static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp)
        rtl_writephy(tp, 0x1f, 0x0004);
        rtl_writephy(tp, 0x1f, 0x0007);
        rtl_writephy(tp, 0x1e, 0x0020);
-       rtl_w1w0_phy(tp, 0x06, 0x0000, 0x0100);
+       rtl_w1w0_phy(tp, 0x15, 0x0000, 0x0100);
        rtl_writephy(tp, 0x1f, 0x0002);
        rtl_writephy(tp, 0x1f, 0x0000);
        rtl_writephy(tp, 0x0d, 0x0007);
@@ -3316,6 +3316,37 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp)
        }
 }
 
+static void rtl_wol_suspend_quirk(struct rtl8169_private *tp)
+{
+       void __iomem *ioaddr = tp->mmio_addr;
+
+       switch (tp->mac_version) {
+       case RTL_GIGA_MAC_VER_29:
+       case RTL_GIGA_MAC_VER_30:
+       case RTL_GIGA_MAC_VER_32:
+       case RTL_GIGA_MAC_VER_33:
+       case RTL_GIGA_MAC_VER_34:
+               RTL_W32(RxConfig, RTL_R32(RxConfig) |
+                       AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
+               break;
+       default:
+               break;
+       }
+}
+
+static bool rtl_wol_pll_power_down(struct rtl8169_private *tp)
+{
+       if (!(__rtl8169_get_wol(tp) & WAKE_ANY))
+               return false;
+
+       rtl_writephy(tp, 0x1f, 0x0000);
+       rtl_writephy(tp, MII_BMCR, 0x0000);
+
+       rtl_wol_suspend_quirk(tp);
+
+       return true;
+}
+
 static void r810x_phy_power_down(struct rtl8169_private *tp)
 {
        rtl_writephy(tp, 0x1f, 0x0000);
@@ -3330,18 +3361,8 @@ static void r810x_phy_power_up(struct rtl8169_private *tp)
 
 static void r810x_pll_power_down(struct rtl8169_private *tp)
 {
-       void __iomem *ioaddr = tp->mmio_addr;
-
-       if (__rtl8169_get_wol(tp) & WAKE_ANY) {
-               rtl_writephy(tp, 0x1f, 0x0000);
-               rtl_writephy(tp, MII_BMCR, 0x0000);
-
-               if (tp->mac_version == RTL_GIGA_MAC_VER_29 ||
-                   tp->mac_version == RTL_GIGA_MAC_VER_30)
-                       RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast |
-                               AcceptMulticast | AcceptMyPhys);
+       if (rtl_wol_pll_power_down(tp))
                return;
-       }
 
        r810x_phy_power_down(tp);
 }
@@ -3430,17 +3451,8 @@ static void r8168_pll_power_down(struct rtl8169_private *tp)
            tp->mac_version == RTL_GIGA_MAC_VER_33)
                rtl_ephy_write(ioaddr, 0x19, 0xff64);
 
-       if (__rtl8169_get_wol(tp) & WAKE_ANY) {
-               rtl_writephy(tp, 0x1f, 0x0000);
-               rtl_writephy(tp, MII_BMCR, 0x0000);
-
-               if (tp->mac_version == RTL_GIGA_MAC_VER_32 ||
-                   tp->mac_version == RTL_GIGA_MAC_VER_33 ||
-                   tp->mac_version == RTL_GIGA_MAC_VER_34)
-                       RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast |
-                               AcceptMulticast | AcceptMyPhys);
+       if (rtl_wol_pll_power_down(tp))
                return;
-       }
 
        r8168_phy_power_down(tp);
 
@@ -5788,11 +5800,30 @@ static const struct dev_pm_ops rtl8169_pm_ops = {
 
 #endif /* !CONFIG_PM */
 
+static void rtl_wol_shutdown_quirk(struct rtl8169_private *tp)
+{
+       void __iomem *ioaddr = tp->mmio_addr;
+
+       /* WoL fails with 8168b when the receiver is disabled. */
+       switch (tp->mac_version) {
+       case RTL_GIGA_MAC_VER_11:
+       case RTL_GIGA_MAC_VER_12:
+       case RTL_GIGA_MAC_VER_17:
+               pci_clear_master(tp->pci_dev);
+
+               RTL_W8(ChipCmd, CmdRxEnb);
+               /* PCI commit */
+               RTL_R8(ChipCmd);
+               break;
+       default:
+               break;
+       }
+}
+
 static void rtl_shutdown(struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
        struct rtl8169_private *tp = netdev_priv(dev);
-       void __iomem *ioaddr = tp->mmio_addr;
 
        rtl8169_net_suspend(dev);
 
@@ -5806,16 +5837,9 @@ static void rtl_shutdown(struct pci_dev *pdev)
        spin_unlock_irq(&tp->lock);
 
        if (system_state == SYSTEM_POWER_OFF) {
-               /* WoL fails with 8168b when the receiver is disabled. */
-               if ((tp->mac_version == RTL_GIGA_MAC_VER_11 ||
-                    tp->mac_version == RTL_GIGA_MAC_VER_12 ||
-                    tp->mac_version == RTL_GIGA_MAC_VER_17) &&
-                   (tp->features & RTL_FEATURE_WOL)) {
-                       pci_clear_master(pdev);
-
-                       RTL_W8(ChipCmd, CmdRxEnb);
-                       /* PCI commit */
-                       RTL_R8(ChipCmd);
+               if (__rtl8169_get_wol(tp) & WAKE_ANY) {
+                       rtl_wol_suspend_quirk(tp);
+                       rtl_wol_shutdown_quirk(tp);
                }
 
                pci_wake_from_d3(pdev, true);
index b9016a3..c90ddb6 100644 (file)
@@ -26,6 +26,7 @@
  *   LAN9215, LAN9216, LAN9217, LAN9218
  *   LAN9210, LAN9211
  *   LAN9220, LAN9221
+ *   LAN89218
  *
  */
 
@@ -1983,6 +1984,7 @@ static int __devinit smsc911x_init(struct net_device *dev)
        case 0x01170000:
        case 0x01160000:
        case 0x01150000:
+       case 0x218A0000:
                /* LAN911[5678] family */
                pdata->generation = pdata->idrev & 0x0000FFFF;
                break;
index 4a1374d..c11a2b8 100644 (file)
@@ -15577,7 +15577,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
 
                cancel_work_sync(&tp->reset_task);
 
-               if (!tg3_flag(tp, USE_PHYLIB)) {
+               if (tg3_flag(tp, USE_PHYLIB)) {
                        tg3_phy_fini(tp);
                        tg3_mdio_fini(tp);
                }
index 1aaf915..8fa4430 100644 (file)
@@ -900,6 +900,7 @@ struct netns_ipvs {
        volatile int            sync_state;
        volatile int            master_syncid;
        volatile int            backup_syncid;
+       struct mutex            sync_mutex;
        /* multicast interface name */
        char                    master_mcast_ifn[IP_VS_IFNAME_MAXLEN];
        char                    backup_mcast_ifn[IP_VS_IFNAME_MAXLEN];
index 673a024..5f097ca 100644 (file)
@@ -66,40 +66,34 @@ static inline int udplite_checksum_init(struct sk_buff *skb, struct udphdr *uh)
        return 0;
 }
 
-static inline int udplite_sender_cscov(struct udp_sock *up, struct udphdr *uh)
+/* Slow-path computation of checksum. Socket is locked. */
+static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb)
 {
+       const struct udp_sock *up = udp_sk(skb->sk);
        int cscov = up->len;
+       __wsum csum = 0;
 
-       /*
-        * Sender has set `partial coverage' option on UDP-Lite socket
-        */
-       if (up->pcflag & UDPLITE_SEND_CC)    {
+       if (up->pcflag & UDPLITE_SEND_CC) {
+               /*
+                * Sender has set `partial coverage' option on UDP-Lite socket.
+                * The special case "up->pcslen == 0" signifies full coverage.
+                */
                if (up->pcslen < up->len) {
-               /* up->pcslen == 0 means that full coverage is required,
-                * partial coverage only if  0 < up->pcslen < up->len */
-                       if (0 < up->pcslen) {
-                              cscov = up->pcslen;
-                       }
-                       uh->len = htons(up->pcslen);
+                       if (0 < up->pcslen)
+                               cscov = up->pcslen;
+                       udp_hdr(skb)->len = htons(up->pcslen);
                }
-       /*
-        * NOTE: Causes for the error case  `up->pcslen > up->len':
-        *        (i)  Application error (will not be penalized).
-        *       (ii)  Payload too big for send buffer: data is split
-        *             into several packets, each with its own header.
-        *             In this case (e.g. last segment), coverage may
-        *             exceed packet length.
-        *       Since packets with coverage length > packet length are
-        *       illegal, we fall back to the defaults here.
-        */
+               /*
+                * NOTE: Causes for the error case  `up->pcslen > up->len':
+                *        (i)  Application error (will not be penalized).
+                *       (ii)  Payload too big for send buffer: data is split
+                *             into several packets, each with its own header.
+                *             In this case (e.g. last segment), coverage may
+                *             exceed packet length.
+                *       Since packets with coverage length > packet length are
+                *       illegal, we fall back to the defaults here.
+                */
        }
-       return cscov;
-}
-
-static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb)
-{
-       int cscov = udplite_sender_cscov(udp_sk(sk), udp_hdr(skb));
-       __wsum csum = 0;
 
        skb->ip_summed = CHECKSUM_NONE;     /* no HW support for checksumming */
 
@@ -115,16 +109,21 @@ static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb)
        return csum;
 }
 
+/* Fast-path computation of checksum. Socket may not be locked. */
 static inline __wsum udplite_csum(struct sk_buff *skb)
 {
-       struct sock *sk = skb->sk;
-       int cscov = udplite_sender_cscov(udp_sk(sk), udp_hdr(skb));
+       const struct udp_sock *up = udp_sk(skb->sk);
        const int off = skb_transport_offset(skb);
-       const int len = skb->len - off;
+       int len = skb->len - off;
 
+       if ((up->pcflag & UDPLITE_SEND_CC) && up->pcslen < len) {
+               if (0 < up->pcslen)
+                       len = up->pcslen;
+               udp_hdr(skb)->len = htons(up->pcslen);
+       }
        skb->ip_summed = CHECKSUM_NONE;     /* no HW support for checksumming */
 
-       return skb_checksum(skb, off, min(cscov, len), 0);
+       return skb_checksum(skb, off, len, 0);
 }
 
 extern void    udplite4_register(void);
index c8008dd..640ded8 100644 (file)
@@ -274,9 +274,7 @@ void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times)
        struct task_cputime sum;
        unsigned long flags;
 
-       spin_lock_irqsave(&cputimer->lock, flags);
        if (!cputimer->running) {
-               cputimer->running = 1;
                /*
                 * The POSIX timer interface allows for absolute time expiry
                 * values through the TIMER_ABSTIME flag, therefore we have
@@ -284,8 +282,11 @@ void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times)
                 * it.
                 */
                thread_group_cputime(tsk, &sum);
+               spin_lock_irqsave(&cputimer->lock, flags);
+               cputimer->running = 1;
                update_gt_cputime(&cputimer->cputime, &sum);
-       }
+       } else
+               spin_lock_irqsave(&cputimer->lock, flags);
        *times = cputimer->cputime;
        spin_unlock_irqrestore(&cputimer->lock, flags);
 }
index 666e4e6..14d0a6a 100644 (file)
@@ -120,10 +120,10 @@ static int remove_migration_pte(struct page *new, struct vm_area_struct *vma,
 
                ptep = pte_offset_map(pmd, addr);
 
-               if (!is_swap_pte(*ptep)) {
-                       pte_unmap(ptep);
-                       goto out;
-               }
+               /*
+                * Peek to check is_swap_pte() before taking ptlock?  No, we
+                * can race mremap's move_ptes(), which skips anon_vma lock.
+                */
 
                ptl = pte_lockptr(mm, pmd);
        }
index 61f1f62..e829236 100644 (file)
@@ -26,6 +26,8 @@
 
 /* Bluetooth L2CAP sockets. */
 
+#include <linux/security.h>
+
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/l2cap.h>
@@ -933,6 +935,8 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
                chan->force_reliable = pchan->force_reliable;
                chan->flushable = pchan->flushable;
                chan->force_active = pchan->force_active;
+
+               security_sk_clone(parent, sk);
        } else {
 
                switch (sk->sk_type) {
index 482722b..5417f61 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/device.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
+#include <linux/security.h>
 #include <net/sock.h>
 
 #include <asm/system.h>
@@ -264,6 +265,8 @@ static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
 
                pi->sec_level = rfcomm_pi(parent)->sec_level;
                pi->role_switch = rfcomm_pi(parent)->role_switch;
+
+               security_sk_clone(parent, sk);
        } else {
                pi->dlc->defer_setup = 0;
 
index 8270f05..a324b00 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/list.h>
+#include <linux/security.h>
 #include <net/sock.h>
 
 #include <asm/system.h>
@@ -403,8 +404,10 @@ static void sco_sock_init(struct sock *sk, struct sock *parent)
 {
        BT_DBG("sk %p", sk);
 
-       if (parent)
+       if (parent) {
                sk->sk_type = parent->sk_type;
+               security_sk_clone(parent, sk);
+       }
 }
 
 static struct proto sco_proto = {
index e738154..1d420f6 100644 (file)
@@ -161,9 +161,10 @@ static void del_nbp(struct net_bridge_port *p)
        call_rcu(&p->rcu, destroy_nbp_rcu);
 }
 
-/* called with RTNL */
-static void del_br(struct net_bridge *br, struct list_head *head)
+/* Delete bridge device */
+void br_dev_delete(struct net_device *dev, struct list_head *head)
 {
+       struct net_bridge *br = netdev_priv(dev);
        struct net_bridge_port *p, *n;
 
        list_for_each_entry_safe(p, n, &br->port_list, list) {
@@ -268,7 +269,7 @@ int br_del_bridge(struct net *net, const char *name)
        }
 
        else
-               del_br(netdev_priv(dev), NULL);
+               br_dev_delete(dev, NULL);
 
        rtnl_unlock();
        return ret;
@@ -449,7 +450,7 @@ void __net_exit br_net_exit(struct net *net)
        rtnl_lock();
        for_each_netdev(net, dev)
                if (dev->priv_flags & IFF_EBRIDGE)
-                       del_br(netdev_priv(dev), &list);
+                       br_dev_delete(dev, &list);
 
        unregister_netdevice_many(&list);
        rtnl_unlock();
index 5b1ed1b..e5f9ece 100644 (file)
@@ -210,6 +210,7 @@ static struct rtnl_link_ops br_link_ops __read_mostly = {
        .priv_size      = sizeof(struct net_bridge),
        .setup          = br_dev_setup,
        .validate       = br_validate,
+       .dellink        = br_dev_delete,
 };
 
 int __init br_netlink_init(void)
index 78cc364..857a021 100644 (file)
@@ -294,6 +294,7 @@ static inline int br_is_root_bridge(const struct net_bridge *br)
 
 /* br_device.c */
 extern void br_dev_setup(struct net_device *dev);
+extern void br_dev_delete(struct net_device *dev, struct list_head *list);
 extern netdev_tx_t br_dev_xmit(struct sk_buff *skb,
                               struct net_device *dev);
 #ifdef CONFIG_NET_POLL_CONTROLLER
index 3231b46..27071ee 100644 (file)
@@ -475,8 +475,11 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 
                list_del_rcu(&rule->list);
 
-               if (rule->action == FR_ACT_GOTO)
+               if (rule->action == FR_ACT_GOTO) {
                        ops->nr_goto_rules--;
+                       if (rtnl_dereference(rule->ctarget) == NULL)
+                               ops->unresolved_rules--;
+               }
 
                /*
                 * Check if this rule is a target to any of them. If so,
index d2fe4e0..0ce3d06 100644 (file)
@@ -328,6 +328,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
                struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw);
                const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1);
 
+               tw->tw_transparent      = inet_sk(sk)->transparent;
                tw->tw_rcv_wscale       = tp->rx_opt.rcv_wscale;
                tcptw->tw_rcv_nxt       = tp->rcv_nxt;
                tcptw->tw_snd_nxt       = tp->snd_nxt;
index ad4ac26..34b2dde 100644 (file)
@@ -1045,8 +1045,10 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
        headroom = NET_SKB_PAD + sizeof(struct iphdr) +
                uhlen + hdr_len;
        old_headroom = skb_headroom(skb);
-       if (skb_cow_head(skb, headroom))
+       if (skb_cow_head(skb, headroom)) {
+               dev_kfree_skb(skb);
                goto abort;
+       }
 
        new_headroom = skb_headroom(skb);
        skb_orphan(skb);
index 5290ac3..e3be48b 100644 (file)
@@ -2283,6 +2283,7 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
        struct ip_vs_service *svc;
        struct ip_vs_dest_user *udest_compat;
        struct ip_vs_dest_user_kern udest;
+       struct netns_ipvs *ipvs = net_ipvs(net);
 
        if (!capable(CAP_NET_ADMIN))
                return -EPERM;
@@ -2303,6 +2304,24 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
        /* increase the module use count */
        ip_vs_use_count_inc();
 
+       /* Handle daemons since they have another lock */
+       if (cmd == IP_VS_SO_SET_STARTDAEMON ||
+           cmd == IP_VS_SO_SET_STOPDAEMON) {
+               struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg;
+
+               if (mutex_lock_interruptible(&ipvs->sync_mutex)) {
+                       ret = -ERESTARTSYS;
+                       goto out_dec;
+               }
+               if (cmd == IP_VS_SO_SET_STARTDAEMON)
+                       ret = start_sync_thread(net, dm->state, dm->mcast_ifn,
+                                               dm->syncid);
+               else
+                       ret = stop_sync_thread(net, dm->state);
+               mutex_unlock(&ipvs->sync_mutex);
+               goto out_dec;
+       }
+
        if (mutex_lock_interruptible(&__ip_vs_mutex)) {
                ret = -ERESTARTSYS;
                goto out_dec;
@@ -2316,15 +2335,6 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
                /* Set timeout values for (tcp tcpfin udp) */
                ret = ip_vs_set_timeout(net, (struct ip_vs_timeout_user *)arg);
                goto out_unlock;
-       } else if (cmd == IP_VS_SO_SET_STARTDAEMON) {
-               struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg;
-               ret = start_sync_thread(net, dm->state, dm->mcast_ifn,
-                                       dm->syncid);
-               goto out_unlock;
-       } else if (cmd == IP_VS_SO_SET_STOPDAEMON) {
-               struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg;
-               ret = stop_sync_thread(net, dm->state);
-               goto out_unlock;
        }
 
        usvc_compat = (struct ip_vs_service_user *)arg;
@@ -2584,6 +2594,33 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
 
        if (copy_from_user(arg, user, copylen) != 0)
                return -EFAULT;
+       /*
+        * Handle daemons first since it has its own locking
+        */
+       if (cmd == IP_VS_SO_GET_DAEMON) {
+               struct ip_vs_daemon_user d[2];
+
+               memset(&d, 0, sizeof(d));
+               if (mutex_lock_interruptible(&ipvs->sync_mutex))
+                       return -ERESTARTSYS;
+
+               if (ipvs->sync_state & IP_VS_STATE_MASTER) {
+                       d[0].state = IP_VS_STATE_MASTER;
+                       strlcpy(d[0].mcast_ifn, ipvs->master_mcast_ifn,
+                               sizeof(d[0].mcast_ifn));
+                       d[0].syncid = ipvs->master_syncid;
+               }
+               if (ipvs->sync_state & IP_VS_STATE_BACKUP) {
+                       d[1].state = IP_VS_STATE_BACKUP;
+                       strlcpy(d[1].mcast_ifn, ipvs->backup_mcast_ifn,
+                               sizeof(d[1].mcast_ifn));
+                       d[1].syncid = ipvs->backup_syncid;
+               }
+               if (copy_to_user(user, &d, sizeof(d)) != 0)
+                       ret = -EFAULT;
+               mutex_unlock(&ipvs->sync_mutex);
+               return ret;
+       }
 
        if (mutex_lock_interruptible(&__ip_vs_mutex))
                return -ERESTARTSYS;
@@ -2681,28 +2718,6 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
        }
        break;
 
-       case IP_VS_SO_GET_DAEMON:
-       {
-               struct ip_vs_daemon_user d[2];
-
-               memset(&d, 0, sizeof(d));
-               if (ipvs->sync_state & IP_VS_STATE_MASTER) {
-                       d[0].state = IP_VS_STATE_MASTER;
-                       strlcpy(d[0].mcast_ifn, ipvs->master_mcast_ifn,
-                               sizeof(d[0].mcast_ifn));
-                       d[0].syncid = ipvs->master_syncid;
-               }
-               if (ipvs->sync_state & IP_VS_STATE_BACKUP) {
-                       d[1].state = IP_VS_STATE_BACKUP;
-                       strlcpy(d[1].mcast_ifn, ipvs->backup_mcast_ifn,
-                               sizeof(d[1].mcast_ifn));
-                       d[1].syncid = ipvs->backup_syncid;
-               }
-               if (copy_to_user(user, &d, sizeof(d)) != 0)
-                       ret = -EFAULT;
-       }
-       break;
-
        default:
                ret = -EINVAL;
        }
@@ -3205,7 +3220,7 @@ static int ip_vs_genl_dump_daemons(struct sk_buff *skb,
        struct net *net = skb_sknet(skb);
        struct netns_ipvs *ipvs = net_ipvs(net);
 
-       mutex_lock(&__ip_vs_mutex);
+       mutex_lock(&ipvs->sync_mutex);
        if ((ipvs->sync_state & IP_VS_STATE_MASTER) && !cb->args[0]) {
                if (ip_vs_genl_dump_daemon(skb, IP_VS_STATE_MASTER,
                                           ipvs->master_mcast_ifn,
@@ -3225,7 +3240,7 @@ static int ip_vs_genl_dump_daemons(struct sk_buff *skb,
        }
 
 nla_put_failure:
-       mutex_unlock(&__ip_vs_mutex);
+       mutex_unlock(&ipvs->sync_mutex);
 
        return skb->len;
 }
@@ -3271,13 +3286,9 @@ static int ip_vs_genl_set_config(struct net *net, struct nlattr **attrs)
        return ip_vs_set_timeout(net, &t);
 }
 
-static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info)
+static int ip_vs_genl_set_daemon(struct sk_buff *skb, struct genl_info *info)
 {
-       struct ip_vs_service *svc = NULL;
-       struct ip_vs_service_user_kern usvc;
-       struct ip_vs_dest_user_kern udest;
        int ret = 0, cmd;
-       int need_full_svc = 0, need_full_dest = 0;
        struct net *net;
        struct netns_ipvs *ipvs;
 
@@ -3285,19 +3296,10 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info)
        ipvs = net_ipvs(net);
        cmd = info->genlhdr->cmd;
 
-       mutex_lock(&__ip_vs_mutex);
-
-       if (cmd == IPVS_CMD_FLUSH) {
-               ret = ip_vs_flush(net);
-               goto out;
-       } else if (cmd == IPVS_CMD_SET_CONFIG) {
-               ret = ip_vs_genl_set_config(net, info->attrs);
-               goto out;
-       } else if (cmd == IPVS_CMD_NEW_DAEMON ||
-                  cmd == IPVS_CMD_DEL_DAEMON) {
-
+       if (cmd == IPVS_CMD_NEW_DAEMON || cmd == IPVS_CMD_DEL_DAEMON) {
                struct nlattr *daemon_attrs[IPVS_DAEMON_ATTR_MAX + 1];
 
+               mutex_lock(&ipvs->sync_mutex);
                if (!info->attrs[IPVS_CMD_ATTR_DAEMON] ||
                    nla_parse_nested(daemon_attrs, IPVS_DAEMON_ATTR_MAX,
                                     info->attrs[IPVS_CMD_ATTR_DAEMON],
@@ -3310,6 +3312,33 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info)
                        ret = ip_vs_genl_new_daemon(net, daemon_attrs);
                else
                        ret = ip_vs_genl_del_daemon(net, daemon_attrs);
+out:
+               mutex_unlock(&ipvs->sync_mutex);
+       }
+       return ret;
+}
+
+static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info)
+{
+       struct ip_vs_service *svc = NULL;
+       struct ip_vs_service_user_kern usvc;
+       struct ip_vs_dest_user_kern udest;
+       int ret = 0, cmd;
+       int need_full_svc = 0, need_full_dest = 0;
+       struct net *net;
+       struct netns_ipvs *ipvs;
+
+       net = skb_sknet(skb);
+       ipvs = net_ipvs(net);
+       cmd = info->genlhdr->cmd;
+
+       mutex_lock(&__ip_vs_mutex);
+
+       if (cmd == IPVS_CMD_FLUSH) {
+               ret = ip_vs_flush(net);
+               goto out;
+       } else if (cmd == IPVS_CMD_SET_CONFIG) {
+               ret = ip_vs_genl_set_config(net, info->attrs);
                goto out;
        } else if (cmd == IPVS_CMD_ZERO &&
                   !info->attrs[IPVS_CMD_ATTR_SERVICE]) {
@@ -3536,13 +3565,13 @@ static struct genl_ops ip_vs_genl_ops[] __read_mostly = {
                .cmd    = IPVS_CMD_NEW_DAEMON,
                .flags  = GENL_ADMIN_PERM,
                .policy = ip_vs_cmd_policy,
-               .doit   = ip_vs_genl_set_cmd,
+               .doit   = ip_vs_genl_set_daemon,
        },
        {
                .cmd    = IPVS_CMD_DEL_DAEMON,
                .flags  = GENL_ADMIN_PERM,
                .policy = ip_vs_cmd_policy,
-               .doit   = ip_vs_genl_set_cmd,
+               .doit   = ip_vs_genl_set_daemon,
        },
        {
                .cmd    = IPVS_CMD_GET_DAEMON,
index 7ee7215..3cdd479 100644 (file)
@@ -61,6 +61,7 @@
 
 #define SYNC_PROTO_VER  1              /* Protocol version in header */
 
+static struct lock_class_key __ipvs_sync_key;
 /*
  *     IPVS sync connection entry
  *     Version 0, i.e. original version.
@@ -1545,6 +1546,7 @@ int start_sync_thread(struct net *net, int state, char *mcast_ifn, __u8 syncid)
        IP_VS_DBG(7, "Each ip_vs_sync_conn entry needs %Zd bytes\n",
                  sizeof(struct ip_vs_sync_conn_v0));
 
+
        if (state == IP_VS_STATE_MASTER) {
                if (ipvs->master_thread)
                        return -EEXIST;
@@ -1667,6 +1669,7 @@ int __net_init ip_vs_sync_net_init(struct net *net)
 {
        struct netns_ipvs *ipvs = net_ipvs(net);
 
+       __mutex_init(&ipvs->sync_mutex, "ipvs->sync_mutex", &__ipvs_sync_key);
        INIT_LIST_HEAD(&ipvs->sync_queue);
        spin_lock_init(&ipvs->sync_lock);
        spin_lock_init(&ipvs->sync_buff_lock);
@@ -1680,7 +1683,9 @@ int __net_init ip_vs_sync_net_init(struct net *net)
 void ip_vs_sync_net_cleanup(struct net *net)
 {
        int retc;
+       struct netns_ipvs *ipvs = net_ipvs(net);
 
+       mutex_lock(&ipvs->sync_mutex);
        retc = stop_sync_thread(net, IP_VS_STATE_MASTER);
        if (retc && retc != -ESRCH)
                pr_err("Failed to stop Master Daemon\n");
@@ -1688,4 +1693,5 @@ void ip_vs_sync_net_cleanup(struct net *net)
        retc = stop_sync_thread(net, IP_VS_STATE_BACKUP);
        if (retc && retc != -ESRCH)
                pr_err("Failed to stop Backup Daemon\n");
+       mutex_unlock(&ipvs->sync_mutex);
 }
index cf616e5..d69facd 100644 (file)
@@ -241,8 +241,8 @@ static int gre_packet(struct nf_conn *ct,
                nf_ct_refresh_acct(ct, ctinfo, skb,
                                   ct->proto.gre.stream_timeout);
                /* Also, more likely to be important, and not a probe. */
-               set_bit(IPS_ASSURED_BIT, &ct->status);
-               nf_conntrack_event_cache(IPCT_ASSURED, ct);
+               if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
+                       nf_conntrack_event_cache(IPCT_ASSURED, ct);
        } else
                nf_ct_refresh_acct(ct, ctinfo, skb,
                                   ct->proto.gre.timeout);
index d306154..5f03e4e 100644 (file)
@@ -91,7 +91,7 @@ int x25_parse_address_block(struct sk_buff *skb,
        int needed;
        int rc;
 
-       if (skb->len < 1) {
+       if (!pskb_may_pull(skb, 1)) {
                /* packet has no address block */
                rc = 0;
                goto empty;
@@ -100,7 +100,7 @@ int x25_parse_address_block(struct sk_buff *skb,
        len = *skb->data;
        needed = 1 + (len >> 4) + (len & 0x0f);
 
-       if (skb->len < needed) {
+       if (!pskb_may_pull(skb, needed)) {
                /* packet is too short to hold the addresses it claims
                   to hold */
                rc = -1;
@@ -295,7 +295,8 @@ static struct sock *x25_find_listener(struct x25_address *addr,
                         * Found a listening socket, now check the incoming
                         * call user data vs this sockets call user data
                         */
-                       if(skb->len > 0 && x25_sk(s)->cudmatchlength > 0) {
+                       if (x25_sk(s)->cudmatchlength > 0 &&
+                               skb->len >= x25_sk(s)->cudmatchlength) {
                                if((memcmp(x25_sk(s)->calluserdata.cuddata,
                                        skb->data,
                                        x25_sk(s)->cudmatchlength)) == 0) {
@@ -951,13 +952,26 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
         *
         *      Facilities length is mandatory in call request packets
         */
-       if (skb->len < 1)
+       if (!pskb_may_pull(skb, 1))
                goto out_clear_request;
        len = skb->data[0] + 1;
-       if (skb->len < len)
+       if (!pskb_may_pull(skb, len))
                goto out_clear_request;
        skb_pull(skb,len);
 
+       /*
+        *      Ensure that the amount of call user data is valid.
+        */
+       if (skb->len > X25_MAX_CUD_LEN)
+               goto out_clear_request;
+
+       /*
+        *      Get all the call user data so it can be used in
+        *      x25_find_listener and skb_copy_from_linear_data up ahead.
+        */
+       if (!pskb_may_pull(skb, skb->len))
+               goto out_clear_request;
+
        /*
         *      Find a listener for the particular address/cud pair.
         */
@@ -1166,6 +1180,9 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock,
         *      byte of the user data is the logical value of the Q Bit.
         */
        if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) {
+               if (!pskb_may_pull(skb, 1))
+                       goto out_kfree_skb;
+
                qbit = skb->data[0];
                skb_pull(skb, 1);
        }
@@ -1244,7 +1261,9 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
        struct x25_sock *x25 = x25_sk(sk);
        struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)msg->msg_name;
        size_t copied;
-       int qbit;
+       int qbit, header_len = x25->neighbour->extended ?
+               X25_EXT_MIN_LEN : X25_STD_MIN_LEN;
+
        struct sk_buff *skb;
        unsigned char *asmptr;
        int rc = -ENOTCONN;
@@ -1265,6 +1284,9 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
 
                skb = skb_dequeue(&x25->interrupt_in_queue);
 
+               if (!pskb_may_pull(skb, X25_STD_MIN_LEN))
+                       goto out_free_dgram;
+
                skb_pull(skb, X25_STD_MIN_LEN);
 
                /*
@@ -1285,10 +1307,12 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
                if (!skb)
                        goto out;
 
+               if (!pskb_may_pull(skb, header_len))
+                       goto out_free_dgram;
+
                qbit = (skb->data[0] & X25_Q_BIT) == X25_Q_BIT;
 
-               skb_pull(skb, x25->neighbour->extended ?
-                               X25_EXT_MIN_LEN : X25_STD_MIN_LEN);
+               skb_pull(skb, header_len);
 
                if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) {
                        asmptr  = skb_push(skb, 1);
index e547ca1..fa2b418 100644 (file)
@@ -32,6 +32,9 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *nb)
        unsigned short frametype;
        unsigned int lci;
 
+       if (!pskb_may_pull(skb, X25_STD_MIN_LEN))
+               return 0;
+
        frametype = skb->data[2];
        lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF);
 
@@ -115,6 +118,9 @@ int x25_lapb_receive_frame(struct sk_buff *skb, struct net_device *dev,
                goto drop;
        }
 
+       if (!pskb_may_pull(skb, 1))
+               return 0;
+
        switch (skb->data[0]) {
 
        case X25_IFACE_DATA:
index f77e4e7..36384a1 100644 (file)
@@ -44,7 +44,7 @@
 int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
                struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask)
 {
-       unsigned char *p = skb->data;
+       unsigned char *p;
        unsigned int len;
 
        *vc_fac_mask = 0;
@@ -60,14 +60,16 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
        memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae));
        memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae));
 
-       if (skb->len < 1)
+       if (!pskb_may_pull(skb, 1))
                return 0;
 
-       len = *p++;
+       len = skb->data[0];
 
-       if (len >= skb->len)
+       if (!pskb_may_pull(skb, 1 + len))
                return -1;
 
+       p = skb->data + 1;
+
        while (len > 0) {
                switch (*p & X25_FAC_CLASS_MASK) {
                case X25_FAC_CLASS_A:
index 0b073b5..a49cd4e 100644 (file)
@@ -107,6 +107,8 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
                /*
                 *      Parse the data in the frame.
                 */
+               if (!pskb_may_pull(skb, X25_STD_MIN_LEN))
+                       goto out_clear;
                skb_pull(skb, X25_STD_MIN_LEN);
 
                len = x25_parse_address_block(skb, &source_addr,
@@ -127,9 +129,11 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
                 *      Copy any Call User Data.
                 */
                if (skb->len > 0) {
-                       skb_copy_from_linear_data(skb,
-                                                 x25->calluserdata.cuddata,
-                                                 skb->len);
+                       if (skb->len > X25_MAX_CUD_LEN)
+                               goto out_clear;
+
+                       skb_copy_bits(skb, 0, x25->calluserdata.cuddata,
+                               skb->len);
                        x25->calluserdata.cudlength = skb->len;
                }
                if (!sock_flag(sk, SOCK_DEAD))
@@ -137,6 +141,9 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
                break;
        }
        case X25_CLEAR_REQUEST:
+               if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2))
+                       goto out_clear;
+
                x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
                x25_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
                break;
@@ -164,6 +171,9 @@ static int x25_state2_machine(struct sock *sk, struct sk_buff *skb, int frametyp
        switch (frametype) {
 
                case X25_CLEAR_REQUEST:
+                       if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2))
+                               goto out_clear;
+
                        x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
                        x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
                        break;
@@ -177,6 +187,11 @@ static int x25_state2_machine(struct sock *sk, struct sk_buff *skb, int frametyp
        }
 
        return 0;
+
+out_clear:
+       x25_write_internal(sk, X25_CLEAR_REQUEST);
+       x25_start_t23timer(sk);
+       return 0;
 }
 
 /*
@@ -206,6 +221,9 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp
                        break;
 
                case X25_CLEAR_REQUEST:
+                       if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2))
+                               goto out_clear;
+
                        x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
                        x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
                        break;
@@ -304,6 +322,12 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp
        }
 
        return queued;
+
+out_clear:
+       x25_write_internal(sk, X25_CLEAR_REQUEST);
+       x25->state = X25_STATE_2;
+       x25_start_t23timer(sk);
+       return 0;
 }
 
 /*
@@ -313,13 +337,13 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp
  */
 static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametype)
 {
+       struct x25_sock *x25 = x25_sk(sk);
+
        switch (frametype) {
 
                case X25_RESET_REQUEST:
                        x25_write_internal(sk, X25_RESET_CONFIRMATION);
                case X25_RESET_CONFIRMATION: {
-                       struct x25_sock *x25 = x25_sk(sk);
-
                        x25_stop_timer(sk);
                        x25->condition = 0x00;
                        x25->va        = 0;
@@ -331,6 +355,9 @@ static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametyp
                        break;
                }
                case X25_CLEAR_REQUEST:
+                       if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2))
+                               goto out_clear;
+
                        x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
                        x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
                        break;
@@ -340,6 +367,12 @@ static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametyp
        }
 
        return 0;
+
+out_clear:
+       x25_write_internal(sk, X25_CLEAR_REQUEST);
+       x25->state = X25_STATE_2;
+       x25_start_t23timer(sk);
+       return 0;
 }
 
 /* Higher level upcall for a LAPB frame */
index 037958f..4acacf3 100644 (file)
@@ -90,6 +90,9 @@ void x25_link_control(struct sk_buff *skb, struct x25_neigh *nb,
                break;
 
        case X25_DIAGNOSTIC:
+               if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 4))
+                       break;
+
                printk(KERN_WARNING "x25: diagnostic #%d - %02X %02X %02X\n",
                       skb->data[3], skb->data[4],
                       skb->data[5], skb->data[6]);
index 24a342e..5170d52 100644 (file)
@@ -269,7 +269,11 @@ int x25_decode(struct sock *sk, struct sk_buff *skb, int *ns, int *nr, int *q,
               int *d, int *m)
 {
        struct x25_sock *x25 = x25_sk(sk);
-       unsigned char *frame = skb->data;
+       unsigned char *frame;
+
+       if (!pskb_may_pull(skb, X25_STD_MIN_LEN))
+               return X25_ILLEGAL;
+       frame = skb->data;
 
        *ns = *nr = *q = *d = *m = 0;
 
@@ -294,6 +298,10 @@ int x25_decode(struct sock *sk, struct sk_buff *skb, int *ns, int *nr, int *q,
                if (frame[2] == X25_RR  ||
                    frame[2] == X25_RNR ||
                    frame[2] == X25_REJ) {
+                       if (!pskb_may_pull(skb, X25_EXT_MIN_LEN))
+                               return X25_ILLEGAL;
+                       frame = skb->data;
+
                        *nr = (frame[3] >> 1) & 0x7F;
                        return frame[2];
                }
@@ -308,6 +316,10 @@ int x25_decode(struct sock *sk, struct sk_buff *skb, int *ns, int *nr, int *q,
 
        if (x25->neighbour->extended) {
                if ((frame[2] & 0x01) == X25_DATA) {
+                       if (!pskb_may_pull(skb, X25_EXT_MIN_LEN))
+                               return X25_ILLEGAL;
+                       frame = skb->data;
+
                        *q  = (frame[0] & X25_Q_BIT) == X25_Q_BIT;
                        *d  = (frame[0] & X25_D_BIT) == X25_D_BIT;
                        *m  = (frame[3] & X25_EXT_M_BIT) == X25_EXT_M_BIT;
index 0e4fccf..d9e1533 100644 (file)
@@ -1097,6 +1097,7 @@ void security_sk_clone(const struct sock *sk, struct sock *newsk)
 {
        security_ops->sk_clone_security(sk, newsk);
 }
+EXPORT_SYMBOL(security_sk_clone);
 
 void security_sk_classify_flow(struct sock *sk, struct flowi *fl)
 {
index e9a2a87..191284a 100644 (file)
@@ -2370,6 +2370,7 @@ static int azx_dev_free(struct snd_device *device)
 static struct snd_pci_quirk position_fix_list[] __devinitdata = {
        SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x1028, 0x02c6, "Dell Inspiron 1010", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
index 7696d05..76752d8 100644 (file)
@@ -3110,6 +3110,7 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
        SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS),
        SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
+       SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520 & W520", CXT5066_AUTO),
        SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD),
        SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD),
        SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),