diff options
author | 2013-10-27 11:03:11 -0400 | |
---|---|---|
committer | 2013-10-27 11:03:11 -0400 | |
commit | 1ec392f3e79af1daa039ffd7fd5245ec48584a3b (patch) | |
tree | 1926f183e81d1ddc79347e6951ee6808c27dd00a | |
parent | Grsec/PaX: 2.9.1-{3.2.51,3.11.6}-201310191259 (diff) | |
download | hardened-patchset-1ec392f3e79af1daa039ffd7fd5245ec48584a3b.tar.gz hardened-patchset-1ec392f3e79af1daa039ffd7fd5245ec48584a3b.tar.bz2 hardened-patchset-1ec392f3e79af1daa039ffd7fd5245ec48584a3b.zip |
Grsec/PaX: 2.9.1-{3.2.51,3.11.6}-20131026085020131026
-rw-r--r-- | 3.11.6/0000_README | 6 | ||||
-rw-r--r-- | 3.11.6/1005_linux-3.11.6.patch | 2260 | ||||
-rw-r--r-- | 3.11.6/4420_grsecurity-2.9.1-3.11.6-201310260850.patch (renamed from 3.11.6/4420_grsecurity-2.9.1-3.11.6-201310191259.patch) | 23 | ||||
-rw-r--r-- | 3.2.51/0000_README | 2 | ||||
-rw-r--r-- | 3.2.51/4420_grsecurity-2.9.1-3.2.51-201310260849.patch (renamed from 3.2.51/4420_grsecurity-2.9.1-3.2.51-201310191257.patch) | 17 |
5 files changed, 18 insertions, 2290 deletions
diff --git a/3.11.6/0000_README b/3.11.6/0000_README index db9995c..2d9249d 100644 --- a/3.11.6/0000_README +++ b/3.11.6/0000_README @@ -2,11 +2,7 @@ README ----------------------------------------------------------------------------- Individual Patch Descriptions: ----------------------------------------------------------------------------- -Patch: 1005_linux-3.11.6.patch -From: http://www.kernel.org -Desc: Linux 3.11.6 - -Patch: 4420_grsecurity-2.9.1-3.11.6-201310191259.patch +Patch: 4420_grsecurity-2.9.1-3.11.6-201310260850.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.11.6/1005_linux-3.11.6.patch b/3.11.6/1005_linux-3.11.6.patch deleted file mode 100644 index ad3cb53..0000000 --- a/3.11.6/1005_linux-3.11.6.patch +++ /dev/null @@ -1,2260 +0,0 @@ -diff --git a/Makefile b/Makefile -index 83121b7..e87ba83 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,6 +1,6 @@ - VERSION = 3 - PATCHLEVEL = 11 --SUBLEVEL = 5 -+SUBLEVEL = 6 - EXTRAVERSION = - NAME = Linux for Workgroups - -diff --git a/arch/arc/include/asm/delay.h b/arch/arc/include/asm/delay.h -index 442ce5d..43de302 100644 ---- a/arch/arc/include/asm/delay.h -+++ b/arch/arc/include/asm/delay.h -@@ -53,11 +53,10 @@ static inline void __udelay(unsigned long usecs) - { - unsigned long loops; - -- /* (long long) cast ensures 64 bit MPY - real or emulated -+ /* (u64) cast ensures 64 bit MPY - real or emulated - * HZ * 4295 is pre-evaluated by gcc - hence only 2 mpy ops - */ -- loops = ((long long)(usecs * 4295 * HZ) * -- (long long)(loops_per_jiffy)) >> 32; -+ loops = ((u64) usecs * 4295 * HZ * loops_per_jiffy) >> 32; - - __delay(loops); - } -diff --git a/arch/arc/include/asm/spinlock.h b/arch/arc/include/asm/spinlock.h -index f158197..b6a8c2d 100644 ---- a/arch/arc/include/asm/spinlock.h -+++ b/arch/arc/include/asm/spinlock.h -@@ -45,7 +45,14 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock) - - static inline void arch_spin_unlock(arch_spinlock_t *lock) - { -- lock->slock = __ARCH_SPIN_LOCK_UNLOCKED__; -+ unsigned int tmp = __ARCH_SPIN_LOCK_UNLOCKED__; -+ -+ __asm__ __volatile__( -+ " ex %0, [%1] \n" -+ : "+r" (tmp) -+ : "r"(&(lock->slock)) -+ : "memory"); -+ - smp_mb(); - } - -diff --git a/arch/arc/include/asm/uaccess.h b/arch/arc/include/asm/uaccess.h -index 3242082..30c9baf 100644 ---- a/arch/arc/include/asm/uaccess.h -+++ b/arch/arc/include/asm/uaccess.h -@@ -43,7 +43,7 @@ - * Because it essentially checks if buffer end is within limit and @len is - * non-ngeative, which implies that buffer start will be within limit too. - * -- * The reason for rewriting being, for majorit yof cases, @len is generally -+ * The reason for rewriting being, for majority of cases, @len is generally - * compile time constant, causing first sub-expression to be compile time - * subsumed. - * -@@ -53,7 +53,7 @@ - * - */ - #define __user_ok(addr, sz) (((sz) <= TASK_SIZE) && \ -- (((addr)+(sz)) <= get_fs())) -+ ((addr) <= (get_fs() - (sz)))) - #define __access_ok(addr, sz) (unlikely(__kernel_ok) || \ - likely(__user_ok((addr), (sz)))) - -diff --git a/arch/arc/kernel/ptrace.c b/arch/arc/kernel/ptrace.c -index 3332385..5d76706 100644 ---- a/arch/arc/kernel/ptrace.c -+++ b/arch/arc/kernel/ptrace.c -@@ -102,7 +102,7 @@ static int genregs_set(struct task_struct *target, - REG_IGNORE_ONE(pad2); - REG_IN_CHUNK(callee, efa, cregs); /* callee_regs[r25..r13] */ - REG_IGNORE_ONE(efa); /* efa update invalid */ -- REG_IN_ONE(stop_pc, &ptregs->ret); /* stop_pc: PC update */ -+ REG_IGNORE_ONE(stop_pc); /* PC updated via @ret */ - - return ret; - } -diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c -index ee6ef2f..7e95e1a 100644 ---- a/arch/arc/kernel/signal.c -+++ b/arch/arc/kernel/signal.c -@@ -101,7 +101,6 @@ SYSCALL_DEFINE0(rt_sigreturn) - { - struct rt_sigframe __user *sf; - unsigned int magic; -- int err; - struct pt_regs *regs = current_pt_regs(); - - /* Always make any pending restarted system calls return -EINTR */ -@@ -119,15 +118,16 @@ SYSCALL_DEFINE0(rt_sigreturn) - if (!access_ok(VERIFY_READ, sf, sizeof(*sf))) - goto badframe; - -- err = restore_usr_regs(regs, sf); -- err |= __get_user(magic, &sf->sigret_magic); -- if (err) -+ if (__get_user(magic, &sf->sigret_magic)) - goto badframe; - - if (unlikely(is_do_ss_needed(magic))) - if (restore_altstack(&sf->uc.uc_stack)) - goto badframe; - -+ if (restore_usr_regs(regs, sf)) -+ goto badframe; -+ - /* Don't restart from sigreturn */ - syscall_wont_restart(regs); - -@@ -191,6 +191,15 @@ setup_rt_frame(int signo, struct k_sigaction *ka, siginfo_t *info, - return 1; - - /* -+ * w/o SA_SIGINFO, struct ucontext is partially populated (only -+ * uc_mcontext/uc_sigmask) for kernel's normal user state preservation -+ * during signal handler execution. This works for SA_SIGINFO as well -+ * although the semantics are now overloaded (the same reg state can be -+ * inspected by userland: but are they allowed to fiddle with it ? -+ */ -+ err |= stash_usr_regs(sf, regs, set); -+ -+ /* - * SA_SIGINFO requires 3 args to signal handler: - * #1: sig-no (common to any handler) - * #2: struct siginfo -@@ -213,14 +222,6 @@ setup_rt_frame(int signo, struct k_sigaction *ka, siginfo_t *info, - magic = MAGIC_SIGALTSTK; - } - -- /* -- * w/o SA_SIGINFO, struct ucontext is partially populated (only -- * uc_mcontext/uc_sigmask) for kernel's normal user state preservation -- * during signal handler execution. This works for SA_SIGINFO as well -- * although the semantics are now overloaded (the same reg state can be -- * inspected by userland: but are they allowed to fiddle with it ? -- */ -- err |= stash_usr_regs(sf, regs, set); - err |= __put_user(magic, &sf->sigret_magic); - if (err) - return err; -diff --git a/arch/arc/kernel/unaligned.c b/arch/arc/kernel/unaligned.c -index c0f832f..00ad070 100644 ---- a/arch/arc/kernel/unaligned.c -+++ b/arch/arc/kernel/unaligned.c -@@ -233,6 +233,12 @@ int misaligned_fixup(unsigned long address, struct pt_regs *regs, - regs->status32 &= ~STATUS_DE_MASK; - } else { - regs->ret += state.instr_len; -+ -+ /* handle zero-overhead-loop */ -+ if ((regs->ret == regs->lp_end) && (regs->lp_count)) { -+ regs->ret = regs->lp_start; -+ regs->lp_count--; -+ } - } - - return 0; -diff --git a/arch/arm/include/asm/jump_label.h b/arch/arm/include/asm/jump_label.h -index bfc198c..863c892 100644 ---- a/arch/arm/include/asm/jump_label.h -+++ b/arch/arm/include/asm/jump_label.h -@@ -16,7 +16,7 @@ - - static __always_inline bool arch_static_branch(struct static_key *key) - { -- asm goto("1:\n\t" -+ asm_volatile_goto("1:\n\t" - JUMP_LABEL_NOP "\n\t" - ".pushsection __jump_table, \"aw\"\n\t" - ".word 1b, %l[l_yes], %c0\n\t" -diff --git a/arch/mips/include/asm/jump_label.h b/arch/mips/include/asm/jump_label.h -index 4d6d77e..e194f95 100644 ---- a/arch/mips/include/asm/jump_label.h -+++ b/arch/mips/include/asm/jump_label.h -@@ -22,7 +22,7 @@ - - static __always_inline bool arch_static_branch(struct static_key *key) - { -- asm goto("1:\tnop\n\t" -+ asm_volatile_goto("1:\tnop\n\t" - "nop\n\t" - ".pushsection __jump_table, \"aw\"\n\t" - WORD_INSN " 1b, %l[l_yes], %0\n\t" -diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S -index 4204d76..029e002 100644 ---- a/arch/mips/kernel/octeon_switch.S -+++ b/arch/mips/kernel/octeon_switch.S -@@ -73,7 +73,7 @@ - 3: - - #if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP) -- PTR_L t8, __stack_chk_guard -+ PTR_LA t8, __stack_chk_guard - LONG_L t9, TASK_STACK_CANARY(a1) - LONG_S t9, 0(t8) - #endif -diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S -index 38af83f..20b7b04 100644 ---- a/arch/mips/kernel/r2300_switch.S -+++ b/arch/mips/kernel/r2300_switch.S -@@ -67,7 +67,7 @@ LEAF(resume) - 1: - - #if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP) -- PTR_L t8, __stack_chk_guard -+ PTR_LA t8, __stack_chk_guard - LONG_L t9, TASK_STACK_CANARY(a1) - LONG_S t9, 0(t8) - #endif -diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S -index 921238a..078de5e 100644 ---- a/arch/mips/kernel/r4k_switch.S -+++ b/arch/mips/kernel/r4k_switch.S -@@ -69,7 +69,7 @@ - 1: - - #if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP) -- PTR_L t8, __stack_chk_guard -+ PTR_LA t8, __stack_chk_guard - LONG_L t9, TASK_STACK_CANARY(a1) - LONG_S t9, 0(t8) - #endif -diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c -index 04e47c6..b3f87a3 100644 ---- a/arch/parisc/kernel/traps.c -+++ b/arch/parisc/kernel/traps.c -@@ -805,14 +805,14 @@ void notrace handle_interruption(int code, struct pt_regs *regs) - else { - - /* -- * The kernel should never fault on its own address space. -+ * The kernel should never fault on its own address space, -+ * unless pagefault_disable() was called before. - */ - -- if (fault_space == 0) -+ if (fault_space == 0 && !in_atomic()) - { - pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC); - parisc_terminate("Kernel Fault", regs, code, fault_address); -- - } - } - -diff --git a/arch/powerpc/include/asm/jump_label.h b/arch/powerpc/include/asm/jump_label.h -index ae098c4..f016bb6 100644 ---- a/arch/powerpc/include/asm/jump_label.h -+++ b/arch/powerpc/include/asm/jump_label.h -@@ -19,7 +19,7 @@ - - static __always_inline bool arch_static_branch(struct static_key *key) - { -- asm goto("1:\n\t" -+ asm_volatile_goto("1:\n\t" - "nop\n\t" - ".pushsection __jump_table, \"aw\"\n\t" - JUMP_ENTRY_TYPE "1b, %l[l_yes], %c0\n\t" -diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S -index b02f91e..7bcd4d6 100644 ---- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S -+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S -@@ -1054,7 +1054,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) - BEGIN_FTR_SECTION - mfspr r8, SPRN_DSCR - ld r7, HSTATE_DSCR(r13) -- std r8, VCPU_DSCR(r7) -+ std r8, VCPU_DSCR(r9) - mtspr SPRN_DSCR, r7 - END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) - -diff --git a/arch/s390/include/asm/jump_label.h b/arch/s390/include/asm/jump_label.h -index 6c32190..346b1c8 100644 ---- a/arch/s390/include/asm/jump_label.h -+++ b/arch/s390/include/asm/jump_label.h -@@ -15,7 +15,7 @@ - - static __always_inline bool arch_static_branch(struct static_key *key) - { -- asm goto("0: brcl 0,0\n" -+ asm_volatile_goto("0: brcl 0,0\n" - ".pushsection __jump_table, \"aw\"\n" - ASM_ALIGN "\n" - ASM_PTR " 0b, %l[label], %0\n" -diff --git a/arch/sparc/include/asm/jump_label.h b/arch/sparc/include/asm/jump_label.h -index 5080d16..ec2e2e2 100644 ---- a/arch/sparc/include/asm/jump_label.h -+++ b/arch/sparc/include/asm/jump_label.h -@@ -9,7 +9,7 @@ - - static __always_inline bool arch_static_branch(struct static_key *key) - { -- asm goto("1:\n\t" -+ asm_volatile_goto("1:\n\t" - "nop\n\t" - "nop\n\t" - ".pushsection __jump_table, \"aw\"\n\t" -diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h -index 47538a6..7290585 100644 ---- a/arch/x86/include/asm/cpufeature.h -+++ b/arch/x86/include/asm/cpufeature.h -@@ -373,7 +373,7 @@ static __always_inline __pure bool __static_cpu_has(u16 bit) - * Catch too early usage of this before alternatives - * have run. - */ -- asm goto("1: jmp %l[t_warn]\n" -+ asm_volatile_goto("1: jmp %l[t_warn]\n" - "2:\n" - ".section .altinstructions,\"a\"\n" - " .long 1b - .\n" -@@ -386,7 +386,7 @@ static __always_inline __pure bool __static_cpu_has(u16 bit) - : : "i" (X86_FEATURE_ALWAYS) : : t_warn); - #endif - -- asm goto("1: jmp %l[t_no]\n" -+ asm_volatile_goto("1: jmp %l[t_no]\n" - "2:\n" - ".section .altinstructions,\"a\"\n" - " .long 1b - .\n" -@@ -448,7 +448,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) - * have. Thus, we force the jump to the widest, 4-byte, signed relative - * offset even though the last would often fit in less bytes. - */ -- asm goto("1: .byte 0xe9\n .long %l[t_dynamic] - 2f\n" -+ asm_volatile_goto("1: .byte 0xe9\n .long %l[t_dynamic] - 2f\n" - "2:\n" - ".section .altinstructions,\"a\"\n" - " .long 1b - .\n" /* src offset */ -diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h -index cccd07f..779c2ef 100644 ---- a/arch/x86/include/asm/e820.h -+++ b/arch/x86/include/asm/e820.h -@@ -29,7 +29,7 @@ extern void e820_setup_gap(void); - extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize, - unsigned long start_addr, unsigned long long end_addr); - struct setup_data; --extern void parse_e820_ext(struct setup_data *data); -+extern void parse_e820_ext(u64 phys_addr, u32 data_len); - - #if defined(CONFIG_X86_64) || \ - (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION)) -diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h -index 3a16c14..0297669 100644 ---- a/arch/x86/include/asm/jump_label.h -+++ b/arch/x86/include/asm/jump_label.h -@@ -13,7 +13,7 @@ - - static __always_inline bool arch_static_branch(struct static_key *key) - { -- asm goto("1:" -+ asm_volatile_goto("1:" - STATIC_KEY_INITIAL_NOP - ".pushsection __jump_table, \"aw\" \n\t" - _ASM_ALIGN "\n\t" -diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c -index d32abea..174da5f 100644 ---- a/arch/x86/kernel/e820.c -+++ b/arch/x86/kernel/e820.c -@@ -658,15 +658,18 @@ __init void e820_setup_gap(void) - * boot_params.e820_map, others are passed via SETUP_E820_EXT node of - * linked list of struct setup_data, which is parsed here. - */ --void __init parse_e820_ext(struct setup_data *sdata) -+void __init parse_e820_ext(u64 phys_addr, u32 data_len) - { - int entries; - struct e820entry *extmap; -+ struct setup_data *sdata; - -+ sdata = early_memremap(phys_addr, data_len); - entries = sdata->len / sizeof(struct e820entry); - extmap = (struct e820entry *)(sdata->data); - __append_e820_map(extmap, entries); - sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); -+ early_iounmap(sdata, data_len); - printk(KERN_INFO "e820: extended physical RAM map:\n"); - e820_print_map("extended"); - } -diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c -index f8ec578..234e1e3 100644 ---- a/arch/x86/kernel/setup.c -+++ b/arch/x86/kernel/setup.c -@@ -426,25 +426,23 @@ static void __init reserve_initrd(void) - static void __init parse_setup_data(void) - { - struct setup_data *data; -- u64 pa_data; -+ u64 pa_data, pa_next; - - pa_data = boot_params.hdr.setup_data; - while (pa_data) { -- u32 data_len, map_len; -+ u32 data_len, map_len, data_type; - - map_len = max(PAGE_SIZE - (pa_data & ~PAGE_MASK), - (u64)sizeof(struct setup_data)); - data = early_memremap(pa_data, map_len); - data_len = data->len + sizeof(struct setup_data); -- if (data_len > map_len) { -- early_iounmap(data, map_len); -- data = early_memremap(pa_data, data_len); -- map_len = data_len; -- } -+ data_type = data->type; -+ pa_next = data->next; -+ early_iounmap(data, map_len); - -- switch (data->type) { -+ switch (data_type) { - case SETUP_E820_EXT: -- parse_e820_ext(data); -+ parse_e820_ext(pa_data, data_len); - break; - case SETUP_DTB: - add_dtb(pa_data); -@@ -452,8 +450,7 @@ static void __init parse_setup_data(void) - default: - break; - } -- pa_data = data->next; -- early_iounmap(data, map_len); -+ pa_data = pa_next; - } - } - -diff --git a/drivers/char/random.c b/drivers/char/random.c -index 0d91fe5..92e6c67 100644 ---- a/drivers/char/random.c -+++ b/drivers/char/random.c -@@ -1462,12 +1462,11 @@ struct ctl_table random_table[] = { - - static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; - --static int __init random_int_secret_init(void) -+int random_int_secret_init(void) - { - get_random_bytes(random_int_secret, sizeof(random_int_secret)); - return 0; - } --late_initcall(random_int_secret_init); - - /* - * Get a random word for internal kernel use only. Similar to urandom but -diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h -index 342f1f3..c42d31c 100644 ---- a/drivers/gpu/drm/i915/i915_reg.h -+++ b/drivers/gpu/drm/i915/i915_reg.h -@@ -3791,6 +3791,9 @@ - #define GEN7_SQ_CHICKEN_MBCUNIT_CONFIG 0x9030 - #define GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB (1<<11) - -+#define HSW_SCRATCH1 0xb038 -+#define HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE (1<<27) -+ - #define HSW_FUSE_STRAP 0x42014 - #define HSW_CDCLK_LIMIT (1 << 24) - -@@ -4624,6 +4627,9 @@ - #define GEN7_ROW_CHICKEN2_GT2 0xf4f4 - #define DOP_CLOCK_GATING_DISABLE (1<<0) - -+#define HSW_ROW_CHICKEN3 0xe49c -+#define HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE (1 << 6) -+ - #define G4X_AUD_VID_DID (dev_priv->info->display_mmio_offset + 0x62020) - #define INTEL_AUDIO_DEVCL 0x808629FB - #define INTEL_AUDIO_DEVBLC 0x80862801 -diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c -index 7fc8a76..90a7c17 100644 ---- a/drivers/gpu/drm/i915/intel_display.c -+++ b/drivers/gpu/drm/i915/intel_display.c -@@ -3890,8 +3890,6 @@ static void intel_connector_check_state(struct intel_connector *connector) - * consider. */ - void intel_connector_dpms(struct drm_connector *connector, int mode) - { -- struct intel_encoder *encoder = intel_attached_encoder(connector); -- - /* All the simple cases only support two dpms states. */ - if (mode != DRM_MODE_DPMS_ON) - mode = DRM_MODE_DPMS_OFF; -@@ -3902,10 +3900,8 @@ void intel_connector_dpms(struct drm_connector *connector, int mode) - connector->dpms = mode; - - /* Only need to change hw state when actually enabled */ -- if (encoder->base.crtc) -- intel_encoder_dpms(encoder, mode); -- else -- WARN_ON(encoder->connectors_active != false); -+ if (connector->encoder) -+ intel_encoder_dpms(to_intel_encoder(connector->encoder), mode); - - intel_modeset_check_state(connector->dev); - } -diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c -index b0e4a0b..cad0482 100644 ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -3603,8 +3603,6 @@ static void valleyview_enable_rps(struct drm_device *dev) - dev_priv->rps.rpe_delay), - dev_priv->rps.rpe_delay); - -- INIT_DELAYED_WORK(&dev_priv->rps.vlv_work, vlv_rps_timer_work); -- - valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay); - - /* requires MSI enabled */ -@@ -4699,6 +4697,11 @@ static void haswell_init_clock_gating(struct drm_device *dev) - I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, - GEN7_WA_L3_CHICKEN_MODE); - -+ /* L3 caching of data atomics doesn't work -- disable it. */ -+ I915_WRITE(HSW_SCRATCH1, HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE); -+ I915_WRITE(HSW_ROW_CHICKEN3, -+ _MASKED_BIT_ENABLE(HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE)); -+ - /* This is required by WaCatErrorRejectionIssue:hsw */ - I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, - I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | -@@ -5562,6 +5565,8 @@ void intel_pm_init(struct drm_device *dev) - - INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work, - intel_gen6_powersave_work); -+ -+ INIT_DELAYED_WORK(&dev_priv->rps.vlv_work, vlv_rps_timer_work); - } - - int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val) -diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c -index 084e694..639b9aa 100644 ---- a/drivers/gpu/drm/radeon/btc_dpm.c -+++ b/drivers/gpu/drm/radeon/btc_dpm.c -@@ -1913,7 +1913,7 @@ static int btc_set_mc_special_registers(struct radeon_device *rdev, - } - j++; - -- if (j > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE) -+ if (j >= SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE) - return -EINVAL; - - tmp = RREG32(MC_PMG_CMD_MRS); -@@ -1928,7 +1928,7 @@ static int btc_set_mc_special_registers(struct radeon_device *rdev, - } - j++; - -- if (j > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE) -+ if (j >= SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE) - return -EINVAL; - break; - case MC_SEQ_RESERVE_M >> 2: -@@ -1942,7 +1942,7 @@ static int btc_set_mc_special_registers(struct radeon_device *rdev, - } - j++; - -- if (j > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE) -+ if (j >= SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE) - return -EINVAL; - break; - default: -diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c -index 94dab1e..8307883 100644 ---- a/drivers/gpu/drm/radeon/evergreen.c -+++ b/drivers/gpu/drm/radeon/evergreen.c -@@ -3126,7 +3126,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) - rdev->config.evergreen.sx_max_export_size = 256; - rdev->config.evergreen.sx_max_export_pos_size = 64; - rdev->config.evergreen.sx_max_export_smx_size = 192; -- rdev->config.evergreen.max_hw_contexts = 8; -+ rdev->config.evergreen.max_hw_contexts = 4; - rdev->config.evergreen.sq_num_cf_insts = 2; - - rdev->config.evergreen.sc_prim_fifo_size = 0x40; -diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h -index 20fd17c..6be00c9 100644 ---- a/drivers/gpu/drm/radeon/evergreend.h -+++ b/drivers/gpu/drm/radeon/evergreend.h -@@ -1494,7 +1494,7 @@ - * 6. COMMAND [29:22] | BYTE_COUNT [20:0] - */ - # define PACKET3_CP_DMA_DST_SEL(x) ((x) << 20) -- /* 0 - SRC_ADDR -+ /* 0 - DST_ADDR - * 1 - GDS - */ - # define PACKET3_CP_DMA_ENGINE(x) ((x) << 27) -@@ -1509,7 +1509,7 @@ - # define PACKET3_CP_DMA_CP_SYNC (1 << 31) - /* COMMAND */ - # define PACKET3_CP_DMA_DIS_WC (1 << 21) --# define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 23) -+# define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 22) - /* 0 - none - * 1 - 8 in 16 - * 2 - 8 in 32 -diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h -index 7c78083..d079cb1 100644 ---- a/drivers/gpu/drm/radeon/r600d.h -+++ b/drivers/gpu/drm/radeon/r600d.h -@@ -1487,7 +1487,7 @@ - */ - # define PACKET3_CP_DMA_CP_SYNC (1 << 31) - /* COMMAND */ --# define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 23) -+# define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 22) - /* 0 - none - * 1 - 8 in 16 - * 2 - 8 in 32 -diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c -index f4d6bce..12e8099 100644 ---- a/drivers/gpu/drm/radeon/radeon_test.c -+++ b/drivers/gpu/drm/radeon/radeon_test.c -@@ -36,8 +36,8 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag) - struct radeon_bo *vram_obj = NULL; - struct radeon_bo **gtt_obj = NULL; - uint64_t gtt_addr, vram_addr; -- unsigned i, n, size; -- int r, ring; -+ unsigned n, size; -+ int i, r, ring; - - switch (flag) { - case RADEON_TEST_COPY_DMA: -diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c -index 1cfba39..1c23b61 100644 ---- a/drivers/gpu/drm/radeon/si_dpm.c -+++ b/drivers/gpu/drm/radeon/si_dpm.c -@@ -5174,7 +5174,7 @@ static int si_set_mc_special_registers(struct radeon_device *rdev, - table->mc_reg_table_entry[k].mc_data[j] |= 0x100; - } - j++; -- if (j > SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE) -+ if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE) - return -EINVAL; - - if (!pi->mem_gddr5) { -@@ -5184,7 +5184,7 @@ static int si_set_mc_special_registers(struct radeon_device *rdev, - table->mc_reg_table_entry[k].mc_data[j] = - (table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16; - j++; -- if (j > SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE) -+ if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE) - return -EINVAL; - } - break; -@@ -5197,7 +5197,7 @@ static int si_set_mc_special_registers(struct radeon_device *rdev, - (temp_reg & 0xffff0000) | - (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff); - j++; -- if (j > SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE) -+ if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE) - return -EINVAL; - break; - default: -diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h -index 2010d6b..a75d25a 100644 ---- a/drivers/gpu/drm/radeon/sid.h -+++ b/drivers/gpu/drm/radeon/sid.h -@@ -1490,7 +1490,7 @@ - * 6. COMMAND [30:21] | BYTE_COUNT [20:0] - */ - # define PACKET3_CP_DMA_DST_SEL(x) ((x) << 20) -- /* 0 - SRC_ADDR -+ /* 0 - DST_ADDR - * 1 - GDS - */ - # define PACKET3_CP_DMA_ENGINE(x) ((x) << 27) -@@ -1505,7 +1505,7 @@ - # define PACKET3_CP_DMA_CP_SYNC (1 << 31) - /* COMMAND */ - # define PACKET3_CP_DMA_DIS_WC (1 << 21) --# define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 23) -+# define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 22) - /* 0 - none - * 1 - 8 in 16 - * 2 - 8 in 32 -diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c -index 98814d1..3288f13 100644 ---- a/drivers/hwmon/applesmc.c -+++ b/drivers/hwmon/applesmc.c -@@ -230,6 +230,7 @@ static int send_argument(const char *key) - - static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) - { -+ u8 status, data = 0; - int i; - - if (send_command(cmd) || send_argument(key)) { -@@ -237,6 +238,7 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) - return -EIO; - } - -+ /* This has no effect on newer (2012) SMCs */ - if (send_byte(len, APPLESMC_DATA_PORT)) { - pr_warn("%.4s: read len fail\n", key); - return -EIO; -@@ -250,6 +252,17 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) - buffer[i] = inb(APPLESMC_DATA_PORT); - } - -+ /* Read the data port until bit0 is cleared */ -+ for (i = 0; i < 16; i++) { -+ udelay(APPLESMC_MIN_WAIT); -+ status = inb(APPLESMC_CMD_PORT); -+ if (!(status & 0x01)) -+ break; -+ data = inb(APPLESMC_DATA_PORT); -+ } -+ if (i) -+ pr_warn("flushed %d bytes, last value is: %d\n", i, data); -+ - return 0; - } - -diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c -index 142b694d..e6b8dcd 100644 ---- a/drivers/i2c/busses/i2c-omap.c -+++ b/drivers/i2c/busses/i2c-omap.c -@@ -944,6 +944,9 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) - /* - * ProDB0017052: Clear ARDY bit twice - */ -+ if (stat & OMAP_I2C_STAT_ARDY) -+ omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ARDY); -+ - if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK | - OMAP_I2C_STAT_AL)) { - omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY | -diff --git a/drivers/watchdog/kempld_wdt.c b/drivers/watchdog/kempld_wdt.c -index 491419e..5c3d4df 100644 ---- a/drivers/watchdog/kempld_wdt.c -+++ b/drivers/watchdog/kempld_wdt.c -@@ -35,7 +35,7 @@ - #define KEMPLD_WDT_STAGE_TIMEOUT(x) (0x1b + (x) * 4) - #define KEMPLD_WDT_STAGE_CFG(x) (0x18 + (x)) - #define STAGE_CFG_GET_PRESCALER(x) (((x) & 0x30) >> 4) --#define STAGE_CFG_SET_PRESCALER(x) (((x) & 0x30) << 4) -+#define STAGE_CFG_SET_PRESCALER(x) (((x) & 0x3) << 4) - #define STAGE_CFG_PRESCALER_MASK 0x30 - #define STAGE_CFG_ACTION_MASK 0x7 - #define STAGE_CFG_ASSERT (1 << 3) -diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c -index 4da59b4..381999c 100644 ---- a/drivers/watchdog/ts72xx_wdt.c -+++ b/drivers/watchdog/ts72xx_wdt.c -@@ -310,7 +310,8 @@ static long ts72xx_wdt_ioctl(struct file *file, unsigned int cmd, - - case WDIOC_GETSTATUS: - case WDIOC_GETBOOTSTATUS: -- return put_user(0, p); -+ error = put_user(0, p); -+ break; - - case WDIOC_KEEPALIVE: - ts72xx_wdt_kick(wdt); -diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c -index d3280b2..8220491 100644 ---- a/fs/btrfs/inode.c -+++ b/fs/btrfs/inode.c -@@ -8036,7 +8036,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, - - - /* check for collisions, even if the name isn't there */ -- ret = btrfs_check_dir_item_collision(root, new_dir->i_ino, -+ ret = btrfs_check_dir_item_collision(dest, new_dir->i_ino, - new_dentry->d_name.name, - new_dentry->d_name.len); - -diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c -index c081e34..03e9beb 100644 ---- a/fs/ext4/xattr.c -+++ b/fs/ext4/xattr.c -@@ -1350,6 +1350,8 @@ retry: - s_min_extra_isize) { - tried_min_extra_isize++; - new_extra_isize = s_min_extra_isize; -+ kfree(is); is = NULL; -+ kfree(bs); bs = NULL; - goto retry; - } - error = -1; -diff --git a/fs/statfs.c b/fs/statfs.c -index c219e733..083dc0a 100644 ---- a/fs/statfs.c -+++ b/fs/statfs.c -@@ -94,7 +94,7 @@ retry: - - int fd_statfs(int fd, struct kstatfs *st) - { -- struct fd f = fdget(fd); -+ struct fd f = fdget_raw(fd); - int error = -EBADF; - if (f.file) { - error = vfs_statfs(&f.file->f_path, st); -diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h -index 842de22..ded4299 100644 ---- a/include/linux/compiler-gcc4.h -+++ b/include/linux/compiler-gcc4.h -@@ -65,6 +65,21 @@ - #define __visible __attribute__((externally_visible)) - #endif - -+/* -+ * GCC 'asm goto' miscompiles certain code sequences: -+ * -+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670 -+ * -+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek. -+ * Fixed in GCC 4.8.2 and later versions. -+ * -+ * (asm goto is automatically volatile - the naming reflects this.) -+ */ -+#if GCC_VERSION <= 40801 -+# define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) -+#else -+# define asm_volatile_goto(x...) do { asm goto(x); } while (0) -+#endif - - #ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP - #if GCC_VERSION >= 40400 -diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h -index c4d870b..19c19a5 100644 ---- a/include/linux/ipc_namespace.h -+++ b/include/linux/ipc_namespace.h -@@ -22,7 +22,7 @@ struct ipc_ids { - int in_use; - unsigned short seq; - unsigned short seq_max; -- struct rw_semaphore rw_mutex; -+ struct rw_semaphore rwsem; - struct idr ipcs_idr; - int next_id; - }; -diff --git a/include/linux/random.h b/include/linux/random.h -index 3b9377d..6312dd9 100644 ---- a/include/linux/random.h -+++ b/include/linux/random.h -@@ -17,6 +17,7 @@ extern void add_interrupt_randomness(int irq, int irq_flags); - extern void get_random_bytes(void *buf, int nbytes); - extern void get_random_bytes_arch(void *buf, int nbytes); - void generate_random_uuid(unsigned char uuid_out[16]); -+extern int random_int_secret_init(void); - - #ifndef MODULE - extern const struct file_operations random_fops, urandom_fops; -diff --git a/init/main.c b/init/main.c -index d03d2ec..586cd33 100644 ---- a/init/main.c -+++ b/init/main.c -@@ -75,6 +75,7 @@ - #include <linux/blkdev.h> - #include <linux/elevator.h> - #include <linux/sched_clock.h> -+#include <linux/random.h> - - #include <asm/io.h> - #include <asm/bugs.h> -@@ -778,6 +779,7 @@ static void __init do_basic_setup(void) - do_ctors(); - usermodehelper_enable(); - do_initcalls(); -+ random_int_secret_init(); - } - - static void __init do_pre_smp_initcalls(void) -diff --git a/ipc/msg.c b/ipc/msg.c -index a877c16..558aa91 100644 ---- a/ipc/msg.c -+++ b/ipc/msg.c -@@ -70,8 +70,6 @@ struct msg_sender { - - #define msg_ids(ns) ((ns)->ids[IPC_MSG_IDS]) - --#define msg_unlock(msq) ipc_unlock(&(msq)->q_perm) -- - static void freeque(struct ipc_namespace *, struct kern_ipc_perm *); - static int newque(struct ipc_namespace *, struct ipc_params *); - #ifdef CONFIG_PROC_FS -@@ -181,7 +179,7 @@ static void msg_rcu_free(struct rcu_head *head) - * @ns: namespace - * @params: ptr to the structure that contains the key and msgflg - * -- * Called with msg_ids.rw_mutex held (writer) -+ * Called with msg_ids.rwsem held (writer) - */ - static int newque(struct ipc_namespace *ns, struct ipc_params *params) - { -@@ -267,8 +265,8 @@ static void expunge_all(struct msg_queue *msq, int res) - * removes the message queue from message queue ID IDR, and cleans up all the - * messages associated with this queue. - * -- * msg_ids.rw_mutex (writer) and the spinlock for this message queue are held -- * before freeque() is called. msg_ids.rw_mutex remains locked on exit. -+ * msg_ids.rwsem (writer) and the spinlock for this message queue are held -+ * before freeque() is called. msg_ids.rwsem remains locked on exit. - */ - static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp) - { -@@ -278,7 +276,8 @@ static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp) - expunge_all(msq, -EIDRM); - ss_wakeup(&msq->q_senders, 1); - msg_rmid(ns, msq); -- msg_unlock(msq); -+ ipc_unlock_object(&msq->q_perm); -+ rcu_read_unlock(); - - list_for_each_entry_safe(msg, t, &msq->q_messages, m_list) { - atomic_dec(&ns->msg_hdrs); -@@ -289,7 +288,7 @@ static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp) - } - - /* -- * Called with msg_ids.rw_mutex and ipcp locked. -+ * Called with msg_ids.rwsem and ipcp locked. - */ - static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg) - { -@@ -393,9 +392,9 @@ copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version) - } - - /* -- * This function handles some msgctl commands which require the rw_mutex -+ * This function handles some msgctl commands which require the rwsem - * to be held in write mode. -- * NOTE: no locks must be held, the rw_mutex is taken inside this function. -+ * NOTE: no locks must be held, the rwsem is taken inside this function. - */ - static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd, - struct msqid_ds __user *buf, int version) -@@ -410,7 +409,7 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd, - return -EFAULT; - } - -- down_write(&msg_ids(ns).rw_mutex); -+ down_write(&msg_ids(ns).rwsem); - rcu_read_lock(); - - ipcp = ipcctl_pre_down_nolock(ns, &msg_ids(ns), msqid, cmd, -@@ -466,7 +465,7 @@ out_unlock0: - out_unlock1: - rcu_read_unlock(); - out_up: -- up_write(&msg_ids(ns).rw_mutex); -+ up_write(&msg_ids(ns).rwsem); - return err; - } - -@@ -501,7 +500,7 @@ static int msgctl_nolock(struct ipc_namespace *ns, int msqid, - msginfo.msgmnb = ns->msg_ctlmnb; - msginfo.msgssz = MSGSSZ; - msginfo.msgseg = MSGSEG; -- down_read(&msg_ids(ns).rw_mutex); -+ down_read(&msg_ids(ns).rwsem); - if (cmd == MSG_INFO) { - msginfo.msgpool = msg_ids(ns).in_use; - msginfo.msgmap = atomic_read(&ns->msg_hdrs); -@@ -512,7 +511,7 @@ static int msgctl_nolock(struct ipc_namespace *ns, int msqid, - msginfo.msgtql = MSGTQL; - } - max_id = ipc_get_maxid(&msg_ids(ns)); -- up_read(&msg_ids(ns).rw_mutex); -+ up_read(&msg_ids(ns).rwsem); - if (copy_to_user(buf, &msginfo, sizeof(struct msginfo))) - return -EFAULT; - return (max_id < 0) ? 0 : max_id; -diff --git a/ipc/namespace.c b/ipc/namespace.c -index 7ee61bf..aba9a58 100644 ---- a/ipc/namespace.c -+++ b/ipc/namespace.c -@@ -81,7 +81,7 @@ void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids, - int next_id; - int total, in_use; - -- down_write(&ids->rw_mutex); -+ down_write(&ids->rwsem); - - in_use = ids->in_use; - -@@ -89,11 +89,12 @@ void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids, - perm = idr_find(&ids->ipcs_idr, next_id); - if (perm == NULL) - continue; -- ipc_lock_by_ptr(perm); -+ rcu_read_lock(); -+ ipc_lock_object(perm); - free(ns, perm); - total++; - } -- up_write(&ids->rw_mutex); -+ up_write(&ids->rwsem); - } - - static void free_ipc_ns(struct ipc_namespace *ns) -diff --git a/ipc/sem.c b/ipc/sem.c -index 87614511..8e2bf30 100644 ---- a/ipc/sem.c -+++ b/ipc/sem.c -@@ -248,12 +248,20 @@ static void merge_queues(struct sem_array *sma) - * Caller must own sem_perm.lock. - * New simple ops cannot start, because simple ops first check - * that sem_perm.lock is free. -+ * that a) sem_perm.lock is free and b) complex_count is 0. - */ - static void sem_wait_array(struct sem_array *sma) - { - int i; - struct sem *sem; - -+ if (sma->complex_count) { -+ /* The thread that increased sma->complex_count waited on -+ * all sem->lock locks. Thus we don't need to wait again. -+ */ -+ return; -+ } -+ - for (i = 0; i < sma->sem_nsems; i++) { - sem = sma->sem_base + i; - spin_unlock_wait(&sem->lock); -@@ -365,7 +373,7 @@ static inline void sem_unlock(struct sem_array *sma, int locknum) - } - - /* -- * sem_lock_(check_) routines are called in the paths where the rw_mutex -+ * sem_lock_(check_) routines are called in the paths where the rwsem - * is not held. - * - * The caller holds the RCU read lock. -@@ -464,7 +472,7 @@ static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s) - * @ns: namespace - * @params: ptr to the structure that contains key, semflg and nsems - * -- * Called with sem_ids.rw_mutex held (as a writer) -+ * Called with sem_ids.rwsem held (as a writer) - */ - - static int newary(struct ipc_namespace *ns, struct ipc_params *params) -@@ -529,7 +537,7 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params) - - - /* -- * Called with sem_ids.rw_mutex and ipcp locked. -+ * Called with sem_ids.rwsem and ipcp locked. - */ - static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg) - { -@@ -540,7 +548,7 @@ static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg) - } - - /* -- * Called with sem_ids.rw_mutex and ipcp locked. -+ * Called with sem_ids.rwsem and ipcp locked. - */ - static inline int sem_more_checks(struct kern_ipc_perm *ipcp, - struct ipc_params *params) -@@ -910,6 +918,24 @@ again: - } - - /** -+ * set_semotime(sma, sops) - set sem_otime -+ * @sma: semaphore array -+ * @sops: operations that modified the array, may be NULL -+ * -+ * sem_otime is replicated to avoid cache line trashing. -+ * This function sets one instance to the current time. -+ */ -+static void set_semotime(struct sem_array *sma, struct sembuf *sops) -+{ -+ if (sops == NULL) { -+ sma->sem_base[0].sem_otime = get_seconds(); -+ } else { -+ sma->sem_base[sops[0].sem_num].sem_otime = -+ get_seconds(); -+ } -+} -+ -+/** - * do_smart_update(sma, sops, nsops, otime, pt) - optimized update_queue - * @sma: semaphore array - * @sops: operations that were performed -@@ -959,17 +985,10 @@ static void do_smart_update(struct sem_array *sma, struct sembuf *sops, int nsop - } - } - } -- if (otime) { -- if (sops == NULL) { -- sma->sem_base[0].sem_otime = get_seconds(); -- } else { -- sma->sem_base[sops[0].sem_num].sem_otime = -- get_seconds(); -- } -- } -+ if (otime) -+ set_semotime(sma, sops); - } - -- - /* The following counts are associated to each semaphore: - * semncnt number of tasks waiting on semval being nonzero - * semzcnt number of tasks waiting on semval being zero -@@ -1031,8 +1050,8 @@ static int count_semzcnt (struct sem_array * sma, ushort semnum) - return semzcnt; - } - --/* Free a semaphore set. freeary() is called with sem_ids.rw_mutex locked -- * as a writer and the spinlock for this semaphore set hold. sem_ids.rw_mutex -+/* Free a semaphore set. freeary() is called with sem_ids.rwsem locked -+ * as a writer and the spinlock for this semaphore set hold. sem_ids.rwsem - * remains locked on exit. - */ - static void freeary(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp) -@@ -1152,7 +1171,7 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, - seminfo.semmnu = SEMMNU; - seminfo.semmap = SEMMAP; - seminfo.semume = SEMUME; -- down_read(&sem_ids(ns).rw_mutex); -+ down_read(&sem_ids(ns).rwsem); - if (cmd == SEM_INFO) { - seminfo.semusz = sem_ids(ns).in_use; - seminfo.semaem = ns->used_sems; -@@ -1161,7 +1180,7 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, - seminfo.semaem = SEMAEM; - } - max_id = ipc_get_maxid(&sem_ids(ns)); -- up_read(&sem_ids(ns).rw_mutex); -+ up_read(&sem_ids(ns).rwsem); - if (copy_to_user(p, &seminfo, sizeof(struct seminfo))) - return -EFAULT; - return (max_id < 0) ? 0: max_id; -@@ -1467,9 +1486,9 @@ copy_semid_from_user(struct semid64_ds *out, void __user *buf, int version) - } - - /* -- * This function handles some semctl commands which require the rw_mutex -+ * This function handles some semctl commands which require the rwsem - * to be held in write mode. -- * NOTE: no locks must be held, the rw_mutex is taken inside this function. -+ * NOTE: no locks must be held, the rwsem is taken inside this function. - */ - static int semctl_down(struct ipc_namespace *ns, int semid, - int cmd, int version, void __user *p) -@@ -1484,7 +1503,7 @@ static int semctl_down(struct ipc_namespace *ns, int semid, - return -EFAULT; - } - -- down_write(&sem_ids(ns).rw_mutex); -+ down_write(&sem_ids(ns).rwsem); - rcu_read_lock(); - - ipcp = ipcctl_pre_down_nolock(ns, &sem_ids(ns), semid, cmd, -@@ -1523,7 +1542,7 @@ out_unlock0: - out_unlock1: - rcu_read_unlock(); - out_up: -- up_write(&sem_ids(ns).rw_mutex); -+ up_write(&sem_ids(ns).rwsem); - return err; - } - -@@ -1831,12 +1850,17 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, - - error = perform_atomic_semop(sma, sops, nsops, un, - task_tgid_vnr(current)); -- if (error <= 0) { -- if (alter && error == 0) -+ if (error == 0) { -+ /* If the operation was successful, then do -+ * the required updates. -+ */ -+ if (alter) - do_smart_update(sma, sops, nsops, 1, &tasks); -- -- goto out_unlock_free; -+ else -+ set_semotime(sma, sops); - } -+ if (error <= 0) -+ goto out_unlock_free; - - /* We need to sleep on this operation, so we put the current - * task into the pending queue and go to sleep. -@@ -2095,6 +2119,14 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it) - struct sem_array *sma = it; - time_t sem_otime; - -+ /* -+ * The proc interface isn't aware of sem_lock(), it calls -+ * ipc_lock_object() directly (in sysvipc_find_ipc). -+ * In order to stay compatible with sem_lock(), we must wait until -+ * all simple semop() calls have left their critical regions. -+ */ -+ sem_wait_array(sma); -+ - sem_otime = get_semotime(sma); - - return seq_printf(s, -diff --git a/ipc/shm.c b/ipc/shm.c -index 2d6833d..d697396 100644 ---- a/ipc/shm.c -+++ b/ipc/shm.c -@@ -19,6 +19,9 @@ - * namespaces support - * OpenVZ, SWsoft Inc. - * Pavel Emelianov <xemul@openvz.org> -+ * -+ * Better ipc lock (kern_ipc_perm.lock) handling -+ * Davidlohr Bueso <davidlohr.bueso@hp.com>, June 2013. - */ - - #include <linux/slab.h> -@@ -80,8 +83,8 @@ void shm_init_ns(struct ipc_namespace *ns) - } - - /* -- * Called with shm_ids.rw_mutex (writer) and the shp structure locked. -- * Only shm_ids.rw_mutex remains locked on exit. -+ * Called with shm_ids.rwsem (writer) and the shp structure locked. -+ * Only shm_ids.rwsem remains locked on exit. - */ - static void do_shm_rmid(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp) - { -@@ -124,8 +127,28 @@ void __init shm_init (void) - IPC_SHM_IDS, sysvipc_shm_proc_show); - } - -+static inline struct shmid_kernel *shm_obtain_object(struct ipc_namespace *ns, int id) -+{ -+ struct kern_ipc_perm *ipcp = ipc_obtain_object(&shm_ids(ns), id); -+ -+ if (IS_ERR(ipcp)) -+ return ERR_CAST(ipcp); -+ -+ return container_of(ipcp, struct shmid_kernel, shm_perm); -+} -+ -+static inline struct shmid_kernel *shm_obtain_object_check(struct ipc_namespace *ns, int id) -+{ -+ struct kern_ipc_perm *ipcp = ipc_obtain_object_check(&shm_ids(ns), id); -+ -+ if (IS_ERR(ipcp)) -+ return ERR_CAST(ipcp); -+ -+ return container_of(ipcp, struct shmid_kernel, shm_perm); -+} -+ - /* -- * shm_lock_(check_) routines are called in the paths where the rw_mutex -+ * shm_lock_(check_) routines are called in the paths where the rwsem - * is not necessarily held. - */ - static inline struct shmid_kernel *shm_lock(struct ipc_namespace *ns, int id) -@@ -144,17 +167,6 @@ static inline void shm_lock_by_ptr(struct shmid_kernel *ipcp) - ipc_lock_object(&ipcp->shm_perm); - } - --static inline struct shmid_kernel *shm_lock_check(struct ipc_namespace *ns, -- int id) --{ -- struct kern_ipc_perm *ipcp = ipc_lock_check(&shm_ids(ns), id); -- -- if (IS_ERR(ipcp)) -- return (struct shmid_kernel *)ipcp; -- -- return container_of(ipcp, struct shmid_kernel, shm_perm); --} -- - static void shm_rcu_free(struct rcu_head *head) - { - struct ipc_rcu *p = container_of(head, struct ipc_rcu, rcu); -@@ -191,7 +203,7 @@ static void shm_open(struct vm_area_struct *vma) - * @ns: namespace - * @shp: struct to free - * -- * It has to be called with shp and shm_ids.rw_mutex (writer) locked, -+ * It has to be called with shp and shm_ids.rwsem (writer) locked, - * but returns with shp unlocked and freed. - */ - static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp) -@@ -238,7 +250,7 @@ static void shm_close(struct vm_area_struct *vma) - struct shmid_kernel *shp; - struct ipc_namespace *ns = sfd->ns; - -- down_write(&shm_ids(ns).rw_mutex); -+ down_write(&shm_ids(ns).rwsem); - /* remove from the list of attaches of the shm segment */ - shp = shm_lock(ns, sfd->id); - BUG_ON(IS_ERR(shp)); -@@ -249,10 +261,10 @@ static void shm_close(struct vm_area_struct *vma) - shm_destroy(ns, shp); - else - shm_unlock(shp); -- up_write(&shm_ids(ns).rw_mutex); -+ up_write(&shm_ids(ns).rwsem); - } - --/* Called with ns->shm_ids(ns).rw_mutex locked */ -+/* Called with ns->shm_ids(ns).rwsem locked */ - static int shm_try_destroy_current(int id, void *p, void *data) - { - struct ipc_namespace *ns = data; -@@ -283,7 +295,7 @@ static int shm_try_destroy_current(int id, void *p, void *data) - return 0; - } - --/* Called with ns->shm_ids(ns).rw_mutex locked */ -+/* Called with ns->shm_ids(ns).rwsem locked */ - static int shm_try_destroy_orphaned(int id, void *p, void *data) - { - struct ipc_namespace *ns = data; -@@ -294,7 +306,7 @@ static int shm_try_destroy_orphaned(int id, void *p, void *data) - * We want to destroy segments without users and with already - * exit'ed originating process. - * -- * As shp->* are changed under rw_mutex, it's safe to skip shp locking. -+ * As shp->* are changed under rwsem, it's safe to skip shp locking. - */ - if (shp->shm_creator != NULL) - return 0; -@@ -308,10 +320,10 @@ static int shm_try_destroy_orphaned(int id, void *p, void *data) - - void shm_destroy_orphaned(struct ipc_namespace *ns) - { -- down_write(&shm_ids(ns).rw_mutex); -+ down_write(&shm_ids(ns).rwsem); - if (shm_ids(ns).in_use) - idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_orphaned, ns); -- up_write(&shm_ids(ns).rw_mutex); -+ up_write(&shm_ids(ns).rwsem); - } - - -@@ -323,10 +335,10 @@ void exit_shm(struct task_struct *task) - return; - - /* Destroy all already created segments, but not mapped yet */ -- down_write(&shm_ids(ns).rw_mutex); -+ down_write(&shm_ids(ns).rwsem); - if (shm_ids(ns).in_use) - idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_current, ns); -- up_write(&shm_ids(ns).rw_mutex); -+ up_write(&shm_ids(ns).rwsem); - } - - static int shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -@@ -460,7 +472,7 @@ static const struct vm_operations_struct shm_vm_ops = { - * @ns: namespace - * @params: ptr to the structure that contains key, size and shmflg - * -- * Called with shm_ids.rw_mutex held as a writer. -+ * Called with shm_ids.rwsem held as a writer. - */ - - static int newseg(struct ipc_namespace *ns, struct ipc_params *params) -@@ -567,7 +579,7 @@ no_file: - } - - /* -- * Called with shm_ids.rw_mutex and ipcp locked. -+ * Called with shm_ids.rwsem and ipcp locked. - */ - static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg) - { -@@ -578,7 +590,7 @@ static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg) - } - - /* -- * Called with shm_ids.rw_mutex and ipcp locked. -+ * Called with shm_ids.rwsem and ipcp locked. - */ - static inline int shm_more_checks(struct kern_ipc_perm *ipcp, - struct ipc_params *params) -@@ -691,7 +703,7 @@ static inline unsigned long copy_shminfo_to_user(void __user *buf, struct shminf - - /* - * Calculate and add used RSS and swap pages of a shm. -- * Called with shm_ids.rw_mutex held as a reader -+ * Called with shm_ids.rwsem held as a reader - */ - static void shm_add_rss_swap(struct shmid_kernel *shp, - unsigned long *rss_add, unsigned long *swp_add) -@@ -718,7 +730,7 @@ static void shm_add_rss_swap(struct shmid_kernel *shp, - } - - /* -- * Called with shm_ids.rw_mutex held as a reader -+ * Called with shm_ids.rwsem held as a reader - */ - static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss, - unsigned long *swp) -@@ -747,9 +759,9 @@ static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss, - } - - /* -- * This function handles some shmctl commands which require the rw_mutex -+ * This function handles some shmctl commands which require the rwsem - * to be held in write mode. -- * NOTE: no locks must be held, the rw_mutex is taken inside this function. -+ * NOTE: no locks must be held, the rwsem is taken inside this function. - */ - static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd, - struct shmid_ds __user *buf, int version) -@@ -764,14 +776,13 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd, - return -EFAULT; - } - -- down_write(&shm_ids(ns).rw_mutex); -+ down_write(&shm_ids(ns).rwsem); - rcu_read_lock(); - -- ipcp = ipcctl_pre_down(ns, &shm_ids(ns), shmid, cmd, -- &shmid64.shm_perm, 0); -+ ipcp = ipcctl_pre_down_nolock(ns, &shm_ids(ns), shmid, cmd, -+ &shmid64.shm_perm, 0); - if (IS_ERR(ipcp)) { - err = PTR_ERR(ipcp); -- /* the ipc lock is not held upon failure */ - goto out_unlock1; - } - -@@ -779,14 +790,16 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd, - - err = security_shm_shmctl(shp, cmd); - if (err) -- goto out_unlock0; -+ goto out_unlock1; - - switch (cmd) { - case IPC_RMID: -+ ipc_lock_object(&shp->shm_perm); - /* do_shm_rmid unlocks the ipc object and rcu */ - do_shm_rmid(ns, ipcp); - goto out_up; - case IPC_SET: -+ ipc_lock_object(&shp->shm_perm); - err = ipc_update_perm(&shmid64.shm_perm, ipcp); - if (err) - goto out_unlock0; -@@ -794,6 +807,7 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd, - break; - default: - err = -EINVAL; -+ goto out_unlock1; - } - - out_unlock0: -@@ -801,33 +815,28 @@ out_unlock0: - out_unlock1: - rcu_read_unlock(); - out_up: -- up_write(&shm_ids(ns).rw_mutex); -+ up_write(&shm_ids(ns).rwsem); - return err; - } - --SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) -+static int shmctl_nolock(struct ipc_namespace *ns, int shmid, -+ int cmd, int version, void __user *buf) - { -+ int err; - struct shmid_kernel *shp; -- int err, version; -- struct ipc_namespace *ns; - -- if (cmd < 0 || shmid < 0) { -- err = -EINVAL; -- goto out; -+ /* preliminary security checks for *_INFO */ -+ if (cmd == IPC_INFO || cmd == SHM_INFO) { -+ err = security_shm_shmctl(NULL, cmd); -+ if (err) -+ return err; - } - -- version = ipc_parse_version(&cmd); -- ns = current->nsproxy->ipc_ns; -- -- switch (cmd) { /* replace with proc interface ? */ -+ switch (cmd) { - case IPC_INFO: - { - struct shminfo64 shminfo; - -- err = security_shm_shmctl(NULL, cmd); -- if (err) -- return err; -- - memset(&shminfo, 0, sizeof(shminfo)); - shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni; - shminfo.shmmax = ns->shm_ctlmax; -@@ -837,9 +846,9 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) - if(copy_shminfo_to_user (buf, &shminfo, version)) - return -EFAULT; - -- down_read(&shm_ids(ns).rw_mutex); -+ down_read(&shm_ids(ns).rwsem); - err = ipc_get_maxid(&shm_ids(ns)); -- up_read(&shm_ids(ns).rw_mutex); -+ up_read(&shm_ids(ns).rwsem); - - if(err<0) - err = 0; -@@ -849,19 +858,15 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) - { - struct shm_info shm_info; - -- err = security_shm_shmctl(NULL, cmd); -- if (err) -- return err; -- - memset(&shm_info, 0, sizeof(shm_info)); -- down_read(&shm_ids(ns).rw_mutex); -+ down_read(&shm_ids(ns).rwsem); - shm_info.used_ids = shm_ids(ns).in_use; - shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp); - shm_info.shm_tot = ns->shm_tot; - shm_info.swap_attempts = 0; - shm_info.swap_successes = 0; - err = ipc_get_maxid(&shm_ids(ns)); -- up_read(&shm_ids(ns).rw_mutex); -+ up_read(&shm_ids(ns).rwsem); - if (copy_to_user(buf, &shm_info, sizeof(shm_info))) { - err = -EFAULT; - goto out; -@@ -876,27 +881,31 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) - struct shmid64_ds tbuf; - int result; - -+ rcu_read_lock(); - if (cmd == SHM_STAT) { -- shp = shm_lock(ns, shmid); -+ shp = shm_obtain_object(ns, shmid); - if (IS_ERR(shp)) { - err = PTR_ERR(shp); -- goto out; -+ goto out_unlock; - } - result = shp->shm_perm.id; - } else { -- shp = shm_lock_check(ns, shmid); -+ shp = shm_obtain_object_check(ns, shmid); - if (IS_ERR(shp)) { - err = PTR_ERR(shp); -- goto out; -+ goto out_unlock; - } - result = 0; - } -+ - err = -EACCES; - if (ipcperms(ns, &shp->shm_perm, S_IRUGO)) - goto out_unlock; -+ - err = security_shm_shmctl(shp, cmd); - if (err) - goto out_unlock; -+ - memset(&tbuf, 0, sizeof(tbuf)); - kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm); - tbuf.shm_segsz = shp->shm_segsz; -@@ -906,43 +915,76 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) - tbuf.shm_cpid = shp->shm_cprid; - tbuf.shm_lpid = shp->shm_lprid; - tbuf.shm_nattch = shp->shm_nattch; -- shm_unlock(shp); -- if(copy_shmid_to_user (buf, &tbuf, version)) -+ rcu_read_unlock(); -+ -+ if (copy_shmid_to_user(buf, &tbuf, version)) - err = -EFAULT; - else - err = result; - goto out; - } -+ default: -+ return -EINVAL; -+ } -+ -+out_unlock: -+ rcu_read_unlock(); -+out: -+ return err; -+} -+ -+SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) -+{ -+ struct shmid_kernel *shp; -+ int err, version; -+ struct ipc_namespace *ns; -+ -+ if (cmd < 0 || shmid < 0) -+ return -EINVAL; -+ -+ version = ipc_parse_version(&cmd); -+ ns = current->nsproxy->ipc_ns; -+ -+ switch (cmd) { -+ case IPC_INFO: -+ case SHM_INFO: -+ case SHM_STAT: -+ case IPC_STAT: -+ return shmctl_nolock(ns, shmid, cmd, version, buf); -+ case IPC_RMID: -+ case IPC_SET: -+ return shmctl_down(ns, shmid, cmd, buf, version); - case SHM_LOCK: - case SHM_UNLOCK: - { - struct file *shm_file; - -- shp = shm_lock_check(ns, shmid); -+ rcu_read_lock(); -+ shp = shm_obtain_object_check(ns, shmid); - if (IS_ERR(shp)) { - err = PTR_ERR(shp); -- goto out; -+ goto out_unlock1; - } - - audit_ipc_obj(&(shp->shm_perm)); -+ err = security_shm_shmctl(shp, cmd); -+ if (err) -+ goto out_unlock1; - -+ ipc_lock_object(&shp->shm_perm); - if (!ns_capable(ns->user_ns, CAP_IPC_LOCK)) { - kuid_t euid = current_euid(); - err = -EPERM; - if (!uid_eq(euid, shp->shm_perm.uid) && - !uid_eq(euid, shp->shm_perm.cuid)) -- goto out_unlock; -+ goto out_unlock0; - if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK)) -- goto out_unlock; -+ goto out_unlock0; - } - -- err = security_shm_shmctl(shp, cmd); -- if (err) -- goto out_unlock; -- - shm_file = shp->shm_file; - if (is_file_hugepages(shm_file)) -- goto out_unlock; -+ goto out_unlock0; - - if (cmd == SHM_LOCK) { - struct user_struct *user = current_user(); -@@ -951,32 +993,31 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) - shp->shm_perm.mode |= SHM_LOCKED; - shp->mlock_user = user; - } -- goto out_unlock; -+ goto out_unlock0; - } - - /* SHM_UNLOCK */ - if (!(shp->shm_perm.mode & SHM_LOCKED)) -- goto out_unlock; -+ goto out_unlock0; - shmem_lock(shm_file, 0, shp->mlock_user); - shp->shm_perm.mode &= ~SHM_LOCKED; - shp->mlock_user = NULL; - get_file(shm_file); -- shm_unlock(shp); -+ ipc_unlock_object(&shp->shm_perm); -+ rcu_read_unlock(); - shmem_unlock_mapping(shm_file->f_mapping); -+ - fput(shm_file); -- goto out; -- } -- case IPC_RMID: -- case IPC_SET: -- err = shmctl_down(ns, shmid, cmd, buf, version); - return err; -+ } - default: - return -EINVAL; - } - --out_unlock: -- shm_unlock(shp); --out: -+out_unlock0: -+ ipc_unlock_object(&shp->shm_perm); -+out_unlock1: -+ rcu_read_unlock(); - return err; - } - -@@ -1044,10 +1085,11 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr, - * additional creator id... - */ - ns = current->nsproxy->ipc_ns; -- shp = shm_lock_check(ns, shmid); -+ rcu_read_lock(); -+ shp = shm_obtain_object_check(ns, shmid); - if (IS_ERR(shp)) { - err = PTR_ERR(shp); -- goto out; -+ goto out_unlock; - } - - err = -EACCES; -@@ -1058,24 +1100,31 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr, - if (err) - goto out_unlock; - -+ ipc_lock_object(&shp->shm_perm); - path = shp->shm_file->f_path; - path_get(&path); - shp->shm_nattch++; - size = i_size_read(path.dentry->d_inode); -- shm_unlock(shp); -+ ipc_unlock_object(&shp->shm_perm); -+ rcu_read_unlock(); - - err = -ENOMEM; - sfd = kzalloc(sizeof(*sfd), GFP_KERNEL); -- if (!sfd) -- goto out_put_dentry; -+ if (!sfd) { -+ path_put(&path); -+ goto out_nattch; -+ } - - file = alloc_file(&path, f_mode, - is_file_hugepages(shp->shm_file) ? - &shm_file_operations_huge : - &shm_file_operations); - err = PTR_ERR(file); -- if (IS_ERR(file)) -- goto out_free; -+ if (IS_ERR(file)) { -+ kfree(sfd); -+ path_put(&path); -+ goto out_nattch; -+ } - - file->private_data = sfd; - file->f_mapping = shp->shm_file->f_mapping; -@@ -1101,7 +1150,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr, - addr > current->mm->start_stack - size - PAGE_SIZE * 5) - goto invalid; - } -- -+ - addr = do_mmap_pgoff(file, addr, size, prot, flags, 0, &populate); - *raddr = addr; - err = 0; -@@ -1116,7 +1165,7 @@ out_fput: - fput(file); - - out_nattch: -- down_write(&shm_ids(ns).rw_mutex); -+ down_write(&shm_ids(ns).rwsem); - shp = shm_lock(ns, shmid); - BUG_ON(IS_ERR(shp)); - shp->shm_nattch--; -@@ -1124,20 +1173,13 @@ out_nattch: - shm_destroy(ns, shp); - else - shm_unlock(shp); -- up_write(&shm_ids(ns).rw_mutex); -- --out: -+ up_write(&shm_ids(ns).rwsem); - return err; - - out_unlock: -- shm_unlock(shp); -- goto out; -- --out_free: -- kfree(sfd); --out_put_dentry: -- path_put(&path); -- goto out_nattch; -+ rcu_read_unlock(); -+out: -+ return err; - } - - SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg) -@@ -1242,8 +1284,7 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr) - #else /* CONFIG_MMU */ - /* under NOMMU conditions, the exact address to be destroyed must be - * given */ -- retval = -EINVAL; -- if (vma->vm_start == addr && vma->vm_ops == &shm_vm_ops) { -+ if (vma && vma->vm_start == addr && vma->vm_ops == &shm_vm_ops) { - do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start); - retval = 0; - } -diff --git a/ipc/util.c b/ipc/util.c -index 0c6566b..fdb8ae7 100644 ---- a/ipc/util.c -+++ b/ipc/util.c -@@ -15,6 +15,14 @@ - * Jun 2006 - namespaces ssupport - * OpenVZ, SWsoft Inc. - * Pavel Emelianov <xemul@openvz.org> -+ * -+ * General sysv ipc locking scheme: -+ * when doing ipc id lookups, take the ids->rwsem -+ * rcu_read_lock() -+ * obtain the ipc object (kern_ipc_perm) -+ * perform security, capabilities, auditing and permission checks, etc. -+ * acquire the ipc lock (kern_ipc_perm.lock) throught ipc_lock_object() -+ * perform data updates (ie: SET, RMID, LOCK/UNLOCK commands) - */ - - #include <linux/mm.h> -@@ -119,7 +127,7 @@ __initcall(ipc_init); - - void ipc_init_ids(struct ipc_ids *ids) - { -- init_rwsem(&ids->rw_mutex); -+ init_rwsem(&ids->rwsem); - - ids->in_use = 0; - ids->seq = 0; -@@ -174,7 +182,7 @@ void __init ipc_init_proc_interface(const char *path, const char *header, - * @ids: Identifier set - * @key: The key to find - * -- * Requires ipc_ids.rw_mutex locked. -+ * Requires ipc_ids.rwsem locked. - * Returns the LOCKED pointer to the ipc structure if found or NULL - * if not. - * If key is found ipc points to the owning ipc structure -@@ -197,7 +205,8 @@ static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key) - continue; - } - -- ipc_lock_by_ptr(ipc); -+ rcu_read_lock(); -+ ipc_lock_object(ipc); - return ipc; - } - -@@ -208,7 +217,7 @@ static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key) - * ipc_get_maxid - get the last assigned id - * @ids: IPC identifier set - * -- * Called with ipc_ids.rw_mutex held. -+ * Called with ipc_ids.rwsem held. - */ - - int ipc_get_maxid(struct ipc_ids *ids) -@@ -246,7 +255,7 @@ int ipc_get_maxid(struct ipc_ids *ids) - * is returned. The 'new' entry is returned in a locked state on success. - * On failure the entry is not locked and a negative err-code is returned. - * -- * Called with writer ipc_ids.rw_mutex held. -+ * Called with writer ipc_ids.rwsem held. - */ - int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) - { -@@ -312,9 +321,9 @@ static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids, - { - int err; - -- down_write(&ids->rw_mutex); -+ down_write(&ids->rwsem); - err = ops->getnew(ns, params); -- up_write(&ids->rw_mutex); -+ up_write(&ids->rwsem); - return err; - } - -@@ -331,7 +340,7 @@ static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids, - * - * On success, the IPC id is returned. - * -- * It is called with ipc_ids.rw_mutex and ipcp->lock held. -+ * It is called with ipc_ids.rwsem and ipcp->lock held. - */ - static int ipc_check_perms(struct ipc_namespace *ns, - struct kern_ipc_perm *ipcp, -@@ -376,7 +385,7 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, - * Take the lock as a writer since we are potentially going to add - * a new entry + read locks are not "upgradable" - */ -- down_write(&ids->rw_mutex); -+ down_write(&ids->rwsem); - ipcp = ipc_findkey(ids, params->key); - if (ipcp == NULL) { - /* key not used */ -@@ -402,7 +411,7 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, - } - ipc_unlock(ipcp); - } -- up_write(&ids->rw_mutex); -+ up_write(&ids->rwsem); - - return err; - } -@@ -413,7 +422,7 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, - * @ids: IPC identifier set - * @ipcp: ipc perm structure containing the identifier to remove - * -- * ipc_ids.rw_mutex (as a writer) and the spinlock for this ID are held -+ * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held - * before this function is called, and remain locked on the exit. - */ - -@@ -613,7 +622,7 @@ struct kern_ipc_perm *ipc_obtain_object(struct ipc_ids *ids, int id) - } - - /** -- * ipc_lock - Lock an ipc structure without rw_mutex held -+ * ipc_lock - Lock an ipc structure without rwsem held - * @ids: IPC identifier set - * @id: ipc id to look for - * -@@ -669,22 +678,6 @@ out: - return out; - } - --struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, int id) --{ -- struct kern_ipc_perm *out; -- -- out = ipc_lock(ids, id); -- if (IS_ERR(out)) -- return out; -- -- if (ipc_checkid(out, id)) { -- ipc_unlock(out); -- return ERR_PTR(-EIDRM); -- } -- -- return out; --} -- - /** - * ipcget - Common sys_*get() code - * @ns : namsepace -@@ -725,7 +718,7 @@ int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out) - } - - /** -- * ipcctl_pre_down - retrieve an ipc and check permissions for some IPC_XXX cmd -+ * ipcctl_pre_down_nolock - retrieve an ipc and check permissions for some IPC_XXX cmd - * @ns: the ipc namespace - * @ids: the table of ids where to look for the ipc - * @id: the id of the ipc to retrieve -@@ -738,29 +731,13 @@ int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out) - * It must be called without any lock held and - * - retrieves the ipc with the given id in the given table. - * - performs some audit and permission check, depending on the given cmd -- * - returns the ipc with the ipc lock held in case of success -- * or an err-code without any lock held otherwise. -+ * - returns a pointer to the ipc object or otherwise, the corresponding error. - * -- * Call holding the both the rw_mutex and the rcu read lock. -+ * Call holding the both the rwsem and the rcu read lock. - */ --struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns, -- struct ipc_ids *ids, int id, int cmd, -- struct ipc64_perm *perm, int extra_perm) --{ -- struct kern_ipc_perm *ipcp; -- -- ipcp = ipcctl_pre_down_nolock(ns, ids, id, cmd, perm, extra_perm); -- if (IS_ERR(ipcp)) -- goto out; -- -- spin_lock(&ipcp->lock); --out: -- return ipcp; --} -- - struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns, -- struct ipc_ids *ids, int id, int cmd, -- struct ipc64_perm *perm, int extra_perm) -+ struct ipc_ids *ids, int id, int cmd, -+ struct ipc64_perm *perm, int extra_perm) - { - kuid_t euid; - int err = -EPERM; -@@ -838,7 +815,8 @@ static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos, - ipc = idr_find(&ids->ipcs_idr, pos); - if (ipc != NULL) { - *new_pos = pos + 1; -- ipc_lock_by_ptr(ipc); -+ rcu_read_lock(); -+ ipc_lock_object(ipc); - return ipc; - } - } -@@ -876,7 +854,7 @@ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos) - * Take the lock - this will be released by the corresponding - * call to stop(). - */ -- down_read(&ids->rw_mutex); -+ down_read(&ids->rwsem); - - /* pos < 0 is invalid */ - if (*pos < 0) -@@ -903,7 +881,7 @@ static void sysvipc_proc_stop(struct seq_file *s, void *it) - - ids = &iter->ns->ids[iface->ids]; - /* Release the lock we took in start() */ -- up_read(&ids->rw_mutex); -+ up_read(&ids->rwsem); - } - - static int sysvipc_proc_show(struct seq_file *s, void *it) -diff --git a/ipc/util.h b/ipc/util.h -index 25299e7..f2f5036 100644 ---- a/ipc/util.h -+++ b/ipc/util.h -@@ -101,10 +101,10 @@ void __init ipc_init_proc_interface(const char *path, const char *header, - #define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER) - #define ipcid_to_seqx(id) ((id) / SEQ_MULTIPLIER) - --/* must be called with ids->rw_mutex acquired for writing */ -+/* must be called with ids->rwsem acquired for writing */ - int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int); - --/* must be called with ids->rw_mutex acquired for reading */ -+/* must be called with ids->rwsem acquired for reading */ - int ipc_get_maxid(struct ipc_ids *); - - /* must be called with both locks acquired. */ -@@ -139,9 +139,6 @@ int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out); - struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns, - struct ipc_ids *ids, int id, int cmd, - struct ipc64_perm *perm, int extra_perm); --struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns, -- struct ipc_ids *ids, int id, int cmd, -- struct ipc64_perm *perm, int extra_perm); - - #ifndef CONFIG_ARCH_WANT_IPC_PARSE_VERSION - /* On IA-64, we always use the "64-bit version" of the IPC structures. */ -@@ -182,19 +179,12 @@ static inline void ipc_assert_locked_object(struct kern_ipc_perm *perm) - assert_spin_locked(&perm->lock); - } - --static inline void ipc_lock_by_ptr(struct kern_ipc_perm *perm) --{ -- rcu_read_lock(); -- ipc_lock_object(perm); --} -- - static inline void ipc_unlock(struct kern_ipc_perm *perm) - { - ipc_unlock_object(perm); - rcu_read_unlock(); - } - --struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, int id); - struct kern_ipc_perm *ipc_obtain_object_check(struct ipc_ids *ids, int id); - int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids, - struct ipc_ops *ops, struct ipc_params *params); -diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c -index 45850f6..4865756 100644 ---- a/sound/pci/hda/patch_hdmi.c -+++ b/sound/pci/hda/patch_hdmi.c -@@ -930,6 +930,14 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, - } - - /* -+ * always configure channel mapping, it may have been changed by the -+ * user in the meantime -+ */ -+ hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca, -+ channels, per_pin->chmap, -+ per_pin->chmap_set); -+ -+ /* - * sizeof(ai) is used instead of sizeof(*hdmi_ai) or - * sizeof(*dp_ai) to avoid partial match/update problems when - * the user switches between HDMI/DP monitors. -@@ -940,20 +948,10 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, - "pin=%d channels=%d\n", - pin_nid, - channels); -- hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca, -- channels, per_pin->chmap, -- per_pin->chmap_set); - hdmi_stop_infoframe_trans(codec, pin_nid); - hdmi_fill_audio_infoframe(codec, pin_nid, - ai.bytes, sizeof(ai)); - hdmi_start_infoframe_trans(codec, pin_nid); -- } else { -- /* For non-pcm audio switch, setup new channel mapping -- * accordingly */ -- if (per_pin->non_pcm != non_pcm) -- hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca, -- channels, per_pin->chmap, -- per_pin->chmap_set); - } - - per_pin->non_pcm = non_pcm; -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index 389db4c..1383f38 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -3308,6 +3308,15 @@ static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec, - } - } - -+static void alc290_fixup_mono_speakers(struct hda_codec *codec, -+ const struct hda_fixup *fix, int action) -+{ -+ if (action == HDA_FIXUP_ACT_PRE_PROBE) -+ /* Remove DAC node 0x03, as it seems to be -+ giving mono output */ -+ snd_hda_override_wcaps(codec, 0x03, 0); -+} -+ - enum { - ALC269_FIXUP_SONY_VAIO, - ALC275_FIXUP_SONY_VAIO_GPIO2, -@@ -3331,9 +3340,12 @@ enum { - ALC269_FIXUP_HP_GPIO_LED, - ALC269_FIXUP_INV_DMIC, - ALC269_FIXUP_LENOVO_DOCK, -+ ALC286_FIXUP_SONY_MIC_NO_PRESENCE, - ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, - ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, - ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, -+ ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, -+ ALC290_FIXUP_MONO_SPEAKERS, - ALC269_FIXUP_HEADSET_MODE, - ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, - ALC269_FIXUP_ASUS_X101_FUNC, -@@ -3521,6 +3533,15 @@ static const struct hda_fixup alc269_fixups[] = { - .chained = true, - .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC - }, -+ [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = { -+ .type = HDA_FIXUP_PINS, -+ .v.pins = (const struct hda_pintbl[]) { -+ { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ -+ { } -+ }, -+ .chained = true, -+ .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC -+ }, - [ALC269_FIXUP_HEADSET_MODE] = { - .type = HDA_FIXUP_FUNC, - .v.func = alc_fixup_headset_mode, -@@ -3529,6 +3550,13 @@ static const struct hda_fixup alc269_fixups[] = { - .type = HDA_FIXUP_FUNC, - .v.func = alc_fixup_headset_mode_no_hp_mic, - }, -+ [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = { -+ .type = HDA_FIXUP_PINS, -+ .v.pins = (const struct hda_pintbl[]) { -+ { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */ -+ { } -+ }, -+ }, - [ALC269_FIXUP_ASUS_X101_FUNC] = { - .type = HDA_FIXUP_FUNC, - .v.func = alc269_fixup_x101_headset_mic, -@@ -3595,6 +3623,12 @@ static const struct hda_fixup alc269_fixups[] = { - { } - }, - }, -+ [ALC290_FIXUP_MONO_SPEAKERS] = { -+ .type = HDA_FIXUP_FUNC, -+ .v.func = alc290_fixup_mono_speakers, -+ .chained = true, -+ .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, -+ }, - }; - - static const struct snd_pci_quirk alc269_fixup_tbl[] = { -@@ -3631,6 +3665,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), -+ SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_MONO_SPEAKERS), - SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), -@@ -3651,6 +3686,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), - SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), - SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101), -+ SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), - SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), - SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), -@@ -4345,6 +4381,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { - SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), -+ SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_ASUS_MODE4), - SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), - SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), - SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), -diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c -index 63fb521..6234a51 100644 ---- a/sound/usb/usx2y/usbusx2yaudio.c -+++ b/sound/usb/usx2y/usbusx2yaudio.c -@@ -299,19 +299,6 @@ static void usX2Y_error_urb_status(struct usX2Ydev *usX2Y, - usX2Y_clients_stop(usX2Y); - } - --static void usX2Y_error_sequence(struct usX2Ydev *usX2Y, -- struct snd_usX2Y_substream *subs, struct urb *urb) --{ -- snd_printk(KERN_ERR --"Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n" --"Most probably some urb of usb-frame %i is still missing.\n" --"Cause could be too long delays in usb-hcd interrupt handling.\n", -- usb_get_current_frame_number(usX2Y->dev), -- subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", -- usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame); -- usX2Y_clients_stop(usX2Y); --} -- - static void i_usX2Y_urb_complete(struct urb *urb) - { - struct snd_usX2Y_substream *subs = urb->context; -@@ -328,12 +315,9 @@ static void i_usX2Y_urb_complete(struct urb *urb) - usX2Y_error_urb_status(usX2Y, subs, urb); - return; - } -- if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF))) -- subs->completed_urb = urb; -- else { -- usX2Y_error_sequence(usX2Y, subs, urb); -- return; -- } -+ -+ subs->completed_urb = urb; -+ - { - struct snd_usX2Y_substream *capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE], - *playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]; -diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c -index f2a1acd..814d0e8 100644 ---- a/sound/usb/usx2y/usx2yhwdeppcm.c -+++ b/sound/usb/usx2y/usx2yhwdeppcm.c -@@ -244,13 +244,8 @@ static void i_usX2Y_usbpcm_urb_complete(struct urb *urb) - usX2Y_error_urb_status(usX2Y, subs, urb); - return; - } -- if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF))) -- subs->completed_urb = urb; -- else { -- usX2Y_error_sequence(usX2Y, subs, urb); -- return; -- } - -+ subs->completed_urb = urb; - capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE]; - capsubs2 = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2]; - playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]; diff --git a/3.11.6/4420_grsecurity-2.9.1-3.11.6-201310191259.patch b/3.11.6/4420_grsecurity-2.9.1-3.11.6-201310260850.patch index 46b1e15..584d2ee 100644 --- a/3.11.6/4420_grsecurity-2.9.1-3.11.6-201310191259.patch +++ b/3.11.6/4420_grsecurity-2.9.1-3.11.6-201310260850.patch @@ -18357,7 +18357,7 @@ index 7f760a9..04b1c65 100644 } diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h -index 4f7923d..20cb24e 100644 +index 4f7923d..d3526c1 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -10,6 +10,9 @@ @@ -18370,7 +18370,7 @@ index 4f7923d..20cb24e 100644 /* * Copy To/From Userspace -@@ -17,13 +20,13 @@ +@@ -17,14 +20,14 @@ /* Handles exceptions in both to and from, but doesn't do access_ok */ __must_check unsigned long @@ -18384,16 +18384,13 @@ index 4f7923d..20cb24e 100644 +copy_user_generic_unrolled(void *to, const void *from, unsigned len) __size_overflow(3); -static __always_inline __must_check unsigned long +-copy_user_generic(void *to, const void *from, unsigned len) +static __always_inline __must_check __size_overflow(3) unsigned long - copy_user_generic(void *to, const void *from, unsigned len) ++copy_user_generic(void *to, const void *from, unsigned long len) { unsigned ret; -@@ -41,142 +44,204 @@ copy_user_generic(void *to, const void *from, unsigned len) - ASM_OUTPUT2("=a" (ret), "=D" (to), "=S" (from), - "=d" (len)), - "1" (to), "2" (from), "3" (len) -- : "memory", "rcx", "r8", "r9", "r10", "r11"); -+ : "memory", "rcx", "r8", "r9", "r11"); + +@@ -45,138 +48,200 @@ copy_user_generic(void *to, const void *from, unsigned len) return ret; } @@ -97256,7 +97253,7 @@ index f5eb43d..1814de8 100644 shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->e_shoff)); shstrtab_sec = shdr + r2(&ehdr->e_shstrndx); diff --git a/security/Kconfig b/security/Kconfig -index e9c6ac7..c5d45c8 100644 +index e9c6ac7..5b9d82e 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -4,6 +4,959 @@ @@ -98185,14 +98182,14 @@ index e9c6ac7..c5d45c8 100644 + headers explicitly in addition to the normal gcc package. + +config PAX_LATENT_ENTROPY -+ bool "Generate some entropy during boot" ++ bool "Generate some entropy during boot and runtime" + default y if GRKERNSEC_CONFIG_AUTO + help -+ By saying Y here the kernel will instrument early boot code to ++ By saying Y here the kernel will instrument some kernel code to + extract some entropy from both original and artificially created + program state. This will help especially embedded systems where + there is little 'natural' source of entropy normally. The cost -+ is some slowdown of the boot process. ++ is some slowdown of the boot process and fork and irq processing. + + When pax_extra_latent_entropy is passed on the kernel command line, + entropy will be extracted from up to the first 4GB of RAM while the diff --git a/3.2.51/0000_README b/3.2.51/0000_README index 7299d26..8ba65d1 100644 --- a/3.2.51/0000_README +++ b/3.2.51/0000_README @@ -122,7 +122,7 @@ Patch: 1050_linux-3.2.51.patch From: http://www.kernel.org Desc: Linux 3.2.51 -Patch: 4420_grsecurity-2.9.1-3.2.51-201310191257.patch +Patch: 4420_grsecurity-2.9.1-3.2.51-201310260849.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.2.51/4420_grsecurity-2.9.1-3.2.51-201310191257.patch b/3.2.51/4420_grsecurity-2.9.1-3.2.51-201310260849.patch index 4e9a590..0ea9ee0 100644 --- a/3.2.51/4420_grsecurity-2.9.1-3.2.51-201310191257.patch +++ b/3.2.51/4420_grsecurity-2.9.1-3.2.51-201310260849.patch @@ -14469,7 +14469,7 @@ index 566e803..86f1302 100644 } diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h -index 1c66d30..6c7b4d8 100644 +index 1c66d30..c815e61 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -10,6 +10,9 @@ @@ -14499,12 +14499,7 @@ index 1c66d30..6c7b4d8 100644 { unsigned ret; -@@ -32,142 +35,204 @@ copy_user_generic(void *to, const void *from, unsigned len) - ASM_OUTPUT2("=a" (ret), "=D" (to), "=S" (from), - "=d" (len)), - "1" (to), "2" (from), "3" (len) -- : "memory", "rcx", "r8", "r9", "r10", "r11"); -+ : "memory", "rcx", "r8", "r9", "r11"); +@@ -36,138 +39,200 @@ copy_user_generic(void *to, const void *from, unsigned len) return ret; } @@ -97045,7 +97040,7 @@ index 38f6617..e70b72b 100755 exuberant() diff --git a/security/Kconfig b/security/Kconfig -index 51bd5a0..433ef3c 100644 +index 51bd5a0..e4faa00 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -4,6 +4,954 @@ @@ -97969,14 +97964,14 @@ index 51bd5a0..433ef3c 100644 + headers explicitly in addition to the normal gcc package. + +config PAX_LATENT_ENTROPY -+ bool "Generate some entropy during boot" ++ bool "Generate some entropy during boot and runtime" + default y if GRKERNSEC_CONFIG_AUTO + help -+ By saying Y here the kernel will instrument early boot code to ++ By saying Y here the kernel will instrument some kernel code to + extract some entropy from both original and artificially created + program state. This will help especially embedded systems where + there is little 'natural' source of entropy normally. The cost -+ is some slowdown of the boot process. ++ is some slowdown of the boot process and fork and irq processing. + + When pax_extra_latent_entropy is passed on the kernel command line, + entropy will be extracted from up to the first 4GB of RAM while the |