diff --git a/debian/changelog b/debian/changelog index 0b9d012fb..28c5c53c8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,25 +1,77 @@ linux-2.6 (3.1.0~rc2-1~experimental.1) UNRELEASED; urgency=low * New upstream release candidate - - perf: do not look at ./config for configuration (Closes: #632923) - (CVE-2011-2905) - - [ Aurelien Jarno ] - * Add configuration files for s390x architecture. [ Ben Hutchings ] - * linux-libc-dev: Install include/asm under arch-specific directory; - mark package as multi-arch-coinstallable (Multi-Arch: same) - * [powerpc] Use libata-based drivers for most PATA controllers - (Closes: #636854): - - Various drivers replaced as for x86 in 2.6.32-10 - - pata_macio replaces ide_pmac * aufs: Disable until it is updated for Linux 3.1 * rt: Disable until it is updated for Linux 3.1 * nfs: Enable NFSv4.1/pNFS (Closes: #627655) -- Ben Hutchings Wed, 27 Jul 2011 23:58:10 +0200 +linux-2.6 (3.0.0-2) unstable; urgency=high + + [ Aurelien Jarno ] + * Add configuration files for s390x architecture. + + [ Ben Hutchings ] + * linux-libc-dev: Install include/asm under arch-specific directory + (thanks to Aurelien for correcting the directory); mark package as + multi-arch-coinstallable (Multi-Arch: same) + * [powerpc] Use libata-based drivers for most PATA controllers + (Closes: #636854): + - Various drivers replaced as for x86 in 2.6.32-10 + - pata_macio replaces ide_pmac + * Add stable 3.0.2, including: + - net: Cap number of elements for sendmmsg + - net: Fix security_socket_sendmsg() bypass problem + - [x86] xen: allow enable use of VGA console on dom0 + - net: Compute protocol sequence numbers and fragment IDs using MD5 + - cifs: cope with negative dentries in cifs_get_root + - ALSA: snd-usb: avoid dividing by zero on invalid input + - ipv6: make fragment identifications less predictable (CVE-2011-2699) + - sch_sfq: fix sfq_enqueue() (Closes: #631945) + - gre: fix improper error handling + - ecryptfs: Add mount option to check uid of device being mounted + = expect uid + - ecryptfs: Return error when lower file pointer is NULL + - ext{3,4}: Properly count journal credits for long symlinks + For the complete list of changes, see: + http://www.kernel.org/pub/linux/kernel/v3.0/ChangeLog-3.0.2 + * [x86] Enable RTS_PSTOR as module + + [ maximilian attems ] + * Add stable 3.0.1, including: + - gro: Only reset frag0 when skb can be pulled (CVE-2011-2723) + - staging: comedi: fix infoleak to userspace (CVE-2011-2909) + - rtc: limit frequency + - CIFS: Fix oops while mounting with prefixpath + - [SCSI] fix crash in scsi_dispatch_cmd() + - tracing: Fix bug when reading system filters on module removal + - tracing: Have "enable" file use refcounts like the "filter" file + - ext4: fix i_blocks/quota accounting when extent insertion fails + - ext4: free allocated and pre-allocated blocks when check_eofblocks_fl + fails + - ext3: Fix oops in ext3_try_to_allocate_with_rsv() + - nfsd4: remember to put RW access on stateid destruction + - nfsd4: fix file leak on open_downgrade + - NFS: Fix spurious readdir cookie loop messages + - proc: fix a race in do_io_accounting() + - ipc/sem.c: fix race with concurrent semtimedop() timeouts and IPC_RMID + - [armel,armhf,hppa] dm io: flush cpu cache with vmapped io + - dm snapshot: flush disk cache when merging + For the complete list of changes, see: + http://www.kernel.org/pub/linux/kernel/v3.0/ChangeLog-3.0.1 + + [ Jonathan Nieder ] + * perf: do not look at ./config for configuration (Closes: #632923) + (CVE-2011-2905) + + [ Uwe Kleine-König ] + * [amd64] Update rt featureset to 3.0.1-rt11 + + -- Ben Hutchings Tue, 16 Aug 2011 06:08:53 +0100 + linux-2.6 (3.0.0-1) unstable; urgency=low * New upstream release: http://kernelnewbies.org/Linux_3.0 diff --git a/debian/config/kernelarch-x86/config b/debian/config/kernelarch-x86/config index f46889d84..29a7be993 100644 --- a/debian/config/kernelarch-x86/config +++ b/debian/config/kernelarch-x86/config @@ -1230,6 +1230,12 @@ CONFIG_RTL8192U=m ## CONFIG_R8712U=m +## +## file: drivers/staging/rts_pstor/Kconfig +## +CONFIG_RTS_PSTOR=m +# RTS_PSTOR_DEBUG is not set + ## ## file: drivers/staging/tm6000/Kconfig ## diff --git a/debian/patches/bugfix/all/stable/3.0.2.patch b/debian/patches/bugfix/all/stable/3.0.2.patch new file mode 100644 index 000000000..8ec641d4f --- /dev/null +++ b/debian/patches/bugfix/all/stable/3.0.2.patch @@ -0,0 +1,6193 @@ +diff --git a/Makefile b/Makefile +index f124b18..794fa28 100644 +diff --git a/arch/cris/arch-v10/drivers/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c +index 85026537..466af40 100644 +--- a/arch/cris/arch-v10/drivers/sync_serial.c ++++ b/arch/cris/arch-v10/drivers/sync_serial.c +@@ -158,7 +158,7 @@ static int sync_serial_open(struct inode *inode, struct file *file); + static int sync_serial_release(struct inode *inode, struct file *file); + static unsigned int sync_serial_poll(struct file *filp, poll_table *wait); + +-static int sync_serial_ioctl(struct file *file, ++static long sync_serial_ioctl(struct file *file, + unsigned int cmd, unsigned long arg); + static ssize_t sync_serial_write(struct file *file, const char *buf, + size_t count, loff_t *ppos); +@@ -625,11 +625,11 @@ static int sync_serial_open(struct inode *inode, struct file *file) + *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; + DEBUG(printk(KERN_DEBUG "sser%d rec started\n", dev)); + } +- ret = 0; ++ err = 0; + + out: + mutex_unlock(&sync_serial_mutex); +- return ret; ++ return err; + } + + static int sync_serial_release(struct inode *inode, struct file *file) +diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c +index 907cfb5..ba0e596 100644 +--- a/arch/cris/arch-v10/kernel/irq.c ++++ b/arch/cris/arch-v10/kernel/irq.c +@@ -20,6 +20,9 @@ + #define crisv10_mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr)); + #define crisv10_unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr)); + ++extern void kgdb_init(void); ++extern void breakpoint(void); ++ + /* don't use set_int_vector, it bypasses the linux interrupt handlers. it is + * global just so that the kernel gdb can use it. + */ +diff --git a/arch/cris/include/asm/thread_info.h b/arch/cris/include/asm/thread_info.h +index 29b74a1..332f19c 100644 +--- a/arch/cris/include/asm/thread_info.h ++++ b/arch/cris/include/asm/thread_info.h +@@ -11,8 +11,6 @@ + + #ifdef __KERNEL__ + +-#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR +- + #ifndef __ASSEMBLY__ + #include + #include +@@ -67,8 +65,10 @@ struct thread_info { + + #define init_thread_info (init_thread_union.thread_info) + ++#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + /* thread information allocation */ +-#define alloc_thread_info(tsk, node) ((struct thread_info *) __get_free_pages(GFP_KERNEL,1)) ++#define alloc_thread_info_node(tsk, node) \ ++ ((struct thread_info *) __get_free_pages(GFP_KERNEL, 1)) + #define free_thread_info(ti) free_pages((unsigned long) (ti), 1) + + #endif /* !__ASSEMBLY__ */ +diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h +index f819559..26fd114 100644 +--- a/arch/parisc/include/asm/atomic.h ++++ b/arch/parisc/include/asm/atomic.h +@@ -259,10 +259,10 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) + + #define ATOMIC64_INIT(i) ((atomic64_t) { (i) }) + +-static __inline__ int ++static __inline__ s64 + __atomic64_add_return(s64 i, atomic64_t *v) + { +- int ret; ++ s64 ret; + unsigned long flags; + _atomic_spin_lock_irqsave(v, flags); + +diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h +index 67a33cc..2388bdb 100644 +--- a/arch/parisc/include/asm/futex.h ++++ b/arch/parisc/include/asm/futex.h +@@ -5,11 +5,14 @@ + + #include + #include ++#include + #include + + static inline int + futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) + { ++ unsigned long int flags; ++ u32 val; + int op = (encoded_op >> 28) & 7; + int cmp = (encoded_op >> 24) & 15; + int oparg = (encoded_op << 8) >> 20; +@@ -18,21 +21,58 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) + if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) + oparg = 1 << oparg; + +- if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) ++ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr))) + return -EFAULT; + + pagefault_disable(); + ++ _atomic_spin_lock_irqsave(uaddr, flags); ++ + switch (op) { + case FUTEX_OP_SET: ++ /* *(int *)UADDR2 = OPARG; */ ++ ret = get_user(oldval, uaddr); ++ if (!ret) ++ ret = put_user(oparg, uaddr); ++ break; + case FUTEX_OP_ADD: ++ /* *(int *)UADDR2 += OPARG; */ ++ ret = get_user(oldval, uaddr); ++ if (!ret) { ++ val = oldval + oparg; ++ ret = put_user(val, uaddr); ++ } ++ break; + case FUTEX_OP_OR: ++ /* *(int *)UADDR2 |= OPARG; */ ++ ret = get_user(oldval, uaddr); ++ if (!ret) { ++ val = oldval | oparg; ++ ret = put_user(val, uaddr); ++ } ++ break; + case FUTEX_OP_ANDN: ++ /* *(int *)UADDR2 &= ~OPARG; */ ++ ret = get_user(oldval, uaddr); ++ if (!ret) { ++ val = oldval & ~oparg; ++ ret = put_user(val, uaddr); ++ } ++ break; + case FUTEX_OP_XOR: ++ /* *(int *)UADDR2 ^= OPARG; */ ++ ret = get_user(oldval, uaddr); ++ if (!ret) { ++ val = oldval ^ oparg; ++ ret = put_user(val, uaddr); ++ } ++ break; + default: + ret = -ENOSYS; + } + ++ _atomic_spin_unlock_irqrestore(uaddr, flags); ++ + pagefault_enable(); + + if (!ret) { +@@ -54,7 +94,9 @@ static inline int + futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + u32 oldval, u32 newval) + { ++ int ret; + u32 val; ++ unsigned long flags; + + /* futex.c wants to do a cmpxchg_inatomic on kernel NULL, which is + * our gateway page, and causes no end of trouble... +@@ -65,12 +107,24 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) + return -EFAULT; + +- if (get_user(val, uaddr)) +- return -EFAULT; +- if (val == oldval && put_user(newval, uaddr)) +- return -EFAULT; ++ /* HPPA has no cmpxchg in hardware and therefore the ++ * best we can do here is use an array of locks. The ++ * lock selected is based on a hash of the userspace ++ * address. This should scale to a couple of CPUs. ++ */ ++ ++ _atomic_spin_lock_irqsave(uaddr, flags); ++ ++ ret = get_user(val, uaddr); ++ ++ if (!ret && val == oldval) ++ ret = put_user(newval, uaddr); ++ + *uval = val; +- return 0; ++ ++ _atomic_spin_unlock_irqrestore(uaddr, flags); ++ ++ return ret; + } + + #endif /*__KERNEL__*/ +diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h +index 3392de3..d61de64 100644 +--- a/arch/parisc/include/asm/unistd.h ++++ b/arch/parisc/include/asm/unistd.h +@@ -821,8 +821,9 @@ + #define __NR_open_by_handle_at (__NR_Linux + 326) + #define __NR_syncfs (__NR_Linux + 327) + #define __NR_setns (__NR_Linux + 328) ++#define __NR_sendmmsg (__NR_Linux + 329) + +-#define __NR_Linux_syscalls (__NR_setns + 1) ++#define __NR_Linux_syscalls (__NR_sendmmsg + 1) + + + #define __IGNORE_select /* newselect */ +diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S +index 34a4f5a..e66366f 100644 +--- a/arch/parisc/kernel/syscall_table.S ++++ b/arch/parisc/kernel/syscall_table.S +@@ -427,6 +427,7 @@ + ENTRY_COMP(open_by_handle_at) + ENTRY_SAME(syncfs) + ENTRY_SAME(setns) ++ ENTRY_COMP(sendmmsg) + + /* Nothing yet */ + +diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c +index c016033..3b22142 100644 +--- a/arch/powerpc/kernel/prom_init.c ++++ b/arch/powerpc/kernel/prom_init.c +@@ -1020,7 +1020,7 @@ static unsigned long __init alloc_up(unsigned long size, unsigned long align) + } + if (addr == 0) + return 0; +- RELOC(alloc_bottom) = addr; ++ RELOC(alloc_bottom) = addr + size; + + prom_debug(" -> %x\n", addr); + prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom)); +@@ -1834,7 +1834,7 @@ static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end, + chunk = alloc_up(room, 0); + if (chunk == 0) + prom_panic("No memory for flatten_device_tree (claim failed)"); +- *mem_end = RELOC(alloc_top); ++ *mem_end = chunk + room; + } + + ret = (void *)*mem_start; +@@ -2053,7 +2053,7 @@ static void __init flatten_device_tree(void) + mem_start = (unsigned long)alloc_up(room, PAGE_SIZE); + if (mem_start == 0) + prom_panic("Can't allocate initial device-tree chunk\n"); +- mem_end = RELOC(alloc_top); ++ mem_end = mem_start + room; + + /* Get root of tree */ + root = call_prom("peer", 1, 1, (phandle)0); +diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c +index e919007..0e86563 100644 +--- a/arch/powerpc/platforms/pseries/dtl.c ++++ b/arch/powerpc/platforms/pseries/dtl.c +@@ -181,7 +181,7 @@ static void dtl_stop(struct dtl *dtl) + + lppaca_of(dtl->cpu).dtl_enable_mask = 0x0; + +- unregister_dtl(hwcpu, __pa(dtl->buf)); ++ unregister_dtl(hwcpu); + } + + static u64 dtl_current_index(struct dtl *dtl) +diff --git a/arch/powerpc/platforms/pseries/kexec.c b/arch/powerpc/platforms/pseries/kexec.c +index 54cf3a4..1118cb7 100644 +--- a/arch/powerpc/platforms/pseries/kexec.c ++++ b/arch/powerpc/platforms/pseries/kexec.c +@@ -26,6 +26,17 @@ static void pseries_kexec_cpu_down(int crash_shutdown, int secondary) + /* Don't risk a hypervisor call if we're crashing */ + if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) { + unsigned long addr; ++ int ret; ++ ++ if (get_lppaca()->dtl_enable_mask) { ++ ret = unregister_dtl(hard_smp_processor_id()); ++ if (ret) { ++ pr_err("WARNING: DTL deregistration for cpu " ++ "%d (hw %d) failed with %d\n", ++ smp_processor_id(), ++ hard_smp_processor_id(), ret); ++ } ++ } + + addr = __pa(get_slb_shadow()); + if (unregister_slb_shadow(hard_smp_processor_id(), addr)) +diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c +index 39e6e0a..ed96b37 100644 +--- a/arch/powerpc/platforms/pseries/lpar.c ++++ b/arch/powerpc/platforms/pseries/lpar.c +@@ -395,7 +395,7 @@ static void pSeries_lpar_hptab_clear(void) + unsigned long ptel; + } ptes[4]; + long lpar_rc; +- int i, j; ++ unsigned long i, j; + + /* Read in batches of 4, + * invalidate only valid entries not in the VRMA +diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h +index 4bf2120..a6921ae 100644 +--- a/arch/powerpc/platforms/pseries/plpar_wrappers.h ++++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h +@@ -73,9 +73,9 @@ static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa) + return vpa_call(0x3, cpu, vpa); + } + +-static inline long unregister_dtl(unsigned long cpu, unsigned long vpa) ++static inline long unregister_dtl(unsigned long cpu) + { +- return vpa_call(0x6, cpu, vpa); ++ return vpa_call(0x6, cpu, 0); + } + + static inline long register_dtl(unsigned long cpu, unsigned long vpa) +diff --git a/arch/sparc/include/asm/bitops_64.h b/arch/sparc/include/asm/bitops_64.h +index 38e9aa1..3fc595a 100644 +--- a/arch/sparc/include/asm/bitops_64.h ++++ b/arch/sparc/include/asm/bitops_64.h +@@ -26,61 +26,28 @@ extern void change_bit(unsigned long nr, volatile unsigned long *addr); + #define smp_mb__before_clear_bit() barrier() + #define smp_mb__after_clear_bit() barrier() + +-#include +-#include + #include + #include + #include + + #ifdef __KERNEL__ + ++extern int ffs(int x); ++extern unsigned long __ffs(unsigned long); ++ ++#include + #include +-#include + + /* + * hweightN: returns the hamming weight (i.e. the number + * of bits set) of a N-bit word + */ + +-#ifdef ULTRA_HAS_POPULATION_COUNT +- +-static inline unsigned int __arch_hweight64(unsigned long w) +-{ +- unsigned int res; +- +- __asm__ ("popc %1,%0" : "=r" (res) : "r" (w)); +- return res; +-} +- +-static inline unsigned int __arch_hweight32(unsigned int w) +-{ +- unsigned int res; +- +- __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffffffff)); +- return res; +-} ++extern unsigned long __arch_hweight64(__u64 w); ++extern unsigned int __arch_hweight32(unsigned int w); ++extern unsigned int __arch_hweight16(unsigned int w); ++extern unsigned int __arch_hweight8(unsigned int w); + +-static inline unsigned int __arch_hweight16(unsigned int w) +-{ +- unsigned int res; +- +- __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffff)); +- return res; +-} +- +-static inline unsigned int __arch_hweight8(unsigned int w) +-{ +- unsigned int res; +- +- __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xff)); +- return res; +-} +- +-#else +- +-#include +- +-#endif + #include + #include + #endif /* __KERNEL__ */ +diff --git a/arch/sparc/include/asm/elf_64.h b/arch/sparc/include/asm/elf_64.h +index e678803..7df8b7f 100644 +--- a/arch/sparc/include/asm/elf_64.h ++++ b/arch/sparc/include/asm/elf_64.h +@@ -59,15 +59,33 @@ + #define R_SPARC_6 45 + + /* Bits present in AT_HWCAP, primarily for Sparc32. */ +- +-#define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */ +-#define HWCAP_SPARC_STBAR 2 +-#define HWCAP_SPARC_SWAP 4 +-#define HWCAP_SPARC_MULDIV 8 +-#define HWCAP_SPARC_V9 16 +-#define HWCAP_SPARC_ULTRA3 32 +-#define HWCAP_SPARC_BLKINIT 64 +-#define HWCAP_SPARC_N2 128 ++#define HWCAP_SPARC_FLUSH 0x00000001 ++#define HWCAP_SPARC_STBAR 0x00000002 ++#define HWCAP_SPARC_SWAP 0x00000004 ++#define HWCAP_SPARC_MULDIV 0x00000008 ++#define HWCAP_SPARC_V9 0x00000010 ++#define HWCAP_SPARC_ULTRA3 0x00000020 ++#define HWCAP_SPARC_BLKINIT 0x00000040 ++#define HWCAP_SPARC_N2 0x00000080 ++ ++/* Solaris compatible AT_HWCAP bits. */ ++#define AV_SPARC_MUL32 0x00000100 /* 32x32 multiply is efficient */ ++#define AV_SPARC_DIV32 0x00000200 /* 32x32 divide is efficient */ ++#define AV_SPARC_FSMULD 0x00000400 /* 'fsmuld' is efficient */ ++#define AV_SPARC_V8PLUS 0x00000800 /* v9 insn available to 32bit */ ++#define AV_SPARC_POPC 0x00001000 /* 'popc' is efficient */ ++#define AV_SPARC_VIS 0x00002000 /* VIS insns available */ ++#define AV_SPARC_VIS2 0x00004000 /* VIS2 insns available */ ++#define AV_SPARC_ASI_BLK_INIT 0x00008000 /* block init ASIs available */ ++#define AV_SPARC_FMAF 0x00010000 /* fused multiply-add */ ++#define AV_SPARC_VIS3 0x00020000 /* VIS3 insns available */ ++#define AV_SPARC_HPC 0x00040000 /* HPC insns available */ ++#define AV_SPARC_RANDOM 0x00080000 /* 'random' insn available */ ++#define AV_SPARC_TRANS 0x00100000 /* transaction insns available */ ++#define AV_SPARC_FJFMAU 0x00200000 /* unfused multiply-add */ ++#define AV_SPARC_IMA 0x00400000 /* integer multiply-add */ ++#define AV_SPARC_ASI_CACHE_SPARING \ ++ 0x00800000 /* cache sparing ASIs available */ + + #define CORE_DUMP_USE_REGSET + +@@ -162,31 +180,8 @@ typedef struct { + #define ELF_ET_DYN_BASE 0x0000010000000000UL + #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL + +- +-/* This yields a mask that user programs can use to figure out what +- instruction set this cpu supports. */ +- +-/* On Ultra, we support all of the v8 capabilities. */ +-static inline unsigned int sparc64_elf_hwcap(void) +-{ +- unsigned int cap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | +- HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV | +- HWCAP_SPARC_V9); +- +- if (tlb_type == cheetah || tlb_type == cheetah_plus) +- cap |= HWCAP_SPARC_ULTRA3; +- else if (tlb_type == hypervisor) { +- if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || +- sun4v_chip_type == SUN4V_CHIP_NIAGARA2) +- cap |= HWCAP_SPARC_BLKINIT; +- if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2) +- cap |= HWCAP_SPARC_N2; +- } +- +- return cap; +-} +- +-#define ELF_HWCAP sparc64_elf_hwcap(); ++extern unsigned long sparc64_elf_hwcap; ++#define ELF_HWCAP sparc64_elf_hwcap + + /* This yields a string that ld.so will use to load implementation + specific libraries for optimization. This is more specific in +diff --git a/arch/sparc/include/asm/hypervisor.h b/arch/sparc/include/asm/hypervisor.h +index 7568640..015a761 100644 +--- a/arch/sparc/include/asm/hypervisor.h ++++ b/arch/sparc/include/asm/hypervisor.h +@@ -2927,6 +2927,13 @@ extern unsigned long sun4v_ncs_request(unsigned long request, + #define HV_FAST_FIRE_GET_PERFREG 0x120 + #define HV_FAST_FIRE_SET_PERFREG 0x121 + ++#define HV_FAST_REBOOT_DATA_SET 0x172 ++ ++#ifndef __ASSEMBLY__ ++extern unsigned long sun4v_reboot_data_set(unsigned long ra, ++ unsigned long len); ++#endif ++ + /* Function numbers for HV_CORE_TRAP. */ + #define HV_CORE_SET_VER 0x00 + #define HV_CORE_PUTCHAR 0x01 +@@ -2940,16 +2947,23 @@ extern unsigned long sun4v_ncs_request(unsigned long request, + #define HV_GRP_CORE 0x0001 + #define HV_GRP_INTR 0x0002 + #define HV_GRP_SOFT_STATE 0x0003 ++#define HV_GRP_TM 0x0080 + #define HV_GRP_PCI 0x0100 + #define HV_GRP_LDOM 0x0101 + #define HV_GRP_SVC_CHAN 0x0102 + #define HV_GRP_NCS 0x0103 + #define HV_GRP_RNG 0x0104 ++#define HV_GRP_PBOOT 0x0105 ++#define HV_GRP_TPM 0x0107 ++#define HV_GRP_SDIO 0x0108 ++#define HV_GRP_SDIO_ERR 0x0109 ++#define HV_GRP_REBOOT_DATA 0x0110 + #define HV_GRP_NIAG_PERF 0x0200 + #define HV_GRP_FIRE_PERF 0x0201 + #define HV_GRP_N2_CPU 0x0202 + #define HV_GRP_NIU 0x0204 + #define HV_GRP_VF_CPU 0x0205 ++#define HV_GRP_KT_CPU 0x0209 + #define HV_GRP_DIAG 0x0300 + + #ifndef __ASSEMBLY__ +diff --git a/arch/sparc/include/asm/spitfire.h b/arch/sparc/include/asm/spitfire.h +index f0d0c40..55a17c6 100644 +--- a/arch/sparc/include/asm/spitfire.h ++++ b/arch/sparc/include/asm/spitfire.h +@@ -42,6 +42,7 @@ + #define SUN4V_CHIP_INVALID 0x00 + #define SUN4V_CHIP_NIAGARA1 0x01 + #define SUN4V_CHIP_NIAGARA2 0x02 ++#define SUN4V_CHIP_NIAGARA3 0x03 + #define SUN4V_CHIP_UNKNOWN 0xff + + #ifndef __ASSEMBLY__ +diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h +index 83c571d..1a8afd1 100644 +--- a/arch/sparc/include/asm/tsb.h ++++ b/arch/sparc/include/asm/tsb.h +@@ -133,29 +133,6 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; + sub TSB, 0x8, TSB; \ + TSB_STORE(TSB, TAG); + +-#define KTSB_LOAD_QUAD(TSB, REG) \ +- ldda [TSB] ASI_NUCLEUS_QUAD_LDD, REG; +- +-#define KTSB_STORE(ADDR, VAL) \ +- stxa VAL, [ADDR] ASI_N; +- +-#define KTSB_LOCK_TAG(TSB, REG1, REG2) \ +-99: lduwa [TSB] ASI_N, REG1; \ +- sethi %hi(TSB_TAG_LOCK_HIGH), REG2;\ +- andcc REG1, REG2, %g0; \ +- bne,pn %icc, 99b; \ +- nop; \ +- casa [TSB] ASI_N, REG1, REG2;\ +- cmp REG1, REG2; \ +- bne,pn %icc, 99b; \ +- nop; \ +- +-#define KTSB_WRITE(TSB, TTE, TAG) \ +- add TSB, 0x8, TSB; \ +- stxa TTE, [TSB] ASI_N; \ +- sub TSB, 0x8, TSB; \ +- stxa TAG, [TSB] ASI_N; +- + /* Do a kernel page table walk. Leaves physical PTE pointer in + * REG1. Jumps to FAIL_LABEL on early page table walk termination. + * VADDR will not be clobbered, but REG2 will. +@@ -239,6 +216,8 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; + (KERNEL_TSB_SIZE_BYTES / 16) + #define KERNEL_TSB4M_NENTRIES 4096 + ++#define KTSB_PHYS_SHIFT 15 ++ + /* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL + * on TSB hit. REG1, REG2, REG3, and REG4 are used as temporaries + * and the found TTE will be left in REG1. REG3 and REG4 must +@@ -247,13 +226,22 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; + * VADDR and TAG will be preserved and not clobbered by this macro. + */ + #define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ +- sethi %hi(swapper_tsb), REG1; \ ++661: sethi %hi(swapper_tsb), REG1; \ + or REG1, %lo(swapper_tsb), REG1; \ ++ .section .swapper_tsb_phys_patch, "ax"; \ ++ .word 661b; \ ++ .previous; \ ++661: nop; \ ++ .section .tsb_ldquad_phys_patch, "ax"; \ ++ .word 661b; \ ++ sllx REG1, KTSB_PHYS_SHIFT, REG1; \ ++ sllx REG1, KTSB_PHYS_SHIFT, REG1; \ ++ .previous; \ + srlx VADDR, PAGE_SHIFT, REG2; \ + and REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \ + sllx REG2, 4, REG2; \ + add REG1, REG2, REG2; \ +- KTSB_LOAD_QUAD(REG2, REG3); \ ++ TSB_LOAD_QUAD(REG2, REG3); \ + cmp REG3, TAG; \ + be,a,pt %xcc, OK_LABEL; \ + mov REG4, REG1; +@@ -263,12 +251,21 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; + * we can make use of that for the index computation. + */ + #define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ +- sethi %hi(swapper_4m_tsb), REG1; \ ++661: sethi %hi(swapper_4m_tsb), REG1; \ + or REG1, %lo(swapper_4m_tsb), REG1; \ ++ .section .swapper_4m_tsb_phys_patch, "ax"; \ ++ .word 661b; \ ++ .previous; \ ++661: nop; \ ++ .section .tsb_ldquad_phys_patch, "ax"; \ ++ .word 661b; \ ++ sllx REG1, KTSB_PHYS_SHIFT, REG1; \ ++ sllx REG1, KTSB_PHYS_SHIFT, REG1; \ ++ .previous; \ + and TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \ + sllx REG2, 4, REG2; \ + add REG1, REG2, REG2; \ +- KTSB_LOAD_QUAD(REG2, REG3); \ ++ TSB_LOAD_QUAD(REG2, REG3); \ + cmp REG3, TAG; \ + be,a,pt %xcc, OK_LABEL; \ + mov REG4, REG1; +diff --git a/arch/sparc/include/asm/xor_64.h b/arch/sparc/include/asm/xor_64.h +index bee4bf4..9ed6ff6 100644 +--- a/arch/sparc/include/asm/xor_64.h ++++ b/arch/sparc/include/asm/xor_64.h +@@ -65,6 +65,7 @@ static struct xor_block_template xor_block_niagara = { + #define XOR_SELECT_TEMPLATE(FASTEST) \ + ((tlb_type == hypervisor && \ + (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || \ +- sun4v_chip_type == SUN4V_CHIP_NIAGARA2)) ? \ ++ sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || \ ++ sun4v_chip_type == SUN4V_CHIP_NIAGARA3)) ? \ + &xor_block_niagara : \ + &xor_block_VIS) +diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c +index 138dbbc..9810fd8 100644 +--- a/arch/sparc/kernel/cpu.c ++++ b/arch/sparc/kernel/cpu.c +@@ -396,6 +396,7 @@ static int show_cpuinfo(struct seq_file *m, void *__unused) + , cpu_data(0).clock_tick + #endif + ); ++ cpucap_info(m); + #ifdef CONFIG_SMP + smp_bogo(m); + #endif +@@ -474,11 +475,18 @@ static void __init sun4v_cpu_probe(void) + sparc_pmu_type = "niagara2"; + break; + ++ case SUN4V_CHIP_NIAGARA3: ++ sparc_cpu_type = "UltraSparc T3 (Niagara3)"; ++ sparc_fpu_type = "UltraSparc T3 integrated FPU"; ++ sparc_pmu_type = "niagara3"; ++ break; ++ + default: + printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n", + prom_cpu_compatible); + sparc_cpu_type = "Unknown SUN4V CPU"; + sparc_fpu_type = "Unknown SUN4V FPU"; ++ sparc_pmu_type = "Unknown SUN4V PMU"; + break; + } + } +diff --git a/arch/sparc/kernel/cpumap.c b/arch/sparc/kernel/cpumap.c +index d91fd78..4197e8d 100644 +--- a/arch/sparc/kernel/cpumap.c ++++ b/arch/sparc/kernel/cpumap.c +@@ -324,6 +324,7 @@ static int iterate_cpu(struct cpuinfo_tree *t, unsigned int root_index) + switch (sun4v_chip_type) { + case SUN4V_CHIP_NIAGARA1: + case SUN4V_CHIP_NIAGARA2: ++ case SUN4V_CHIP_NIAGARA3: + rover_inc_table = niagara_iterate_method; + break; + default: +diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c +index dd1342c..7429b47 100644 +--- a/arch/sparc/kernel/ds.c ++++ b/arch/sparc/kernel/ds.c +@@ -15,12 +15,15 @@ + #include + #include + ++#include + #include + #include + #include + #include + #include + ++#include "kernel.h" ++ + #define DRV_MODULE_NAME "ds" + #define PFX DRV_MODULE_NAME ": " + #define DRV_MODULE_VERSION "1.0" +@@ -828,18 +831,32 @@ void ldom_set_var(const char *var, const char *value) + } + } + ++static char full_boot_str[256] __attribute__((aligned(32))); ++static int reboot_data_supported; ++ + void ldom_reboot(const char *boot_command) + { + /* Don't bother with any of this if the boot_command + * is empty. + */ + if (boot_command && strlen(boot_command)) { +- char full_boot_str[256]; ++ unsigned long len; + + strcpy(full_boot_str, "boot "); + strcpy(full_boot_str + strlen("boot "), boot_command); ++ len = strlen(full_boot_str); + +- ldom_set_var("reboot-command", full_boot_str); ++ if (reboot_data_supported) { ++ unsigned long ra = kimage_addr_to_ra(full_boot_str); ++ unsigned long hv_ret; ++ ++ hv_ret = sun4v_reboot_data_set(ra, len); ++ if (hv_ret != HV_EOK) ++ pr_err("SUN4V: Unable to set reboot data " ++ "hv_ret=%lu\n", hv_ret); ++ } else { ++ ldom_set_var("reboot-command", full_boot_str); ++ } + } + sun4v_mach_sir(); + } +@@ -1237,6 +1254,16 @@ static struct vio_driver ds_driver = { + + static int __init ds_init(void) + { ++ unsigned long hv_ret, major, minor; ++ ++ if (tlb_type == hypervisor) { ++ hv_ret = sun4v_get_version(HV_GRP_REBOOT_DATA, &major, &minor); ++ if (hv_ret == HV_EOK) { ++ pr_info("SUN4V: Reboot data supported (maj=%lu,min=%lu).\n", ++ major, minor); ++ reboot_data_supported = 1; ++ } ++ } + kthread_run(ds_thread, NULL, "kldomd"); + + return vio_register_driver(&ds_driver); +diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h +index d1f1361..e27f8ea 100644 +--- a/arch/sparc/kernel/entry.h ++++ b/arch/sparc/kernel/entry.h +@@ -42,6 +42,20 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr, + extern void fpload(unsigned long *fpregs, unsigned long *fsr); + + #else /* CONFIG_SPARC32 */ ++struct popc_3insn_patch_entry { ++ unsigned int addr; ++ unsigned int insns[3]; ++}; ++extern struct popc_3insn_patch_entry __popc_3insn_patch, ++ __popc_3insn_patch_end; ++ ++struct popc_6insn_patch_entry { ++ unsigned int addr; ++ unsigned int insns[6]; ++}; ++extern struct popc_6insn_patch_entry __popc_6insn_patch, ++ __popc_6insn_patch_end; ++ + extern void __init per_cpu_patch(void); + extern void __init sun4v_patch(void); + extern void __init boot_cpu_id_too_large(int cpu); +diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S +index aa594c7..0cbab31 100644 +--- a/arch/sparc/kernel/head_64.S ++++ b/arch/sparc/kernel/head_64.S +@@ -132,6 +132,8 @@ prom_sun4v_name: + .asciz "sun4v" + prom_niagara_prefix: + .asciz "SUNW,UltraSPARC-T" ++prom_sparc_prefix: ++ .asciz "SPARC-T" + .align 4 + prom_root_compatible: + .skip 64 +@@ -382,6 +384,22 @@ sun4v_chip_type: + 90: ldub [%g7], %g2 + ldub [%g1], %g4 + cmp %g2, %g4 ++ bne,pn %icc, 89f ++ add %g7, 1, %g7 ++ subcc %g3, 1, %g3 ++ bne,pt %xcc, 90b ++ add %g1, 1, %g1 ++ ba,pt %xcc, 91f ++ nop ++ ++89: sethi %hi(prom_cpu_compatible), %g1 ++ or %g1, %lo(prom_cpu_compatible), %g1 ++ sethi %hi(prom_sparc_prefix), %g7 ++ or %g7, %lo(prom_sparc_prefix), %g7 ++ mov 7, %g3 ++90: ldub [%g7], %g2 ++ ldub [%g1], %g4 ++ cmp %g2, %g4 + bne,pn %icc, 4f + add %g7, 1, %g7 + subcc %g3, 1, %g3 +@@ -390,6 +408,15 @@ sun4v_chip_type: + + sethi %hi(prom_cpu_compatible), %g1 + or %g1, %lo(prom_cpu_compatible), %g1 ++ ldub [%g1 + 7], %g2 ++ cmp %g2, '3' ++ be,pt %xcc, 5f ++ mov SUN4V_CHIP_NIAGARA3, %g4 ++ ba,pt %xcc, 4f ++ nop ++ ++91: sethi %hi(prom_cpu_compatible), %g1 ++ or %g1, %lo(prom_cpu_compatible), %g1 + ldub [%g1 + 17], %g2 + cmp %g2, '1' + be,pt %xcc, 5f +@@ -397,6 +424,7 @@ sun4v_chip_type: + cmp %g2, '2' + be,pt %xcc, 5f + mov SUN4V_CHIP_NIAGARA2, %g4 ++ + 4: + mov SUN4V_CHIP_UNKNOWN, %g4 + 5: sethi %hi(sun4v_chip_type), %g2 +@@ -514,6 +542,9 @@ niagara_tlb_fixup: + cmp %g1, SUN4V_CHIP_NIAGARA2 + be,pt %xcc, niagara2_patch + nop ++ cmp %g1, SUN4V_CHIP_NIAGARA3 ++ be,pt %xcc, niagara2_patch ++ nop + + call generic_patch_copyops + nop +@@ -528,7 +559,7 @@ niagara2_patch: + nop + call niagara_patch_bzero + nop +- call niagara2_patch_pageops ++ call niagara_patch_pageops + nop + + ba,a,pt %xcc, 80f +diff --git a/arch/sparc/kernel/hvapi.c b/arch/sparc/kernel/hvapi.c +index 7c60afb..c2d055d 100644 +--- a/arch/sparc/kernel/hvapi.c ++++ b/arch/sparc/kernel/hvapi.c +@@ -28,16 +28,23 @@ static struct api_info api_table[] = { + { .group = HV_GRP_CORE, .flags = FLAG_PRE_API }, + { .group = HV_GRP_INTR, }, + { .group = HV_GRP_SOFT_STATE, }, ++ { .group = HV_GRP_TM, }, + { .group = HV_GRP_PCI, .flags = FLAG_PRE_API }, + { .group = HV_GRP_LDOM, }, + { .group = HV_GRP_SVC_CHAN, .flags = FLAG_PRE_API }, + { .group = HV_GRP_NCS, .flags = FLAG_PRE_API }, + { .group = HV_GRP_RNG, }, ++ { .group = HV_GRP_PBOOT, }, ++ { .group = HV_GRP_TPM, }, ++ { .group = HV_GRP_SDIO, }, ++ { .group = HV_GRP_SDIO_ERR, }, ++ { .group = HV_GRP_REBOOT_DATA, }, + { .group = HV_GRP_NIAG_PERF, .flags = FLAG_PRE_API }, + { .group = HV_GRP_FIRE_PERF, }, + { .group = HV_GRP_N2_CPU, }, + { .group = HV_GRP_NIU, }, + { .group = HV_GRP_VF_CPU, }, ++ { .group = HV_GRP_KT_CPU, }, + { .group = HV_GRP_DIAG, .flags = FLAG_PRE_API }, + }; + +diff --git a/arch/sparc/kernel/hvcalls.S b/arch/sparc/kernel/hvcalls.S +index 8a5f35f..58d60de 100644 +--- a/arch/sparc/kernel/hvcalls.S ++++ b/arch/sparc/kernel/hvcalls.S +@@ -798,3 +798,10 @@ ENTRY(sun4v_niagara2_setperf) + retl + nop + ENDPROC(sun4v_niagara2_setperf) ++ ++ENTRY(sun4v_reboot_data_set) ++ mov HV_FAST_REBOOT_DATA_SET, %o5 ++ ta HV_FAST_TRAP ++ retl ++ nop ++ENDPROC(sun4v_reboot_data_set) +diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h +index 6f6544c..fd6c36b 100644 +--- a/arch/sparc/kernel/kernel.h ++++ b/arch/sparc/kernel/kernel.h +@@ -4,12 +4,27 @@ + #include + + #include ++#include ++#include + + /* cpu.c */ + extern const char *sparc_pmu_type; + extern unsigned int fsr_storage; + extern int ncpus_probed; + ++#ifdef CONFIG_SPARC64 ++/* setup_64.c */ ++struct seq_file; ++extern void cpucap_info(struct seq_file *); ++ ++static inline unsigned long kimage_addr_to_ra(const char *p) ++{ ++ unsigned long val = (unsigned long) p; ++ ++ return kern_base + (val - KERNBASE); ++} ++#endif ++ + #ifdef CONFIG_SPARC32 + /* cpu.c */ + extern void cpu_probe(void); +diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S +index 1d36147..79f3103 100644 +--- a/arch/sparc/kernel/ktlb.S ++++ b/arch/sparc/kernel/ktlb.S +@@ -47,16 +47,16 @@ kvmap_itlb_tsb_miss: + kvmap_itlb_vmalloc_addr: + KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_itlb_longpath) + +- KTSB_LOCK_TAG(%g1, %g2, %g7) ++ TSB_LOCK_TAG(%g1, %g2, %g7) + + /* Load and check PTE. */ + ldxa [%g5] ASI_PHYS_USE_EC, %g5 + mov 1, %g7 + sllx %g7, TSB_TAG_INVALID_BIT, %g7 + brgez,a,pn %g5, kvmap_itlb_longpath +- KTSB_STORE(%g1, %g7) ++ TSB_STORE(%g1, %g7) + +- KTSB_WRITE(%g1, %g5, %g6) ++ TSB_WRITE(%g1, %g5, %g6) + + /* fallthrough to TLB load */ + +@@ -102,9 +102,9 @@ kvmap_itlb_longpath: + kvmap_itlb_obp: + OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_itlb_longpath) + +- KTSB_LOCK_TAG(%g1, %g2, %g7) ++ TSB_LOCK_TAG(%g1, %g2, %g7) + +- KTSB_WRITE(%g1, %g5, %g6) ++ TSB_WRITE(%g1, %g5, %g6) + + ba,pt %xcc, kvmap_itlb_load + nop +@@ -112,17 +112,17 @@ kvmap_itlb_obp: + kvmap_dtlb_obp: + OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_dtlb_longpath) + +- KTSB_LOCK_TAG(%g1, %g2, %g7) ++ TSB_LOCK_TAG(%g1, %g2, %g7) + +- KTSB_WRITE(%g1, %g5, %g6) ++ TSB_WRITE(%g1, %g5, %g6) + + ba,pt %xcc, kvmap_dtlb_load + nop + + .align 32 + kvmap_dtlb_tsb4m_load: +- KTSB_LOCK_TAG(%g1, %g2, %g7) +- KTSB_WRITE(%g1, %g5, %g6) ++ TSB_LOCK_TAG(%g1, %g2, %g7) ++ TSB_WRITE(%g1, %g5, %g6) + ba,pt %xcc, kvmap_dtlb_load + nop + +@@ -222,16 +222,16 @@ kvmap_linear_patch: + kvmap_dtlb_vmalloc_addr: + KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_dtlb_longpath) + +- KTSB_LOCK_TAG(%g1, %g2, %g7) ++ TSB_LOCK_TAG(%g1, %g2, %g7) + + /* Load and check PTE. */ + ldxa [%g5] ASI_PHYS_USE_EC, %g5 + mov 1, %g7 + sllx %g7, TSB_TAG_INVALID_BIT, %g7 + brgez,a,pn %g5, kvmap_dtlb_longpath +- KTSB_STORE(%g1, %g7) ++ TSB_STORE(%g1, %g7) + +- KTSB_WRITE(%g1, %g5, %g6) ++ TSB_WRITE(%g1, %g5, %g6) + + /* fallthrough to TLB load */ + +diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c +index 42f28c7..acaebb6 100644 +--- a/arch/sparc/kernel/mdesc.c ++++ b/arch/sparc/kernel/mdesc.c +@@ -508,6 +508,8 @@ const char *mdesc_node_name(struct mdesc_handle *hp, u64 node) + } + EXPORT_SYMBOL(mdesc_node_name); + ++static u64 max_cpus = 64; ++ + static void __init report_platform_properties(void) + { + struct mdesc_handle *hp = mdesc_grab(); +@@ -543,8 +545,10 @@ static void __init report_platform_properties(void) + if (v) + printk("PLATFORM: watchdog-max-timeout [%llu ms]\n", *v); + v = mdesc_get_property(hp, pn, "max-cpus", NULL); +- if (v) +- printk("PLATFORM: max-cpus [%llu]\n", *v); ++ if (v) { ++ max_cpus = *v; ++ printk("PLATFORM: max-cpus [%llu]\n", max_cpus); ++ } + + #ifdef CONFIG_SMP + { +@@ -715,7 +719,7 @@ static void __cpuinit set_proc_ids(struct mdesc_handle *hp) + } + + static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask, +- unsigned char def) ++ unsigned long def, unsigned long max) + { + u64 val; + +@@ -726,6 +730,9 @@ static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask, + if (!val || val >= 64) + goto use_default; + ++ if (val > max) ++ val = max; ++ + *mask = ((1U << val) * 64U) - 1U; + return; + +@@ -736,19 +743,28 @@ use_default: + static void __cpuinit get_mondo_data(struct mdesc_handle *hp, u64 mp, + struct trap_per_cpu *tb) + { ++ static int printed; + const u64 *val; + + val = mdesc_get_property(hp, mp, "q-cpu-mondo-#bits", NULL); +- get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7); ++ get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7, ilog2(max_cpus * 2)); + + val = mdesc_get_property(hp, mp, "q-dev-mondo-#bits", NULL); +- get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7); ++ get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7, 8); + + val = mdesc_get_property(hp, mp, "q-resumable-#bits", NULL); +- get_one_mondo_bits(val, &tb->resum_qmask, 6); ++ get_one_mondo_bits(val, &tb->resum_qmask, 6, 7); + + val = mdesc_get_property(hp, mp, "q-nonresumable-#bits", NULL); +- get_one_mondo_bits(val, &tb->nonresum_qmask, 2); ++ get_one_mondo_bits(val, &tb->nonresum_qmask, 2, 2); ++ if (!printed++) { ++ pr_info("SUN4V: Mondo queue sizes " ++ "[cpu(%u) dev(%u) r(%u) nr(%u)]\n", ++ tb->cpu_mondo_qmask + 1, ++ tb->dev_mondo_qmask + 1, ++ tb->resum_qmask + 1, ++ tb->nonresum_qmask + 1); ++ } + } + + static void * __cpuinit mdesc_iterate_over_cpus(void *(*func)(struct mdesc_handle *, u64, int, void *), void *arg, cpumask_t *mask) +diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c +index 8ac23e6..343b0f9 100644 +--- a/arch/sparc/kernel/pcr.c ++++ b/arch/sparc/kernel/pcr.c +@@ -80,8 +80,11 @@ static void n2_pcr_write(u64 val) + { + unsigned long ret; + +- ret = sun4v_niagara2_setperf(HV_N2_PERF_SPARC_CTL, val); +- if (ret != HV_EOK) ++ if (val & PCR_N2_HTRACE) { ++ ret = sun4v_niagara2_setperf(HV_N2_PERF_SPARC_CTL, val); ++ if (ret != HV_EOK) ++ write_pcr(val); ++ } else + write_pcr(val); + } + +@@ -106,6 +109,10 @@ static int __init register_perf_hsvc(void) + perf_hsvc_group = HV_GRP_N2_CPU; + break; + ++ case SUN4V_CHIP_NIAGARA3: ++ perf_hsvc_group = HV_GRP_KT_CPU; ++ break; ++ + default: + return -ENODEV; + } +diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c +index 2cb0e1c..6860d40 100644 +--- a/arch/sparc/kernel/perf_event.c ++++ b/arch/sparc/kernel/perf_event.c +@@ -1301,7 +1301,8 @@ static bool __init supported_pmu(void) + sparc_pmu = &niagara1_pmu; + return true; + } +- if (!strcmp(sparc_pmu_type, "niagara2")) { ++ if (!strcmp(sparc_pmu_type, "niagara2") || ++ !strcmp(sparc_pmu_type, "niagara3")) { + sparc_pmu = &niagara2_pmu; + return true; + } +diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c +index c4dd099..3e9daea 100644 +--- a/arch/sparc/kernel/setup_64.c ++++ b/arch/sparc/kernel/setup_64.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -46,6 +47,8 @@ + #include + #include + #include ++#include ++#include + + #ifdef CONFIG_IP_PNP + #include +@@ -269,6 +272,40 @@ void __init sun4v_patch(void) + sun4v_hvapi_init(); + } + ++static void __init popc_patch(void) ++{ ++ struct popc_3insn_patch_entry *p3; ++ struct popc_6insn_patch_entry *p6; ++ ++ p3 = &__popc_3insn_patch; ++ while (p3 < &__popc_3insn_patch_end) { ++ unsigned long i, addr = p3->addr; ++ ++ for (i = 0; i < 3; i++) { ++ *(unsigned int *) (addr + (i * 4)) = p3->insns[i]; ++ wmb(); ++ __asm__ __volatile__("flush %0" ++ : : "r" (addr + (i * 4))); ++ } ++ ++ p3++; ++ } ++ ++ p6 = &__popc_6insn_patch; ++ while (p6 < &__popc_6insn_patch_end) { ++ unsigned long i, addr = p6->addr; ++ ++ for (i = 0; i < 6; i++) { ++ *(unsigned int *) (addr + (i * 4)) = p6->insns[i]; ++ wmb(); ++ __asm__ __volatile__("flush %0" ++ : : "r" (addr + (i * 4))); ++ } ++ ++ p6++; ++ } ++} ++ + #ifdef CONFIG_SMP + void __init boot_cpu_id_too_large(int cpu) + { +@@ -278,6 +315,154 @@ void __init boot_cpu_id_too_large(int cpu) + } + #endif + ++/* On Ultra, we support all of the v8 capabilities. */ ++unsigned long sparc64_elf_hwcap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | ++ HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV | ++ HWCAP_SPARC_V9); ++EXPORT_SYMBOL(sparc64_elf_hwcap); ++ ++static const char *hwcaps[] = { ++ "flush", "stbar", "swap", "muldiv", "v9", ++ "ultra3", "blkinit", "n2", ++ ++ /* These strings are as they appear in the machine description ++ * 'hwcap-list' property for cpu nodes. ++ */ ++ "mul32", "div32", "fsmuld", "v8plus", "popc", "vis", "vis2", ++ "ASIBlkInit", "fmaf", "vis3", "hpc", "random", "trans", "fjfmau", ++ "ima", "cspare", ++}; ++ ++void cpucap_info(struct seq_file *m) ++{ ++ unsigned long caps = sparc64_elf_hwcap; ++ int i, printed = 0; ++ ++ seq_puts(m, "cpucaps\t\t: "); ++ for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { ++ unsigned long bit = 1UL << i; ++ if (caps & bit) { ++ seq_printf(m, "%s%s", ++ printed ? "," : "", hwcaps[i]); ++ printed++; ++ } ++ } ++ seq_putc(m, '\n'); ++} ++ ++static void __init report_hwcaps(unsigned long caps) ++{ ++ int i, printed = 0; ++ ++ printk(KERN_INFO "CPU CAPS: ["); ++ for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { ++ unsigned long bit = 1UL << i; ++ if (caps & bit) { ++ printk(KERN_CONT "%s%s", ++ printed ? "," : "", hwcaps[i]); ++ if (++printed == 8) { ++ printk(KERN_CONT "]\n"); ++ printk(KERN_INFO "CPU CAPS: ["); ++ printed = 0; ++ } ++ } ++ } ++ printk(KERN_CONT "]\n"); ++} ++ ++static unsigned long __init mdesc_cpu_hwcap_list(void) ++{ ++ struct mdesc_handle *hp; ++ unsigned long caps = 0; ++ const char *prop; ++ int len; ++ u64 pn; ++ ++ hp = mdesc_grab(); ++ if (!hp) ++ return 0; ++ ++ pn = mdesc_node_by_name(hp, MDESC_NODE_NULL, "cpu"); ++ if (pn == MDESC_NODE_NULL) ++ goto out; ++ ++ prop = mdesc_get_property(hp, pn, "hwcap-list", &len); ++ if (!prop) ++ goto out; ++ ++ while (len) { ++ int i, plen; ++ ++ for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { ++ unsigned long bit = 1UL << i; ++ ++ if (!strcmp(prop, hwcaps[i])) { ++ caps |= bit; ++ break; ++ } ++ } ++ ++ plen = strlen(prop) + 1; ++ prop += plen; ++ len -= plen; ++ } ++ ++out: ++ mdesc_release(hp); ++ return caps; ++} ++ ++/* This yields a mask that user programs can use to figure out what ++ * instruction set this cpu supports. ++ */ ++static void __init init_sparc64_elf_hwcap(void) ++{ ++ unsigned long cap = sparc64_elf_hwcap; ++ unsigned long mdesc_caps; ++ ++ if (tlb_type == cheetah || tlb_type == cheetah_plus) ++ cap |= HWCAP_SPARC_ULTRA3; ++ else if (tlb_type == hypervisor) { ++ if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || ++ sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || ++ sun4v_chip_type == SUN4V_CHIP_NIAGARA3) ++ cap |= HWCAP_SPARC_BLKINIT; ++ if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || ++ sun4v_chip_type == SUN4V_CHIP_NIAGARA3) ++ cap |= HWCAP_SPARC_N2; ++ } ++ ++ cap |= (AV_SPARC_MUL32 | AV_SPARC_DIV32 | AV_SPARC_V8PLUS); ++ ++ mdesc_caps = mdesc_cpu_hwcap_list(); ++ if (!mdesc_caps) { ++ if (tlb_type == spitfire) ++ cap |= AV_SPARC_VIS; ++ if (tlb_type == cheetah || tlb_type == cheetah_plus) ++ cap |= AV_SPARC_VIS | AV_SPARC_VIS2; ++ if (tlb_type == cheetah_plus) ++ cap |= AV_SPARC_POPC; ++ if (tlb_type == hypervisor) { ++ if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1) ++ cap |= AV_SPARC_ASI_BLK_INIT; ++ if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || ++ sun4v_chip_type == SUN4V_CHIP_NIAGARA3) ++ cap |= (AV_SPARC_VIS | AV_SPARC_VIS2 | ++ AV_SPARC_ASI_BLK_INIT | ++ AV_SPARC_POPC); ++ if (sun4v_chip_type == SUN4V_CHIP_NIAGARA3) ++ cap |= (AV_SPARC_VIS3 | AV_SPARC_HPC | ++ AV_SPARC_FMAF); ++ } ++ } ++ sparc64_elf_hwcap = cap | mdesc_caps; ++ ++ report_hwcaps(sparc64_elf_hwcap); ++ ++ if (sparc64_elf_hwcap & AV_SPARC_POPC) ++ popc_patch(); ++} ++ + void __init setup_arch(char **cmdline_p) + { + /* Initialize PROM console and command line. */ +@@ -337,6 +522,7 @@ void __init setup_arch(char **cmdline_p) + init_cur_cpu_trap(current_thread_info()); + + paging_init(); ++ init_sparc64_elf_hwcap(); + } + + extern int stop_a_enabled; +diff --git a/arch/sparc/kernel/sparc_ksyms_64.c b/arch/sparc/kernel/sparc_ksyms_64.c +index 372ad59..83b47ab 100644 +--- a/arch/sparc/kernel/sparc_ksyms_64.c ++++ b/arch/sparc/kernel/sparc_ksyms_64.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -38,5 +39,15 @@ EXPORT_SYMBOL(sun4v_niagara_setperf); + EXPORT_SYMBOL(sun4v_niagara2_getperf); + EXPORT_SYMBOL(sun4v_niagara2_setperf); + ++/* from hweight.S */ ++EXPORT_SYMBOL(__arch_hweight8); ++EXPORT_SYMBOL(__arch_hweight16); ++EXPORT_SYMBOL(__arch_hweight32); ++EXPORT_SYMBOL(__arch_hweight64); ++ ++/* from ffs_ffz.S */ ++EXPORT_SYMBOL(ffs); ++EXPORT_SYMBOL(__ffs); ++ + /* Exporting a symbol from /init/main.c */ + EXPORT_SYMBOL(saved_command_line); +diff --git a/arch/sparc/kernel/sstate.c b/arch/sparc/kernel/sstate.c +index 8cdbe59..c59af54 100644 +--- a/arch/sparc/kernel/sstate.c ++++ b/arch/sparc/kernel/sstate.c +@@ -14,14 +14,9 @@ + #include + #include + +-static int hv_supports_soft_state; +- +-static unsigned long kimage_addr_to_ra(const char *p) +-{ +- unsigned long val = (unsigned long) p; ++#include "kernel.h" + +- return kern_base + (val - KERNBASE); +-} ++static int hv_supports_soft_state; + + static void do_set_sstate(unsigned long state, const char *msg) + { +diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c +index b2b019e..9043106 100644 +--- a/arch/sparc/kernel/unaligned_64.c ++++ b/arch/sparc/kernel/unaligned_64.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + #include + + enum direction { +@@ -373,16 +374,11 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) + } + } + +-static char popc_helper[] = { +-0, 1, 1, 2, 1, 2, 2, 3, +-1, 2, 2, 3, 2, 3, 3, 4, +-}; +- + int handle_popc(u32 insn, struct pt_regs *regs) + { +- u64 value; +- int ret, i, rd = ((insn >> 25) & 0x1f); + int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; ++ int ret, rd = ((insn >> 25) & 0x1f); ++ u64 value; + + perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); + if (insn & 0x2000) { +@@ -392,10 +388,7 @@ int handle_popc(u32 insn, struct pt_regs *regs) + maybe_flush_windows(0, insn & 0x1f, rd, from_kernel); + value = fetch_reg(insn & 0x1f, regs); + } +- for (ret = 0, i = 0; i < 16; i++) { +- ret += popc_helper[value & 0xf]; +- value >>= 4; +- } ++ ret = hweight64(value); + if (rd < 16) { + if (rd) + regs->u_regs[rd] = ret; +diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S +index c022075..0e16056 100644 +--- a/arch/sparc/kernel/vmlinux.lds.S ++++ b/arch/sparc/kernel/vmlinux.lds.S +@@ -107,7 +107,26 @@ SECTIONS + *(.sun4v_2insn_patch) + __sun4v_2insn_patch_end = .; + } +- ++ .swapper_tsb_phys_patch : { ++ __swapper_tsb_phys_patch = .; ++ *(.swapper_tsb_phys_patch) ++ __swapper_tsb_phys_patch_end = .; ++ } ++ .swapper_4m_tsb_phys_patch : { ++ __swapper_4m_tsb_phys_patch = .; ++ *(.swapper_4m_tsb_phys_patch) ++ __swapper_4m_tsb_phys_patch_end = .; ++ } ++ .popc_3insn_patch : { ++ __popc_3insn_patch = .; ++ *(.popc_3insn_patch) ++ __popc_3insn_patch_end = .; ++ } ++ .popc_6insn_patch : { ++ __popc_6insn_patch = .; ++ *(.popc_6insn_patch) ++ __popc_6insn_patch_end = .; ++ } + PERCPU_SECTION(SMP_CACHE_BYTES) + + . = ALIGN(PAGE_SIZE); +diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile +index 7f01b8f..a3fc437 100644 +--- a/arch/sparc/lib/Makefile ++++ b/arch/sparc/lib/Makefile +@@ -31,13 +31,13 @@ lib-$(CONFIG_SPARC64) += NGmemcpy.o NGcopy_from_user.o NGcopy_to_user.o + lib-$(CONFIG_SPARC64) += NGpatch.o NGpage.o NGbzero.o + + lib-$(CONFIG_SPARC64) += NG2memcpy.o NG2copy_from_user.o NG2copy_to_user.o +-lib-$(CONFIG_SPARC64) += NG2patch.o NG2page.o ++lib-$(CONFIG_SPARC64) += NG2patch.o + + lib-$(CONFIG_SPARC64) += GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o + lib-$(CONFIG_SPARC64) += GENpatch.o GENpage.o GENbzero.o + + lib-$(CONFIG_SPARC64) += copy_in_user.o user_fixup.o memmove.o +-lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o ++lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o + + obj-y += iomap.o + obj-$(CONFIG_SPARC32) += atomic32.o +diff --git a/arch/sparc/lib/NG2page.S b/arch/sparc/lib/NG2page.S +deleted file mode 100644 +index 73b6b7c..0000000 +--- a/arch/sparc/lib/NG2page.S ++++ /dev/null +@@ -1,61 +0,0 @@ +-/* NG2page.S: Niagara-2 optimized clear and copy page. +- * +- * Copyright (C) 2007 (davem@davemloft.net) +- */ +- +-#include +-#include +-#include +- +- .text +- .align 32 +- +- /* This is heavily simplified from the sun4u variants +- * because Niagara-2 does not have any D-cache aliasing issues. +- */ +-NG2copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ +- prefetch [%o1 + 0x00], #one_read +- prefetch [%o1 + 0x40], #one_read +- VISEntryHalf +- set PAGE_SIZE, %g7 +- sub %o0, %o1, %g3 +-1: stxa %g0, [%o1 + %g3] ASI_BLK_INIT_QUAD_LDD_P +- subcc %g7, 64, %g7 +- ldda [%o1] ASI_BLK_P, %f0 +- stda %f0, [%o1 + %g3] ASI_BLK_P +- add %o1, 64, %o1 +- bne,pt %xcc, 1b +- prefetch [%o1 + 0x40], #one_read +- membar #Sync +- VISExitHalf +- retl +- nop +- +-#define BRANCH_ALWAYS 0x10680000 +-#define NOP 0x01000000 +-#define NG_DO_PATCH(OLD, NEW) \ +- sethi %hi(NEW), %g1; \ +- or %g1, %lo(NEW), %g1; \ +- sethi %hi(OLD), %g2; \ +- or %g2, %lo(OLD), %g2; \ +- sub %g1, %g2, %g1; \ +- sethi %hi(BRANCH_ALWAYS), %g3; \ +- sll %g1, 11, %g1; \ +- srl %g1, 11 + 2, %g1; \ +- or %g3, %lo(BRANCH_ALWAYS), %g3; \ +- or %g3, %g1, %g3; \ +- stw %g3, [%g2]; \ +- sethi %hi(NOP), %g3; \ +- or %g3, %lo(NOP), %g3; \ +- stw %g3, [%g2 + 0x4]; \ +- flush %g2; +- +- .globl niagara2_patch_pageops +- .type niagara2_patch_pageops,#function +-niagara2_patch_pageops: +- NG_DO_PATCH(copy_user_page, NG2copy_user_page) +- NG_DO_PATCH(_clear_page, NGclear_page) +- NG_DO_PATCH(clear_user_page, NGclear_user_page) +- retl +- nop +- .size niagara2_patch_pageops,.-niagara2_patch_pageops +diff --git a/arch/sparc/lib/NGpage.S b/arch/sparc/lib/NGpage.S +index 428920d..b9e790b 100644 +--- a/arch/sparc/lib/NGpage.S ++++ b/arch/sparc/lib/NGpage.S +@@ -16,55 +16,91 @@ + */ + + NGcopy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ +- prefetch [%o1 + 0x00], #one_read +- mov 8, %g1 +- mov 16, %g2 +- mov 24, %g3 ++ save %sp, -192, %sp ++ rd %asi, %g3 ++ wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi + set PAGE_SIZE, %g7 ++ prefetch [%i1 + 0x00], #one_read ++ prefetch [%i1 + 0x40], #one_read + +-1: ldda [%o1 + %g0] ASI_BLK_INIT_QUAD_LDD_P, %o2 +- ldda [%o1 + %g2] ASI_BLK_INIT_QUAD_LDD_P, %o4 +- prefetch [%o1 + 0x40], #one_read +- add %o1, 32, %o1 +- stxa %o2, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P +- stxa %o3, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P +- ldda [%o1 + %g0] ASI_BLK_INIT_QUAD_LDD_P, %o2 +- stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P +- stxa %o5, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P +- ldda [%o1 + %g2] ASI_BLK_INIT_QUAD_LDD_P, %o4 +- add %o1, 32, %o1 +- add %o0, 32, %o0 +- stxa %o2, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P +- stxa %o3, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P +- stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P +- stxa %o5, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P +- subcc %g7, 64, %g7 ++1: prefetch [%i1 + 0x80], #one_read ++ prefetch [%i1 + 0xc0], #one_read ++ ldda [%i1 + 0x00] %asi, %o2 ++ ldda [%i1 + 0x10] %asi, %o4 ++ ldda [%i1 + 0x20] %asi, %l2 ++ ldda [%i1 + 0x30] %asi, %l4 ++ stxa %o2, [%i0 + 0x00] %asi ++ stxa %o3, [%i0 + 0x08] %asi ++ stxa %o4, [%i0 + 0x10] %asi ++ stxa %o5, [%i0 + 0x18] %asi ++ stxa %l2, [%i0 + 0x20] %asi ++ stxa %l3, [%i0 + 0x28] %asi ++ stxa %l4, [%i0 + 0x30] %asi ++ stxa %l5, [%i0 + 0x38] %asi ++ ldda [%i1 + 0x40] %asi, %o2 ++ ldda [%i1 + 0x50] %asi, %o4 ++ ldda [%i1 + 0x60] %asi, %l2 ++ ldda [%i1 + 0x70] %asi, %l4 ++ stxa %o2, [%i0 + 0x40] %asi ++ stxa %o3, [%i0 + 0x48] %asi ++ stxa %o4, [%i0 + 0x50] %asi ++ stxa %o5, [%i0 + 0x58] %asi ++ stxa %l2, [%i0 + 0x60] %asi ++ stxa %l3, [%i0 + 0x68] %asi ++ stxa %l4, [%i0 + 0x70] %asi ++ stxa %l5, [%i0 + 0x78] %asi ++ add %i1, 128, %i1 ++ subcc %g7, 128, %g7 + bne,pt %xcc, 1b +- add %o0, 32, %o0 ++ add %i0, 128, %i0 ++ wr %g3, 0x0, %asi + membar #Sync +- retl +- nop ++ ret ++ restore + +- .globl NGclear_page, NGclear_user_page ++ .align 32 + NGclear_page: /* %o0=dest */ + NGclear_user_page: /* %o0=dest, %o1=vaddr */ +- mov 8, %g1 +- mov 16, %g2 +- mov 24, %g3 ++ rd %asi, %g3 ++ wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi + set PAGE_SIZE, %g7 + +-1: stxa %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P +- stxa %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P +- stxa %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P +- stxa %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P +- add %o0, 32, %o0 +- stxa %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P +- stxa %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P +- stxa %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P +- stxa %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P +- subcc %g7, 64, %g7 ++1: stxa %g0, [%o0 + 0x00] %asi ++ stxa %g0, [%o0 + 0x08] %asi ++ stxa %g0, [%o0 + 0x10] %asi ++ stxa %g0, [%o0 + 0x18] %asi ++ stxa %g0, [%o0 + 0x20] %asi ++ stxa %g0, [%o0 + 0x28] %asi ++ stxa %g0, [%o0 + 0x30] %asi ++ stxa %g0, [%o0 + 0x38] %asi ++ stxa %g0, [%o0 + 0x40] %asi ++ stxa %g0, [%o0 + 0x48] %asi ++ stxa %g0, [%o0 + 0x50] %asi ++ stxa %g0, [%o0 + 0x58] %asi ++ stxa %g0, [%o0 + 0x60] %asi ++ stxa %g0, [%o0 + 0x68] %asi ++ stxa %g0, [%o0 + 0x70] %asi ++ stxa %g0, [%o0 + 0x78] %asi ++ stxa %g0, [%o0 + 0x80] %asi ++ stxa %g0, [%o0 + 0x88] %asi ++ stxa %g0, [%o0 + 0x90] %asi ++ stxa %g0, [%o0 + 0x98] %asi ++ stxa %g0, [%o0 + 0xa0] %asi ++ stxa %g0, [%o0 + 0xa8] %asi ++ stxa %g0, [%o0 + 0xb0] %asi ++ stxa %g0, [%o0 + 0xb8] %asi ++ stxa %g0, [%o0 + 0xc0] %asi ++ stxa %g0, [%o0 + 0xc8] %asi ++ stxa %g0, [%o0 + 0xd0] %asi ++ stxa %g0, [%o0 + 0xd8] %asi ++ stxa %g0, [%o0 + 0xe0] %asi ++ stxa %g0, [%o0 + 0xe8] %asi ++ stxa %g0, [%o0 + 0xf0] %asi ++ stxa %g0, [%o0 + 0xf8] %asi ++ subcc %g7, 256, %g7 + bne,pt %xcc, 1b +- add %o0, 32, %o0 ++ add %o0, 256, %o0 ++ wr %g3, 0x0, %asi + membar #Sync + retl + nop +diff --git a/arch/sparc/lib/ffs.S b/arch/sparc/lib/ffs.S +new file mode 100644 +index 0000000..b39389f +--- /dev/null ++++ b/arch/sparc/lib/ffs.S +@@ -0,0 +1,84 @@ ++#include ++ ++ .register %g2,#scratch ++ ++ .text ++ .align 32 ++ ++ENTRY(ffs) ++ brnz,pt %o0, 1f ++ mov 1, %o1 ++ retl ++ clr %o0 ++ nop ++ nop ++ENTRY(__ffs) ++ sllx %o0, 32, %g1 /* 1 */ ++ srlx %o0, 32, %g2 ++ ++ clr %o1 /* 2 */ ++ movrz %g1, %g2, %o0 ++ ++ movrz %g1, 32, %o1 /* 3 */ ++1: clr %o2 ++ ++ sllx %o0, (64 - 16), %g1 /* 4 */ ++ srlx %o0, 16, %g2 ++ ++ movrz %g1, %g2, %o0 /* 5 */ ++ clr %o3 ++ ++ movrz %g1, 16, %o2 /* 6 */ ++ clr %o4 ++ ++ and %o0, 0xff, %g1 /* 7 */ ++ srlx %o0, 8, %g2 ++ ++ movrz %g1, %g2, %o0 /* 8 */ ++ clr %o5 ++ ++ movrz %g1, 8, %o3 /* 9 */ ++ add %o2, %o1, %o2 ++ ++ and %o0, 0xf, %g1 /* 10 */ ++ srlx %o0, 4, %g2 ++ ++ movrz %g1, %g2, %o0 /* 11 */ ++ add %o2, %o3, %o2 ++ ++ movrz %g1, 4, %o4 /* 12 */ ++ ++ and %o0, 0x3, %g1 /* 13 */ ++ srlx %o0, 2, %g2 ++ ++ movrz %g1, %g2, %o0 /* 14 */ ++ add %o2, %o4, %o2 ++ ++ movrz %g1, 2, %o5 /* 15 */ ++ ++ and %o0, 0x1, %g1 /* 16 */ ++ ++ add %o2, %o5, %o2 /* 17 */ ++ xor %g1, 0x1, %g1 ++ ++ retl /* 18 */ ++ add %o2, %g1, %o0 ++ENDPROC(ffs) ++ENDPROC(__ffs) ++ ++ .section .popc_6insn_patch, "ax" ++ .word ffs ++ brz,pn %o0, 98f ++ neg %o0, %g1 ++ xnor %o0, %g1, %o1 ++ popc %o1, %o0 ++98: retl ++ nop ++ .word __ffs ++ neg %o0, %g1 ++ xnor %o0, %g1, %o1 ++ popc %o1, %o0 ++ retl ++ sub %o0, 1, %o0 ++ nop ++ .previous +diff --git a/arch/sparc/lib/hweight.S b/arch/sparc/lib/hweight.S +new file mode 100644 +index 0000000..95414e0 +--- /dev/null ++++ b/arch/sparc/lib/hweight.S +@@ -0,0 +1,51 @@ ++#include ++ ++ .text ++ .align 32 ++ENTRY(__arch_hweight8) ++ ba,pt %xcc, __sw_hweight8 ++ nop ++ nop ++ENDPROC(__arch_hweight8) ++ .section .popc_3insn_patch, "ax" ++ .word __arch_hweight8 ++ sllx %o0, 64-8, %g1 ++ retl ++ popc %g1, %o0 ++ .previous ++ ++ENTRY(__arch_hweight16) ++ ba,pt %xcc, __sw_hweight16 ++ nop ++ nop ++ENDPROC(__arch_hweight16) ++ .section .popc_3insn_patch, "ax" ++ .word __arch_hweight16 ++ sllx %o0, 64-16, %g1 ++ retl ++ popc %g1, %o0 ++ .previous ++ ++ENTRY(__arch_hweight32) ++ ba,pt %xcc, __sw_hweight32 ++ nop ++ nop ++ENDPROC(__arch_hweight32) ++ .section .popc_3insn_patch, "ax" ++ .word __arch_hweight32 ++ sllx %o0, 64-32, %g1 ++ retl ++ popc %g1, %o0 ++ .previous ++ ++ENTRY(__arch_hweight64) ++ ba,pt %xcc, __sw_hweight64 ++ nop ++ nop ++ENDPROC(__arch_hweight64) ++ .section .popc_3insn_patch, "ax" ++ .word __arch_hweight64 ++ retl ++ popc %o0, %o0 ++ nop ++ .previous +diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c +index 3fd8e18..581531d 100644 +--- a/arch/sparc/mm/init_64.c ++++ b/arch/sparc/mm/init_64.c +@@ -1597,6 +1597,44 @@ static void __init tsb_phys_patch(void) + static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR]; + extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; + ++static void patch_one_ktsb_phys(unsigned int *start, unsigned int *end, unsigned long pa) ++{ ++ pa >>= KTSB_PHYS_SHIFT; ++ ++ while (start < end) { ++ unsigned int *ia = (unsigned int *)(unsigned long)*start; ++ ++ ia[0] = (ia[0] & ~0x3fffff) | (pa >> 10); ++ __asm__ __volatile__("flush %0" : : "r" (ia)); ++ ++ ia[1] = (ia[1] & ~0x3ff) | (pa & 0x3ff); ++ __asm__ __volatile__("flush %0" : : "r" (ia + 1)); ++ ++ start++; ++ } ++} ++ ++static void ktsb_phys_patch(void) ++{ ++ extern unsigned int __swapper_tsb_phys_patch; ++ extern unsigned int __swapper_tsb_phys_patch_end; ++ unsigned long ktsb_pa; ++ ++ ktsb_pa = kern_base + ((unsigned long)&swapper_tsb[0] - KERNBASE); ++ patch_one_ktsb_phys(&__swapper_tsb_phys_patch, ++ &__swapper_tsb_phys_patch_end, ktsb_pa); ++#ifndef CONFIG_DEBUG_PAGEALLOC ++ { ++ extern unsigned int __swapper_4m_tsb_phys_patch; ++ extern unsigned int __swapper_4m_tsb_phys_patch_end; ++ ktsb_pa = (kern_base + ++ ((unsigned long)&swapper_4m_tsb[0] - KERNBASE)); ++ patch_one_ktsb_phys(&__swapper_4m_tsb_phys_patch, ++ &__swapper_4m_tsb_phys_patch_end, ktsb_pa); ++ } ++#endif ++} ++ + static void __init sun4v_ktsb_init(void) + { + unsigned long ktsb_pa; +@@ -1716,8 +1754,10 @@ void __init paging_init(void) + sun4u_pgprot_init(); + + if (tlb_type == cheetah_plus || +- tlb_type == hypervisor) ++ tlb_type == hypervisor) { + tsb_phys_patch(); ++ ktsb_phys_patch(); ++ } + + if (tlb_type == hypervisor) { + sun4v_patch_tlb_handlers(); +diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile +index 17c565d..a6575b9 100644 +--- a/arch/x86/xen/Makefile ++++ b/arch/x86/xen/Makefile +@@ -18,5 +18,5 @@ obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \ + obj-$(CONFIG_SMP) += smp.o + obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o + obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o +- ++obj-$(CONFIG_XEN_DOM0) += vga.o + obj-$(CONFIG_SWIOTLB_XEN) += pci-swiotlb-xen.o +diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c +index 5525163..5325742 100644 +--- a/arch/x86/xen/enlighten.c ++++ b/arch/x86/xen/enlighten.c +@@ -1248,6 +1248,14 @@ asmlinkage void __init xen_start_kernel(void) + if (pci_xen) + x86_init.pci.arch_init = pci_xen_init; + } else { ++ const struct dom0_vga_console_info *info = ++ (void *)((char *)xen_start_info + ++ xen_start_info->console.dom0.info_off); ++ ++ xen_init_vga(info, xen_start_info->console.dom0.info_size); ++ xen_start_info->console.domU.mfn = 0; ++ xen_start_info->console.domU.evtchn = 0; ++ + /* Make sure ACS will be enabled */ + pci_request_acs(); + } +diff --git a/arch/x86/xen/vga.c b/arch/x86/xen/vga.c +new file mode 100644 +index 0000000..1cd7f4d +--- /dev/null ++++ b/arch/x86/xen/vga.c +@@ -0,0 +1,67 @@ ++#include ++#include ++ ++#include ++#include ++ ++#include ++ ++#include "xen-ops.h" ++ ++void __init xen_init_vga(const struct dom0_vga_console_info *info, size_t size) ++{ ++ struct screen_info *screen_info = &boot_params.screen_info; ++ ++ /* This is drawn from a dump from vgacon:startup in ++ * standard Linux. */ ++ screen_info->orig_video_mode = 3; ++ screen_info->orig_video_isVGA = 1; ++ screen_info->orig_video_lines = 25; ++ screen_info->orig_video_cols = 80; ++ screen_info->orig_video_ega_bx = 3; ++ screen_info->orig_video_points = 16; ++ screen_info->orig_y = screen_info->orig_video_lines - 1; ++ ++ switch (info->video_type) { ++ case XEN_VGATYPE_TEXT_MODE_3: ++ if (size < offsetof(struct dom0_vga_console_info, u.text_mode_3) ++ + sizeof(info->u.text_mode_3)) ++ break; ++ screen_info->orig_video_lines = info->u.text_mode_3.rows; ++ screen_info->orig_video_cols = info->u.text_mode_3.columns; ++ screen_info->orig_x = info->u.text_mode_3.cursor_x; ++ screen_info->orig_y = info->u.text_mode_3.cursor_y; ++ screen_info->orig_video_points = ++ info->u.text_mode_3.font_height; ++ break; ++ ++ case XEN_VGATYPE_VESA_LFB: ++ if (size < offsetof(struct dom0_vga_console_info, ++ u.vesa_lfb.gbl_caps)) ++ break; ++ screen_info->orig_video_isVGA = VIDEO_TYPE_VLFB; ++ screen_info->lfb_width = info->u.vesa_lfb.width; ++ screen_info->lfb_height = info->u.vesa_lfb.height; ++ screen_info->lfb_depth = info->u.vesa_lfb.bits_per_pixel; ++ screen_info->lfb_base = info->u.vesa_lfb.lfb_base; ++ screen_info->lfb_size = info->u.vesa_lfb.lfb_size; ++ screen_info->lfb_linelength = info->u.vesa_lfb.bytes_per_line; ++ screen_info->red_size = info->u.vesa_lfb.red_size; ++ screen_info->red_pos = info->u.vesa_lfb.red_pos; ++ screen_info->green_size = info->u.vesa_lfb.green_size; ++ screen_info->green_pos = info->u.vesa_lfb.green_pos; ++ screen_info->blue_size = info->u.vesa_lfb.blue_size; ++ screen_info->blue_pos = info->u.vesa_lfb.blue_pos; ++ screen_info->rsvd_size = info->u.vesa_lfb.rsvd_size; ++ screen_info->rsvd_pos = info->u.vesa_lfb.rsvd_pos; ++ if (size >= offsetof(struct dom0_vga_console_info, ++ u.vesa_lfb.gbl_caps) ++ + sizeof(info->u.vesa_lfb.gbl_caps)) ++ screen_info->capabilities = info->u.vesa_lfb.gbl_caps; ++ if (size >= offsetof(struct dom0_vga_console_info, ++ u.vesa_lfb.mode_attrs) ++ + sizeof(info->u.vesa_lfb.mode_attrs)) ++ screen_info->vesa_attributes = info->u.vesa_lfb.mode_attrs; ++ break; ++ } ++} +diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h +index 97dfdc8..b095739 100644 +--- a/arch/x86/xen/xen-ops.h ++++ b/arch/x86/xen/xen-ops.h +@@ -88,6 +88,17 @@ static inline void xen_uninit_lock_cpu(int cpu) + } + #endif + ++struct dom0_vga_console_info; ++ ++#ifdef CONFIG_XEN_DOM0 ++void __init xen_init_vga(const struct dom0_vga_console_info *, size_t size); ++#else ++static inline void __init xen_init_vga(const struct dom0_vga_console_info *info, ++ size_t size) ++{ ++} ++#endif ++ + /* Declare an asm function, along with symbols needed to make it + inlineable */ + #define DECL_ASM(ret, name, ...) \ +diff --git a/crypto/md5.c b/crypto/md5.c +index 30efc7d..7febeaa 100644 +--- a/crypto/md5.c ++++ b/crypto/md5.c +@@ -21,99 +21,9 @@ + #include + #include + #include ++#include + #include + +-#define F1(x, y, z) (z ^ (x & (y ^ z))) +-#define F2(x, y, z) F1(z, x, y) +-#define F3(x, y, z) (x ^ y ^ z) +-#define F4(x, y, z) (y ^ (x | ~z)) +- +-#define MD5STEP(f, w, x, y, z, in, s) \ +- (w += f(x, y, z) + in, w = (w<>(32-s)) + x) +- +-static void md5_transform(u32 *hash, u32 const *in) +-{ +- u32 a, b, c, d; +- +- a = hash[0]; +- b = hash[1]; +- c = hash[2]; +- d = hash[3]; +- +- MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); +- MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); +- MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); +- MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); +- MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); +- MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); +- MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); +- MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); +- MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); +- MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); +- MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); +- MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); +- MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); +- MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); +- MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); +- MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); +- +- MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); +- MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); +- MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); +- MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); +- MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); +- MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); +- MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); +- MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); +- MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); +- MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); +- MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); +- MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); +- MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); +- MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); +- MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); +- MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); +- +- MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); +- MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); +- MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); +- MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); +- MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); +- MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); +- MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); +- MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); +- MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); +- MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); +- MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); +- MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); +- MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); +- MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); +- MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); +- MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); +- +- MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); +- MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); +- MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); +- MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); +- MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); +- MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); +- MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); +- MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); +- MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); +- MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); +- MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); +- MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); +- MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); +- MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); +- MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); +- MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); +- +- hash[0] += a; +- hash[1] += b; +- hash[2] += c; +- hash[3] += d; +-} +- + /* XXX: this stuff can be optimized */ + static inline void le32_to_cpu_array(u32 *buf, unsigned int words) + { +diff --git a/drivers/char/random.c b/drivers/char/random.c +index d4ddeba..c35a785 100644 +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -1300,330 +1300,14 @@ ctl_table random_table[] = { + }; + #endif /* CONFIG_SYSCTL */ + +-/******************************************************************** +- * +- * Random functions for networking +- * +- ********************************************************************/ +- +-/* +- * TCP initial sequence number picking. This uses the random number +- * generator to pick an initial secret value. This value is hashed +- * along with the TCP endpoint information to provide a unique +- * starting point for each pair of TCP endpoints. This defeats +- * attacks which rely on guessing the initial TCP sequence number. +- * This algorithm was suggested by Steve Bellovin. +- * +- * Using a very strong hash was taking an appreciable amount of the total +- * TCP connection establishment time, so this is a weaker hash, +- * compensated for by changing the secret periodically. +- */ +- +-/* F, G and H are basic MD4 functions: selection, majority, parity */ +-#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +-#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z))) +-#define H(x, y, z) ((x) ^ (y) ^ (z)) +- +-/* +- * The generic round function. The application is so specific that +- * we don't bother protecting all the arguments with parens, as is generally +- * good macro practice, in favor of extra legibility. +- * Rotation is separate from addition to prevent recomputation +- */ +-#define ROUND(f, a, b, c, d, x, s) \ +- (a += f(b, c, d) + x, a = (a << s) | (a >> (32 - s))) +-#define K1 0 +-#define K2 013240474631UL +-#define K3 015666365641UL ++static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; + +-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +- +-static __u32 twothirdsMD4Transform(__u32 const buf[4], __u32 const in[12]) ++static int __init random_int_secret_init(void) + { +- __u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; +- +- /* Round 1 */ +- ROUND(F, a, b, c, d, in[ 0] + K1, 3); +- ROUND(F, d, a, b, c, in[ 1] + K1, 7); +- ROUND(F, c, d, a, b, in[ 2] + K1, 11); +- ROUND(F, b, c, d, a, in[ 3] + K1, 19); +- ROUND(F, a, b, c, d, in[ 4] + K1, 3); +- ROUND(F, d, a, b, c, in[ 5] + K1, 7); +- ROUND(F, c, d, a, b, in[ 6] + K1, 11); +- ROUND(F, b, c, d, a, in[ 7] + K1, 19); +- ROUND(F, a, b, c, d, in[ 8] + K1, 3); +- ROUND(F, d, a, b, c, in[ 9] + K1, 7); +- ROUND(F, c, d, a, b, in[10] + K1, 11); +- ROUND(F, b, c, d, a, in[11] + K1, 19); +- +- /* Round 2 */ +- ROUND(G, a, b, c, d, in[ 1] + K2, 3); +- ROUND(G, d, a, b, c, in[ 3] + K2, 5); +- ROUND(G, c, d, a, b, in[ 5] + K2, 9); +- ROUND(G, b, c, d, a, in[ 7] + K2, 13); +- ROUND(G, a, b, c, d, in[ 9] + K2, 3); +- ROUND(G, d, a, b, c, in[11] + K2, 5); +- ROUND(G, c, d, a, b, in[ 0] + K2, 9); +- ROUND(G, b, c, d, a, in[ 2] + K2, 13); +- ROUND(G, a, b, c, d, in[ 4] + K2, 3); +- ROUND(G, d, a, b, c, in[ 6] + K2, 5); +- ROUND(G, c, d, a, b, in[ 8] + K2, 9); +- ROUND(G, b, c, d, a, in[10] + K2, 13); +- +- /* Round 3 */ +- ROUND(H, a, b, c, d, in[ 3] + K3, 3); +- ROUND(H, d, a, b, c, in[ 7] + K3, 9); +- ROUND(H, c, d, a, b, in[11] + K3, 11); +- ROUND(H, b, c, d, a, in[ 2] + K3, 15); +- ROUND(H, a, b, c, d, in[ 6] + K3, 3); +- ROUND(H, d, a, b, c, in[10] + K3, 9); +- ROUND(H, c, d, a, b, in[ 1] + K3, 11); +- ROUND(H, b, c, d, a, in[ 5] + K3, 15); +- ROUND(H, a, b, c, d, in[ 9] + K3, 3); +- ROUND(H, d, a, b, c, in[ 0] + K3, 9); +- ROUND(H, c, d, a, b, in[ 4] + K3, 11); +- ROUND(H, b, c, d, a, in[ 8] + K3, 15); +- +- return buf[1] + b; /* "most hashed" word */ +- /* Alternative: return sum of all words? */ +-} +-#endif +- +-#undef ROUND +-#undef F +-#undef G +-#undef H +-#undef K1 +-#undef K2 +-#undef K3 +- +-/* This should not be decreased so low that ISNs wrap too fast. */ +-#define REKEY_INTERVAL (300 * HZ) +-/* +- * Bit layout of the tcp sequence numbers (before adding current time): +- * bit 24-31: increased after every key exchange +- * bit 0-23: hash(source,dest) +- * +- * The implementation is similar to the algorithm described +- * in the Appendix of RFC 1185, except that +- * - it uses a 1 MHz clock instead of a 250 kHz clock +- * - it performs a rekey every 5 minutes, which is equivalent +- * to a (source,dest) tulple dependent forward jump of the +- * clock by 0..2^(HASH_BITS+1) +- * +- * Thus the average ISN wraparound time is 68 minutes instead of +- * 4.55 hours. +- * +- * SMP cleanup and lock avoidance with poor man's RCU. +- * Manfred Spraul +- * +- */ +-#define COUNT_BITS 8 +-#define COUNT_MASK ((1 << COUNT_BITS) - 1) +-#define HASH_BITS 24 +-#define HASH_MASK ((1 << HASH_BITS) - 1) +- +-static struct keydata { +- __u32 count; /* already shifted to the final position */ +- __u32 secret[12]; +-} ____cacheline_aligned ip_keydata[2]; +- +-static unsigned int ip_cnt; +- +-static void rekey_seq_generator(struct work_struct *work); +- +-static DECLARE_DELAYED_WORK(rekey_work, rekey_seq_generator); +- +-/* +- * Lock avoidance: +- * The ISN generation runs lockless - it's just a hash over random data. +- * State changes happen every 5 minutes when the random key is replaced. +- * Synchronization is performed by having two copies of the hash function +- * state and rekey_seq_generator always updates the inactive copy. +- * The copy is then activated by updating ip_cnt. +- * The implementation breaks down if someone blocks the thread +- * that processes SYN requests for more than 5 minutes. Should never +- * happen, and even if that happens only a not perfectly compliant +- * ISN is generated, nothing fatal. +- */ +-static void rekey_seq_generator(struct work_struct *work) +-{ +- struct keydata *keyptr = &ip_keydata[1 ^ (ip_cnt & 1)]; +- +- get_random_bytes(keyptr->secret, sizeof(keyptr->secret)); +- keyptr->count = (ip_cnt & COUNT_MASK) << HASH_BITS; +- smp_wmb(); +- ip_cnt++; +- schedule_delayed_work(&rekey_work, +- round_jiffies_relative(REKEY_INTERVAL)); +-} +- +-static inline struct keydata *get_keyptr(void) +-{ +- struct keydata *keyptr = &ip_keydata[ip_cnt & 1]; +- +- smp_rmb(); +- +- return keyptr; +-} +- +-static __init int seqgen_init(void) +-{ +- rekey_seq_generator(NULL); ++ get_random_bytes(random_int_secret, sizeof(random_int_secret)); + return 0; + } +-late_initcall(seqgen_init); +- +-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +-__u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, +- __be16 sport, __be16 dport) +-{ +- __u32 seq; +- __u32 hash[12]; +- struct keydata *keyptr = get_keyptr(); +- +- /* The procedure is the same as for IPv4, but addresses are longer. +- * Thus we must use twothirdsMD4Transform. +- */ +- +- memcpy(hash, saddr, 16); +- hash[4] = ((__force u16)sport << 16) + (__force u16)dport; +- memcpy(&hash[5], keyptr->secret, sizeof(__u32) * 7); +- +- seq = twothirdsMD4Transform((const __u32 *)daddr, hash) & HASH_MASK; +- seq += keyptr->count; +- +- seq += ktime_to_ns(ktime_get_real()); +- +- return seq; +-} +-EXPORT_SYMBOL(secure_tcpv6_sequence_number); +-#endif +- +-/* The code below is shamelessly stolen from secure_tcp_sequence_number(). +- * All blames to Andrey V. Savochkin . +- */ +-__u32 secure_ip_id(__be32 daddr) +-{ +- struct keydata *keyptr; +- __u32 hash[4]; +- +- keyptr = get_keyptr(); +- +- /* +- * Pick a unique starting offset for each IP destination. +- * The dest ip address is placed in the starting vector, +- * which is then hashed with random data. +- */ +- hash[0] = (__force __u32)daddr; +- hash[1] = keyptr->secret[9]; +- hash[2] = keyptr->secret[10]; +- hash[3] = keyptr->secret[11]; +- +- return half_md4_transform(hash, keyptr->secret); +-} +- +-#ifdef CONFIG_INET +- +-__u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, +- __be16 sport, __be16 dport) +-{ +- __u32 seq; +- __u32 hash[4]; +- struct keydata *keyptr = get_keyptr(); +- +- /* +- * Pick a unique starting offset for each TCP connection endpoints +- * (saddr, daddr, sport, dport). +- * Note that the words are placed into the starting vector, which is +- * then mixed with a partial MD4 over random data. +- */ +- hash[0] = (__force u32)saddr; +- hash[1] = (__force u32)daddr; +- hash[2] = ((__force u16)sport << 16) + (__force u16)dport; +- hash[3] = keyptr->secret[11]; +- +- seq = half_md4_transform(hash, keyptr->secret) & HASH_MASK; +- seq += keyptr->count; +- /* +- * As close as possible to RFC 793, which +- * suggests using a 250 kHz clock. +- * Further reading shows this assumes 2 Mb/s networks. +- * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate. +- * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but +- * we also need to limit the resolution so that the u32 seq +- * overlaps less than one time per MSL (2 minutes). +- * Choosing a clock of 64 ns period is OK. (period of 274 s) +- */ +- seq += ktime_to_ns(ktime_get_real()) >> 6; +- +- return seq; +-} +- +-/* Generate secure starting point for ephemeral IPV4 transport port search */ +-u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) +-{ +- struct keydata *keyptr = get_keyptr(); +- u32 hash[4]; +- +- /* +- * Pick a unique starting offset for each ephemeral port search +- * (saddr, daddr, dport) and 48bits of random data. +- */ +- hash[0] = (__force u32)saddr; +- hash[1] = (__force u32)daddr; +- hash[2] = (__force u32)dport ^ keyptr->secret[10]; +- hash[3] = keyptr->secret[11]; +- +- return half_md4_transform(hash, keyptr->secret); +-} +-EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral); +- +-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +-u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, +- __be16 dport) +-{ +- struct keydata *keyptr = get_keyptr(); +- u32 hash[12]; +- +- memcpy(hash, saddr, 16); +- hash[4] = (__force u32)dport; +- memcpy(&hash[5], keyptr->secret, sizeof(__u32) * 7); +- +- return twothirdsMD4Transform((const __u32 *)daddr, hash); +-} +-#endif +- +-#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) +-/* Similar to secure_tcp_sequence_number but generate a 48 bit value +- * bit's 32-47 increase every key exchange +- * 0-31 hash(source, dest) +- */ +-u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, +- __be16 sport, __be16 dport) +-{ +- u64 seq; +- __u32 hash[4]; +- struct keydata *keyptr = get_keyptr(); +- +- hash[0] = (__force u32)saddr; +- hash[1] = (__force u32)daddr; +- hash[2] = ((__force u16)sport << 16) + (__force u16)dport; +- hash[3] = keyptr->secret[11]; +- +- seq = half_md4_transform(hash, keyptr->secret); +- seq |= ((u64)keyptr->count) << (32 - HASH_BITS); +- +- seq += ktime_to_ns(ktime_get_real()); +- seq &= (1ull << 48) - 1; +- +- return seq; +-} +-EXPORT_SYMBOL(secure_dccp_sequence_number); +-#endif +- +-#endif /* CONFIG_INET */ +- ++late_initcall(random_int_secret_init); + + /* + * Get a random word for internal kernel use only. Similar to urandom but +@@ -1631,17 +1315,15 @@ EXPORT_SYMBOL(secure_dccp_sequence_number); + * value is not cryptographically secure but for several uses the cost of + * depleting entropy is too high + */ +-DEFINE_PER_CPU(__u32 [4], get_random_int_hash); ++DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash); + unsigned int get_random_int(void) + { +- struct keydata *keyptr; + __u32 *hash = get_cpu_var(get_random_int_hash); +- int ret; ++ unsigned int ret; + +- keyptr = get_keyptr(); + hash[0] += current->pid + jiffies + get_cycles(); +- +- ret = half_md4_transform(hash, keyptr->secret); ++ md5_transform(hash, random_int_secret); ++ ret = hash[0]; + put_cpu_var(get_random_int_hash); + + return ret; +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 0929219..1bbb85b 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -127,6 +127,23 @@ static const u8 edid_header[] = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 + }; + ++ /* ++ * Sanity check the header of the base EDID block. Return 8 if the header ++ * is perfect, down to 0 if it's totally wrong. ++ */ ++int drm_edid_header_is_valid(const u8 *raw_edid) ++{ ++ int i, score = 0; ++ ++ for (i = 0; i < sizeof(edid_header); i++) ++ if (raw_edid[i] == edid_header[i]) ++ score++; ++ ++ return score; ++} ++EXPORT_SYMBOL(drm_edid_header_is_valid); ++ ++ + /* + * Sanity check the EDID block (base or extension). Return 0 if the block + * doesn't check out, or 1 if it's valid. +@@ -139,12 +156,7 @@ drm_edid_block_valid(u8 *raw_edid) + struct edid *edid = (struct edid *)raw_edid; + + if (raw_edid[0] == 0x00) { +- int score = 0; +- +- for (i = 0; i < sizeof(edid_header); i++) +- if (raw_edid[i] == edid_header[i]) +- score++; +- ++ int score = drm_edid_header_is_valid(raw_edid); + if (score == 8) ; + else if (score >= 6) { + DRM_DEBUG("Fixing EDID header, your hardware may be failing\n"); +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 296fbd6..7eef6e1 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -61,7 +61,6 @@ static void i915_write_hws_pga(struct drm_device *dev) + static int i915_init_phys_hws(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = dev->dev_private; +- struct intel_ring_buffer *ring = LP_RING(dev_priv); + + /* Program Hardware Status Page */ + dev_priv->status_page_dmah = +@@ -71,10 +70,9 @@ static int i915_init_phys_hws(struct drm_device *dev) + DRM_ERROR("Can not allocate hardware status page\n"); + return -ENOMEM; + } +- ring->status_page.page_addr = +- (void __force __iomem *)dev_priv->status_page_dmah->vaddr; + +- memset_io(ring->status_page.page_addr, 0, PAGE_SIZE); ++ memset_io((void __force __iomem *)dev_priv->status_page_dmah->vaddr, ++ 0, PAGE_SIZE); + + i915_write_hws_pga(dev); + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 3b03f85..9b1d669 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -306,12 +306,15 @@ static void i915_hotplug_work_func(struct work_struct *work) + struct drm_mode_config *mode_config = &dev->mode_config; + struct intel_encoder *encoder; + ++ mutex_lock(&mode_config->mutex); + DRM_DEBUG_KMS("running encoder hotplug functions\n"); + + list_for_each_entry(encoder, &mode_config->encoder_list, base.head) + if (encoder->hot_plug) + encoder->hot_plug(encoder); + ++ mutex_unlock(&mode_config->mutex); ++ + /* Just fire off a uevent and let userspace tell us what to do */ + drm_helper_hpd_irq_event(dev); + } +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 0f1c799..5609c06 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -2699,14 +2699,18 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) + I915_WRITE(PF_WIN_SZ(pipe), dev_priv->pch_pf_size); + } + ++ /* ++ * On ILK+ LUT must be loaded before the pipe is running but with ++ * clocks enabled ++ */ ++ intel_crtc_load_lut(crtc); ++ + intel_enable_pipe(dev_priv, pipe, is_pch_port); + intel_enable_plane(dev_priv, plane, pipe); + + if (is_pch_port) + ironlake_pch_enable(crtc); + +- intel_crtc_load_lut(crtc); +- + mutex_lock(&dev->struct_mutex); + intel_update_fbc(dev); + mutex_unlock(&dev->struct_mutex); +diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c +index a06ff07..05f500c 100644 +--- a/drivers/gpu/drm/i915/intel_panel.c ++++ b/drivers/gpu/drm/i915/intel_panel.c +@@ -83,11 +83,15 @@ intel_pch_panel_fitting(struct drm_device *dev, + u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; + if (scaled_width > scaled_height) { /* pillar */ + width = scaled_height / mode->vdisplay; ++ if (width & 1) ++ width++; + x = (adjusted_mode->hdisplay - width + 1) / 2; + y = 0; + height = adjusted_mode->vdisplay; + } else if (scaled_width < scaled_height) { /* letter */ + height = scaled_width / mode->hdisplay; ++ if (height & 1) ++ height++; + y = (adjusted_mode->vdisplay - height + 1) / 2; + x = 0; + width = adjusted_mode->hdisplay; +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index 95c4b14..1f61fc7 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -1319,6 +1319,9 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) + ring->get_seqno = pc_render_get_seqno; + } + ++ if (!I915_NEED_GFX_HWS(dev)) ++ ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; ++ + ring->dev = dev; + INIT_LIST_HEAD(&ring->active_list); + INIT_LIST_HEAD(&ring->request_list); +diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c +index 9792d4f..6d6b5f1 100644 +--- a/drivers/gpu/drm/radeon/radeon_connectors.c ++++ b/drivers/gpu/drm/radeon/radeon_connectors.c +@@ -430,6 +430,45 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr + return 0; + } + ++/* ++ * Some integrated ATI Radeon chipset implementations (e. g. ++ * Asus M2A-VM HDMI) may indicate the availability of a DDC, ++ * even when there's no monitor connected. For these connectors ++ * following DDC probe extension will be applied: check also for the ++ * availability of EDID with at least a correct EDID header. Only then, ++ * DDC is assumed to be available. This prevents drm_get_edid() and ++ * drm_edid_block_valid() from periodically dumping data and kernel ++ * errors into the logs and onto the terminal. ++ */ ++static bool radeon_connector_needs_extended_probe(struct radeon_device *dev, ++ uint32_t supported_device, ++ int connector_type) ++{ ++ /* Asus M2A-VM HDMI board sends data to i2c bus even, ++ * if HDMI add-on card is not plugged in or HDMI is disabled in ++ * BIOS. Valid DDC can only be assumed, if also a valid EDID header ++ * can be retrieved via i2c bus during DDC probe */ ++ if ((dev->pdev->device == 0x791e) && ++ (dev->pdev->subsystem_vendor == 0x1043) && ++ (dev->pdev->subsystem_device == 0x826d)) { ++ if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) && ++ (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) ++ return true; ++ } ++ /* ECS A740GM-M with ATI RADEON 2100 sends data to i2c bus ++ * for a DVI connector that is not implemented */ ++ if ((dev->pdev->device == 0x796e) && ++ (dev->pdev->subsystem_vendor == 0x1019) && ++ (dev->pdev->subsystem_device == 0x2615)) { ++ if ((connector_type == DRM_MODE_CONNECTOR_DVID) && ++ (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) ++ return true; ++ } ++ ++ /* Default: no EDID header probe required for DDC probing */ ++ return false; ++} ++ + static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, + struct drm_connector *connector) + { +@@ -661,7 +700,8 @@ radeon_vga_detect(struct drm_connector *connector, bool force) + ret = connector_status_disconnected; + + if (radeon_connector->ddc_bus) +- dret = radeon_ddc_probe(radeon_connector); ++ dret = radeon_ddc_probe(radeon_connector, ++ radeon_connector->requires_extended_probe); + if (dret) { + if (radeon_connector->edid) { + kfree(radeon_connector->edid); +@@ -833,7 +873,8 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) + bool dret = false; + + if (radeon_connector->ddc_bus) +- dret = radeon_ddc_probe(radeon_connector); ++ dret = radeon_ddc_probe(radeon_connector, ++ radeon_connector->requires_extended_probe); + if (dret) { + if (radeon_connector->edid) { + kfree(radeon_connector->edid); +@@ -1251,7 +1292,8 @@ radeon_dp_detect(struct drm_connector *connector, bool force) + if (radeon_dp_getdpcd(radeon_connector)) + ret = connector_status_connected; + } else { +- if (radeon_ddc_probe(radeon_connector)) ++ if (radeon_ddc_probe(radeon_connector, ++ radeon_connector->requires_extended_probe)) + ret = connector_status_connected; + } + } +@@ -1406,6 +1448,9 @@ radeon_add_atom_connector(struct drm_device *dev, + radeon_connector->shared_ddc = shared_ddc; + radeon_connector->connector_object_id = connector_object_id; + radeon_connector->hpd = *hpd; ++ radeon_connector->requires_extended_probe = ++ radeon_connector_needs_extended_probe(rdev, supported_device, ++ connector_type); + radeon_connector->router = *router; + if (router->ddc_valid || router->cd_valid) { + radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); +@@ -1752,6 +1797,9 @@ radeon_add_legacy_connector(struct drm_device *dev, + radeon_connector->devices = supported_device; + radeon_connector->connector_object_id = connector_object_id; + radeon_connector->hpd = *hpd; ++ radeon_connector->requires_extended_probe = ++ radeon_connector_needs_extended_probe(rdev, supported_device, ++ connector_type); + switch (connector_type) { + case DRM_MODE_CONNECTOR_VGA: + drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); +diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c +index 7cfaa7e..440e6ec 100644 +--- a/drivers/gpu/drm/radeon/radeon_device.c ++++ b/drivers/gpu/drm/radeon/radeon_device.c +@@ -704,8 +704,9 @@ int radeon_device_init(struct radeon_device *rdev, + rdev->gpu_lockup = false; + rdev->accel_working = false; + +- DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X).\n", +- radeon_family_name[rdev->family], pdev->vendor, pdev->device); ++ DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X).\n", ++ radeon_family_name[rdev->family], pdev->vendor, pdev->device, ++ pdev->subsystem_vendor, pdev->subsystem_device); + + /* mutex initialization are all done here so we + * can recall function without having locking issues */ +diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c +index 292f73f..ed085ce 100644 +--- a/drivers/gpu/drm/radeon/radeon_display.c ++++ b/drivers/gpu/drm/radeon/radeon_display.c +@@ -777,8 +777,17 @@ static int radeon_ddc_dump(struct drm_connector *connector) + if (!radeon_connector->ddc_bus) + return -1; + edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter); ++ /* Log EDID retrieval status here. In particular with regard to ++ * connectors with requires_extended_probe flag set, that will prevent ++ * function radeon_dvi_detect() to fetch EDID on this connector, ++ * as long as there is no valid EDID header found */ + if (edid) { ++ DRM_INFO("Radeon display connector %s: Found valid EDID", ++ drm_get_connector_name(connector)); + kfree(edid); ++ } else { ++ DRM_INFO("Radeon display connector %s: No monitor connected or invalid EDID", ++ drm_get_connector_name(connector)); + } + return ret; + } +diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c +index 781196d..6c111c1 100644 +--- a/drivers/gpu/drm/radeon/radeon_i2c.c ++++ b/drivers/gpu/drm/radeon/radeon_i2c.c +@@ -32,17 +32,17 @@ + * radeon_ddc_probe + * + */ +-bool radeon_ddc_probe(struct radeon_connector *radeon_connector) ++bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_extended_probe) + { +- u8 out_buf[] = { 0x0, 0x0}; +- u8 buf[2]; ++ u8 out = 0x0; ++ u8 buf[8]; + int ret; + struct i2c_msg msgs[] = { + { + .addr = 0x50, + .flags = 0, + .len = 1, +- .buf = out_buf, ++ .buf = &out, + }, + { + .addr = 0x50, +@@ -52,15 +52,31 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector) + } + }; + ++ /* Read 8 bytes from i2c for extended probe of EDID header */ ++ if (requires_extended_probe) ++ msgs[1].len = 8; ++ + /* on hw with routers, select right port */ + if (radeon_connector->router.ddc_valid) + radeon_router_select_ddc_port(radeon_connector); + + ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2); +- if (ret == 2) +- return true; +- +- return false; ++ if (ret != 2) ++ /* Couldn't find an accessible DDC on this connector */ ++ return false; ++ if (requires_extended_probe) { ++ /* Probe also for valid EDID header ++ * EDID header starts with: ++ * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00. ++ * Only the first 6 bytes must be valid as ++ * drm_edid_block_valid() can fix the last 2 bytes */ ++ if (drm_edid_header_is_valid(buf) < 6) { ++ /* Couldn't find an accessible EDID on this ++ * connector */ ++ return false; ++ } ++ } ++ return true; + } + + /* bit banging i2c */ +diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h +index 6df4e3c..d09031c 100644 +--- a/drivers/gpu/drm/radeon/radeon_mode.h ++++ b/drivers/gpu/drm/radeon/radeon_mode.h +@@ -438,6 +438,9 @@ struct radeon_connector { + struct radeon_i2c_chan *ddc_bus; + /* some systems have an hdmi and vga port with a shared ddc line */ + bool shared_ddc; ++ /* for some Radeon chip families we apply an additional EDID header ++ check as part of the DDC probe */ ++ bool requires_extended_probe; + bool use_digital; + /* we need to mind the EDID between detect + and get modes due to analog/digital/tvencoder */ +@@ -514,7 +517,8 @@ extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c, + u8 val); + extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector); + extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector); +-extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); ++extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector, ++ bool requires_extended_probe); + extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); + + extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector); +diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c +index 9798811..b145b5a 100644 +--- a/drivers/isdn/i4l/isdn_net.c ++++ b/drivers/isdn/i4l/isdn_net.c +@@ -2531,6 +2531,9 @@ static void _isdn_setup(struct net_device *dev) + + /* Setup the generic properties */ + dev->flags = IFF_NOARP|IFF_POINTOPOINT; ++ ++ /* isdn prepends a header in the tx path, can't share skbs */ ++ dev->priv_flags &= ~IFF_TX_SKB_SHARING; + dev->header_ops = NULL; + dev->netdev_ops = &isdn_netdev_ops; + +diff --git a/drivers/net/Makefile b/drivers/net/Makefile +index 776a478..d5ce011 100644 +--- a/drivers/net/Makefile ++++ b/drivers/net/Makefile +@@ -283,6 +283,7 @@ obj-$(CONFIG_USB_HSO) += usb/ + obj-$(CONFIG_USB_USBNET) += usb/ + obj-$(CONFIG_USB_ZD1201) += usb/ + obj-$(CONFIG_USB_IPHETH) += usb/ ++obj-$(CONFIG_USB_CDC_PHONET) += usb/ + + obj-$(CONFIG_WLAN) += wireless/ + obj-$(CONFIG_NET_TULIP) += tulip/ +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 63c22b0..9ea2f21 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1625,8 +1625,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) + + if (slave_dev->type != ARPHRD_ETHER) + bond_setup_by_slave(bond_dev, slave_dev); +- else ++ else { + ether_setup(bond_dev); ++ bond_dev->priv_flags &= ~IFF_TX_SKB_SHARING; ++ } + + netdev_bonding_change(bond_dev, + NETDEV_POST_TYPE_CHANGE); +@@ -4398,7 +4400,7 @@ static void bond_setup(struct net_device *bond_dev) + bond_dev->tx_queue_len = 0; + bond_dev->flags |= IFF_MASTER|IFF_MULTICAST; + bond_dev->priv_flags |= IFF_BONDING; +- bond_dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; ++ bond_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); + + /* At first, we block adding VLANs. That's the only way to + * prevent problems that occur when adding VLANs over an +diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c +index 88fcb25..0624610 100644 +--- a/drivers/net/bonding/bond_sysfs.c ++++ b/drivers/net/bonding/bond_sysfs.c +@@ -992,6 +992,7 @@ static ssize_t bonding_store_primary(struct device *d, + int i; + struct slave *slave; + struct bonding *bond = to_bond(d); ++ char ifname[IFNAMSIZ]; + + if (!rtnl_trylock()) + return restart_syscall(); +@@ -1002,32 +1003,33 @@ static ssize_t bonding_store_primary(struct device *d, + if (!USES_PRIMARY(bond->params.mode)) { + pr_info("%s: Unable to set primary slave; %s is in mode %d\n", + bond->dev->name, bond->dev->name, bond->params.mode); +- } else { +- bond_for_each_slave(bond, slave, i) { +- if (strnicmp +- (slave->dev->name, buf, +- strlen(slave->dev->name)) == 0) { +- pr_info("%s: Setting %s as primary slave.\n", +- bond->dev->name, slave->dev->name); +- bond->primary_slave = slave; +- strcpy(bond->params.primary, slave->dev->name); +- bond_select_active_slave(bond); +- goto out; +- } +- } ++ goto out; ++ } + +- /* if we got here, then we didn't match the name of any slave */ ++ sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ + +- if (strlen(buf) == 0 || buf[0] == '\n') { +- pr_info("%s: Setting primary slave to None.\n", +- bond->dev->name); +- bond->primary_slave = NULL; +- bond_select_active_slave(bond); +- } else { +- pr_info("%s: Unable to set %.*s as primary slave as it is not a slave.\n", +- bond->dev->name, (int)strlen(buf) - 1, buf); ++ /* check to see if we are clearing primary */ ++ if (!strlen(ifname) || buf[0] == '\n') { ++ pr_info("%s: Setting primary slave to None.\n", ++ bond->dev->name); ++ bond->primary_slave = NULL; ++ bond_select_active_slave(bond); ++ goto out; ++ } ++ ++ bond_for_each_slave(bond, slave, i) { ++ if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { ++ pr_info("%s: Setting %s as primary slave.\n", ++ bond->dev->name, slave->dev->name); ++ bond->primary_slave = slave; ++ strcpy(bond->params.primary, slave->dev->name); ++ bond_select_active_slave(bond); ++ goto out; + } + } ++ ++ pr_info("%s: Unable to set %.*s as primary slave.\n", ++ bond->dev->name, (int)strlen(buf) - 1, buf); + out: + write_unlock_bh(&bond->curr_slave_lock); + read_unlock(&bond->lock); +@@ -1162,6 +1164,7 @@ static ssize_t bonding_store_active_slave(struct device *d, + struct slave *old_active = NULL; + struct slave *new_active = NULL; + struct bonding *bond = to_bond(d); ++ char ifname[IFNAMSIZ]; + + if (!rtnl_trylock()) + return restart_syscall(); +@@ -1170,56 +1173,62 @@ static ssize_t bonding_store_active_slave(struct device *d, + read_lock(&bond->lock); + write_lock_bh(&bond->curr_slave_lock); + +- if (!USES_PRIMARY(bond->params.mode)) ++ if (!USES_PRIMARY(bond->params.mode)) { + pr_info("%s: Unable to change active slave; %s is in mode %d\n", + bond->dev->name, bond->dev->name, bond->params.mode); +- else { +- bond_for_each_slave(bond, slave, i) { +- if (strnicmp +- (slave->dev->name, buf, +- strlen(slave->dev->name)) == 0) { +- old_active = bond->curr_active_slave; +- new_active = slave; +- if (new_active == old_active) { +- /* do nothing */ +- pr_info("%s: %s is already the current active slave.\n", ++ goto out; ++ } ++ ++ sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ ++ ++ /* check to see if we are clearing active */ ++ if (!strlen(ifname) || buf[0] == '\n') { ++ pr_info("%s: Clearing current active slave.\n", ++ bond->dev->name); ++ bond->curr_active_slave = NULL; ++ bond_select_active_slave(bond); ++ goto out; ++ } ++ ++ bond_for_each_slave(bond, slave, i) { ++ if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { ++ old_active = bond->curr_active_slave; ++ new_active = slave; ++ if (new_active == old_active) { ++ /* do nothing */ ++ pr_info("%s: %s is already the current" ++ " active slave.\n", ++ bond->dev->name, ++ slave->dev->name); ++ goto out; ++ } ++ else { ++ if ((new_active) && ++ (old_active) && ++ (new_active->link == BOND_LINK_UP) && ++ IS_UP(new_active->dev)) { ++ pr_info("%s: Setting %s as active" ++ " slave.\n", + bond->dev->name, + slave->dev->name); +- goto out; ++ bond_change_active_slave(bond, ++ new_active); + } + else { +- if ((new_active) && +- (old_active) && +- (new_active->link == BOND_LINK_UP) && +- IS_UP(new_active->dev)) { +- pr_info("%s: Setting %s as active slave.\n", +- bond->dev->name, +- slave->dev->name); +- bond_change_active_slave(bond, new_active); +- } +- else { +- pr_info("%s: Could not set %s as active slave; either %s is down or the link is down.\n", +- bond->dev->name, +- slave->dev->name, +- slave->dev->name); +- } +- goto out; ++ pr_info("%s: Could not set %s as" ++ " active slave; either %s is" ++ " down or the link is down.\n", ++ bond->dev->name, ++ slave->dev->name, ++ slave->dev->name); + } ++ goto out; + } + } +- +- /* if we got here, then we didn't match the name of any slave */ +- +- if (strlen(buf) == 0 || buf[0] == '\n') { +- pr_info("%s: Setting active slave to None.\n", +- bond->dev->name); +- bond->primary_slave = NULL; +- bond_select_active_slave(bond); +- } else { +- pr_info("%s: Unable to set %.*s as active slave as it is not a slave.\n", +- bond->dev->name, (int)strlen(buf) - 1, buf); +- } + } ++ ++ pr_info("%s: Unable to set %.*s as active slave.\n", ++ bond->dev->name, (int)strlen(buf) - 1, buf); + out: + write_unlock_bh(&bond->curr_slave_lock); + read_unlock(&bond->lock); +diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c +index dd8ab05..8d28602 100644 +--- a/drivers/net/e1000e/lib.c ++++ b/drivers/net/e1000e/lib.c +@@ -190,7 +190,8 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) + /* Check for LOM (vs. NIC) or one of two valid mezzanine cards */ + if (!((nvm_data & NVM_COMPAT_LOM) || + (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_DUAL) || +- (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD))) ++ (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD) || ++ (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES))) + goto out; + + ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, +diff --git a/drivers/net/gianfar_ptp.c b/drivers/net/gianfar_ptp.c +index d8e1753..c413479 100644 +--- a/drivers/net/gianfar_ptp.c ++++ b/drivers/net/gianfar_ptp.c +@@ -193,14 +193,9 @@ static void set_alarm(struct etsects *etsects) + /* Caller must hold etsects->lock. */ + static void set_fipers(struct etsects *etsects) + { +- u32 tmr_ctrl = gfar_read(&etsects->regs->tmr_ctrl); +- +- gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl & (~TE)); +- gfar_write(&etsects->regs->tmr_prsc, etsects->tmr_prsc); ++ set_alarm(etsects); + gfar_write(&etsects->regs->tmr_fiper1, etsects->tmr_fiper1); + gfar_write(&etsects->regs->tmr_fiper2, etsects->tmr_fiper2); +- set_alarm(etsects); +- gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl|TE); + } + + /* +@@ -511,7 +506,7 @@ static int gianfar_ptp_probe(struct platform_device *dev) + gfar_write(&etsects->regs->tmr_fiper1, etsects->tmr_fiper1); + gfar_write(&etsects->regs->tmr_fiper2, etsects->tmr_fiper2); + set_alarm(etsects); +- gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl|FS|RTPE|TE); ++ gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl|FS|RTPE|TE|FRD); + + spin_unlock_irqrestore(&etsects->lock, flags); + +diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c +index 4fecaed..2b98461 100644 +--- a/drivers/net/ifb.c ++++ b/drivers/net/ifb.c +@@ -145,7 +145,7 @@ static void ifb_setup(struct net_device *dev) + + dev->flags |= IFF_NOARP; + dev->flags &= ~IFF_MULTICAST; +- dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; ++ dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); + random_ether_addr(dev->dev_addr); + } + +diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c +index d6aeaa5..2f3c48d 100644 +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -547,7 +547,7 @@ void macvlan_common_setup(struct net_device *dev) + { + ether_setup(dev); + +- dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; ++ dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); + dev->netdev_ops = &macvlan_netdev_ops; + dev->destructor = free_netdev; + dev->header_ops = &macvlan_hard_header_ops, +diff --git a/drivers/net/niu.c b/drivers/net/niu.c +index cc25bff..2f8c351 100644 +--- a/drivers/net/niu.c ++++ b/drivers/net/niu.c +@@ -9196,7 +9196,7 @@ static int __devinit niu_ldg_init(struct niu *np) + + first_chan = 0; + for (i = 0; i < port; i++) +- first_chan += parent->rxchan_per_port[port]; ++ first_chan += parent->rxchan_per_port[i]; + num_chan = parent->rxchan_per_port[port]; + + for (i = first_chan; i < (first_chan + num_chan); i++) { +@@ -9212,7 +9212,7 @@ static int __devinit niu_ldg_init(struct niu *np) + + first_chan = 0; + for (i = 0; i < port; i++) +- first_chan += parent->txchan_per_port[port]; ++ first_chan += parent->txchan_per_port[i]; + num_chan = parent->txchan_per_port[port]; + for (i = first_chan; i < (first_chan + num_chan); i++) { + err = niu_ldg_assign_ldn(np, parent, +diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c +index 2cd8dc5..cb6e0b4 100644 +--- a/drivers/net/phy/dp83640.c ++++ b/drivers/net/phy/dp83640.c +@@ -34,8 +34,7 @@ + #define PAGESEL 0x13 + #define LAYER4 0x02 + #define LAYER2 0x01 +-#define MAX_RXTS 4 +-#define MAX_TXTS 4 ++#define MAX_RXTS 64 + #define N_EXT_TS 1 + #define PSF_PTPVER 2 + #define PSF_EVNT 0x4000 +@@ -218,7 +217,7 @@ static void phy2rxts(struct phy_rxts *p, struct rxts *rxts) + rxts->seqid = p->seqid; + rxts->msgtype = (p->msgtype >> 12) & 0xf; + rxts->hash = p->msgtype & 0x0fff; +- rxts->tmo = jiffies + HZ; ++ rxts->tmo = jiffies + 2; + } + + static u64 phy2txts(struct phy_txts *p) +diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c +index 5990621..5f838ef 100644 +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -236,6 +236,7 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_1 }, + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, + { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, ++ { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4302), 0, 0, RTL_CFG_0 }, + { PCI_DEVICE(PCI_VENDOR_ID_AT, 0xc107), 0, 0, RTL_CFG_0 }, + { PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 }, + { PCI_VENDOR_ID_LINKSYS, 0x1032, +diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c +index b436e00..f6d26ab 100644 +--- a/drivers/net/sis190.c ++++ b/drivers/net/sis190.c +@@ -1824,6 +1824,16 @@ static int sis190_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) + generic_mii_ioctl(&tp->mii_if, if_mii(ifr), cmd, NULL); + } + ++static int sis190_mac_addr(struct net_device *dev, void *p) ++{ ++ int rc; ++ ++ rc = eth_mac_addr(dev, p); ++ if (!rc) ++ sis190_init_rxfilter(dev); ++ return rc; ++} ++ + static const struct net_device_ops sis190_netdev_ops = { + .ndo_open = sis190_open, + .ndo_stop = sis190_close, +@@ -1832,7 +1842,7 @@ static const struct net_device_ops sis190_netdev_ops = { + .ndo_tx_timeout = sis190_tx_timeout, + .ndo_set_multicast_list = sis190_set_rx_mode, + .ndo_change_mtu = eth_change_mtu, +- .ndo_set_mac_address = eth_mac_addr, ++ .ndo_set_mac_address = sis190_mac_addr, + .ndo_validate_addr = eth_validate_addr, + #ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = sis190_netpoll, +diff --git a/drivers/net/tun.c b/drivers/net/tun.c +index 5235f48..fb50e5a 100644 +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -528,6 +528,7 @@ static void tun_net_init(struct net_device *dev) + dev->netdev_ops = &tap_netdev_ops; + /* Ethernet TAP Device */ + ether_setup(dev); ++ dev->priv_flags &= ~IFF_TX_SKB_SHARING; + + random_ether_addr(dev->dev_addr); + +diff --git a/drivers/net/veth.c b/drivers/net/veth.c +index 8461576..4bf7c6d 100644 +--- a/drivers/net/veth.c ++++ b/drivers/net/veth.c +@@ -262,6 +262,8 @@ static void veth_setup(struct net_device *dev) + { + ether_setup(dev); + ++ dev->priv_flags &= ~IFF_TX_SKB_SHARING; ++ + dev->netdev_ops = &veth_netdev_ops; + dev->ethtool_ops = &veth_ethtool_ops; + dev->features |= NETIF_F_LLTX; +diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c +index fc433f2..13f9997 100644 +--- a/drivers/net/wan/hdlc_fr.c ++++ b/drivers/net/wan/hdlc_fr.c +@@ -1083,9 +1083,10 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type) + + used = pvc_is_used(pvc); + +- if (type == ARPHRD_ETHER) ++ if (type == ARPHRD_ETHER) { + dev = alloc_netdev(0, "pvceth%d", ether_setup); +- else ++ dev->priv_flags &= ~IFF_TX_SKB_SHARING; ++ } else + dev = alloc_netdev(0, "pvc%d", pvc_setup); + + if (!dev) { +diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c +index 55cf71f..e1b3e3c 100644 +--- a/drivers/net/wireless/airo.c ++++ b/drivers/net/wireless/airo.c +@@ -2823,6 +2823,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, + dev->wireless_data = &ai->wireless_data; + dev->irq = irq; + dev->base_addr = port; ++ dev->priv_flags &= ~IFF_TX_SKB_SHARING; + + SET_NETDEV_DEV(dev, dmdev); + +diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c +index f344cc2..c32f9d1 100644 +--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c ++++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c +@@ -309,11 +309,7 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, + u8 i; + u32 val; + +- if (ah->is_pciexpress != true) +- return; +- +- /* Do not touch SerDes registers */ +- if (ah->config.pcie_powersave_enable == 2) ++ if (ah->is_pciexpress != true || ah->aspm_enabled != true) + return; + + /* Nothing to do on restore for 11N */ +diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +index ff8150e..7e07f0f 100644 +--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +@@ -306,7 +306,7 @@ static const struct ar9300_eeprom ar9300_default = { + { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, + +- { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, ++ { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, + +@@ -883,7 +883,7 @@ static const struct ar9300_eeprom ar9300_x113 = { + { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, + +- { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, ++ { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, + +@@ -2039,7 +2039,7 @@ static const struct ar9300_eeprom ar9300_x112 = { + { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, + +- { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, ++ { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, + +diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c +index 392bf0f..7e02fb4 100644 +--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c +@@ -351,11 +351,7 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah, + int restore, + int power_off) + { +- if (ah->is_pciexpress != true) +- return; +- +- /* Do not touch SerDes registers */ +- if (ah->config.pcie_powersave_enable == 2) ++ if (ah->is_pciexpress != true || ah->aspm_enabled != true) + return; + + /* Nothing to do on restore for 11N */ +diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h +index 443090d..efdbe98 100644 +--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h ++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h +@@ -848,7 +848,7 @@ + #define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220) + #define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + 0x240) + #define AR_PHY_TX_IQCAL_STATUS_B1 (AR_SM1_BASE + 0x48c) +-#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i) (AR_SM_BASE + 0x450 + ((_i) << 2)) ++#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i) (AR_SM1_BASE + 0x450 + ((_i) << 2)) + + /* + * Channel 2 Register Map +diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c +index 1be7c8b..03900ca 100644 +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -299,6 +299,14 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah) + REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); + } + ++static void ath9k_hw_aspm_init(struct ath_hw *ah) ++{ ++ struct ath_common *common = ath9k_hw_common(ah); ++ ++ if (common->bus_ops->aspm_init) ++ common->bus_ops->aspm_init(common); ++} ++ + /* This should work for all families including legacy */ + static bool ath9k_hw_chip_test(struct ath_hw *ah) + { +@@ -359,7 +367,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) + ah->config.additional_swba_backoff = 0; + ah->config.ack_6mb = 0x0; + ah->config.cwm_ignore_extcca = 0; +- ah->config.pcie_powersave_enable = 0; + ah->config.pcie_clock_req = 0; + ah->config.pcie_waen = 0; + ah->config.analog_shiftreg = 1; +@@ -577,7 +584,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) + + + if (ah->is_pciexpress) +- ath9k_hw_configpcipowersave(ah, 0, 0); ++ ath9k_hw_aspm_init(ah); + else + ath9k_hw_disablepcie(ah); + +diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h +index 4b157c5..939cc9d 100644 +--- a/drivers/net/wireless/ath/ath9k/hw.h ++++ b/drivers/net/wireless/ath/ath9k/hw.h +@@ -215,7 +215,6 @@ struct ath9k_ops_config { + int additional_swba_backoff; + int ack_6mb; + u32 cwm_ignore_extcca; +- u8 pcie_powersave_enable; + bool pcieSerDesWrite; + u8 pcie_clock_req; + u32 pcie_waen; +@@ -671,6 +670,7 @@ struct ath_hw { + + bool sw_mgmt_crypto; + bool is_pciexpress; ++ bool aspm_enabled; + bool is_monitoring; + bool need_an_top2_fixup; + u16 tx_trig_level; +@@ -870,6 +870,7 @@ struct ath_bus_ops { + bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); + void (*bt_coex_prep)(struct ath_common *common); + void (*extn_synch_en)(struct ath_common *common); ++ void (*aspm_init)(struct ath_common *common); + }; + + static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) +diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c +index 45c585a..5a9fd21 100644 +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -665,8 +665,10 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band) + static void ath9k_init_txpower_limits(struct ath_softc *sc) + { + struct ath_hw *ah = sc->sc_ah; ++ struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath9k_channel *curchan = ah->curchan; + ++ ah->txchainmask = common->tx_chainmask; + if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) + ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ); + if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) +diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c +index 3bad0b2..be4ea13 100644 +--- a/drivers/net/wireless/ath/ath9k/pci.c ++++ b/drivers/net/wireless/ath/ath9k/pci.c +@@ -16,6 +16,7 @@ + + #include + #include ++#include + #include + #include "ath9k.h" + +@@ -115,12 +116,38 @@ static void ath_pci_extn_synch_enable(struct ath_common *common) + pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl); + } + ++static void ath_pci_aspm_init(struct ath_common *common) ++{ ++ struct ath_softc *sc = (struct ath_softc *) common->priv; ++ struct ath_hw *ah = sc->sc_ah; ++ struct pci_dev *pdev = to_pci_dev(sc->dev); ++ struct pci_dev *parent; ++ int pos; ++ u8 aspm; ++ ++ if (!pci_is_pcie(pdev)) ++ return; ++ ++ parent = pdev->bus->self; ++ if (WARN_ON(!parent)) ++ return; ++ ++ pos = pci_pcie_cap(parent); ++ pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm); ++ if (aspm & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) { ++ ah->aspm_enabled = true; ++ /* Initialize PCIe PM and SERDES registers. */ ++ ath9k_hw_configpcipowersave(ah, 0, 0); ++ } ++} ++ + static const struct ath_bus_ops ath_pci_bus_ops = { + .ath_bus_type = ATH_PCI, + .read_cachesize = ath_pci_read_cachesize, + .eeprom_read = ath_pci_eeprom_read, + .bt_coex_prep = ath_pci_bt_coex_prep, + .extn_synch_en = ath_pci_extn_synch_enable, ++ .aspm_init = ath_pci_aspm_init, + }; + + static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c +index d508482..89a116f 100644 +--- a/drivers/net/wireless/hostap/hostap_main.c ++++ b/drivers/net/wireless/hostap/hostap_main.c +@@ -855,6 +855,7 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local, + + iface = netdev_priv(dev); + ether_setup(dev); ++ dev->priv_flags &= ~IFF_TX_SKB_SHARING; + + /* kernel callbacks */ + if (iface) { +diff --git a/drivers/net/wireless/iwlegacy/iwl-3945.c b/drivers/net/wireless/iwlegacy/iwl-3945.c +index d096dc2..dcc1552 100644 +--- a/drivers/net/wireless/iwlegacy/iwl-3945.c ++++ b/drivers/net/wireless/iwlegacy/iwl-3945.c +@@ -1747,7 +1747,11 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) + } + + memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); +- ++ /* ++ * We do not commit tx power settings while channel changing, ++ * do it now if tx power changed. ++ */ ++ iwl_legacy_set_tx_power(priv, priv->tx_power_next, false); + return 0; + } + +diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c +index facc94e..0a1babb 100644 +--- a/drivers/net/wireless/iwlegacy/iwl-4965.c ++++ b/drivers/net/wireless/iwlegacy/iwl-4965.c +@@ -1237,7 +1237,12 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c + + memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); + iwl_legacy_print_rx_config_cmd(priv, ctx); +- goto set_tx_power; ++ /* ++ * We do not commit tx power settings while channel changing, ++ * do it now if tx power changed. ++ */ ++ iwl_legacy_set_tx_power(priv, priv->tx_power_next, false); ++ return 0; + } + + /* If we are currently associated and the new config requires +@@ -1317,7 +1322,6 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c + + iwl4965_init_sensitivity(priv); + +-set_tx_power: + /* If we issue a new RXON command which required a tune then we must + * send a new TXPOWER command or we won't be able to Tx any frames */ + ret = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true); +diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c +index e816c27..f1c3f49 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-5000.c ++++ b/drivers/net/wireless/iwlwifi/iwl-5000.c +@@ -421,6 +421,7 @@ static struct iwl_base_params iwl5000_base_params = { + .chain_noise_scale = 1000, + .wd_timeout = IWL_LONG_WD_TIMEOUT, + .max_event_log_size = 512, ++ .no_idle_support = true, + }; + static struct iwl_ht_params iwl5000_ht_params = { + .ht_greenfield_support = true, +diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h +index a54d416..b76996a 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-core.h ++++ b/drivers/net/wireless/iwlwifi/iwl-core.h +@@ -195,6 +195,7 @@ struct iwl_mod_params { + * @temperature_kelvin: temperature report by uCode in kelvin + * @max_event_log_size: size of event log buffer size for ucode event logging + * @shadow_reg_enable: HW shadhow register bit ++ * @no_idle_support: do not support idle mode + */ + struct iwl_base_params { + int eeprom_size; +@@ -216,6 +217,7 @@ struct iwl_base_params { + bool temperature_kelvin; + u32 max_event_log_size; + const bool shadow_reg_enable; ++ const bool no_idle_support; + }; + /* + * @advanced_bt_coexist: support advanced bt coexist +diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c +index 595c930..4a05a6a 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-power.c ++++ b/drivers/net/wireless/iwlwifi/iwl-power.c +@@ -355,7 +355,8 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, + + dtimper = priv->hw->conf.ps_dtim_period ?: 1; + +- if (priv->hw->conf.flags & IEEE80211_CONF_IDLE) ++ if (!priv->cfg->base_params->no_idle_support && ++ priv->hw->conf.flags & IEEE80211_CONF_IDLE) + iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); + else if (iwl_tt_is_low_power_state(priv)) { + /* in thermal throttling low power state */ +diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c +index 2a6aa85..5a45228 100644 +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c +@@ -784,8 +784,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) + /* + * Add space for the TXWI in front of the skb. + */ +- skb_push(entry->skb, TXWI_DESC_SIZE); +- memset(entry->skb, 0, TXWI_DESC_SIZE); ++ memset(skb_push(entry->skb, TXWI_DESC_SIZE), 0, TXWI_DESC_SIZE); + + /* + * Register descriptor details in skb frame descriptor. +diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c +index 93bec14..a76fdbe 100644 +--- a/drivers/net/wireless/rt2x00/rt2x00mac.c ++++ b/drivers/net/wireless/rt2x00/rt2x00mac.c +@@ -113,7 +113,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) + * due to possible race conditions in mac80211. + */ + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) +- goto exit_fail; ++ goto exit_free_skb; + + /* + * Use the ATIM queue if appropriate and present. +@@ -127,7 +127,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) + ERROR(rt2x00dev, + "Attempt to send packet over invalid queue %d.\n" + "Please file bug report to %s.\n", qid, DRV_PROJECT); +- goto exit_fail; ++ goto exit_free_skb; + } + + /* +@@ -159,6 +159,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) + + exit_fail: + rt2x00queue_pause_queue(queue); ++ exit_free_skb: + dev_kfree_skb_any(skb); + } + EXPORT_SYMBOL_GPL(rt2x00mac_tx); +diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c +index 254b64b..c872a23 100644 +--- a/drivers/net/wireless/rtlwifi/pci.c ++++ b/drivers/net/wireless/rtlwifi/pci.c +@@ -1709,15 +1709,17 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, + pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn); + pcipriv->ndis_adapter.funcnumber = PCI_FUNC(pdev->devfn); + +- /*find bridge info */ +- pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor; +- for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { +- if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { +- pcipriv->ndis_adapter.pcibridge_vendor = tmp; +- RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, +- ("Pci Bridge Vendor is found index: %d\n", +- tmp)); +- break; ++ if (bridge_pdev) { ++ /*find bridge info if available */ ++ pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor; ++ for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { ++ if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { ++ pcipriv->ndis_adapter.pcibridge_vendor = tmp; ++ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ++ ("Pci Bridge Vendor is found index:" ++ " %d\n", tmp)); ++ break; ++ } + } + } + +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index 3c7857c..e1678b9 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -797,8 +797,8 @@ exit: + * Hwmon device + */ + static ssize_t asus_hwmon_pwm1(struct device *dev, +- struct device_attribute *attr, +- char *buf) ++ struct device_attribute *attr, ++ char *buf) + { + struct asus_wmi *asus = dev_get_drvdata(dev); + u32 value; +@@ -809,7 +809,7 @@ static ssize_t asus_hwmon_pwm1(struct device *dev, + if (err < 0) + return err; + +- value |= 0xFF; ++ value &= 0xFF; + + if (value == 1) /* Low Speed */ + value = 85; +@@ -869,7 +869,7 @@ static mode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj, + * - reverved bits are non-zero + * - sfun and presence bit are not set + */ +- if (value != ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000 ++ if (value == ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000 + || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT))) + ok = false; + } +@@ -904,6 +904,7 @@ static int asus_wmi_hwmon_init(struct asus_wmi *asus) + pr_err("Could not register asus hwmon device\n"); + return PTR_ERR(hwmon); + } ++ dev_set_drvdata(hwmon, asus); + asus->hwmon_device = hwmon; + result = sysfs_create_group(&hwmon->kobj, &hwmon_attribute_group); + if (result) +@@ -1164,14 +1165,18 @@ ASUS_WMI_CREATE_DEVICE_ATTR(cardr, 0644, ASUS_WMI_DEVID_CARDREADER); + static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) + { +- int value; ++ int value, rv; + + if (!count || sscanf(buf, "%i", &value) != 1) + return -EINVAL; + if (value < 0 || value > 2) + return -EINVAL; + +- return asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL); ++ rv = asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL); ++ if (rv < 0) ++ return rv; ++ ++ return count; + } + + static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv); +diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c +index efa0255..1da606c 100644 +--- a/drivers/scsi/mpt2sas/mpt2sas_base.c ++++ b/drivers/scsi/mpt2sas/mpt2sas_base.c +@@ -94,7 +94,7 @@ module_param(diag_buffer_enable, int, 0); + MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers " + "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)"); + +-int mpt2sas_fwfault_debug; ++static int mpt2sas_fwfault_debug; + MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault " + "and halt firmware - (default=0)"); + +@@ -857,7 +857,7 @@ _base_interrupt(int irq, void *bus_id) + completed_cmds = 0; + cb_idx = 0xFF; + do { +- rd.word = rpf->Words; ++ rd.word = le64_to_cpu(rpf->Words); + if (rd.u.low == UINT_MAX || rd.u.high == UINT_MAX) + goto out; + reply = 0; +@@ -906,7 +906,7 @@ _base_interrupt(int irq, void *bus_id) + + next: + +- rpf->Words = ULLONG_MAX; ++ rpf->Words = cpu_to_le64(ULLONG_MAX); + ioc->reply_post_host_index = (ioc->reply_post_host_index == + (ioc->reply_post_queue_depth - 1)) ? 0 : + ioc->reply_post_host_index + 1; +@@ -1817,7 +1817,9 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc) + char desc[16]; + u8 revision; + u32 iounit_pg1_flags; ++ u32 bios_version; + ++ bios_version = le32_to_cpu(ioc->bios_pg3.BiosVersion); + pci_read_config_byte(ioc->pdev, PCI_CLASS_REVISION, &revision); + strncpy(desc, ioc->manu_pg0.ChipName, 16); + printk(MPT2SAS_INFO_FMT "%s: FWVersion(%02d.%02d.%02d.%02d), " +@@ -1828,10 +1830,10 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc) + (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8, + ioc->facts.FWVersion.Word & 0x000000FF, + revision, +- (ioc->bios_pg3.BiosVersion & 0xFF000000) >> 24, +- (ioc->bios_pg3.BiosVersion & 0x00FF0000) >> 16, +- (ioc->bios_pg3.BiosVersion & 0x0000FF00) >> 8, +- ioc->bios_pg3.BiosVersion & 0x000000FF); ++ (bios_version & 0xFF000000) >> 24, ++ (bios_version & 0x00FF0000) >> 16, ++ (bios_version & 0x0000FF00) >> 8, ++ bios_version & 0x000000FF); + + _base_display_dell_branding(ioc); + _base_display_intel_branding(ioc); +@@ -2150,7 +2152,7 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc) + static int + _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) + { +- Mpi2IOCFactsReply_t *facts; ++ struct mpt2sas_facts *facts; + u32 queue_size, queue_diff; + u16 max_sge_elements; + u16 num_of_reply_frames; +@@ -2783,7 +2785,7 @@ _base_handshake_req_reply_wait(struct MPT2SAS_ADAPTER *ioc, int request_bytes, + int i; + u8 failed; + u16 dummy; +- u32 *mfp; ++ __le32 *mfp; + + /* make sure doorbell is not in use */ + if ((readl(&ioc->chip->Doorbell) & MPI2_DOORBELL_USED)) { +@@ -2871,7 +2873,7 @@ _base_handshake_req_reply_wait(struct MPT2SAS_ADAPTER *ioc, int request_bytes, + writel(0, &ioc->chip->HostInterruptStatus); + + if (ioc->logging_level & MPT_DEBUG_INIT) { +- mfp = (u32 *)reply; ++ mfp = (__le32 *)reply; + printk(KERN_INFO "\toffset:data\n"); + for (i = 0; i < reply_bytes/4; i++) + printk(KERN_INFO "\t[0x%02x]:%08x\n", i*4, +@@ -3097,7 +3099,8 @@ static int + _base_get_port_facts(struct MPT2SAS_ADAPTER *ioc, int port, int sleep_flag) + { + Mpi2PortFactsRequest_t mpi_request; +- Mpi2PortFactsReply_t mpi_reply, *pfacts; ++ Mpi2PortFactsReply_t mpi_reply; ++ struct mpt2sas_port_facts *pfacts; + int mpi_reply_sz, mpi_request_sz, r; + + dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, +@@ -3139,7 +3142,8 @@ static int + _base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) + { + Mpi2IOCFactsRequest_t mpi_request; +- Mpi2IOCFactsReply_t mpi_reply, *facts; ++ Mpi2IOCFactsReply_t mpi_reply; ++ struct mpt2sas_facts *facts; + int mpi_reply_sz, mpi_request_sz, r; + + dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, +@@ -3225,17 +3229,6 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) + mpi_request.MsgVersion = cpu_to_le16(MPI2_VERSION); + mpi_request.HeaderVersion = cpu_to_le16(MPI2_HEADER_VERSION); + +- /* In MPI Revision I (0xA), the SystemReplyFrameSize(offset 0x18) was +- * removed and made reserved. For those with older firmware will need +- * this fix. It was decided that the Reply and Request frame sizes are +- * the same. +- */ +- if ((ioc->facts.HeaderVersion >> 8) < 0xA) { +- mpi_request.Reserved7 = cpu_to_le16(ioc->reply_sz); +-/* mpi_request.SystemReplyFrameSize = +- * cpu_to_le16(ioc->reply_sz); +- */ +- } + + mpi_request.SystemRequestFrameSize = cpu_to_le16(ioc->request_sz/4); + mpi_request.ReplyDescriptorPostQueueDepth = +@@ -3243,25 +3236,17 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) + mpi_request.ReplyFreeQueueDepth = + cpu_to_le16(ioc->reply_free_queue_depth); + +-#if BITS_PER_LONG > 32 + mpi_request.SenseBufferAddressHigh = +- cpu_to_le32(ioc->sense_dma >> 32); ++ cpu_to_le32((u64)ioc->sense_dma >> 32); + mpi_request.SystemReplyAddressHigh = +- cpu_to_le32(ioc->reply_dma >> 32); ++ cpu_to_le32((u64)ioc->reply_dma >> 32); + mpi_request.SystemRequestFrameBaseAddress = +- cpu_to_le64(ioc->request_dma); ++ cpu_to_le64((u64)ioc->request_dma); + mpi_request.ReplyFreeQueueAddress = +- cpu_to_le64(ioc->reply_free_dma); ++ cpu_to_le64((u64)ioc->reply_free_dma); + mpi_request.ReplyDescriptorPostQueueAddress = +- cpu_to_le64(ioc->reply_post_free_dma); +-#else +- mpi_request.SystemRequestFrameBaseAddress = +- cpu_to_le32(ioc->request_dma); +- mpi_request.ReplyFreeQueueAddress = +- cpu_to_le32(ioc->reply_free_dma); +- mpi_request.ReplyDescriptorPostQueueAddress = +- cpu_to_le32(ioc->reply_post_free_dma); +-#endif ++ cpu_to_le64((u64)ioc->reply_post_free_dma); ++ + + /* This time stamp specifies number of milliseconds + * since epoch ~ midnight January 1, 1970. +@@ -3271,10 +3256,10 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) + (current_time.tv_usec / 1000)); + + if (ioc->logging_level & MPT_DEBUG_INIT) { +- u32 *mfp; ++ __le32 *mfp; + int i; + +- mfp = (u32 *)&mpi_request; ++ mfp = (__le32 *)&mpi_request; + printk(KERN_INFO "\toffset:data\n"); + for (i = 0; i < sizeof(Mpi2IOCInitRequest_t)/4; i++) + printk(KERN_INFO "\t[0x%02x]:%08x\n", i*4, +@@ -3759,7 +3744,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) + + /* initialize Reply Post Free Queue */ + for (i = 0; i < ioc->reply_post_queue_depth; i++) +- ioc->reply_post_free[i].Words = ULLONG_MAX; ++ ioc->reply_post_free[i].Words = cpu_to_le64(ULLONG_MAX); + + r = _base_send_ioc_init(ioc, sleep_flag); + if (r) +diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h +index dcc289c..451dc1c 100644 +--- a/drivers/scsi/mpt2sas/mpt2sas_base.h ++++ b/drivers/scsi/mpt2sas/mpt2sas_base.h +@@ -541,6 +541,53 @@ struct _tr_list { + + typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr); + ++/* IOC Facts and Port Facts converted from little endian to cpu */ ++union mpi2_version_union { ++ MPI2_VERSION_STRUCT Struct; ++ u32 Word; ++}; ++ ++struct mpt2sas_facts { ++ u16 MsgVersion; ++ u16 HeaderVersion; ++ u8 IOCNumber; ++ u8 VP_ID; ++ u8 VF_ID; ++ u16 IOCExceptions; ++ u16 IOCStatus; ++ u32 IOCLogInfo; ++ u8 MaxChainDepth; ++ u8 WhoInit; ++ u8 NumberOfPorts; ++ u8 MaxMSIxVectors; ++ u16 RequestCredit; ++ u16 ProductID; ++ u32 IOCCapabilities; ++ union mpi2_version_union FWVersion; ++ u16 IOCRequestFrameSize; ++ u16 Reserved3; ++ u16 MaxInitiators; ++ u16 MaxTargets; ++ u16 MaxSasExpanders; ++ u16 MaxEnclosures; ++ u16 ProtocolFlags; ++ u16 HighPriorityCredit; ++ u16 MaxReplyDescriptorPostQueueDepth; ++ u8 ReplyFrameSize; ++ u8 MaxVolumes; ++ u16 MaxDevHandle; ++ u16 MaxPersistentEntries; ++ u16 MinDevHandle; ++}; ++ ++struct mpt2sas_port_facts { ++ u8 PortNumber; ++ u8 VP_ID; ++ u8 VF_ID; ++ u8 PortType; ++ u16 MaxPostedCmdBuffers; ++}; ++ + /** + * struct MPT2SAS_ADAPTER - per adapter struct + * @list: ioc_list +@@ -749,8 +796,8 @@ struct MPT2SAS_ADAPTER { + u32 event_masks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS]; + + /* static config pages */ +- Mpi2IOCFactsReply_t facts; +- Mpi2PortFactsReply_t *pfacts; ++ struct mpt2sas_facts facts; ++ struct mpt2sas_port_facts *pfacts; + Mpi2ManufacturingPage0_t manu_pg0; + Mpi2BiosPage2_t bios_pg2; + Mpi2BiosPage3_t bios_pg3; +@@ -840,7 +887,7 @@ struct MPT2SAS_ADAPTER { + + /* reply free queue */ + u16 reply_free_queue_depth; +- u32 *reply_free; ++ __le32 *reply_free; + dma_addr_t reply_free_dma; + struct dma_pool *reply_free_dma_pool; + u32 reply_free_host_index; +diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c +index 437c2d9..d1c3bba 100644 +--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c ++++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c +@@ -2706,13 +2706,13 @@ static DEVICE_ATTR(ioc_reset_count, S_IRUGO, + _ctl_ioc_reset_count_show, NULL); + + struct DIAG_BUFFER_START { +- u32 Size; +- u32 DiagVersion; ++ __le32 Size; ++ __le32 DiagVersion; + u8 BufferType; + u8 Reserved[3]; +- u32 Reserved1; +- u32 Reserved2; +- u32 Reserved3; ++ __le32 Reserved1; ++ __le32 Reserved2; ++ __le32 Reserved3; + }; + /** + * _ctl_host_trace_buffer_size_show - host buffer size (trace only) +diff --git a/drivers/scsi/mpt2sas/mpt2sas_debug.h b/drivers/scsi/mpt2sas/mpt2sas_debug.h +index 3dcddfe..9731f8e 100644 +--- a/drivers/scsi/mpt2sas/mpt2sas_debug.h ++++ b/drivers/scsi/mpt2sas/mpt2sas_debug.h +@@ -164,7 +164,7 @@ static inline void + _debug_dump_mf(void *mpi_request, int sz) + { + int i; +- u32 *mfp = (u32 *)mpi_request; ++ __le32 *mfp = (__le32 *)mpi_request; + + printk(KERN_INFO "mf:\n\t"); + for (i = 0; i < sz; i++) { +diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c +index a7dbc68..e327a3c 100644 +--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c ++++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c +@@ -1956,7 +1956,7 @@ _scsih_slave_configure(struct scsi_device *sdev) + case MPI2_RAID_VOL_TYPE_RAID1E: + qdepth = MPT2SAS_RAID_QUEUE_DEPTH; + if (ioc->manu_pg10.OEMIdentifier && +- (ioc->manu_pg10.GenericFlags0 & ++ (le32_to_cpu(ioc->manu_pg10.GenericFlags0) & + MFG10_GF0_R10_DISPLAY) && + !(raid_device->num_pds % 2)) + r_level = "RAID10"; +@@ -4598,7 +4598,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) + Mpi2SasEnclosurePage0_t enclosure_pg0; + u32 ioc_status; + u16 parent_handle; +- __le64 sas_address, sas_address_parent = 0; ++ u64 sas_address, sas_address_parent = 0; + int i; + unsigned long flags; + struct _sas_port *mpt2sas_port = NULL; +@@ -5404,7 +5404,7 @@ _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc, + { + struct MPT2SAS_TARGET *target_priv_data; + struct _sas_device *sas_device; +- __le64 sas_address; ++ u64 sas_address; + unsigned long flags; + Mpi2EventDataSasDeviceStatusChange_t *event_data = + fw_event->event_data; +@@ -6566,7 +6566,7 @@ _scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc) + Mpi2ExpanderPage0_t expander_pg0; + Mpi2ConfigReply_t mpi_reply; + u16 ioc_status; +- __le64 sas_address; ++ u64 sas_address; + u16 handle; + + printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__); +@@ -7505,7 +7505,7 @@ _scsih_suspend(struct pci_dev *pdev, pm_message_t state) + { + struct Scsi_Host *shost = pci_get_drvdata(pdev); + struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); +- u32 device_state; ++ pci_power_t device_state; + + mpt2sas_base_stop_watchdog(ioc); + scsi_block_requests(shost); +@@ -7532,7 +7532,7 @@ _scsih_resume(struct pci_dev *pdev) + { + struct Scsi_Host *shost = pci_get_drvdata(pdev); + struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); +- u32 device_state = pdev->current_state; ++ pci_power_t device_state = pdev->current_state; + int r; + + printk(MPT2SAS_INFO_FMT "pdev=0x%p, slot=%s, previous " +diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c +index cb1cdec..15c7980 100644 +--- a/drivers/scsi/mpt2sas/mpt2sas_transport.c ++++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c +@@ -299,7 +299,6 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc, + void *data_out = NULL; + dma_addr_t data_out_dma; + u32 sz; +- u64 *sas_address_le; + u16 wait_state_count; + + if (ioc->shost_recovery || ioc->pci_error_recovery) { +@@ -372,8 +371,7 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc, + mpi_request->PhysicalPort = 0xFF; + mpi_request->VF_ID = 0; /* TODO */ + mpi_request->VP_ID = 0; +- sas_address_le = (u64 *)&mpi_request->SASAddress; +- *sas_address_le = cpu_to_le64(sas_address); ++ mpi_request->SASAddress = cpu_to_le64(sas_address); + mpi_request->RequestDataLength = + cpu_to_le16(sizeof(struct rep_manu_request)); + psge = &mpi_request->SGL; +@@ -1049,14 +1047,14 @@ struct phy_error_log_reply{ + u8 function; /* 0x11 */ + u8 function_result; + u8 response_length; +- u16 expander_change_count; ++ __be16 expander_change_count; + u8 reserved_1[3]; + u8 phy_identifier; + u8 reserved_2[2]; +- u32 invalid_dword; +- u32 running_disparity_error; +- u32 loss_of_dword_sync; +- u32 phy_reset_problem; ++ __be32 invalid_dword; ++ __be32 running_disparity_error; ++ __be32 loss_of_dword_sync; ++ __be32 phy_reset_problem; + }; + + /** +@@ -1085,7 +1083,6 @@ _transport_get_expander_phy_error_log(struct MPT2SAS_ADAPTER *ioc, + void *data_out = NULL; + dma_addr_t data_out_dma; + u32 sz; +- u64 *sas_address_le; + u16 wait_state_count; + + if (ioc->shost_recovery || ioc->pci_error_recovery) { +@@ -1160,8 +1157,7 @@ _transport_get_expander_phy_error_log(struct MPT2SAS_ADAPTER *ioc, + mpi_request->PhysicalPort = 0xFF; + mpi_request->VF_ID = 0; /* TODO */ + mpi_request->VP_ID = 0; +- sas_address_le = (u64 *)&mpi_request->SASAddress; +- *sas_address_le = cpu_to_le64(phy->identify.sas_address); ++ mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); + mpi_request->RequestDataLength = + cpu_to_le16(sizeof(struct phy_error_log_request)); + psge = &mpi_request->SGL; +@@ -1406,7 +1402,6 @@ _transport_expander_phy_control(struct MPT2SAS_ADAPTER *ioc, + void *data_out = NULL; + dma_addr_t data_out_dma; + u32 sz; +- u64 *sas_address_le; + u16 wait_state_count; + + if (ioc->shost_recovery) { +@@ -1486,8 +1481,7 @@ _transport_expander_phy_control(struct MPT2SAS_ADAPTER *ioc, + mpi_request->PhysicalPort = 0xFF; + mpi_request->VF_ID = 0; /* TODO */ + mpi_request->VP_ID = 0; +- sas_address_le = (u64 *)&mpi_request->SASAddress; +- *sas_address_le = cpu_to_le64(phy->identify.sas_address); ++ mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); + mpi_request->RequestDataLength = + cpu_to_le16(sizeof(struct phy_error_log_request)); + psge = &mpi_request->SGL; +@@ -1914,7 +1908,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, + mpi_request->PhysicalPort = 0xFF; + mpi_request->VF_ID = 0; /* TODO */ + mpi_request->VP_ID = 0; +- *((u64 *)&mpi_request->SASAddress) = (rphy) ? ++ mpi_request->SASAddress = (rphy) ? + cpu_to_le64(rphy->identify.sas_address) : + cpu_to_le64(ioc->sas_hba.sas_address); + mpi_request->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4); +diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c +index aa97efc..62487a7 100644 +--- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c ++++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c +@@ -6198,6 +6198,7 @@ int ar6000_create_ap_interface(struct ar6_softc *ar, char *ap_ifname) + + ether_setup(dev); + init_netdev(dev, ap_ifname); ++ dev->priv_flags &= ~IFF_TX_SKB_SHARING; + + if (register_netdev(dev)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: register_netdev failed\n")); +diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c +index bc4b12c..fc7e57b 100644 +--- a/fs/cifs/cifsfs.c ++++ b/fs/cifs/cifsfs.c +@@ -581,6 +581,10 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) + mutex_unlock(&dir->i_mutex); + dput(dentry); + dentry = child; ++ if (!dentry->d_inode) { ++ dput(dentry); ++ dentry = ERR_PTR(-ENOENT); ++ } + } while (!IS_ERR(dentry)); + _FreeXid(xid); + kfree(full_path); +diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c +index 9b018c8..a7b2dcd 100644 +--- a/fs/cifs/inode.c ++++ b/fs/cifs/inode.c +@@ -764,20 +764,10 @@ char *cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, + if (full_path == NULL) + return full_path; + +- if (dfsplen) { ++ if (dfsplen) + strncpy(full_path, tcon->treeName, dfsplen); +- /* switch slash direction in prepath depending on whether +- * windows or posix style path names +- */ +- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { +- int i; +- for (i = 0; i < dfsplen; i++) { +- if (full_path[i] == '\\') +- full_path[i] = '/'; +- } +- } +- } + strncpy(full_path + dfsplen, vol->prepath, pplen); ++ convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); + full_path[dfsplen + pplen] = 0; /* add trailing null */ + return full_path; + } +diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c +index 147aa22..c1b9c4b 100644 +--- a/fs/cifs/transport.c ++++ b/fs/cifs/transport.c +@@ -362,6 +362,8 @@ cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov, + mid = AllocMidQEntry(hdr, server); + if (mid == NULL) { + mutex_unlock(&server->srv_mutex); ++ atomic_dec(&server->inFlight); ++ wake_up(&server->request_q); + return -ENOMEM; + } + +diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c +index 9f1bb74..b4a6bef 100644 +--- a/fs/ecryptfs/main.c ++++ b/fs/ecryptfs/main.c +@@ -175,6 +175,7 @@ enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, + ecryptfs_opt_encrypted_view, ecryptfs_opt_fnek_sig, + ecryptfs_opt_fn_cipher, ecryptfs_opt_fn_cipher_key_bytes, + ecryptfs_opt_unlink_sigs, ecryptfs_opt_mount_auth_tok_only, ++ ecryptfs_opt_check_dev_ruid, + ecryptfs_opt_err }; + + static const match_table_t tokens = { +@@ -191,6 +192,7 @@ static const match_table_t tokens = { + {ecryptfs_opt_fn_cipher_key_bytes, "ecryptfs_fn_key_bytes=%u"}, + {ecryptfs_opt_unlink_sigs, "ecryptfs_unlink_sigs"}, + {ecryptfs_opt_mount_auth_tok_only, "ecryptfs_mount_auth_tok_only"}, ++ {ecryptfs_opt_check_dev_ruid, "ecryptfs_check_dev_ruid"}, + {ecryptfs_opt_err, NULL} + }; + +@@ -236,6 +238,7 @@ static void ecryptfs_init_mount_crypt_stat( + * ecryptfs_parse_options + * @sb: The ecryptfs super block + * @options: The options passed to the kernel ++ * @check_ruid: set to 1 if device uid should be checked against the ruid + * + * Parse mount options: + * debug=N - ecryptfs_verbosity level for debug output +@@ -251,7 +254,8 @@ static void ecryptfs_init_mount_crypt_stat( + * + * Returns zero on success; non-zero on error + */ +-static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) ++static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, ++ uid_t *check_ruid) + { + char *p; + int rc = 0; +@@ -276,6 +280,8 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) + char *cipher_key_bytes_src; + char *fn_cipher_key_bytes_src; + ++ *check_ruid = 0; ++ + if (!options) { + rc = -EINVAL; + goto out; +@@ -380,6 +386,9 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) + mount_crypt_stat->flags |= + ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY; + break; ++ case ecryptfs_opt_check_dev_ruid: ++ *check_ruid = 1; ++ break; + case ecryptfs_opt_err: + default: + printk(KERN_WARNING +@@ -475,6 +484,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags + const char *err = "Getting sb failed"; + struct inode *inode; + struct path path; ++ uid_t check_ruid; + int rc; + + sbi = kmem_cache_zalloc(ecryptfs_sb_info_cache, GFP_KERNEL); +@@ -483,7 +493,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags + goto out; + } + +- rc = ecryptfs_parse_options(sbi, raw_data); ++ rc = ecryptfs_parse_options(sbi, raw_data, &check_ruid); + if (rc) { + err = "Error parsing options"; + goto out; +@@ -521,6 +531,15 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags + "known incompatibilities\n"); + goto out_free; + } ++ ++ if (check_ruid && path.dentry->d_inode->i_uid != current_uid()) { ++ rc = -EPERM; ++ printk(KERN_ERR "Mount of device (uid: %d) not owned by " ++ "requested user (uid: %d)\n", ++ path.dentry->d_inode->i_uid, current_uid()); ++ goto out_free; ++ } ++ + ecryptfs_set_superblock_lower(s, path.dentry->d_sb); + s->s_maxbytes = path.dentry->d_sb->s_maxbytes; + s->s_blocksize = path.dentry->d_sb->s_blocksize; +diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c +index 85d4309..3745f7c 100644 +--- a/fs/ecryptfs/read_write.c ++++ b/fs/ecryptfs/read_write.c +@@ -39,15 +39,16 @@ + int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, + loff_t offset, size_t size) + { +- struct ecryptfs_inode_info *inode_info; ++ struct file *lower_file; + mm_segment_t fs_save; + ssize_t rc; + +- inode_info = ecryptfs_inode_to_private(ecryptfs_inode); +- BUG_ON(!inode_info->lower_file); ++ lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file; ++ if (!lower_file) ++ return -EIO; + fs_save = get_fs(); + set_fs(get_ds()); +- rc = vfs_write(inode_info->lower_file, data, size, &offset); ++ rc = vfs_write(lower_file, data, size, &offset); + set_fs(fs_save); + mark_inode_dirty_sync(ecryptfs_inode); + return rc; +@@ -225,15 +226,16 @@ out: + int ecryptfs_read_lower(char *data, loff_t offset, size_t size, + struct inode *ecryptfs_inode) + { +- struct ecryptfs_inode_info *inode_info = +- ecryptfs_inode_to_private(ecryptfs_inode); ++ struct file *lower_file; + mm_segment_t fs_save; + ssize_t rc; + +- BUG_ON(!inode_info->lower_file); ++ lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file; ++ if (!lower_file) ++ return -EIO; + fs_save = get_fs(); + set_fs(get_ds()); +- rc = vfs_read(inode_info->lower_file, data, size, &offset); ++ rc = vfs_read(lower_file, data, size, &offset); + set_fs(fs_save); + return rc; + } +diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c +index 34b6d9b..e5a7111 100644 +--- a/fs/ext3/namei.c ++++ b/fs/ext3/namei.c +@@ -2210,9 +2210,11 @@ static int ext3_symlink (struct inode * dir, + /* + * For non-fast symlinks, we just allocate inode and put it on + * orphan list in the first transaction => we need bitmap, +- * group descriptor, sb, inode block, quota blocks. ++ * group descriptor, sb, inode block, quota blocks, and ++ * possibly selinux xattr blocks. + */ +- credits = 4 + EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb); ++ credits = 4 + EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb) + ++ EXT3_XATTR_TRANS_BLOCKS; + } else { + /* + * Fast symlink. We have to add entry to directory +diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c +index b754b77..458a394 100644 +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -2264,9 +2264,11 @@ static int ext4_symlink(struct inode *dir, + /* + * For non-fast symlinks, we just allocate inode and put it on + * orphan list in the first transaction => we need bitmap, +- * group descriptor, sb, inode block, quota blocks. ++ * group descriptor, sb, inode block, quota blocks, and ++ * possibly selinux xattr blocks. + */ +- credits = 4 + EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb); ++ credits = 4 + EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb) + ++ EXT4_XATTR_TRANS_BLOCKS; + } else { + /* + * Fast symlink. We have to add entry to directory +diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h +index 33d12f8..0ec3687 100644 +--- a/include/drm/drm_crtc.h ++++ b/include/drm/drm_crtc.h +@@ -802,6 +802,7 @@ extern struct drm_display_mode *drm_gtf_mode_complex(struct drm_device *dev, + extern int drm_add_modes_noedid(struct drm_connector *connector, + int hdisplay, int vdisplay); + ++extern int drm_edid_header_is_valid(const u8 *raw_edid); + extern bool drm_edid_is_valid(struct edid *edid); + struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, + int hsize, int vsize, int fresh); +diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h +index c4d6dbf..28c0d11 100644 +--- a/include/drm/i915_drm.h ++++ b/include/drm/i915_drm.h +@@ -237,7 +237,7 @@ typedef struct _drm_i915_sarea { + #define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture) + #define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_i915_get_pipe_from_crtc_id) + #define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise) +-#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_IOCTL_I915_OVERLAY_ATTRS, struct drm_intel_overlay_put_image) ++#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_OVERLAY_PUT_IMAGE, struct drm_intel_overlay_put_image) + #define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs) + + /* Allow drivers to submit batchbuffers directly to hardware, relying +diff --git a/include/linux/cryptohash.h b/include/linux/cryptohash.h +index ec78a4b..d2984fb 100644 +--- a/include/linux/cryptohash.h ++++ b/include/linux/cryptohash.h +@@ -8,6 +8,11 @@ + void sha_init(__u32 *buf); + void sha_transform(__u32 *digest, const char *data, __u32 *W); + ++#define MD5_DIGEST_WORDS 4 ++#define MD5_MESSAGE_BYTES 64 ++ ++void md5_transform(__u32 *hash, __u32 const *in); ++ + __u32 half_md4_transform(__u32 buf[4], __u32 const in[8]); + + #endif +diff --git a/include/linux/if.h b/include/linux/if.h +index 3bc63e6..03489ca 100644 +--- a/include/linux/if.h ++++ b/include/linux/if.h +@@ -76,6 +76,8 @@ + #define IFF_BRIDGE_PORT 0x4000 /* device used as bridge port */ + #define IFF_OVS_DATAPATH 0x8000 /* device used as Open vSwitch + * datapath port */ ++#define IFF_TX_SKB_SHARING 0x10000 /* The interface supports sharing ++ * skbs on transmit */ + + #define IF_GET_IFACE 0x0001 /* for querying only */ + #define IF_GET_PROTO 0x0002 +diff --git a/include/linux/mm.h b/include/linux/mm.h +index 1036614..ec6e33d 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -959,6 +959,8 @@ int invalidate_inode_page(struct page *page); + #ifdef CONFIG_MMU + extern int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, + unsigned long address, unsigned int flags); ++extern int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm, ++ unsigned long address, unsigned int fault_flags); + #else + static inline int handle_mm_fault(struct mm_struct *mm, + struct vm_area_struct *vma, unsigned long address, +@@ -968,6 +970,14 @@ static inline int handle_mm_fault(struct mm_struct *mm, + BUG(); + return VM_FAULT_SIGBUS; + } ++static inline int fixup_user_fault(struct task_struct *tsk, ++ struct mm_struct *mm, unsigned long address, ++ unsigned int fault_flags) ++{ ++ /* should never happen if there's no MMU */ ++ BUG(); ++ return -EFAULT; ++} + #endif + + extern int make_pages_present(unsigned long addr, unsigned long end); +@@ -985,8 +995,6 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, + int get_user_pages_fast(unsigned long start, int nr_pages, int write, + struct page **pages); + struct page *get_dump_page(unsigned long addr); +-extern int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm, +- unsigned long address, unsigned int fault_flags); + + extern int try_to_release_page(struct page * page, gfp_t gfp_mask); + extern void do_invalidatepage(struct page *page, unsigned long offset); +diff --git a/include/linux/random.h b/include/linux/random.h +index fb7ab9d..d13059f 100644 +--- a/include/linux/random.h ++++ b/include/linux/random.h +@@ -57,17 +57,6 @@ extern void add_interrupt_randomness(int irq); + extern void get_random_bytes(void *buf, int nbytes); + void generate_random_uuid(unsigned char uuid_out[16]); + +-extern __u32 secure_ip_id(__be32 daddr); +-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); +-extern __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, +- __be16 sport, __be16 dport); +-extern __u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, +- __be16 sport, __be16 dport); +-extern u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, +- __be16 sport, __be16 dport); +- + #ifndef MODULE + extern const struct file_operations random_fops, urandom_fops; + #endif +diff --git a/include/net/ipv6.h b/include/net/ipv6.h +index c033ed0..3b5ac1f 100644 +--- a/include/net/ipv6.h ++++ b/include/net/ipv6.h +@@ -463,17 +463,7 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add + return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr)); + } + +-static __inline__ void ipv6_select_ident(struct frag_hdr *fhdr) +-{ +- static u32 ipv6_fragmentation_id = 1; +- static DEFINE_SPINLOCK(ip6_id_lock); +- +- spin_lock_bh(&ip6_id_lock); +- fhdr->identification = htonl(ipv6_fragmentation_id); +- if (++ipv6_fragmentation_id == 0) +- ipv6_fragmentation_id = 1; +- spin_unlock_bh(&ip6_id_lock); +-} ++extern void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt); + + /* + * Prototypes exported by ipv6 +diff --git a/include/net/secure_seq.h b/include/net/secure_seq.h +new file mode 100644 +index 0000000..d97f689 +--- /dev/null ++++ b/include/net/secure_seq.h +@@ -0,0 +1,20 @@ ++#ifndef _NET_SECURE_SEQ ++#define _NET_SECURE_SEQ ++ ++#include ++ ++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); ++extern __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, ++ __be16 sport, __be16 dport); ++extern __u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, ++ __be16 sport, __be16 dport); ++extern u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, ++ __be16 sport, __be16 dport); ++extern u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, ++ __be16 sport, __be16 dport); ++ ++#endif /* _NET_SECURE_SEQ */ +diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h +index 5271a74..45ce307 100644 +--- a/include/net/transp_v6.h ++++ b/include/net/transp_v6.h +@@ -14,6 +14,8 @@ extern struct proto tcpv6_prot; + + struct flowi6; + ++extern void initialize_hashidentrnd(void); ++ + /* extension headers */ + extern int ipv6_exthdrs_init(void); + extern void ipv6_exthdrs_exit(void); +diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h +index 70213b4..6acd9ce 100644 +--- a/include/xen/interface/xen.h ++++ b/include/xen/interface/xen.h +@@ -450,6 +450,45 @@ struct start_info { + int8_t cmd_line[MAX_GUEST_CMDLINE]; + }; + ++struct dom0_vga_console_info { ++ uint8_t video_type; ++#define XEN_VGATYPE_TEXT_MODE_3 0x03 ++#define XEN_VGATYPE_VESA_LFB 0x23 ++ ++ union { ++ struct { ++ /* Font height, in pixels. */ ++ uint16_t font_height; ++ /* Cursor location (column, row). */ ++ uint16_t cursor_x, cursor_y; ++ /* Number of rows and columns (dimensions in characters). */ ++ uint16_t rows, columns; ++ } text_mode_3; ++ ++ struct { ++ /* Width and height, in pixels. */ ++ uint16_t width, height; ++ /* Bytes per scan line. */ ++ uint16_t bytes_per_line; ++ /* Bits per pixel. */ ++ uint16_t bits_per_pixel; ++ /* LFB physical address, and size (in units of 64kB). */ ++ uint32_t lfb_base; ++ uint32_t lfb_size; ++ /* RGB mask offsets and sizes, as defined by VBE 1.2+ */ ++ uint8_t red_pos, red_size; ++ uint8_t green_pos, green_size; ++ uint8_t blue_pos, blue_size; ++ uint8_t rsvd_pos, rsvd_size; ++ ++ /* VESA capabilities (offset 0xa, VESA command 0x4f00). */ ++ uint32_t gbl_caps; ++ /* Mode attributes (offset 0x0, VESA command 0x4f01). */ ++ uint16_t mode_attrs; ++ } vesa_lfb; ++ } u; ++}; ++ + /* These flags are passed in the 'flags' field of start_info_t. */ + #define SIF_PRIVILEGED (1<<0) /* Is the domain privileged? */ + #define SIF_INITDOMAIN (1<<1) /* Is this the initial control domain? */ +diff --git a/kernel/futex.c b/kernel/futex.c +index 7a0a4ed..8b6da25 100644 +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -218,6 +218,8 @@ static void drop_futex_key_refs(union futex_key *key) + * @uaddr: virtual address of the futex + * @fshared: 0 for a PROCESS_PRIVATE futex, 1 for PROCESS_SHARED + * @key: address where result is stored. ++ * @rw: mapping needs to be read/write (values: VERIFY_READ, ++ * VERIFY_WRITE) + * + * Returns a negative error code or 0 + * The key words are stored in *key on success. +@@ -229,12 +231,12 @@ static void drop_futex_key_refs(union futex_key *key) + * lock_page() might sleep, the caller should not hold a spinlock. + */ + static int +-get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key) ++get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw) + { + unsigned long address = (unsigned long)uaddr; + struct mm_struct *mm = current->mm; + struct page *page, *page_head; +- int err; ++ int err, ro = 0; + + /* + * The futex address must be "naturally" aligned. +@@ -262,8 +264,18 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key) + + again: + err = get_user_pages_fast(address, 1, 1, &page); ++ /* ++ * If write access is not required (eg. FUTEX_WAIT), try ++ * and get read-only access. ++ */ ++ if (err == -EFAULT && rw == VERIFY_READ) { ++ err = get_user_pages_fast(address, 1, 0, &page); ++ ro = 1; ++ } + if (err < 0) + return err; ++ else ++ err = 0; + + #ifdef CONFIG_TRANSPARENT_HUGEPAGE + page_head = page; +@@ -305,6 +317,13 @@ again: + if (!page_head->mapping) { + unlock_page(page_head); + put_page(page_head); ++ /* ++ * ZERO_PAGE pages don't have a mapping. Avoid a busy loop ++ * trying to find one. RW mapping would have COW'd (and thus ++ * have a mapping) so this page is RO and won't ever change. ++ */ ++ if ((page_head == ZERO_PAGE(address))) ++ return -EFAULT; + goto again; + } + +@@ -316,6 +335,15 @@ again: + * the object not the particular process. + */ + if (PageAnon(page_head)) { ++ /* ++ * A RO anonymous page will never change and thus doesn't make ++ * sense for futex operations. ++ */ ++ if (ro) { ++ err = -EFAULT; ++ goto out; ++ } ++ + key->both.offset |= FUT_OFF_MMSHARED; /* ref taken on mm */ + key->private.mm = mm; + key->private.address = address; +@@ -327,9 +355,10 @@ again: + + get_futex_key_refs(key); + ++out: + unlock_page(page_head); + put_page(page_head); +- return 0; ++ return err; + } + + static inline void put_futex_key(union futex_key *key) +@@ -940,7 +969,7 @@ futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset) + if (!bitset) + return -EINVAL; + +- ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key); ++ ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key, VERIFY_READ); + if (unlikely(ret != 0)) + goto out; + +@@ -986,10 +1015,10 @@ futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2, + int ret, op_ret; + + retry: +- ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1); ++ ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1, VERIFY_READ); + if (unlikely(ret != 0)) + goto out; +- ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2); ++ ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, VERIFY_WRITE); + if (unlikely(ret != 0)) + goto out_put_key1; + +@@ -1243,10 +1272,11 @@ retry: + pi_state = NULL; + } + +- ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1); ++ ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1, VERIFY_READ); + if (unlikely(ret != 0)) + goto out; +- ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2); ++ ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, ++ requeue_pi ? VERIFY_WRITE : VERIFY_READ); + if (unlikely(ret != 0)) + goto out_put_key1; + +@@ -1790,7 +1820,7 @@ static int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags, + * while the syscall executes. + */ + retry: +- ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q->key); ++ ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q->key, VERIFY_READ); + if (unlikely(ret != 0)) + return ret; + +@@ -1941,7 +1971,7 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, int detect, + } + + retry: +- ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q.key); ++ ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q.key, VERIFY_WRITE); + if (unlikely(ret != 0)) + goto out; + +@@ -2060,7 +2090,7 @@ retry: + if ((uval & FUTEX_TID_MASK) != vpid) + return -EPERM; + +- ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key); ++ ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key, VERIFY_WRITE); + if (unlikely(ret != 0)) + goto out; + +@@ -2249,7 +2279,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, + debug_rt_mutex_init_waiter(&rt_waiter); + rt_waiter.task = NULL; + +- ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2); ++ ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, VERIFY_WRITE); + if (unlikely(ret != 0)) + goto out; + +diff --git a/lib/Makefile b/lib/Makefile +index 6b597fd..578414a 100644 +--- a/lib/Makefile ++++ b/lib/Makefile +@@ -10,7 +10,7 @@ endif + lib-y := ctype.o string.o vsprintf.o cmdline.o \ + rbtree.o radix-tree.o dump_stack.o timerqueue.o\ + idr.o int_sqrt.o extable.o prio_tree.o \ +- sha1.o irq_regs.o reciprocal_div.o argv_split.o \ ++ sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \ + proportions.o prio_heap.o ratelimit.o show_mem.o \ + is_single_threaded.o plist.o decompress.o find_next_bit.o + +diff --git a/lib/md5.c b/lib/md5.c +new file mode 100644 +index 0000000..c777180 +--- /dev/null ++++ b/lib/md5.c +@@ -0,0 +1,95 @@ ++#include ++#include ++#include ++ ++#define F1(x, y, z) (z ^ (x & (y ^ z))) ++#define F2(x, y, z) F1(z, x, y) ++#define F3(x, y, z) (x ^ y ^ z) ++#define F4(x, y, z) (y ^ (x | ~z)) ++ ++#define MD5STEP(f, w, x, y, z, in, s) \ ++ (w += f(x, y, z) + in, w = (w<>(32-s)) + x) ++ ++void md5_transform(__u32 *hash, __u32 const *in) ++{ ++ u32 a, b, c, d; ++ ++ a = hash[0]; ++ b = hash[1]; ++ c = hash[2]; ++ d = hash[3]; ++ ++ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); ++ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); ++ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); ++ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); ++ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); ++ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); ++ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); ++ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); ++ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); ++ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); ++ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); ++ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); ++ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); ++ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); ++ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); ++ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); ++ ++ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); ++ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); ++ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); ++ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); ++ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); ++ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); ++ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); ++ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); ++ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); ++ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); ++ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); ++ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); ++ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); ++ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); ++ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); ++ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); ++ ++ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); ++ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); ++ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); ++ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); ++ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); ++ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); ++ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); ++ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); ++ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); ++ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); ++ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); ++ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); ++ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); ++ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); ++ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); ++ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); ++ ++ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); ++ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); ++ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); ++ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); ++ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); ++ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); ++ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); ++ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); ++ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); ++ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); ++ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); ++ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); ++ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); ++ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); ++ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); ++ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); ++ ++ hash[0] += a; ++ hash[1] += b; ++ hash[2] += c; ++ hash[3] += d; ++} ++EXPORT_SYMBOL(md5_transform); +diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c +index 6e82148..5b4f51d 100644 +--- a/net/8021q/vlan_dev.c ++++ b/net/8021q/vlan_dev.c +@@ -694,7 +694,7 @@ void vlan_setup(struct net_device *dev) + ether_setup(dev); + + dev->priv_flags |= IFF_802_1Q_VLAN; +- dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; ++ dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); + dev->tx_queue_len = 0; + + dev->netdev_ops = &vlan_netdev_ops; +diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c +index 8c100c9..d4f5dff 100644 +--- a/net/bluetooth/bnep/netdev.c ++++ b/net/bluetooth/bnep/netdev.c +@@ -231,6 +231,7 @@ void bnep_net_setup(struct net_device *dev) + dev->addr_len = ETH_ALEN; + + ether_setup(dev); ++ dev->priv_flags &= ~IFF_TX_SKB_SHARING; + dev->netdev_ops = &bnep_netdev_ops; + + dev->watchdog_timeo = HZ * 2; +diff --git a/net/core/Makefile b/net/core/Makefile +index 8a04dd2..0d357b1 100644 +--- a/net/core/Makefile ++++ b/net/core/Makefile +@@ -3,7 +3,7 @@ + # + + obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ +- gen_stats.o gen_estimator.o net_namespace.o ++ gen_stats.o gen_estimator.o net_namespace.o secure_seq.o + + obj-$(CONFIG_SYSCTL) += sysctl_net_core.o + +diff --git a/net/core/link_watch.c b/net/core/link_watch.c +index a7b3421..357bd4e 100644 +--- a/net/core/link_watch.c ++++ b/net/core/link_watch.c +@@ -126,7 +126,7 @@ static void linkwatch_schedule_work(int urgent) + return; + + /* It's already running which is good enough. */ +- if (!cancel_delayed_work(&linkwatch_work)) ++ if (!__cancel_delayed_work(&linkwatch_work)) + return; + + /* Otherwise we reschedule it again for immediate execution. */ +diff --git a/net/core/pktgen.c b/net/core/pktgen.c +index f76079c..e35a6fb 100644 +--- a/net/core/pktgen.c ++++ b/net/core/pktgen.c +@@ -1070,7 +1070,9 @@ static ssize_t pktgen_if_write(struct file *file, + len = num_arg(&user_buffer[i], 10, &value); + if (len < 0) + return len; +- ++ if ((value > 0) && ++ (!(pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING))) ++ return -ENOTSUPP; + i += len; + pkt_dev->clone_skb = value; + +@@ -3555,7 +3557,6 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) + pkt_dev->min_pkt_size = ETH_ZLEN; + pkt_dev->max_pkt_size = ETH_ZLEN; + pkt_dev->nfrags = 0; +- pkt_dev->clone_skb = pg_clone_skb_d; + pkt_dev->delay = pg_delay_d; + pkt_dev->count = pg_count_d; + pkt_dev->sofar = 0; +@@ -3563,7 +3564,6 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) + pkt_dev->udp_src_max = 9; + pkt_dev->udp_dst_min = 9; + pkt_dev->udp_dst_max = 9; +- + pkt_dev->vlan_p = 0; + pkt_dev->vlan_cfi = 0; + pkt_dev->vlan_id = 0xffff; +@@ -3575,6 +3575,8 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) + err = pktgen_setup_dev(pkt_dev, ifname); + if (err) + goto out1; ++ if (pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING) ++ pkt_dev->clone_skb = pg_clone_skb_d; + + pkt_dev->entry = proc_create_data(ifname, 0600, pg_proc_dir, + &pktgen_if_fops, pkt_dev); +diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c +new file mode 100644 +index 0000000..45329d7 +--- /dev/null ++++ b/net/core/secure_seq.c +@@ -0,0 +1,184 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++static u32 net_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; ++ ++static int __init net_secret_init(void) ++{ ++ get_random_bytes(net_secret, sizeof(net_secret)); ++ return 0; ++} ++late_initcall(net_secret_init); ++ ++static u32 seq_scale(u32 seq) ++{ ++ /* ++ * As close as possible to RFC 793, which ++ * suggests using a 250 kHz clock. ++ * Further reading shows this assumes 2 Mb/s networks. ++ * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate. ++ * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but ++ * we also need to limit the resolution so that the u32 seq ++ * overlaps less than one time per MSL (2 minutes). ++ * Choosing a clock of 64 ns period is OK. (period of 274 s) ++ */ ++ return seq + (ktime_to_ns(ktime_get_real()) >> 6); ++} ++ ++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) ++__u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, ++ __be16 sport, __be16 dport) ++{ ++ u32 secret[MD5_MESSAGE_BYTES / 4]; ++ u32 hash[MD5_DIGEST_WORDS]; ++ u32 i; ++ ++ memcpy(hash, saddr, 16); ++ for (i = 0; i < 4; i++) ++ secret[i] = net_secret[i] + daddr[i]; ++ secret[4] = net_secret[4] + ++ (((__force u16)sport << 16) + (__force u16)dport); ++ for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) ++ secret[i] = net_secret[i]; ++ ++ md5_transform(hash, secret); ++ ++ return seq_scale(hash[0]); ++} ++EXPORT_SYMBOL(secure_tcpv6_sequence_number); ++ ++u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, ++ __be16 dport) ++{ ++ u32 secret[MD5_MESSAGE_BYTES / 4]; ++ u32 hash[MD5_DIGEST_WORDS]; ++ u32 i; ++ ++ memcpy(hash, saddr, 16); ++ for (i = 0; i < 4; i++) ++ secret[i] = net_secret[i] + (__force u32) daddr[i]; ++ secret[4] = net_secret[4] + (__force u32)dport; ++ for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) ++ secret[i] = net_secret[i]; ++ ++ md5_transform(hash, secret); ++ ++ return hash[0]; ++} ++#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) ++{ ++ u32 hash[MD5_DIGEST_WORDS]; ++ ++ hash[0] = (__force u32)saddr; ++ hash[1] = (__force u32)daddr; ++ hash[2] = ((__force u16)sport << 16) + (__force u16)dport; ++ hash[3] = net_secret[15]; ++ ++ md5_transform(hash, net_secret); ++ ++ return seq_scale(hash[0]); ++} ++ ++u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) ++{ ++ u32 hash[MD5_DIGEST_WORDS]; ++ ++ hash[0] = (__force u32)saddr; ++ hash[1] = (__force u32)daddr; ++ hash[2] = (__force u32)dport ^ net_secret[14]; ++ hash[3] = net_secret[15]; ++ ++ md5_transform(hash, net_secret); ++ ++ return hash[0]; ++} ++EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral); ++#endif ++ ++#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) ++u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, ++ __be16 sport, __be16 dport) ++{ ++ u32 hash[MD5_DIGEST_WORDS]; ++ u64 seq; ++ ++ hash[0] = (__force u32)saddr; ++ hash[1] = (__force u32)daddr; ++ hash[2] = ((__force u16)sport << 16) + (__force u16)dport; ++ hash[3] = net_secret[15]; ++ ++ md5_transform(hash, net_secret); ++ ++ seq = hash[0] | (((u64)hash[1]) << 32); ++ seq += ktime_to_ns(ktime_get_real()); ++ seq &= (1ull << 48) - 1; ++ ++ return seq; ++} ++EXPORT_SYMBOL(secure_dccp_sequence_number); ++ ++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) ++u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, ++ __be16 sport, __be16 dport) ++{ ++ u32 secret[MD5_MESSAGE_BYTES / 4]; ++ u32 hash[MD5_DIGEST_WORDS]; ++ u64 seq; ++ u32 i; ++ ++ memcpy(hash, saddr, 16); ++ for (i = 0; i < 4; i++) ++ secret[i] = net_secret[i] + daddr[i]; ++ secret[4] = net_secret[4] + ++ (((__force u16)sport << 16) + (__force u16)dport); ++ for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) ++ secret[i] = net_secret[i]; ++ ++ md5_transform(hash, secret); ++ ++ seq = hash[0] | (((u64)hash[1]) << 32); ++ seq += ktime_to_ns(ktime_get_real()); ++ seq &= (1ull << 48) - 1; ++ ++ return seq; ++} ++EXPORT_SYMBOL(secure_dccpv6_sequence_number); ++#endif ++#endif +diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c +index 8c36adf..332639b 100644 +--- a/net/dccp/ipv4.c ++++ b/net/dccp/ipv4.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + #include "ackvec.h" + #include "ccid.h" +diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c +index 8dc4348..b74f761 100644 +--- a/net/dccp/ipv6.c ++++ b/net/dccp/ipv6.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + + #include "dccp.h" + #include "ipv6.h" +@@ -69,13 +70,7 @@ static inline void dccp_v6_send_check(struct sock *sk, struct sk_buff *skb) + dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr); + } + +-static inline __u32 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, +- __be16 sport, __be16 dport ) +-{ +- return secure_tcpv6_sequence_number(saddr, daddr, sport, dport); +-} +- +-static inline __u32 dccp_v6_init_sequence(struct sk_buff *skb) ++static inline __u64 dccp_v6_init_sequence(struct sk_buff *skb) + { + return secure_dccpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, + ipv6_hdr(skb)->saddr.s6_addr32, +diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c +index 44d2b42..2780e9b 100644 +--- a/net/ethernet/eth.c ++++ b/net/ethernet/eth.c +@@ -340,6 +340,7 @@ void ether_setup(struct net_device *dev) + dev->addr_len = ETH_ALEN; + dev->tx_queue_len = 1000; /* Ethernet wants good queues */ + dev->flags = IFF_BROADCAST|IFF_MULTICAST; ++ dev->priv_flags = IFF_TX_SKB_SHARING; + + memset(dev->broadcast, 0xFF, ETH_ALEN); + +diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c +index 0d4a184..4155abc 100644 +--- a/net/ipv4/devinet.c ++++ b/net/ipv4/devinet.c +@@ -1134,15 +1134,15 @@ static void inetdev_send_gratuitous_arp(struct net_device *dev, + struct in_device *in_dev) + + { +- struct in_ifaddr *ifa = in_dev->ifa_list; +- +- if (!ifa) +- return; ++ struct in_ifaddr *ifa; + +- arp_send(ARPOP_REQUEST, ETH_P_ARP, +- ifa->ifa_local, dev, +- ifa->ifa_local, NULL, +- dev->dev_addr, NULL); ++ for (ifa = in_dev->ifa_list; ifa; ++ ifa = ifa->ifa_next) { ++ arp_send(ARPOP_REQUEST, ETH_P_ARP, ++ ifa->ifa_local, dev, ++ ifa->ifa_local, NULL, ++ dev->dev_addr, NULL); ++ } + } + + /* Called only under RTNL semaphore */ +diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c +index c6933f2..3e3f75d 100644 +--- a/net/ipv4/gre.c ++++ b/net/ipv4/gre.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -97,27 +98,17 @@ drop: + static void gre_err(struct sk_buff *skb, u32 info) + { + const struct gre_protocol *proto; +- u8 ver; +- +- if (!pskb_may_pull(skb, 12)) +- goto drop; ++ const struct iphdr *iph = (const struct iphdr *)skb->data; ++ u8 ver = skb->data[(iph->ihl<<2) + 1]&0x7f; + +- ver = skb->data[1]&0x7f; + if (ver >= GREPROTO_MAX) +- goto drop; ++ return; + + rcu_read_lock(); + proto = rcu_dereference(gre_proto[ver]); +- if (!proto || !proto->err_handler) +- goto drop_unlock; +- proto->err_handler(skb, info); +- rcu_read_unlock(); +- return; +- +-drop_unlock: ++ if (proto && proto->err_handler) ++ proto->err_handler(skb, info); + rcu_read_unlock(); +-drop: +- kfree_skb(skb); + } + + static const struct net_protocol net_gre_protocol = { +diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c +index 5395e45..23ef31b 100644 +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -380,6 +380,7 @@ static struct rtable *icmp_route_lookup(struct net *net, + struct icmp_bxm *param) + { + struct rtable *rt, *rt2; ++ struct flowi4 fl4_dec; + int err; + + memset(fl4, 0, sizeof(*fl4)); +@@ -408,19 +409,19 @@ static struct rtable *icmp_route_lookup(struct net *net, + } else + return rt; + +- err = xfrm_decode_session_reverse(skb_in, flowi4_to_flowi(fl4), AF_INET); ++ err = xfrm_decode_session_reverse(skb_in, flowi4_to_flowi(&fl4_dec), AF_INET); + if (err) + goto relookup_failed; + +- if (inet_addr_type(net, fl4->saddr) == RTN_LOCAL) { +- rt2 = __ip_route_output_key(net, fl4); ++ if (inet_addr_type(net, fl4_dec.saddr) == RTN_LOCAL) { ++ rt2 = __ip_route_output_key(net, &fl4_dec); + if (IS_ERR(rt2)) + err = PTR_ERR(rt2); + } else { + struct flowi4 fl4_2 = {}; + unsigned long orefdst; + +- fl4_2.daddr = fl4->saddr; ++ fl4_2.daddr = fl4_dec.saddr; + rt2 = ip_route_output_key(net, &fl4_2); + if (IS_ERR(rt2)) { + err = PTR_ERR(rt2); +@@ -428,7 +429,7 @@ static struct rtable *icmp_route_lookup(struct net *net, + } + /* Ugh! */ + orefdst = skb_in->_skb_refdst; /* save old refdst */ +- err = ip_route_input(skb_in, fl4->daddr, fl4->saddr, ++ err = ip_route_input(skb_in, fl4_dec.daddr, fl4_dec.saddr, + RT_TOS(tos), rt2->dst.dev); + + dst_release(&rt2->dst); +@@ -440,10 +441,11 @@ static struct rtable *icmp_route_lookup(struct net *net, + goto relookup_failed; + + rt2 = (struct rtable *) xfrm_lookup(net, &rt2->dst, +- flowi4_to_flowi(fl4), NULL, ++ flowi4_to_flowi(&fl4_dec), NULL, + XFRM_LOOKUP_ICMP); + if (!IS_ERR(rt2)) { + dst_release(&rt->dst); ++ memcpy(fl4, &fl4_dec, sizeof(*fl4)); + rt = rt2; + } else if (PTR_ERR(rt2) == -EPERM) { + if (rt) +diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c +index f1d27f6..283c0a2 100644 +--- a/net/ipv4/igmp.c ++++ b/net/ipv4/igmp.c +@@ -1718,7 +1718,7 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode, + + pmc->sfcount[sfmode]--; + for (j=0; jsfcount[MCAST_EXCLUDE] != 0)) { + #ifdef CONFIG_IP_MULTICAST + struct ip_sf_list *psf; +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index 3c0369a..984ec65 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -21,6 +21,7 @@ + + #include + #include ++#include + #include + + /* +diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c +index ce616d9..6877645 100644 +--- a/net/ipv4/inetpeer.c ++++ b/net/ipv4/inetpeer.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + /* + * Theory of operations. +diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c +index 84f26e8..0c99db4 100644 +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -734,7 +734,7 @@ static inline int ip_ufo_append_data(struct sock *sk, + int getfrag(void *from, char *to, int offset, int len, + int odd, struct sk_buff *skb), + void *from, int length, int hh_len, int fragheaderlen, +- int transhdrlen, int mtu, unsigned int flags) ++ int transhdrlen, int maxfraglen, unsigned int flags) + { + struct sk_buff *skb; + int err; +@@ -767,7 +767,7 @@ static inline int ip_ufo_append_data(struct sock *sk, + skb->csum = 0; + + /* specify the length of each IP datagram fragment */ +- skb_shinfo(skb)->gso_size = mtu - fragheaderlen; ++ skb_shinfo(skb)->gso_size = maxfraglen - fragheaderlen; + skb_shinfo(skb)->gso_type = SKB_GSO_UDP; + __skb_queue_tail(queue, skb); + } +@@ -831,7 +831,7 @@ static int __ip_append_data(struct sock *sk, + (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) { + err = ip_ufo_append_data(sk, queue, getfrag, from, length, + hh_len, fragheaderlen, transhdrlen, +- mtu, flags); ++ maxfraglen, flags); + if (err) + goto error; + return 0; +diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c +index 30a7763..f81af8d 100644 +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -1796,7 +1796,7 @@ static struct mr_table *ipmr_rt_fib_lookup(struct net *net, struct sk_buff *skb) + struct flowi4 fl4 = { + .daddr = iph->daddr, + .saddr = iph->saddr, +- .flowi4_tos = iph->tos, ++ .flowi4_tos = RT_TOS(iph->tos), + .flowi4_oif = rt->rt_oif, + .flowi4_iif = rt->rt_iif, + .flowi4_mark = rt->rt_mark, +diff --git a/net/ipv4/netfilter/nf_nat_proto_common.c b/net/ipv4/netfilter/nf_nat_proto_common.c +index 3e61faf..f52d41e 100644 +--- a/net/ipv4/netfilter/nf_nat_proto_common.c ++++ b/net/ipv4/netfilter/nf_nat_proto_common.c +@@ -12,6 +12,7 @@ + #include + + #include ++#include + #include + #include + #include +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index aa13ef1..cdabdbf 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -108,6 +108,7 @@ + #ifdef CONFIG_SYSCTL + #include + #endif ++#include + + #define RT_FL_TOS(oldflp4) \ + ((u32)(oldflp4->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))) +@@ -725,6 +726,7 @@ static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) + ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | + (rt1->rt_mark ^ rt2->rt_mark) | + (rt1->rt_key_tos ^ rt2->rt_key_tos) | ++ (rt1->rt_route_iif ^ rt2->rt_route_iif) | + (rt1->rt_oif ^ rt2->rt_oif) | + (rt1->rt_iif ^ rt2->rt_iif)) == 0; + } +@@ -1703,7 +1705,7 @@ void ip_rt_get_source(u8 *addr, struct sk_buff *skb, struct rtable *rt) + memset(&fl4, 0, sizeof(fl4)); + fl4.daddr = iph->daddr; + fl4.saddr = iph->saddr; +- fl4.flowi4_tos = iph->tos; ++ fl4.flowi4_tos = RT_TOS(iph->tos); + fl4.flowi4_oif = rt->dst.dev->ifindex; + fl4.flowi4_iif = skb->dev->ifindex; + fl4.flowi4_mark = skb->mark; +@@ -2281,8 +2283,8 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, + if ((((__force u32)rth->rt_key_dst ^ (__force u32)daddr) | + ((__force u32)rth->rt_key_src ^ (__force u32)saddr) | + (rth->rt_iif ^ iif) | +- rth->rt_oif | + (rth->rt_key_tos ^ tos)) == 0 && ++ rt_is_input_route(rth) && + rth->rt_mark == skb->mark && + net_eq(dev_net(rth->dst.dev), net) && + !rt_is_expired(rth)) { +diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c +index 708dc20..b3e6956 100644 +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -72,6 +72,7 @@ + #include + #include + #include ++#include + + #include + #include +diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c +index 3b5669a..5591236 100644 +--- a/net/ipv6/af_inet6.c ++++ b/net/ipv6/af_inet6.c +@@ -1078,6 +1078,8 @@ static int __init inet6_init(void) + goto out; + } + ++ initialize_hashidentrnd(); ++ + err = proto_register(&tcpv6_prot, 1); + if (err) + goto out; +diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c +index b531972..73f1a00 100644 +--- a/net/ipv6/inet6_hashtables.c ++++ b/net/ipv6/inet6_hashtables.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + + int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw) +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index 9d4b165..1661296 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -596,6 +596,35 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) + return offset; + } + ++static u32 hashidentrnd __read_mostly; ++#define FID_HASH_SZ 16 ++static u32 ipv6_fragmentation_id[FID_HASH_SZ]; ++ ++void __init initialize_hashidentrnd(void) ++{ ++ get_random_bytes(&hashidentrnd, sizeof(hashidentrnd)); ++} ++ ++static u32 __ipv6_select_ident(const struct in6_addr *addr) ++{ ++ u32 newid, oldid, hash = jhash2((u32 *)addr, 4, hashidentrnd); ++ u32 *pid = &ipv6_fragmentation_id[hash % FID_HASH_SZ]; ++ ++ do { ++ oldid = *pid; ++ newid = oldid + 1; ++ if (!(hash + newid)) ++ newid++; ++ } while (cmpxchg(pid, oldid, newid) != oldid); ++ ++ return hash + newid; ++} ++ ++void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt) ++{ ++ fhdr->identification = htonl(__ipv6_select_ident(&rt->rt6i_dst.addr)); ++} ++ + int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) + { + struct sk_buff *frag; +@@ -680,7 +709,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) + skb_reset_network_header(skb); + memcpy(skb_network_header(skb), tmp_hdr, hlen); + +- ipv6_select_ident(fh); ++ ipv6_select_ident(fh, rt); + fh->nexthdr = nexthdr; + fh->reserved = 0; + fh->frag_off = htons(IP6_MF); +@@ -826,7 +855,7 @@ slow_path: + fh->nexthdr = nexthdr; + fh->reserved = 0; + if (!frag_id) { +- ipv6_select_ident(fh); ++ ipv6_select_ident(fh, rt); + frag_id = fh->identification; + } else + fh->identification = frag_id; +@@ -1072,7 +1101,8 @@ static inline int ip6_ufo_append_data(struct sock *sk, + int getfrag(void *from, char *to, int offset, int len, + int odd, struct sk_buff *skb), + void *from, int length, int hh_len, int fragheaderlen, +- int transhdrlen, int mtu,unsigned int flags) ++ int transhdrlen, int mtu,unsigned int flags, ++ struct rt6_info *rt) + + { + struct sk_buff *skb; +@@ -1116,7 +1146,7 @@ static inline int ip6_ufo_append_data(struct sock *sk, + skb_shinfo(skb)->gso_size = (mtu - fragheaderlen - + sizeof(struct frag_hdr)) & ~7; + skb_shinfo(skb)->gso_type = SKB_GSO_UDP; +- ipv6_select_ident(&fhdr); ++ ipv6_select_ident(&fhdr, rt); + skb_shinfo(skb)->ip6_frag_id = fhdr.identification; + __skb_queue_tail(&sk->sk_write_queue, skb); + +@@ -1282,7 +1312,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, + + err = ip6_ufo_append_data(sk, getfrag, from, length, + hh_len, fragheaderlen, +- transhdrlen, mtu, flags); ++ transhdrlen, mtu, flags, rt); + if (err) + goto error; + return 0; +diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c +index 87551ca..7c43e86 100644 +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -61,6 +61,7 @@ + #include + #include + #include ++#include + + #include + +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index 328985c..29213b5 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -1359,7 +1359,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, u32 features) + fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen); + fptr->nexthdr = nexthdr; + fptr->reserved = 0; +- ipv6_select_ident(fptr); ++ ipv6_select_ident(fptr, (struct rt6_info *)skb_dst(skb)); + + /* Fragment the skb. ipv6 header and the remaining fields of the + * fragment header are updated in ipv6_gso_segment() +diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c +index a8193f5..d2726a7 100644 +--- a/net/l2tp/l2tp_eth.c ++++ b/net/l2tp/l2tp_eth.c +@@ -103,7 +103,7 @@ static struct net_device_ops l2tp_eth_netdev_ops = { + static void l2tp_eth_dev_setup(struct net_device *dev) + { + ether_setup(dev); +- ++ dev->priv_flags &= ~IFF_TX_SKB_SHARING; + dev->netdev_ops = &l2tp_eth_netdev_ops; + dev->destructor = free_netdev; + } +diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c +index dee30ae..895eec1 100644 +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -699,6 +699,7 @@ static const struct net_device_ops ieee80211_monitorif_ops = { + static void ieee80211_if_setup(struct net_device *dev) + { + ether_setup(dev); ++ dev->priv_flags &= ~IFF_TX_SKB_SHARING; + dev->netdev_ops = &ieee80211_dataif_ops; + dev->destructor = free_netdev; + } +diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c +index 699c79a..a178cb3 100644 +--- a/net/netfilter/ipvs/ip_vs_ctl.c ++++ b/net/netfilter/ipvs/ip_vs_ctl.c +@@ -3771,6 +3771,7 @@ err_sock: + void ip_vs_control_cleanup(void) + { + EnterFunction(2); ++ unregister_netdevice_notifier(&ip_vs_dst_notifier); + ip_vs_genl_unregister(); + nf_unregister_sockopt(&ip_vs_sockopts); + LeaveFunction(2); +diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c +index b6ea6af..69400e3 100644 +--- a/net/sched/sch_sfq.c ++++ b/net/sched/sch_sfq.c +@@ -410,7 +410,12 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) + /* Return Congestion Notification only if we dropped a packet + * from this flow. + */ +- return (qlen != slot->qlen) ? NET_XMIT_CN : NET_XMIT_SUCCESS; ++ if (qlen != slot->qlen) ++ return NET_XMIT_CN; ++ ++ /* As we dropped a packet, better let upper stack know this */ ++ qdisc_tree_decrease_qlen(sch, 1); ++ return NET_XMIT_SUCCESS; + } + + static struct sk_buff * +diff --git a/net/socket.c b/net/socket.c +index 02dc82d..ed46dbb 100644 +--- a/net/socket.c ++++ b/net/socket.c +@@ -1871,8 +1871,14 @@ SYSCALL_DEFINE2(shutdown, int, fd, int, how) + #define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen) + #define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags) + ++struct used_address { ++ struct sockaddr_storage name; ++ unsigned int name_len; ++}; ++ + static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, +- struct msghdr *msg_sys, unsigned flags, int nosec) ++ struct msghdr *msg_sys, unsigned flags, ++ struct used_address *used_address) + { + struct compat_msghdr __user *msg_compat = + (struct compat_msghdr __user *)msg; +@@ -1953,8 +1959,28 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, + + if (sock->file->f_flags & O_NONBLOCK) + msg_sys->msg_flags |= MSG_DONTWAIT; +- err = (nosec ? sock_sendmsg_nosec : sock_sendmsg)(sock, msg_sys, +- total_len); ++ /* ++ * If this is sendmmsg() and current destination address is same as ++ * previously succeeded address, omit asking LSM's decision. ++ * used_address->name_len is initialized to UINT_MAX so that the first ++ * destination address never matches. ++ */ ++ if (used_address && used_address->name_len == msg_sys->msg_namelen && ++ !memcmp(&used_address->name, msg->msg_name, ++ used_address->name_len)) { ++ err = sock_sendmsg_nosec(sock, msg_sys, total_len); ++ goto out_freectl; ++ } ++ err = sock_sendmsg(sock, msg_sys, total_len); ++ /* ++ * If this is sendmmsg() and sending to current destination address was ++ * successful, remember it. ++ */ ++ if (used_address && err >= 0) { ++ used_address->name_len = msg_sys->msg_namelen; ++ memcpy(&used_address->name, msg->msg_name, ++ used_address->name_len); ++ } + + out_freectl: + if (ctl_buf != ctl) +@@ -1979,7 +2005,7 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) + if (!sock) + goto out; + +- err = __sys_sendmsg(sock, msg, &msg_sys, flags, 0); ++ err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL); + + fput_light(sock->file, fput_needed); + out: +@@ -1998,6 +2024,10 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, + struct mmsghdr __user *entry; + struct compat_mmsghdr __user *compat_entry; + struct msghdr msg_sys; ++ struct used_address used_address; ++ ++ if (vlen > UIO_MAXIOV) ++ vlen = UIO_MAXIOV; + + datagrams = 0; + +@@ -2005,27 +2035,22 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, + if (!sock) + return err; + +- err = sock_error(sock->sk); +- if (err) +- goto out_put; +- ++ used_address.name_len = UINT_MAX; + entry = mmsg; + compat_entry = (struct compat_mmsghdr __user *)mmsg; ++ err = 0; + + while (datagrams < vlen) { +- /* +- * No need to ask LSM for more than the first datagram. +- */ + if (MSG_CMSG_COMPAT & flags) { + err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry, +- &msg_sys, flags, datagrams); ++ &msg_sys, flags, &used_address); + if (err < 0) + break; + err = __put_user(err, &compat_entry->msg_len); + ++compat_entry; + } else { + err = __sys_sendmsg(sock, (struct msghdr __user *)entry, +- &msg_sys, flags, datagrams); ++ &msg_sys, flags, &used_address); + if (err < 0) + break; + err = put_user(err, &entry->msg_len); +@@ -2037,29 +2062,11 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, + ++datagrams; + } + +-out_put: + fput_light(sock->file, fput_needed); + +- if (err == 0) +- return datagrams; +- +- if (datagrams != 0) { +- /* +- * We may send less entries than requested (vlen) if the +- * sock is non blocking... +- */ +- if (err != -EAGAIN) { +- /* +- * ... or if sendmsg returns an error after we +- * send some datagrams, where we record the +- * error to return on the next call or if the +- * app asks about it using getsockopt(SO_ERROR). +- */ +- sock->sk->sk_err = -err; +- } +- ++ /* We only return an error if no datagrams were able to be sent */ ++ if (datagrams != 0) + return datagrams; +- } + + return err; + } +diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c +index 58064d9..791ab2e 100644 +--- a/net/xfrm/xfrm_algo.c ++++ b/net/xfrm/xfrm_algo.c +@@ -462,8 +462,8 @@ static struct xfrm_algo_desc ealg_list[] = { + .desc = { + .sadb_alg_id = SADB_X_EALG_AESCTR, + .sadb_alg_ivlen = 8, +- .sadb_alg_minbits = 128, +- .sadb_alg_maxbits = 256 ++ .sadb_alg_minbits = 160, ++ .sadb_alg_maxbits = 288 + } + }, + }; +diff --git a/sound/core/timer.c b/sound/core/timer.c +index 7c1cbf0..950eed0 100644 +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -531,6 +531,8 @@ int snd_timer_stop(struct snd_timer_instance *timeri) + if (err < 0) + return err; + timer = timeri->timer; ++ if (!timer) ++ return -EINVAL; + spin_lock_irqsave(&timer->lock, flags); + timeri->cticks = timeri->ticks; + timeri->pticks = 0; +diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c +index ff29380..c49317c 100644 +--- a/sound/soc/codecs/sgtl5000.c ++++ b/sound/soc/codecs/sgtl5000.c +@@ -33,73 +33,31 @@ + #define SGTL5000_DAP_REG_OFFSET 0x0100 + #define SGTL5000_MAX_REG_OFFSET 0x013A + +-/* default value of sgtl5000 registers except DAP */ +-static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET >> 1] = { +- 0xa011, /* 0x0000, CHIP_ID. 11 stand for revison 17 */ +- 0x0000, /* 0x0002, CHIP_DIG_POWER. */ +- 0x0008, /* 0x0004, CHIP_CKL_CTRL */ +- 0x0010, /* 0x0006, CHIP_I2S_CTRL */ +- 0x0000, /* 0x0008, reserved */ +- 0x0008, /* 0x000A, CHIP_SSS_CTRL */ +- 0x0000, /* 0x000C, reserved */ +- 0x020c, /* 0x000E, CHIP_ADCDAC_CTRL */ +- 0x3c3c, /* 0x0010, CHIP_DAC_VOL */ +- 0x0000, /* 0x0012, reserved */ +- 0x015f, /* 0x0014, CHIP_PAD_STRENGTH */ +- 0x0000, /* 0x0016, reserved */ +- 0x0000, /* 0x0018, reserved */ +- 0x0000, /* 0x001A, reserved */ +- 0x0000, /* 0x001E, reserved */ +- 0x0000, /* 0x0020, CHIP_ANA_ADC_CTRL */ +- 0x1818, /* 0x0022, CHIP_ANA_HP_CTRL */ +- 0x0111, /* 0x0024, CHIP_ANN_CTRL */ +- 0x0000, /* 0x0026, CHIP_LINREG_CTRL */ +- 0x0000, /* 0x0028, CHIP_REF_CTRL */ +- 0x0000, /* 0x002A, CHIP_MIC_CTRL */ +- 0x0000, /* 0x002C, CHIP_LINE_OUT_CTRL */ +- 0x0404, /* 0x002E, CHIP_LINE_OUT_VOL */ +- 0x7060, /* 0x0030, CHIP_ANA_POWER */ +- 0x5000, /* 0x0032, CHIP_PLL_CTRL */ +- 0x0000, /* 0x0034, CHIP_CLK_TOP_CTRL */ +- 0x0000, /* 0x0036, CHIP_ANA_STATUS */ +- 0x0000, /* 0x0038, reserved */ +- 0x0000, /* 0x003A, CHIP_ANA_TEST2 */ +- 0x0000, /* 0x003C, CHIP_SHORT_CTRL */ +- 0x0000, /* reserved */ +-}; +- +-/* default value of dap registers */ +-static const u16 sgtl5000_dap_regs[] = { +- 0x0000, /* 0x0100, DAP_CONTROL */ +- 0x0000, /* 0x0102, DAP_PEQ */ +- 0x0040, /* 0x0104, DAP_BASS_ENHANCE */ +- 0x051f, /* 0x0106, DAP_BASS_ENHANCE_CTRL */ +- 0x0000, /* 0x0108, DAP_AUDIO_EQ */ +- 0x0040, /* 0x010A, DAP_SGTL_SURROUND */ +- 0x0000, /* 0x010C, DAP_FILTER_COEF_ACCESS */ +- 0x0000, /* 0x010E, DAP_COEF_WR_B0_MSB */ +- 0x0000, /* 0x0110, DAP_COEF_WR_B0_LSB */ +- 0x0000, /* 0x0112, reserved */ +- 0x0000, /* 0x0114, reserved */ +- 0x002f, /* 0x0116, DAP_AUDIO_EQ_BASS_BAND0 */ +- 0x002f, /* 0x0118, DAP_AUDIO_EQ_BAND0 */ +- 0x002f, /* 0x011A, DAP_AUDIO_EQ_BAND2 */ +- 0x002f, /* 0x011C, DAP_AUDIO_EQ_BAND3 */ +- 0x002f, /* 0x011E, DAP_AUDIO_EQ_TREBLE_BAND4 */ +- 0x8000, /* 0x0120, DAP_MAIN_CHAN */ +- 0x0000, /* 0x0122, DAP_MIX_CHAN */ +- 0x0510, /* 0x0124, DAP_AVC_CTRL */ +- 0x1473, /* 0x0126, DAP_AVC_THRESHOLD */ +- 0x0028, /* 0x0128, DAP_AVC_ATTACK */ +- 0x0050, /* 0x012A, DAP_AVC_DECAY */ +- 0x0000, /* 0x012C, DAP_COEF_WR_B1_MSB */ +- 0x0000, /* 0x012E, DAP_COEF_WR_B1_LSB */ +- 0x0000, /* 0x0130, DAP_COEF_WR_B2_MSB */ +- 0x0000, /* 0x0132, DAP_COEF_WR_B2_LSB */ +- 0x0000, /* 0x0134, DAP_COEF_WR_A1_MSB */ +- 0x0000, /* 0x0136, DAP_COEF_WR_A1_LSB */ +- 0x0000, /* 0x0138, DAP_COEF_WR_A2_MSB */ +- 0x0000, /* 0x013A, DAP_COEF_WR_A2_LSB */ ++/* default value of sgtl5000 registers */ ++static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET] = { ++ [SGTL5000_CHIP_CLK_CTRL] = 0x0008, ++ [SGTL5000_CHIP_I2S_CTRL] = 0x0010, ++ [SGTL5000_CHIP_SSS_CTRL] = 0x0008, ++ [SGTL5000_CHIP_DAC_VOL] = 0x3c3c, ++ [SGTL5000_CHIP_PAD_STRENGTH] = 0x015f, ++ [SGTL5000_CHIP_ANA_HP_CTRL] = 0x1818, ++ [SGTL5000_CHIP_ANA_CTRL] = 0x0111, ++ [SGTL5000_CHIP_LINE_OUT_VOL] = 0x0404, ++ [SGTL5000_CHIP_ANA_POWER] = 0x7060, ++ [SGTL5000_CHIP_PLL_CTRL] = 0x5000, ++ [SGTL5000_DAP_BASS_ENHANCE] = 0x0040, ++ [SGTL5000_DAP_BASS_ENHANCE_CTRL] = 0x051f, ++ [SGTL5000_DAP_SURROUND] = 0x0040, ++ [SGTL5000_DAP_EQ_BASS_BAND0] = 0x002f, ++ [SGTL5000_DAP_EQ_BASS_BAND1] = 0x002f, ++ [SGTL5000_DAP_EQ_BASS_BAND2] = 0x002f, ++ [SGTL5000_DAP_EQ_BASS_BAND3] = 0x002f, ++ [SGTL5000_DAP_EQ_BASS_BAND4] = 0x002f, ++ [SGTL5000_DAP_MAIN_CHAN] = 0x8000, ++ [SGTL5000_DAP_AVC_CTRL] = 0x0510, ++ [SGTL5000_DAP_AVC_THRESHOLD] = 0x1473, ++ [SGTL5000_DAP_AVC_ATTACK] = 0x0028, ++ [SGTL5000_DAP_AVC_DECAY] = 0x0050, + }; + + /* regulator supplies for sgtl5000, VDDD is an optional external supply */ +@@ -1022,12 +980,10 @@ static int sgtl5000_suspend(struct snd_soc_codec *codec, pm_message_t state) + static int sgtl5000_restore_regs(struct snd_soc_codec *codec) + { + u16 *cache = codec->reg_cache; +- int i; +- int regular_regs = SGTL5000_CHIP_SHORT_CTRL >> 1; ++ u16 reg; + + /* restore regular registers */ +- for (i = 0; i < regular_regs; i++) { +- int reg = i << 1; ++ for (reg = 0; reg <= SGTL5000_CHIP_SHORT_CTRL; reg += 2) { + + /* this regs depends on the others */ + if (reg == SGTL5000_CHIP_ANA_POWER || +@@ -1037,35 +993,31 @@ static int sgtl5000_restore_regs(struct snd_soc_codec *codec) + reg == SGTL5000_CHIP_CLK_CTRL) + continue; + +- snd_soc_write(codec, reg, cache[i]); ++ snd_soc_write(codec, reg, cache[reg]); + } + + /* restore dap registers */ +- for (i = SGTL5000_DAP_REG_OFFSET >> 1; +- i < SGTL5000_MAX_REG_OFFSET >> 1; i++) { +- int reg = i << 1; +- +- snd_soc_write(codec, reg, cache[i]); +- } ++ for (reg = SGTL5000_DAP_REG_OFFSET; reg < SGTL5000_MAX_REG_OFFSET; reg += 2) ++ snd_soc_write(codec, reg, cache[reg]); + + /* + * restore power and other regs according + * to set_power() and set_clock() + */ + snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL, +- cache[SGTL5000_CHIP_LINREG_CTRL >> 1]); ++ cache[SGTL5000_CHIP_LINREG_CTRL]); + + snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER, +- cache[SGTL5000_CHIP_ANA_POWER >> 1]); ++ cache[SGTL5000_CHIP_ANA_POWER]); + + snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL, +- cache[SGTL5000_CHIP_CLK_CTRL >> 1]); ++ cache[SGTL5000_CHIP_CLK_CTRL]); + + snd_soc_write(codec, SGTL5000_CHIP_REF_CTRL, +- cache[SGTL5000_CHIP_REF_CTRL >> 1]); ++ cache[SGTL5000_CHIP_REF_CTRL]); + + snd_soc_write(codec, SGTL5000_CHIP_LINE_OUT_CTRL, +- cache[SGTL5000_CHIP_LINE_OUT_CTRL >> 1]); ++ cache[SGTL5000_CHIP_LINE_OUT_CTRL]); + return 0; + } + +@@ -1460,16 +1412,6 @@ static __devinit int sgtl5000_i2c_probe(struct i2c_client *client, + if (!sgtl5000) + return -ENOMEM; + +- /* +- * copy DAP default values to default value array. +- * sgtl5000 register space has a big hole, merge it +- * at init phase makes life easy. +- * FIXME: should we drop 'const' of sgtl5000_regs? +- */ +- memcpy((void *)(&sgtl5000_regs[0] + (SGTL5000_DAP_REG_OFFSET >> 1)), +- sgtl5000_dap_regs, +- SGTL5000_MAX_REG_OFFSET - SGTL5000_DAP_REG_OFFSET); +- + i2c_set_clientdata(client, sgtl5000); + + ret = snd_soc_register_codec(&client->dev, +diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c +index 4432ef7..a213813 100644 +--- a/sound/usb/caiaq/input.c ++++ b/sound/usb/caiaq/input.c +@@ -30,7 +30,7 @@ static unsigned short keycode_ak1[] = { KEY_C, KEY_B, KEY_A }; + static unsigned short keycode_rk2[] = { KEY_1, KEY_2, KEY_3, KEY_4, + KEY_5, KEY_6, KEY_7 }; + static unsigned short keycode_rk3[] = { KEY_1, KEY_2, KEY_3, KEY_4, +- KEY_5, KEY_6, KEY_7, KEY_5, KEY_6 }; ++ KEY_5, KEY_6, KEY_7, KEY_8, KEY_9 }; + + static unsigned short keycode_kore[] = { + KEY_FN_F1, /* "menu" */ +diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c +index b0ef9f5..05842c8 100644 +--- a/sound/usb/endpoint.c ++++ b/sound/usb/endpoint.c +@@ -352,7 +352,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) + continue; + } + if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) || +- ((protocol == UAC_VERSION_2) && (fmt->bLength != 6))) { ++ ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) { + snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", + dev->devnum, iface_no, altno); + continue; +diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c +index c22fa76..c04d7c7 100644 +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -1191,6 +1191,11 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void + + if (state->mixer->protocol == UAC_VERSION_1) { + csize = hdr->bControlSize; ++ if (!csize) { ++ snd_printdd(KERN_ERR "usbaudio: unit %u: " ++ "invalid bControlSize == 0\n", unitid); ++ return -EINVAL; ++ } + channels = (hdr->bLength - 7) / csize - 1; + bmaControls = hdr->bmaControls; + } else { +@@ -1934,15 +1939,13 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) + struct mixer_build state; + int err; + const struct usbmix_ctl_map *map; +- struct usb_host_interface *hostif; + void *p; + +- hostif = mixer->chip->ctrl_intf; + memset(&state, 0, sizeof(state)); + state.chip = mixer->chip; + state.mixer = mixer; +- state.buffer = hostif->extra; +- state.buflen = hostif->extralen; ++ state.buffer = mixer->hostif->extra; ++ state.buflen = mixer->hostif->extralen; + + /* check the mapping table */ + for (map = usbmix_ctl_maps; map->id; map++) { +@@ -1955,7 +1958,8 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) + } + + p = NULL; +- while ((p = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, p, UAC_OUTPUT_TERMINAL)) != NULL) { ++ while ((p = snd_usb_find_csint_desc(mixer->hostif->extra, mixer->hostif->extralen, ++ p, UAC_OUTPUT_TERMINAL)) != NULL) { + if (mixer->protocol == UAC_VERSION_1) { + struct uac1_output_terminal_descriptor *desc = p; + +@@ -2162,17 +2166,15 @@ int snd_usb_mixer_activate(struct usb_mixer_interface *mixer) + /* create the handler for the optional status interrupt endpoint */ + static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer) + { +- struct usb_host_interface *hostif; + struct usb_endpoint_descriptor *ep; + void *transfer_buffer; + int buffer_length; + unsigned int epnum; + +- hostif = mixer->chip->ctrl_intf; + /* we need one interrupt input endpoint */ +- if (get_iface_desc(hostif)->bNumEndpoints < 1) ++ if (get_iface_desc(mixer->hostif)->bNumEndpoints < 1) + return 0; +- ep = get_endpoint(hostif, 0); ++ ep = get_endpoint(mixer->hostif, 0); + if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_int(ep)) + return 0; + +@@ -2202,7 +2204,6 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, + }; + struct usb_mixer_interface *mixer; + struct snd_info_entry *entry; +- struct usb_host_interface *host_iface; + int err; + + strcpy(chip->card->mixername, "USB Mixer"); +@@ -2219,8 +2220,8 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, + return -ENOMEM; + } + +- host_iface = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0]; +- switch (get_iface_desc(host_iface)->bInterfaceProtocol) { ++ mixer->hostif = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0]; ++ switch (get_iface_desc(mixer->hostif)->bInterfaceProtocol) { + case UAC_VERSION_1: + default: + mixer->protocol = UAC_VERSION_1; +diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h +index ae1a14d..81b2d8a 100644 +--- a/sound/usb/mixer.h ++++ b/sound/usb/mixer.h +@@ -3,6 +3,7 @@ + + struct usb_mixer_interface { + struct snd_usb_audio *chip; ++ struct usb_host_interface *hostif; + struct list_head list; + unsigned int ignore_ctl_error; + struct urb *urb; diff --git a/debian/patches/bugfix/all/stable/gen-patch b/debian/patches/bugfix/all/stable/gen-patch index 380803877..8e5625939 100755 --- a/debian/patches/bugfix/all/stable/gen-patch +++ b/debian/patches/bugfix/all/stable/gen-patch @@ -6,7 +6,7 @@ from debian_linux.config import ConfigCoreHierarchy from debian_linux.debian import Changelog class Version(object): - _rules = ur"^(\d+\.\d+\.\d+)\.(\d+)$" + _rules = ur"^(\d+\.\d+)\.(\d+)$" _re = re.compile(_rules) def __init__(self, version): diff --git a/debian/patches/features/all/rt/gen-patch b/debian/patches/features/all/rt/gen-patch old mode 100644 new mode 100755 diff --git a/debian/rules.real b/debian/rules.real index b3234b5d0..649f10ad4 100644 --- a/debian/rules.real +++ b/debian/rules.real @@ -8,6 +8,7 @@ SHELL := bash -e DEB_HOST_ARCH := $(shell dpkg-architecture -a'$(ARCH)' -qDEB_HOST_ARCH) DEB_HOST_GNU_TYPE := $(shell dpkg-architecture -a'$(ARCH)' -qDEB_HOST_GNU_TYPE) +DEB_HOST_MULTIARCH:= $(shell dpkg-architecture -a'$(ARCH)' -qDEB_HOST_MULTIARCH) DEB_BUILD_ARCH := $(shell dpkg-architecture -a'$(ARCH)' -qDEB_BUILD_ARCH) UPLOADER := $(shell dpkg-parsechangelog | sed -ne 's,^Maintainer: .[^<]*<\([^>]*\)>,\1,p') @@ -310,8 +311,8 @@ install-libc-dev_$(ARCH): find $(OUT_DIR)/include \( -name .install -o -name ..install.cmd \) -execdir rm {} + # Move include/asm to arch-specific directory - mkdir -p $(OUT_DIR)/$(DEB_HOST_GNU_TYPE)/include - mv $(OUT_DIR)/include/asm $(OUT_DIR)/$(DEB_HOST_GNU_TYPE)/include/ + mkdir -p $(OUT_DIR)/include/$(DEB_HOST_MULTIARCH) + mv $(OUT_DIR)/include/asm $(OUT_DIR)/include/$(DEB_HOST_MULTIARCH)/ +$(MAKE_SELF) install-base