diff --git a/arch/arm/configs/evervolv_bravo_defconfig b/arch/arm/configs/evervolv_bravo_defconfig index 281674c1fbbd..97040b647db0 100644 --- a/arch/arm/configs/evervolv_bravo_defconfig +++ b/arch/arm/configs/evervolv_bravo_defconfig @@ -48,7 +48,8 @@ CONFIG_SWAP=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y CONFIG_HAVE_GENERIC_HARDIRQS=y # diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index bc2a90da2504..6a8949c5c6b2 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -358,6 +358,9 @@ validate_event(struct cpu_hw_events *cpuc, { struct hw_perf_event fake_event = event->hw; + if (is_software_event(event)) + return 1; + if (event->pmu != &pmu || event->state <= PERF_EVENT_STATE_OFF) return 1; diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 428f4fe0b5f7..7b4007b2c3a0 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1980,8 +1980,11 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, if (tty->ops->flush_chars) tty->ops->flush_chars(tty); } else { + while (nr > 0) { + mutex_lock(&tty->output_lock); c = tty->ops->write(tty, b, nr); + mutex_unlock(&tty->output_lock); if (c < 0) { retval = c; goto break_out; diff --git a/include/linux/mm.h b/include/linux/mm.h index a021c046e774..89839c7d25b6 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1490,7 +1490,7 @@ int write_one_page(struct page *page, int wait); void task_dirty_inc(struct task_struct *tsk); /* readahead.c */ -#define VM_MAX_READAHEAD 128 /* kbytes */ +#define VM_MAX_READAHEAD 2048 /* kbytes */ #define VM_MIN_READAHEAD 16 /* kbytes (includes current page) */ int force_page_cache_readahead(struct address_space *mapping, struct file *filp, diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h index 2cfa4bc8dea6..4541898b9199 100644 --- a/include/linux/pkt_sched.h +++ b/include/linux/pkt_sched.h @@ -118,6 +118,7 @@ struct tc_fifo_qopt { struct tc_prio_qopt { int bands; /* Number of bands */ __u8 priomap[TC_PRIO_MAX+1]; /* Map: logical priority -> PRIO band */ + __u8 enable_flow; /* Enable dequeue */ }; /* MULTIQ section */ diff --git a/kernel/futex.c b/kernel/futex.c index 902fc39067a2..8cdeccd80571 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -1234,6 +1234,13 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags, u32 curval2; if (requeue_pi) { + /* + * Requeue PI only works on two distinct uaddrs. This + * check is only valid for private futexes. See below. + */ + if (uaddr1 == uaddr2) + return -EINVAL; + /* * requeue_pi requires a pi_state, try to allocate it now * without any locks in case it fails. @@ -1271,6 +1278,15 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags, if (unlikely(ret != 0)) goto out_put_key1; + /* + * The check above which compares uaddrs is not sufficient for + * shared futexes. We need to compare the keys: + */ + if (requeue_pi && match_futex(&key1, &key2)) { + ret = -EINVAL; + goto out_put_keys; + } + hb1 = hash_futex(&key1); hb2 = hash_futex(&key2); @@ -2288,6 +2304,15 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, if (ret) goto out_key2; + /* + * The check above which compares uaddrs is not sufficient for + * shared futexes. We need to compare the keys: + */ + if (match_futex(&q.key, &key2)) { + ret = -EINVAL; + goto out_put_keys; + } + /* Queue the futex_q, drop the hb lock, wait for wakeup. */ futex_wait_queue_me(hb, &q, to); diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index fbd710d619bf..716aff5a37c8 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -28,6 +28,7 @@ struct prio_sched_data struct tcf_proto *filter_list; u8 prio2band[TC_PRIO_MAX+1]; struct Qdisc *queues[TCQ_PRIO_BANDS]; + u8 enable_flow; }; @@ -97,6 +98,9 @@ static struct sk_buff *prio_peek(struct Qdisc *sch) struct prio_sched_data *q = qdisc_priv(sch); int prio; + if (!q->enable_flow) + return NULL; + for (prio = 0; prio < q->bands; prio++) { struct Qdisc *qdisc = q->queues[prio]; struct sk_buff *skb = qdisc->ops->peek(qdisc); @@ -111,6 +115,9 @@ static struct sk_buff *prio_dequeue(struct Qdisc* sch) struct prio_sched_data *q = qdisc_priv(sch); int prio; + if (!q->enable_flow) + return NULL; + for (prio = 0; prio < q->bands; prio++) { struct Qdisc *qdisc = q->queues[prio]; struct sk_buff *skb = qdisc->dequeue(qdisc); @@ -151,6 +158,7 @@ prio_reset(struct Qdisc* sch) for (prio=0; priobands; prio++) qdisc_reset(q->queues[prio]); sch->q.qlen = 0; + q->enable_flow = 1; } static void @@ -183,6 +191,7 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt) } sch_tree_lock(sch); + q->enable_flow = qopt->enable_flow; q->bands = qopt->bands; memcpy(q->prio2band, qopt->priomap, TC_PRIO_MAX+1); @@ -245,6 +254,7 @@ static int prio_dump(struct Qdisc *sch, struct sk_buff *skb) struct tc_prio_qopt opt; opt.bands = q->bands; + opt.enable_flow = q->enable_flow; memcpy(&opt.priomap, q->prio2band, TC_PRIO_MAX+1); NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);