commit:     b4ff8e8d4d51f14358d6a01bc8ddc449a85729c9
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Thu Aug 14 11:42:09 2014 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Thu Aug 14 11:42:09 2014 +0000
URL:        
http://git.overlays.gentoo.org/gitweb/?p=proj/linux-patches.git;a=commit;h=b4ff8e8d

Linux patch 3.4.103

---
 0000_README              |    4 +
 1102_linux-3.4.103.patch | 1133 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1137 insertions(+)

diff --git a/0000_README b/0000_README
index 4747723..9f3e940 100644
--- a/0000_README
+++ b/0000_README
@@ -447,6 +447,10 @@ Patch:  1101_linux-3.4.102.patch
 From:   http://www.kernel.org
 Desc:   Linux 3.4.102
 
+Patch:  1102_linux-3.4.103.patch
+From:   http://www.kernel.org
+Desc:   Linux 3.4.103
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1102_linux-3.4.103.patch b/1102_linux-3.4.103.patch
new file mode 100644
index 0000000..8d0b2b8
--- /dev/null
+++ b/1102_linux-3.4.103.patch
@@ -0,0 +1,1133 @@
+diff --git a/Makefile b/Makefile
+index dd03fa5777a0..36f0913bd1d6 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 3
+ PATCHLEVEL = 4
+-SUBLEVEL = 102
++SUBLEVEL = 103
+ EXTRAVERSION =
+ NAME = Saber-toothed Squirrel
+ 
+diff --git a/arch/sparc/include/asm/pgtable_64.h 
b/arch/sparc/include/asm/pgtable_64.h
+index 656de8bc0ed6..cd24caf1732d 100644
+--- a/arch/sparc/include/asm/pgtable_64.h
++++ b/arch/sparc/include/asm/pgtable_64.h
+@@ -24,7 +24,8 @@
+ 
+ /* The kernel image occupies 0x4000000 to 0x6000000 (4MB --> 96MB).
+  * The page copy blockops can use 0x6000000 to 0x8000000.
+- * The TSB is mapped in the 0x8000000 to 0xa000000 range.
++ * The 8K TSB is mapped in the 0x8000000 to 0x8400000 range.
++ * The 4M TSB is mapped in the 0x8400000 to 0x8800000 range.
+  * The PROM resides in an area spanning 0xf0000000 to 0x100000000.
+  * The vmalloc area spans 0x100000000 to 0x200000000.
+  * Since modules need to be in the lowest 32-bits of the address space,
+@@ -33,7 +34,8 @@
+  * 0x400000000.
+  */
+ #define       TLBTEMP_BASE            _AC(0x0000000006000000,UL)
+-#define       TSBMAP_BASE             _AC(0x0000000008000000,UL)
++#define       TSBMAP_8K_BASE          _AC(0x0000000008000000,UL)
++#define       TSBMAP_4M_BASE          _AC(0x0000000008400000,UL)
+ #define MODULES_VADDR         _AC(0x0000000010000000,UL)
+ #define MODULES_LEN           _AC(0x00000000e0000000,UL)
+ #define MODULES_END           _AC(0x00000000f0000000,UL)
+diff --git a/arch/sparc/include/asm/tlbflush_64.h 
b/arch/sparc/include/asm/tlbflush_64.h
+index f0d6a9700f4c..1a4bb971e06d 100644
+--- a/arch/sparc/include/asm/tlbflush_64.h
++++ b/arch/sparc/include/asm/tlbflush_64.h
+@@ -35,6 +35,8 @@ static inline void flush_tlb_range(struct vm_area_struct 
*vma,
+ {
+ }
+ 
++void flush_tlb_kernel_range(unsigned long start, unsigned long end);
++
+ #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
+ 
+ extern void flush_tlb_pending(void);
+@@ -49,11 +51,6 @@ extern void __flush_tlb_kernel_range(unsigned long start, 
unsigned long end);
+ 
+ #ifndef CONFIG_SMP
+ 
+-#define flush_tlb_kernel_range(start,end) \
+-do {  flush_tsb_kernel_range(start,end); \
+-      __flush_tlb_kernel_range(start,end); \
+-} while (0)
+-
+ static inline void global_flush_tlb_page(struct mm_struct *mm, unsigned long 
vaddr)
+ {
+       __flush_tlb_page(CTX_HWBITS(mm->context), vaddr);
+@@ -64,11 +61,6 @@ static inline void global_flush_tlb_page(struct mm_struct 
*mm, unsigned long vad
+ extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long 
end);
+ extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr);
+ 
+-#define flush_tlb_kernel_range(start, end) \
+-do {  flush_tsb_kernel_range(start,end); \
+-      smp_flush_tlb_kernel_range(start, end); \
+-} while (0)
+-
+ #define global_flush_tlb_page(mm, vaddr) \
+       smp_flush_tlb_page(mm, vaddr)
+ 
+diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c
+index 435e406fdec3..1beaf60a5f78 100644
+--- a/arch/sparc/kernel/ldc.c
++++ b/arch/sparc/kernel/ldc.c
+@@ -1339,7 +1339,7 @@ int ldc_connect(struct ldc_channel *lp)
+       if (!(lp->flags & LDC_FLAG_ALLOCED_QUEUES) ||
+           !(lp->flags & LDC_FLAG_REGISTERED_QUEUES) ||
+           lp->hs_state != LDC_HS_OPEN)
+-              err = -EINVAL;
++              err = ((lp->hs_state > LDC_HS_OPEN) ? 0 : -EINVAL);
+       else
+               err = start_handshake(lp);
+ 
+diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
+index bb2886ac1df3..bbf7e955cb19 100644
+--- a/arch/sparc/kernel/smp_64.c
++++ b/arch/sparc/kernel/smp_64.c
+@@ -151,7 +151,7 @@ void cpu_panic(void)
+ #define NUM_ROUNDS    64      /* magic value */
+ #define NUM_ITERS     5       /* likewise */
+ 
+-static DEFINE_SPINLOCK(itc_sync_lock);
++static DEFINE_RAW_SPINLOCK(itc_sync_lock);
+ static unsigned long go[SLAVE + 1];
+ 
+ #define DEBUG_TICK_SYNC       0
+@@ -259,7 +259,7 @@ static void smp_synchronize_one_tick(int cpu)
+       go[MASTER] = 0;
+       membar_safe("#StoreLoad");
+ 
+-      spin_lock_irqsave(&itc_sync_lock, flags);
++      raw_spin_lock_irqsave(&itc_sync_lock, flags);
+       {
+               for (i = 0; i < NUM_ROUNDS*NUM_ITERS; i++) {
+                       while (!go[MASTER])
+@@ -270,7 +270,7 @@ static void smp_synchronize_one_tick(int cpu)
+                       membar_safe("#StoreLoad");
+               }
+       }
+-      spin_unlock_irqrestore(&itc_sync_lock, flags);
++      raw_spin_unlock_irqrestore(&itc_sync_lock, flags);
+ }
+ 
+ #if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU)
+diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S
+index d97f3eb72e06..085c60fd4b6b 100644
+--- a/arch/sparc/kernel/sys32.S
++++ b/arch/sparc/kernel/sys32.S
+@@ -87,7 +87,7 @@ SIGN1(sys32_io_submit, compat_sys_io_submit, %o1)
+ SIGN1(sys32_mq_open, compat_sys_mq_open, %o1)
+ SIGN1(sys32_select, compat_sys_select, %o0)
+ SIGN1(sys32_mkdir, sys_mkdir, %o1)
+-SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5)
++SIGN1(sys32_futex, compat_sys_futex, %o1)
+ SIGN1(sys32_sysfs, compat_sys_sysfs, %o0)
+ SIGN2(sys32_sendfile, compat_sys_sendfile, %o0, %o1)
+ SIGN2(sys32_sendfile64, compat_sys_sendfile64, %o0, %o1)
+diff --git a/arch/sparc/kernel/unaligned_64.c 
b/arch/sparc/kernel/unaligned_64.c
+index dae85bc2eda5..a3c3a5bcd126 100644
+--- a/arch/sparc/kernel/unaligned_64.c
++++ b/arch/sparc/kernel/unaligned_64.c
+@@ -156,17 +156,23 @@ static unsigned long *fetch_reg_addr(unsigned int reg, 
struct pt_regs *regs)
+ unsigned long compute_effective_address(struct pt_regs *regs,
+                                       unsigned int insn, unsigned int rd)
+ {
++      int from_kernel = (regs->tstate & TSTATE_PRIV) != 0;
+       unsigned int rs1 = (insn >> 14) & 0x1f;
+       unsigned int rs2 = insn & 0x1f;
+-      int from_kernel = (regs->tstate & TSTATE_PRIV) != 0;
++      unsigned long addr;
+ 
+       if (insn & 0x2000) {
+               maybe_flush_windows(rs1, 0, rd, from_kernel);
+-              return (fetch_reg(rs1, regs) + sign_extend_imm13(insn));
++              addr = (fetch_reg(rs1, regs) + sign_extend_imm13(insn));
+       } else {
+               maybe_flush_windows(rs1, rs2, rd, from_kernel);
+-              return (fetch_reg(rs1, regs) + fetch_reg(rs2, regs));
++              addr = (fetch_reg(rs1, regs) + fetch_reg(rs2, regs));
+       }
++
++      if (!from_kernel && test_thread_flag(TIF_32BIT))
++              addr &= 0xffffffff;
++
++      return addr;
+ }
+ 
+ /* This is just to make gcc think die_if_kernel does return... */
+diff --git a/arch/sparc/lib/NG2memcpy.S b/arch/sparc/lib/NG2memcpy.S
+index 0aed75653b50..e993fc8d7c66 100644
+--- a/arch/sparc/lib/NG2memcpy.S
++++ b/arch/sparc/lib/NG2memcpy.S
+@@ -236,6 +236,7 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
+        */
+       VISEntryHalf
+ 
++      membar          #Sync
+       alignaddr       %o1, %g0, %g0
+ 
+       add             %o1, (64 - 1), %o4
+diff --git a/arch/sparc/math-emu/math_32.c b/arch/sparc/math-emu/math_32.c
+index aa4d55b0bdf0..5ce8f2f64604 100644
+--- a/arch/sparc/math-emu/math_32.c
++++ b/arch/sparc/math-emu/math_32.c
+@@ -499,7 +499,7 @@ static int do_one_mathemu(u32 insn, unsigned long *pfsr, 
unsigned long *fregs)
+               case 0: fsr = *pfsr;
+                       if (IR == -1) IR = 2;
+                       /* fcc is always fcc0 */
+-                      fsr &= ~0xc00; fsr |= (IR << 10); break;
++                      fsr &= ~0xc00; fsr |= (IR << 10);
+                       *pfsr = fsr;
+                       break;
+               case 1: rd->s = IR; break;
+diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
+index 1fe0429b6314..1387acafc62c 100644
+--- a/arch/sparc/mm/fault_64.c
++++ b/arch/sparc/mm/fault_64.c
+@@ -95,38 +95,51 @@ static unsigned int get_user_insn(unsigned long tpc)
+       pte_t *ptep, pte;
+       unsigned long pa;
+       u32 insn = 0;
+-      unsigned long pstate;
+ 
+-      if (pgd_none(*pgdp))
+-              goto outret;
++      if (pgd_none(*pgdp) || unlikely(pgd_bad(*pgdp)))
++              goto out;
+       pudp = pud_offset(pgdp, tpc);
+-      if (pud_none(*pudp))
+-              goto outret;
+-      pmdp = pmd_offset(pudp, tpc);
+-      if (pmd_none(*pmdp))
+-              goto outret;
+-
+-      /* This disables preemption for us as well. */
+-      __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
+-      __asm__ __volatile__("wrpr %0, %1, %%pstate"
+-                              : : "r" (pstate), "i" (PSTATE_IE));
+-      ptep = pte_offset_map(pmdp, tpc);
+-      pte = *ptep;
+-      if (!pte_present(pte))
++      if (pud_none(*pudp) || unlikely(pud_bad(*pudp)))
+               goto out;
+ 
+-      pa  = (pte_pfn(pte) << PAGE_SHIFT);
+-      pa += (tpc & ~PAGE_MASK);
+-
+-      /* Use phys bypass so we don't pollute dtlb/dcache. */
+-      __asm__ __volatile__("lduwa [%1] %2, %0"
+-                           : "=r" (insn)
+-                           : "r" (pa), "i" (ASI_PHYS_USE_EC));
++      /* This disables preemption for us as well. */
++      local_irq_disable();
+ 
++      pmdp = pmd_offset(pudp, tpc);
++      if (pmd_none(*pmdp) || unlikely(pmd_bad(*pmdp)))
++              goto out_irq_enable;
++
++#ifdef CONFIG_TRANSPARENT_HUGEPAGE
++      if (pmd_trans_huge(*pmdp)) {
++              if (pmd_trans_splitting(*pmdp))
++                      goto out_irq_enable;
++
++              pa  = pmd_pfn(*pmdp) << PAGE_SHIFT;
++              pa += tpc & ~HPAGE_MASK;
++
++              /* Use phys bypass so we don't pollute dtlb/dcache. */
++              __asm__ __volatile__("lduwa [%1] %2, %0"
++                                   : "=r" (insn)
++                                   : "r" (pa), "i" (ASI_PHYS_USE_EC));
++      } else
++#endif
++      {
++              ptep = pte_offset_map(pmdp, tpc);
++              pte = *ptep;
++              if (pte_present(pte)) {
++                      pa  = (pte_pfn(pte) << PAGE_SHIFT);
++                      pa += (tpc & ~PAGE_MASK);
++
++                      /* Use phys bypass so we don't pollute dtlb/dcache. */
++                      __asm__ __volatile__("lduwa [%1] %2, %0"
++                                           : "=r" (insn)
++                                           : "r" (pa), "i" (ASI_PHYS_USE_EC));
++              }
++              pte_unmap(ptep);
++      }
++out_irq_enable:
++      local_irq_enable();
+ out:
+-      pte_unmap(ptep);
+-      __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate));
+-outret:
+       return insn;
+ }
+ 
+@@ -154,7 +167,8 @@ show_signal_msg(struct pt_regs *regs, int sig, int code,
+ extern unsigned long compute_effective_address(struct pt_regs *, unsigned 
int, unsigned int);
+ 
+ static void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
+-                           unsigned int insn, int fault_code)
++                           unsigned long fault_addr, unsigned int insn,
++                           int fault_code)
+ {
+       unsigned long addr;
+       siginfo_t info;
+@@ -162,10 +176,18 @@ static void do_fault_siginfo(int code, int sig, struct 
pt_regs *regs,
+       info.si_code = code;
+       info.si_signo = sig;
+       info.si_errno = 0;
+-      if (fault_code & FAULT_CODE_ITLB)
++      if (fault_code & FAULT_CODE_ITLB) {
+               addr = regs->tpc;
+-      else
+-              addr = compute_effective_address(regs, insn, 0);
++      } else {
++              /* If we were able to probe the faulting instruction, use it
++               * to compute a precise fault address.  Otherwise use the fault
++               * time provided address which may only have page granularity.
++               */
++              if (insn)
++                      addr = compute_effective_address(regs, insn, 0);
++              else
++                      addr = fault_addr;
++      }
+       info.si_addr = (void __user *) addr;
+       info.si_trapno = 0;
+ 
+@@ -240,7 +262,7 @@ static void __kprobes do_kernel_fault(struct pt_regs 
*regs, int si_code,
+               /* The si_code was set to make clear whether
+                * this was a SEGV_MAPERR or SEGV_ACCERR fault.
+                */
+-              do_fault_siginfo(si_code, SIGSEGV, regs, insn, fault_code);
++              do_fault_siginfo(si_code, SIGSEGV, regs, address, insn, 
fault_code);
+               return;
+       }
+ 
+@@ -260,18 +282,6 @@ static void noinline __kprobes 
bogus_32bit_fault_tpc(struct pt_regs *regs)
+       show_regs(regs);
+ }
+ 
+-static void noinline __kprobes bogus_32bit_fault_address(struct pt_regs *regs,
+-                                                       unsigned long addr)
+-{
+-      static int times;
+-
+-      if (times++ < 10)
+-              printk(KERN_ERR "FAULT[%s:%d]: 32-bit process "
+-                     "reports 64-bit fault address [%lx]\n",
+-                     current->comm, current->pid, addr);
+-      show_regs(regs);
+-}
+-
+ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
+ {
+       struct mm_struct *mm = current->mm;
+@@ -300,10 +310,8 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs 
*regs)
+                               goto intr_or_no_mm;
+                       }
+               }
+-              if (unlikely((address >> 32) != 0)) {
+-                      bogus_32bit_fault_address(regs, address);
++              if (unlikely((address >> 32) != 0))
+                       goto intr_or_no_mm;
+-              }
+       }
+ 
+       if (regs->tstate & TSTATE_PRIV) {
+@@ -515,7 +523,7 @@ do_sigbus:
+        * Send a sigbus, regardless of whether we were in kernel
+        * or user mode.
+        */
+-      do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, insn, fault_code);
++      do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, address, insn, fault_code);
+ 
+       /* Kernel mode? Handle exceptions or die */
+       if (regs->tstate & TSTATE_PRIV)
+diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
+index 7f8238f4f954..7eb24bddf268 100644
+--- a/arch/sparc/mm/init_64.c
++++ b/arch/sparc/mm/init_64.c
+@@ -308,6 +308,10 @@ void update_mmu_cache(struct vm_area_struct *vma, 
unsigned long address, pte_t *
+       tsb_index = MM_TSB_BASE;
+       tsb_hash_shift = PAGE_SHIFT;
+ 
++      /* Don't insert a non-valid PTE into the TSB, we'll deadlock.  */
++      if (!(pte_val(pte) & _PAGE_VALID))
++              return;
++
+       spin_lock_irqsave(&mm->context.lock, flags);
+ 
+ #ifdef CONFIG_HUGETLB_PAGE
+@@ -2417,3 +2421,26 @@ void __flush_tlb_all(void)
+       __asm__ __volatile__("wrpr      %0, 0, %%pstate"
+                            : : "r" (pstate));
+ }
++
++#ifdef CONFIG_SMP
++#define do_flush_tlb_kernel_range     smp_flush_tlb_kernel_range
++#else
++#define do_flush_tlb_kernel_range     __flush_tlb_kernel_range
++#endif
++
++void flush_tlb_kernel_range(unsigned long start, unsigned long end)
++{
++      if (start < HI_OBP_ADDRESS && end > LOW_OBP_ADDRESS) {
++              if (start < LOW_OBP_ADDRESS) {
++                      flush_tsb_kernel_range(start, LOW_OBP_ADDRESS);
++                      do_flush_tlb_kernel_range(start, LOW_OBP_ADDRESS);
++              }
++              if (end > HI_OBP_ADDRESS) {
++                      flush_tsb_kernel_range(end, HI_OBP_ADDRESS);
++                      do_flush_tlb_kernel_range(end, HI_OBP_ADDRESS);
++              }
++      } else {
++              flush_tsb_kernel_range(start, end);
++              do_flush_tlb_kernel_range(start, end);
++      }
++}
+diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c
+index f4e84f3440dd..41530193e6d6 100644
+--- a/arch/sparc/mm/tsb.c
++++ b/arch/sparc/mm/tsb.c
+@@ -150,7 +150,19 @@ static void setup_tsb_params(struct mm_struct *mm, 
unsigned long tsb_idx, unsign
+       mm->context.tsb_block[tsb_idx].tsb_nentries =
+               tsb_bytes / sizeof(struct tsb);
+ 
+-      base = TSBMAP_BASE;
++      switch (tsb_idx) {
++      case MM_TSB_BASE:
++              base = TSBMAP_8K_BASE;
++              break;
++#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
++      case MM_TSB_HUGE:
++              base = TSBMAP_4M_BASE;
++              break;
++#endif
++      default:
++              BUG();
++      }
++
+       tte = pgprot_val(PAGE_KERNEL_LOCKED);
+       tsb_paddr = __pa(mm->context.tsb_block[tsb_idx].tsb);
+       BUG_ON(tsb_paddr & (tsb_bytes - 1UL));
+diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
+index c4bb95b051f3..6749acf6f3f4 100644
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -455,6 +455,7 @@ static int macvlan_init(struct net_device *dev)
+                                 (lowerdev->state & MACVLAN_STATE_MASK);
+       dev->features           = lowerdev->features & MACVLAN_FEATURES;
+       dev->features           |= NETIF_F_LLTX;
++      dev->vlan_features      = lowerdev->vlan_features & MACVLAN_FEATURES;
+       dev->gso_max_size       = lowerdev->gso_max_size;
+       dev->iflink             = lowerdev->ifindex;
+       dev->hard_header_len    = lowerdev->hard_header_len;
+diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c
+index 8327cc596c34..9f047a04215e 100644
+--- a/drivers/net/ppp/pptp.c
++++ b/drivers/net/ppp/pptp.c
+@@ -281,7 +281,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct 
sk_buff *skb)
+       nf_reset(skb);
+ 
+       skb->ip_summed = CHECKSUM_NONE;
+-      ip_select_ident(skb, &rt->dst, NULL);
++      ip_select_ident(skb, NULL);
+       ip_send_check(iph);
+ 
+       ip_local_out(skb);
+diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c
+index 160e7510aca6..0787b9756165 100644
+--- a/drivers/sbus/char/bbc_envctrl.c
++++ b/drivers/sbus/char/bbc_envctrl.c
+@@ -452,6 +452,9 @@ static void attach_one_temp(struct bbc_i2c_bus *bp, struct 
platform_device *op,
+       if (!tp)
+               return;
+ 
++      INIT_LIST_HEAD(&tp->bp_list);
++      INIT_LIST_HEAD(&tp->glob_list);
++
+       tp->client = bbc_i2c_attach(bp, op);
+       if (!tp->client) {
+               kfree(tp);
+@@ -497,6 +500,9 @@ static void attach_one_fan(struct bbc_i2c_bus *bp, struct 
platform_device *op,
+       if (!fp)
+               return;
+ 
++      INIT_LIST_HEAD(&fp->bp_list);
++      INIT_LIST_HEAD(&fp->glob_list);
++
+       fp->client = bbc_i2c_attach(bp, op);
+       if (!fp->client) {
+               kfree(fp);
+diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c
+index 542668292900..7179f72b11ea 100644
+--- a/drivers/sbus/char/bbc_i2c.c
++++ b/drivers/sbus/char/bbc_i2c.c
+@@ -301,13 +301,18 @@ static struct bbc_i2c_bus * __init attach_one_i2c(struct 
platform_device *op, in
+       if (!bp)
+               return NULL;
+ 
++      INIT_LIST_HEAD(&bp->temps);
++      INIT_LIST_HEAD(&bp->fans);
++
+       bp->i2c_control_regs = of_ioremap(&op->resource[0], 0, 0x2, 
"bbc_i2c_regs");
+       if (!bp->i2c_control_regs)
+               goto fail;
+ 
+-      bp->i2c_bussel_reg = of_ioremap(&op->resource[1], 0, 0x1, 
"bbc_i2c_bussel");
+-      if (!bp->i2c_bussel_reg)
+-              goto fail;
++      if (op->num_resources == 2) {
++              bp->i2c_bussel_reg = of_ioremap(&op->resource[1], 0, 0x1, 
"bbc_i2c_bussel");
++              if (!bp->i2c_bussel_reg)
++                      goto fail;
++      }
+ 
+       bp->waiting = 0;
+       init_waitqueue_head(&bp->wq);
+diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c
+index f0d93eb7e6ec..c9549aa135b2 100644
+--- a/drivers/tty/serial/sunsab.c
++++ b/drivers/tty/serial/sunsab.c
+@@ -157,6 +157,15 @@ receive_chars(struct uart_sunsab_port *up,
+           (up->port.line == up->port.cons->index))
+               saw_console_brk = 1;
+ 
++      if (count == 0) {
++              if (unlikely(stat->sreg.isr1 & SAB82532_ISR1_BRK)) {
++                      stat->sreg.isr0 &= ~(SAB82532_ISR0_PERR |
++                                           SAB82532_ISR0_FERR);
++                      up->port.icount.brk++;
++                      uart_handle_break(&up->port);
++              }
++      }
++
+       for (i = 0; i < count; i++) {
+               unsigned char ch = buf[i], flag;
+ 
+diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h
+index 2d643649f0f8..168d30dfe807 100644
+--- a/include/net/inetpeer.h
++++ b/include/net/inetpeer.h
+@@ -46,13 +46,12 @@ struct inet_peer {
+       };
+       /*
+        * Once inet_peer is queued for deletion (refcnt == -1), following 
fields
+-       * are not available: rid, ip_id_count, tcp_ts, tcp_ts_stamp
++       * are not available: rid, tcp_ts, tcp_ts_stamp
+        * We can share memory with rcu_head to help keep inet_peer small.
+        */
+       union {
+               struct {
+                       atomic_t                        rid;            /* Frag 
reception counter */
+-                      atomic_t                        ip_id_count;    /* IP 
ID for the next packet */
+                       __u32                           tcp_ts;
+                       __u32                           tcp_ts_stamp;
+               };
+@@ -102,7 +101,7 @@ extern bool inet_peer_xrlim_allow(struct inet_peer *peer, 
int timeout);
+ extern void inetpeer_invalidate_tree(int family);
+ 
+ /*
+- * temporary check to make sure we dont access rid, ip_id_count, tcp_ts,
++ * temporary check to make sure we dont access rid, tcp_ts,
+  * tcp_ts_stamp if no refcount is taken on inet_peer
+  */
+ static inline void inet_peer_refcheck(const struct inet_peer *p)
+@@ -110,13 +109,4 @@ static inline void inet_peer_refcheck(const struct 
inet_peer *p)
+       WARN_ON_ONCE(atomic_read(&p->refcnt) <= 0);
+ }
+ 
+-
+-/* can be called with or without local BH being disabled */
+-static inline int inet_getid(struct inet_peer *p, int more)
+-{
+-      more++;
+-      inet_peer_refcheck(p);
+-      return atomic_add_return(more, &p->ip_id_count) - more;
+-}
+-
+ #endif /* _NET_INETPEER_H */
+diff --git a/include/net/ip.h b/include/net/ip.h
+index 6d6b12f4753c..34d004892143 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -264,9 +264,10 @@ int ip_dont_fragment(struct sock *sk, struct dst_entry 
*dst)
+                !(dst_metric_locked(dst, RTAX_MTU)));
+ }
+ 
+-extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int 
more);
++u32 ip_idents_reserve(u32 hash, int segs);
++void __ip_select_ident(struct iphdr *iph, int segs);
+ 
+-static inline void ip_select_ident(struct sk_buff *skb, struct dst_entry 
*dst, struct sock *sk)
++static inline void ip_select_ident_segs(struct sk_buff *skb, struct sock *sk, 
int segs)
+ {
+       struct iphdr *iph = ip_hdr(skb);
+ 
+@@ -276,24 +277,20 @@ static inline void ip_select_ident(struct sk_buff *skb, 
struct dst_entry *dst, s
+                * does not change, they drop every other packet in
+                * a TCP stream using header compression.
+                */
+-              iph->id = (sk && inet_sk(sk)->inet_daddr) ?
+-                                      htons(inet_sk(sk)->inet_id++) : 0;
+-      } else
+-              __ip_select_ident(iph, dst, 0);
+-}
+-
+-static inline void ip_select_ident_more(struct sk_buff *skb, struct dst_entry 
*dst, struct sock *sk, int more)
+-{
+-      struct iphdr *iph = ip_hdr(skb);
+-
+-      if ((iph->frag_off & htons(IP_DF)) && !skb->local_df) {
+               if (sk && inet_sk(sk)->inet_daddr) {
+                       iph->id = htons(inet_sk(sk)->inet_id);
+-                      inet_sk(sk)->inet_id += 1 + more;
+-              } else
++                      inet_sk(sk)->inet_id += segs;
++              } else {
+                       iph->id = 0;
+-      } else
+-              __ip_select_ident(iph, dst, more);
++              }
++      } else {
++              __ip_select_ident(iph, segs);
++      }
++}
++
++static inline void ip_select_ident(struct sk_buff *skb, struct sock *sk)
++{
++      ip_select_ident_segs(skb, sk, 1);
+ }
+ 
+ /*
+diff --git a/include/net/ipip.h b/include/net/ipip.h
+index 4dccfe3bf731..e8ee3bb1b1ca 100644
+--- a/include/net/ipip.h
++++ b/include/net/ipip.h
+@@ -50,7 +50,7 @@ struct ip_tunnel_prl_entry {
+       int pkt_len = skb->len - skb_transport_offset(skb);             \
+                                                                       \
+       skb->ip_summed = CHECKSUM_NONE;                                 \
+-      ip_select_ident(skb, &rt->dst, NULL);                           \
++      ip_select_ident(skb, NULL);                             \
+                                                                       \
+       err = ip_local_out(skb);                                        \
+       if (likely(net_xmit_eval(err) == 0)) {                          \
+diff --git a/include/net/ipv6.h b/include/net/ipv6.h
+index fa7af9183dc9..117eaa578d0d 100644
+--- a/include/net/ipv6.h
++++ b/include/net/ipv6.h
+@@ -392,14 +392,19 @@ void ip6_frag_init(struct inet_frag_queue *q, void *a);
+ int ip6_frag_match(struct inet_frag_queue *q, void *a);
+ 
+ /* more secured version of ipv6_addr_hash() */
+-static inline u32 ipv6_addr_jhash(const struct in6_addr *a)
++static inline u32 __ipv6_addr_jhash(const struct in6_addr *a, const u32 
initval)
+ {
+       u32 v = (__force u32)a->s6_addr32[0] ^ (__force u32)a->s6_addr32[1];
+ 
+       return jhash_3words(v,
+                           (__force u32)a->s6_addr32[2],
+                           (__force u32)a->s6_addr32[3],
+-                          ipv6_hash_secret);
++                          initval);
++}
++
++static inline u32 ipv6_addr_jhash(const struct in6_addr *a)
++{
++      return __ipv6_addr_jhash(a, ipv6_hash_secret);
+ }
+ 
+ static inline int ipv6_addr_any(const struct in6_addr *a)
+diff --git a/include/net/secure_seq.h b/include/net/secure_seq.h
+index c2e542b27a5a..b1c3d1c63c4e 100644
+--- a/include/net/secure_seq.h
++++ b/include/net/secure_seq.h
+@@ -3,8 +3,6 @@
+ 
+ #include <linux/types.h>
+ 
+-extern __u32 secure_ip_id(__be32 daddr);
+-extern __u32 secure_ipv6_id(const __be32 daddr[4]);
+ extern u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 
dport);
+ extern u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 
*daddr,
+                                     __be16 dport);
+diff --git a/net/compat.c b/net/compat.c
+index 93f542335e19..2c774d889d39 100644
+--- a/net/compat.c
++++ b/net/compat.c
+@@ -85,7 +85,7 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct 
iovec *kern_iov,
+ {
+       int tot_len;
+ 
+-      if (kern_msg->msg_namelen) {
++      if (kern_msg->msg_name && kern_msg->msg_namelen) {
+               if (mode == VERIFY_READ) {
+                       int err = move_addr_to_kernel(kern_msg->msg_name,
+                                                     kern_msg->msg_namelen,
+@@ -93,10 +93,11 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct 
iovec *kern_iov,
+                       if (err < 0)
+                               return err;
+               }
+-              if (kern_msg->msg_name)
+-                      kern_msg->msg_name = kern_address;
+-      } else
++              kern_msg->msg_name = kern_address;
++      } else {
+               kern_msg->msg_name = NULL;
++              kern_msg->msg_namelen = 0;
++      }
+ 
+       tot_len = iov_from_user_compat_to_kern(kern_iov,
+                                         (struct compat_iovec __user 
*)kern_msg->msg_iov,
+diff --git a/net/core/iovec.c b/net/core/iovec.c
+index 7fd34a56aeb3..d1628b79286b 100644
+--- a/net/core/iovec.c
++++ b/net/core/iovec.c
+@@ -39,7 +39,7 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct 
sockaddr_storage *a
+ {
+       int size, ct, err;
+ 
+-      if (m->msg_namelen) {
++      if (m->msg_name && m->msg_namelen) {
+               if (mode == VERIFY_READ) {
+                       void __user *namep;
+                       namep = (void __user __force *) m->msg_name;
+@@ -48,10 +48,10 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, 
struct sockaddr_storage *a
+                       if (err < 0)
+                               return err;
+               }
+-              if (m->msg_name)
+-                      m->msg_name = address;
++              m->msg_name = address;
+       } else {
+               m->msg_name = NULL;
++              m->msg_namelen = 0;
+       }
+ 
+       size = m->msg_iovlen * sizeof(struct iovec);
+@@ -157,6 +157,10 @@ EXPORT_SYMBOL(memcpy_fromiovec);
+ int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
+                       int offset, int len)
+ {
++      /* No data? Done! */
++      if (len == 0)
++              return 0;
++
+       /* Skip over the finished iovecs */
+       while (offset >= iov->iov_len) {
+               offset -= iov->iov_len;
+diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c
+index 99b2596531bb..6ecbd58418b3 100644
+--- a/net/core/secure_seq.c
++++ b/net/core/secure_seq.c
+@@ -79,29 +79,6 @@ u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const 
__be32 *daddr,
+ #endif
+ 
+ #ifdef CONFIG_INET
+-__u32 secure_ip_id(__be32 daddr)
+-{
+-      u32 hash[MD5_DIGEST_WORDS];
+-
+-      hash[0] = (__force __u32) daddr;
+-      hash[1] = net_secret[13];
+-      hash[2] = net_secret[14];
+-      hash[3] = net_secret[15];
+-
+-      md5_transform(hash, net_secret);
+-
+-      return hash[0];
+-}
+-
+-__u32 secure_ipv6_id(const __be32 daddr[4])
+-{
+-      __u32 hash[4];
+-
+-      memcpy(hash, daddr, 16);
+-      md5_transform(hash, net_secret);
+-
+-      return hash[0];
+-}
+ 
+ __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
+                                __be16 sport, __be16 dport)
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 8de819475378..728f49babfe0 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -2748,7 +2748,6 @@ struct sk_buff *skb_segment(struct sk_buff *skb, 
netdev_features_t features)
+               tail = nskb;
+ 
+               __copy_skb_header(nskb, skb);
+-              nskb->mac_len = skb->mac_len;
+ 
+               /* nskb and skb might have different headroom */
+               if (nskb->ip_summed == CHECKSUM_PARTIAL)
+@@ -2758,6 +2757,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, 
netdev_features_t features)
+               skb_set_network_header(nskb, skb->mac_len);
+               nskb->transport_header = (nskb->network_header +
+                                         skb_network_header_len(skb));
++              skb_reset_mac_len(nskb);
+               skb_copy_from_linear_data(skb, nskb->data, doffset);
+ 
+               if (fskb != skb_shinfo(skb)->frag_list)
+diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
+index 3f0bb3b3819d..782467708c10 100644
+--- a/net/ipv4/igmp.c
++++ b/net/ipv4/igmp.c
+@@ -343,7 +343,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device 
*dev, int size)
+       pip->saddr    = fl4.saddr;
+       pip->protocol = IPPROTO_IGMP;
+       pip->tot_len  = 0;      /* filled in later */
+-      ip_select_ident(skb, &rt->dst, NULL);
++      ip_select_ident(skb, NULL);
+       ((u8*)&pip[1])[0] = IPOPT_RA;
+       ((u8*)&pip[1])[1] = 4;
+       ((u8*)&pip[1])[2] = 0;
+@@ -687,7 +687,7 @@ static int igmp_send_report(struct in_device *in_dev, 
struct ip_mc_list *pmc,
+       iph->daddr    = dst;
+       iph->saddr    = fl4.saddr;
+       iph->protocol = IPPROTO_IGMP;
+-      ip_select_ident(skb, &rt->dst, NULL);
++      ip_select_ident(skb, NULL);
+       ((u8*)&iph[1])[0] = IPOPT_RA;
+       ((u8*)&iph[1])[1] = 4;
+       ((u8*)&iph[1])[2] = 0;
+diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
+index d63a9268cff6..db1b6a73e0ff 100644
+--- a/net/ipv4/inetpeer.c
++++ b/net/ipv4/inetpeer.c
+@@ -26,20 +26,7 @@
+  *  Theory of operations.
+  *  We keep one entry for each peer IP address.  The nodes contains 
long-living
+  *  information about the peer which doesn't depend on routes.
+- *  At this moment this information consists only of ID field for the next
+- *  outgoing IP packet.  This field is incremented with each packet as encoded
+- *  in inet_getid() function (include/net/inetpeer.h).
+- *  At the moment of writing this notes identifier of IP packets is generated
+- *  to be unpredictable using this code only for packets subjected
+- *  (actually or potentially) to defragmentation.  I.e. DF packets less than
+- *  PMTU in size when local fragmentation is disabled use a constant ID and do
+- *  not use this code (see ip_select_ident() in include/net/ip.h).
+  *
+- *  Route cache entries hold references to our nodes.
+- *  New cache entries get references via lookup by destination IP address in
+- *  the avl tree.  The reference is grabbed only when it's needed i.e. only
+- *  when we try to output IP packet which needs an unpredictable ID (see
+- *  __ip_select_ident() in net/ipv4/route.c).
+  *  Nodes are removed only when reference counter goes to 0.
+  *  When it's happened the node may be removed when a sufficient amount of
+  *  time has been passed since its last use.  The less-recently-used entry can
+@@ -62,7 +49,6 @@
+  *            refcnt: atomically against modifications on other CPU;
+  *               usually under some other lock to prevent node disappearing
+  *            daddr: unchangeable
+- *            ip_id_count: atomic value (no lock needed)
+  */
+ 
+ static struct kmem_cache *peer_cachep __read_mostly;
+@@ -488,10 +474,6 @@ relookup:
+               p->daddr = *daddr;
+               atomic_set(&p->refcnt, 1);
+               atomic_set(&p->rid, 0);
+-              atomic_set(&p->ip_id_count,
+-                              (daddr->family == AF_INET) ?
+-                                      secure_ip_id(daddr->addr.a4) :
+-                                      secure_ipv6_id(daddr->addr.a6));
+               p->tcp_ts_stamp = 0;
+               p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW;
+               p->rate_tokens = 0;
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
+index d6407b563fd8..7827436ae843 100644
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -161,7 +161,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock 
*sk,
+       iph->daddr    = (opt && opt->opt.srr ? opt->opt.faddr : daddr);
+       iph->saddr    = saddr;
+       iph->protocol = sk->sk_protocol;
+-      ip_select_ident(skb, &rt->dst, sk);
++      ip_select_ident(skb, sk);
+ 
+       if (opt && opt->opt.optlen) {
+               iph->ihl += opt->opt.optlen>>2;
+@@ -403,8 +403,7 @@ packet_routed:
+               ip_options_build(skb, &inet_opt->opt, inet->inet_daddr, rt, 0);
+       }
+ 
+-      ip_select_ident_more(skb, &rt->dst, sk,
+-                           (skb_shinfo(skb)->gso_segs ?: 1) - 1);
++      ip_select_ident_segs(skb, sk, skb_shinfo(skb)->gso_segs ?: 1);
+ 
+       skb->priority = sk->sk_priority;
+       skb->mark = sk->sk_mark;
+@@ -1347,7 +1346,7 @@ struct sk_buff *__ip_make_skb(struct sock *sk,
+       iph->ihl = 5;
+       iph->tos = inet->tos;
+       iph->frag_off = df;
+-      ip_select_ident(skb, &rt->dst, sk);
++      ip_select_ident(skb, sk);
+       iph->ttl = ttl;
+       iph->protocol = sk->sk_protocol;
+       ip_copy_addrs(iph, fl4);
+diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
+index 94cd1ef1e319..5ccef6e06dc5 100644
+--- a/net/ipv4/ipmr.c
++++ b/net/ipv4/ipmr.c
+@@ -1576,7 +1576,7 @@ static void ip_encap(struct sk_buff *skb, __be32 saddr, 
__be32 daddr)
+       iph->protocol   =       IPPROTO_IPIP;
+       iph->ihl        =       5;
+       iph->tot_len    =       htons(skb->len);
+-      ip_select_ident(skb, skb_dst(skb), NULL);
++      ip_select_ident(skb, NULL);
+       ip_send_check(iph);
+ 
+       memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
+index 48c6ebcb7fe0..c1b3970caa68 100644
+--- a/net/ipv4/raw.c
++++ b/net/ipv4/raw.c
+@@ -384,7 +384,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 
*fl4,
+               iph->check   = 0;
+               iph->tot_len = htons(length);
+               if (!iph->id)
+-                      ip_select_ident(skb, &rt->dst, NULL);
++                      ip_select_ident(skb, NULL);
+ 
+               iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
+       }
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 90bc88bbd2a4..fd6843371f2e 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -1341,46 +1341,53 @@ void rt_bind_peer(struct rtable *rt, __be32 daddr, int 
create)
+               rt->rt_peer_genid = rt_peer_genid();
+ }
+ 
+-/*
+- * Peer allocation may fail only in serious out-of-memory conditions.  However
+- * we still can generate some output.
+- * Random ID selection looks a bit dangerous because we have no chances to
+- * select ID being unique in a reasonable period of time.
+- * But broken packet identifier may be better than no packet at all.
++#define IP_IDENTS_SZ 2048u
++struct ip_ident_bucket {
++      atomic_t        id;
++      u32             stamp32;
++};
++
++static struct ip_ident_bucket *ip_idents __read_mostly;
++
++/* In order to protect privacy, we add a perturbation to identifiers
++ * if one generator is seldom used. This makes hard for an attacker
++ * to infer how many packets were sent between two points in time.
+  */
+-static void ip_select_fb_ident(struct iphdr *iph)
++u32 ip_idents_reserve(u32 hash, int segs)
+ {
+-      static DEFINE_SPINLOCK(ip_fb_id_lock);
+-      static u32 ip_fallback_id;
+-      u32 salt;
++      struct ip_ident_bucket *bucket = ip_idents + hash % IP_IDENTS_SZ;
++      u32 old = ACCESS_ONCE(bucket->stamp32);
++      u32 now = (u32)jiffies;
++      u32 delta = 0;
++
++      if (old != now && cmpxchg(&bucket->stamp32, old, now) == old) {
++              u64 x = random32();
++
++              x *= (now - old);
++              delta = (u32)(x >> 32);
++      }
+ 
+-      spin_lock_bh(&ip_fb_id_lock);
+-      salt = secure_ip_id((__force __be32)ip_fallback_id ^ iph->daddr);
+-      iph->id = htons(salt & 0xFFFF);
+-      ip_fallback_id = salt;
+-      spin_unlock_bh(&ip_fb_id_lock);
++      return atomic_add_return(segs + delta, &bucket->id) - segs;
+ }
++EXPORT_SYMBOL(ip_idents_reserve);
+ 
+-void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more)
++void __ip_select_ident(struct iphdr *iph, int segs)
+ {
+-      struct rtable *rt = (struct rtable *) dst;
+-
+-      if (rt && !(rt->dst.flags & DST_NOPEER)) {
+-              if (rt->peer == NULL)
+-                      rt_bind_peer(rt, rt->rt_dst, 1);
++      static u32 ip_idents_hashrnd __read_mostly;
++      static bool hashrnd_initialized = false;
++      u32 hash, id;
+ 
+-              /* If peer is attached to destination, it is never detached,
+-                 so that we need not to grab a lock to dereference it.
+-               */
+-              if (rt->peer) {
+-                      iph->id = htons(inet_getid(rt->peer, more));
+-                      return;
+-              }
+-      } else if (!rt)
+-              printk(KERN_DEBUG "rt_bind_peer(0) @%p\n",
+-                     __builtin_return_address(0));
++      if (unlikely(!hashrnd_initialized)) {
++              hashrnd_initialized = true;
++              get_random_bytes(&ip_idents_hashrnd, sizeof(ip_idents_hashrnd));
++      }
+ 
+-      ip_select_fb_ident(iph);
++      hash = jhash_3words((__force u32)iph->daddr,
++                          (__force u32)iph->saddr,
++                          iph->protocol,
++                          ip_idents_hashrnd);
++      id = ip_idents_reserve(hash, segs);
++      iph->id = htons(id);
+ }
+ EXPORT_SYMBOL(__ip_select_ident);
+ 
+@@ -3009,7 +3016,6 @@ static int rt_fill_info(struct net *net,
+       error = rt->dst.error;
+       if (peer) {
+               inet_peer_refcheck(rt->peer);
+-              id = atomic_read(&peer->ip_id_count) & 0xffff;
+               if (peer->tcp_ts_stamp) {
+                       ts = peer->tcp_ts;
+                       tsage = get_seconds() - peer->tcp_ts_stamp;
+@@ -3441,6 +3447,12 @@ int __init ip_rt_init(void)
+ {
+       int rc = 0;
+ 
++      ip_idents = kmalloc(IP_IDENTS_SZ * sizeof(*ip_idents), GFP_KERNEL);
++      if (!ip_idents)
++              panic("IP: failed to allocate ip_idents\n");
++
++      get_random_bytes(ip_idents, IP_IDENTS_SZ * sizeof(*ip_idents));
++
+ #ifdef CONFIG_IP_ROUTE_CLASSID
+       ip_rt_acct = __alloc_percpu(256 * sizeof(struct ip_rt_acct), 
__alignof__(struct ip_rt_acct));
+       if (!ip_rt_acct)
+diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c
+index 80fa2bfd7ede..c042e529a11e 100644
+--- a/net/ipv4/tcp_vegas.c
++++ b/net/ipv4/tcp_vegas.c
+@@ -218,7 +218,8 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, 
u32 in_flight)
+                        * This is:
+                        *     (actual rate in segments) * baseRTT
+                        */
+-                      target_cwnd = tp->snd_cwnd * vegas->baseRTT / rtt;
++                      target_cwnd = (u64)tp->snd_cwnd * vegas->baseRTT;
++                      do_div(target_cwnd, rtt);
+ 
+                       /* Calculate the difference between the window we had,
+                        * and the window we would like to have. This quantity
+diff --git a/net/ipv4/tcp_veno.c b/net/ipv4/tcp_veno.c
+index ac43cd747bce..b4d1858be550 100644
+--- a/net/ipv4/tcp_veno.c
++++ b/net/ipv4/tcp_veno.c
+@@ -144,7 +144,7 @@ static void tcp_veno_cong_avoid(struct sock *sk, u32 ack, 
u32 in_flight)
+ 
+               rtt = veno->minrtt;
+ 
+-              target_cwnd = (tp->snd_cwnd * veno->basertt);
++              target_cwnd = (u64)tp->snd_cwnd * veno->basertt;
+               target_cwnd <<= V_PARAM_SHIFT;
+               do_div(target_cwnd, rtt);
+ 
+diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
+index 938553efbf8e..5531eb2a56a5 100644
+--- a/net/ipv4/xfrm4_mode_tunnel.c
++++ b/net/ipv4/xfrm4_mode_tunnel.c
+@@ -54,12 +54,12 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, 
struct sk_buff *skb)
+ 
+       top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ?
+               0 : (XFRM_MODE_SKB_CB(skb)->frag_off & htons(IP_DF));
+-      ip_select_ident(skb, dst->child, NULL);
+ 
+       top_iph->ttl = ip4_dst_hoplimit(dst->child);
+ 
+       top_iph->saddr = x->props.saddr.a4;
+       top_iph->daddr = x->id.daddr.a4;
++      ip_select_ident(skb, NULL);
+ 
+       return 0;
+ }
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index 6225b7cf12b9..2bf7916c816f 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -599,22 +599,19 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 
**nexthdr)
+ 
+ void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt)
+ {
+-      static atomic_t ipv6_fragmentation_id;
+-      int ident;
++      static u32 ip6_idents_hashrnd __read_mostly;
++      static bool hashrnd_initialized = false;
++      u32 hash, id;
+ 
+-      if (rt && !(rt->dst.flags & DST_NOPEER)) {
+-              struct inet_peer *peer;
+-
+-              if (!rt->rt6i_peer)
+-                      rt6_bind_peer(rt, 1);
+-              peer = rt->rt6i_peer;
+-              if (peer) {
+-                      fhdr->identification = htonl(inet_getid(peer, 0));
+-                      return;
+-              }
++      if (unlikely(!hashrnd_initialized)) {
++              hashrnd_initialized = true;
++              get_random_bytes(&ip6_idents_hashrnd, 
sizeof(ip6_idents_hashrnd));
+       }
+-      ident = atomic_inc_return(&ipv6_fragmentation_id);
+-      fhdr->identification = htonl(ident);
++      hash = __ipv6_addr_jhash(&rt->rt6i_dst.addr, ip6_idents_hashrnd);
++      hash = __ipv6_addr_jhash(&rt->rt6i_src.addr, hash);
++
++      id = ip_idents_reserve(hash, 1);
++      fhdr->identification = htonl(id);
+ }
+ 
+ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
+diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
+index ec78ab63dd46..559d307163b1 100644
+--- a/net/netfilter/ipvs/ip_vs_xmit.c
++++ b/net/netfilter/ipvs/ip_vs_xmit.c
+@@ -853,7 +853,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn 
*cp,
+       iph->daddr              =       cp->daddr.ip;
+       iph->saddr              =       saddr;
+       iph->ttl                =       old_iph->ttl;
+-      ip_select_ident(skb, &rt->dst, NULL);
++      ip_select_ident(skb, NULL);
+ 
+       /* Another hack: avoid icmp_send in ip_fragment */
+       skb->local_df = 1;
+diff --git a/net/sctp/associola.c b/net/sctp/associola.c
+index 25b207b3ffe4..da54d2922f51 100644
+--- a/net/sctp/associola.c
++++ b/net/sctp/associola.c
+@@ -1188,6 +1188,7 @@ void sctp_assoc_update(struct sctp_association *asoc,
+       asoc->c = new->c;
+       asoc->peer.rwnd = new->peer.rwnd;
+       asoc->peer.sack_needed = new->peer.sack_needed;
++      asoc->peer.auth_capable = new->peer.auth_capable;
+       asoc->peer.i = new->peer.i;
+       sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_INITIAL,
+                        asoc->peer.i.initial_tsn, GFP_ATOMIC);
+diff --git a/net/sctp/output.c b/net/sctp/output.c
+index cf3e22c586a6..5bd9aa93139d 100644
+--- a/net/sctp/output.c
++++ b/net/sctp/output.c
+@@ -587,7 +587,7 @@ out:
+       return err;
+ no_route:
+       kfree_skb(nskb);
+-      IP_INC_STATS_BH(&init_net, IPSTATS_MIB_OUTNOROUTES);
++      IP_INC_STATS(&init_net, IPSTATS_MIB_OUTNOROUTES);
+ 
+       /* FIXME: Returning the 'err' will effect all the associations
+        * associated with a socket, although only one of the paths of the

Reply via email to