From: Greg Kroah-Hartman Date: Wed, 23 Mar 2011 22:20:29 +0000 (-0700) Subject: .37 patches X-Git-Tag: v2.6.37.6~17 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8fa1d639cb1eb1d16e97f7ad4565d00aa184e2f1;p=thirdparty%2Fkernel%2Fstable-queue.git .37 patches --- diff --git a/queue-2.6.37/aio-wake-all-waiters-when-destroying-ctx.patch b/queue-2.6.37/aio-wake-all-waiters-when-destroying-ctx.patch new file mode 100644 index 00000000000..e0c66dfa7de --- /dev/null +++ b/queue-2.6.37/aio-wake-all-waiters-when-destroying-ctx.patch @@ -0,0 +1,82 @@ +From e91f90bb0bb10be9cc8efd09a3cf4ecffcad0db1 Mon Sep 17 00:00:00 2001 +From: Roland Dreier +Date: Tue, 22 Mar 2011 16:35:10 -0700 +Subject: aio: wake all waiters when destroying ctx + +From: Roland Dreier + +commit e91f90bb0bb10be9cc8efd09a3cf4ecffcad0db1 upstream. + +The test program below will hang because io_getevents() uses +add_wait_queue_exclusive(), which means the wake_up() in io_destroy() only +wakes up one of the threads. Fix this by using wake_up_all() in the aio +code paths where we want to make sure no one gets stuck. + + // t.c -- compile with gcc -lpthread -laio t.c + + #include + #include + #include + #include + + static const int nthr = 2; + + void *getev(void *ctx) + { + struct io_event ev; + io_getevents(ctx, 1, 1, &ev, NULL); + printf("io_getevents returned\n"); + return NULL; + } + + int main(int argc, char *argv[]) + { + io_context_t ctx = 0; + pthread_t thread[nthr]; + int i; + + io_setup(1024, &ctx); + + for (i = 0; i < nthr; ++i) + pthread_create(&thread[i], NULL, getev, ctx); + + sleep(1); + + io_destroy(ctx); + + for (i = 0; i < nthr; ++i) + pthread_join(thread[i], NULL); + + return 0; + } + +Signed-off-by: Roland Dreier +Reviewed-by: Jeff Moyer +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/aio.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/aio.c ++++ b/fs/aio.c +@@ -512,7 +512,7 @@ static inline void really_put_req(struct + ctx->reqs_active--; + + if (unlikely(!ctx->reqs_active && ctx->dead)) +- wake_up(&ctx->wait); ++ wake_up_all(&ctx->wait); + } + + static void aio_fput_routine(struct work_struct *data) +@@ -1233,7 +1233,7 @@ static void io_destroy(struct kioctx *io + * by other CPUs at this point. Right now, we rely on the + * locking done by the above calls to ensure this consistency. + */ +- wake_up(&ioctx->wait); ++ wake_up_all(&ioctx->wait); + put_ioctx(ioctx); /* once for the lookup */ + } + diff --git a/queue-2.6.37/alsa-hda-via-add-missing-support-for-vt1718s-in-a-a-path.patch b/queue-2.6.37/alsa-hda-via-add-missing-support-for-vt1718s-in-a-a-path.patch new file mode 100644 index 00000000000..ddb11e064d9 --- /dev/null +++ b/queue-2.6.37/alsa-hda-via-add-missing-support-for-vt1718s-in-a-a-path.patch @@ -0,0 +1,33 @@ +From ab657e0cacc39d88145871c6a3c844597c02d406 Mon Sep 17 00:00:00 2001 +From: Lydia Wang +Date: Tue, 22 Mar 2011 16:23:23 +0800 +Subject: ALSA: hda - VIA: Add missing support for VT1718S in A-A path + +From: Lydia Wang + +commit ab657e0cacc39d88145871c6a3c844597c02d406 upstream. + +Modify mute_aa_path() function to support VT1718S codec. + +Signed-off-by: Lydia Wang +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_via.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/sound/pci/hda/patch_via.c ++++ b/sound/pci/hda/patch_via.c +@@ -1324,6 +1324,11 @@ static void mute_aa_path(struct hda_code + start_idx = 2; + end_idx = 4; + break; ++ case VT1718S: ++ nid_mixer = 0x21; ++ start_idx = 1; ++ end_idx = 3; ++ break; + default: + return; + } diff --git a/queue-2.6.37/alsa-hda-via-fix-codec-type-for-vt1708bce-at-the-right-timing.patch b/queue-2.6.37/alsa-hda-via-fix-codec-type-for-vt1708bce-at-the-right-timing.patch new file mode 100644 index 00000000000..fee98c5bb69 --- /dev/null +++ b/queue-2.6.37/alsa-hda-via-fix-codec-type-for-vt1708bce-at-the-right-timing.patch @@ -0,0 +1,52 @@ +From 0341ccd7557fecafe6a79c55158670cf629d269e Mon Sep 17 00:00:00 2001 +From: Lydia Wang +Date: Tue, 22 Mar 2011 16:25:03 +0800 +Subject: ALSA: hda - VIA: Fix codec type for VT1708BCE at the right timing + +From: Lydia Wang + +commit 0341ccd7557fecafe6a79c55158670cf629d269e upstream. + +Add get_codec_type() in via_new_spec() function to make sure getting +correct codec type before building mixer controls. + +Signed-off-by: Lydia Wang +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_via.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/sound/pci/hda/patch_via.c ++++ b/sound/pci/hda/patch_via.c +@@ -159,6 +159,7 @@ struct via_spec { + #endif + }; + ++static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec); + static struct via_spec * via_new_spec(struct hda_codec *codec) + { + struct via_spec *spec; +@@ -169,6 +170,10 @@ static struct via_spec * via_new_spec(st + + codec->spec = spec; + spec->codec = codec; ++ spec->codec_type = get_codec_type(codec); ++ /* VT1708BCE & VT1708S are almost same */ ++ if (spec->codec_type == VT1708BCE) ++ spec->codec_type = VT1708S; + return spec; + } + +@@ -2204,10 +2209,6 @@ static int via_init(struct hda_codec *co + for (i = 0; i < spec->num_iverbs; i++) + snd_hda_sequence_write(codec, spec->init_verbs[i]); + +- spec->codec_type = get_codec_type(codec); +- if (spec->codec_type == VT1708BCE) +- spec->codec_type = VT1708S; /* VT1708BCE & VT1708S are almost +- same */ + /* Lydia Add for EAPD enable */ + if (!spec->dig_in_nid) { /* No Digital In connection */ + if (spec->dig_in_pin) { diff --git a/queue-2.6.37/alsa-hda-via-fix-independent-headphone-no-sound-issue.patch b/queue-2.6.37/alsa-hda-via-fix-independent-headphone-no-sound-issue.patch new file mode 100644 index 00000000000..fa59507328a --- /dev/null +++ b/queue-2.6.37/alsa-hda-via-fix-independent-headphone-no-sound-issue.patch @@ -0,0 +1,49 @@ +From ce0e5a9e81fbb153ee15ca60246c6722f07fc546 Mon Sep 17 00:00:00 2001 +From: Lydia Wang +Date: Tue, 22 Mar 2011 16:22:37 +0800 +Subject: ALSA: hda - VIA: Fix independent headphone no sound issue + +From: Lydia Wang + +commit ce0e5a9e81fbb153ee15ca60246c6722f07fc546 upstream. + +Modify via_independent_hp_put() function to support VT1718S and VT1812 +codecs, and fix independent headphone no sound issue. + +Signed-off-by: Lydia Wang +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_via.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +--- a/sound/pci/hda/patch_via.c ++++ b/sound/pci/hda/patch_via.c +@@ -1192,8 +1192,16 @@ static int via_independent_hp_put(struct + /* Get Independent Mode index of headphone pin widget */ + spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel + ? 1 : 0; +- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel); ++ if (spec->codec_type == VT1718S) ++ snd_hda_codec_write(codec, nid, 0, ++ AC_VERB_SET_CONNECT_SEL, pinsel ? 2 : 0); ++ else ++ snd_hda_codec_write(codec, nid, 0, ++ AC_VERB_SET_CONNECT_SEL, pinsel); + ++ if (spec->codec_type == VT1812) ++ snd_hda_codec_write(codec, 0x35, 0, ++ AC_VERB_SET_CONNECT_SEL, pinsel); + if (spec->multiout.hp_nid && spec->multiout.hp_nid + != spec->multiout.dac_nids[HDA_FRONT]) + snd_hda_codec_setup_stream(codec, spec->multiout.hp_nid, +@@ -1212,6 +1220,8 @@ static int via_independent_hp_put(struct + activate_ctl(codec, "Headphone Playback Switch", + spec->hp_independent_mode); + } ++ /* update jack power state */ ++ set_jack_power_state(codec); + return 0; + } + diff --git a/queue-2.6.37/alsa-hda-via-fix-invalid-a-a-path-volume-adjust-issue.patch b/queue-2.6.37/alsa-hda-via-fix-invalid-a-a-path-volume-adjust-issue.patch new file mode 100644 index 00000000000..22263d3b707 --- /dev/null +++ b/queue-2.6.37/alsa-hda-via-fix-invalid-a-a-path-volume-adjust-issue.patch @@ -0,0 +1,38 @@ +From 169222813eec8403c76394fb7b35ecab98e3c607 Mon Sep 17 00:00:00 2001 +From: Lydia Wang +Date: Tue, 22 Mar 2011 16:24:10 +0800 +Subject: ALSA: hda - VIA: Fix invalid A-A path volume adjust issue + +From: Lydia Wang + +commit 169222813eec8403c76394fb7b35ecab98e3c607 upstream. + +Modify vt_auto_create_analog_input_ctls() function to fix invalid a-a path +volume adjust issue for VT1708S, VT1702 and VT1716S codecs. + +Signed-off-by: Lydia Wang +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_via.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/sound/pci/hda/patch_via.c ++++ b/sound/pci/hda/patch_via.c +@@ -2455,7 +2455,14 @@ static int vt_auto_create_analog_input_c + else + type_idx = 0; + label = hda_get_autocfg_input_label(codec, cfg, i); +- err = via_new_analog_input(spec, label, type_idx, idx, cap_nid); ++ if (spec->codec_type == VT1708S || ++ spec->codec_type == VT1702 || ++ spec->codec_type == VT1716S) ++ err = via_new_analog_input(spec, label, type_idx, ++ idx+1, cap_nid); ++ else ++ err = via_new_analog_input(spec, label, type_idx, ++ idx, cap_nid); + if (err < 0) + return err; + snd_hda_add_imux_item(imux, label, idx, NULL); diff --git a/queue-2.6.37/alsa-hda-via-fix-stereo-mixer-recording-no-sound-issue.patch b/queue-2.6.37/alsa-hda-via-fix-stereo-mixer-recording-no-sound-issue.patch new file mode 100644 index 00000000000..216cae8bafd --- /dev/null +++ b/queue-2.6.37/alsa-hda-via-fix-stereo-mixer-recording-no-sound-issue.patch @@ -0,0 +1,48 @@ +From bff5fbf50bd498c217994bd2d41a53ac3141185a Mon Sep 17 00:00:00 2001 +From: Lydia Wang +Date: Tue, 22 Mar 2011 16:21:38 +0800 +Subject: ALSA: hda - VIA: Fix stereo mixer recording no sound issue + +From: Lydia Wang + +commit bff5fbf50bd498c217994bd2d41a53ac3141185a upstream. + +Modify function via_mux_enum_put() to fix stereo mixer recording +no sound issue. + +Signed-off-by: Lydia Wang +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_via.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/sound/pci/hda/patch_via.c ++++ b/sound/pci/hda/patch_via.c +@@ -1102,6 +1102,7 @@ static int via_mux_enum_put(struct snd_k + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct via_spec *spec = codec->spec; + unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); ++ int ret; + + if (!spec->mux_nids[adc_idx]) + return -EINVAL; +@@ -1110,12 +1111,14 @@ static int via_mux_enum_put(struct snd_k + AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0) + snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); +- /* update jack power state */ +- set_jack_power_state(codec); + +- return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, ++ ret = snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, + spec->mux_nids[adc_idx], + &spec->cur_mux[adc_idx]); ++ /* update jack power state */ ++ set_jack_power_state(codec); ++ ++ return ret; + } + + static int via_independent_hp_info(struct snd_kcontrol *kcontrol, diff --git a/queue-2.6.37/alsa-hda-via-fix-vt1708-can-t-build-up-headphone-control-issue.patch b/queue-2.6.37/alsa-hda-via-fix-vt1708-can-t-build-up-headphone-control-issue.patch new file mode 100644 index 00000000000..920cc346ebf --- /dev/null +++ b/queue-2.6.37/alsa-hda-via-fix-vt1708-can-t-build-up-headphone-control-issue.patch @@ -0,0 +1,38 @@ +From ee3c35c0827de02de414d08b2ddcbb910c2263ab Mon Sep 17 00:00:00 2001 +From: Lydia Wang +Date: Tue, 22 Mar 2011 16:26:36 +0800 +Subject: ALSA: hda - VIA: Fix VT1708 can't build up Headphone control issue + +From: Lydia Wang + +commit ee3c35c0827de02de414d08b2ddcbb910c2263ab upstream. + +Since VT1708 didn't support the control of getting connection number, +building of headphone control will fail in via_hp_build() function. + +Signed-off-by: Lydia Wang +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_via.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/sound/pci/hda/patch_via.c ++++ b/sound/pci/hda/patch_via.c +@@ -1267,9 +1267,12 @@ static int via_hp_build(struct hda_codec + break; + } + +- nums = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS); +- if (nums <= 1) +- return 0; ++ if (spec->codec_type != VT1708) { ++ nums = snd_hda_get_connections(codec, nid, ++ conn, HDA_MAX_CONNECTIONS); ++ if (nums <= 1) ++ return 0; ++ } + + knew = via_clone_control(spec, &via_hp_mixer[0]); + if (knew == NULL) diff --git a/queue-2.6.37/cgroups-if-you-list_empty-a-head-then-don-t-list_del-it.patch b/queue-2.6.37/cgroups-if-you-list_empty-a-head-then-don-t-list_del-it.patch new file mode 100644 index 00000000000..f9b3a34e235 --- /dev/null +++ b/queue-2.6.37/cgroups-if-you-list_empty-a-head-then-don-t-list_del-it.patch @@ -0,0 +1,80 @@ +From 8d2587970b8bdf7c8d9208e3f4bb93182aef1a0f Mon Sep 17 00:00:00 2001 +From: Phil Carmody +Date: Tue, 22 Mar 2011 16:30:13 -0700 +Subject: cgroups: if you list_empty() a head then don't list_del() it + +From: Phil Carmody + +commit 8d2587970b8bdf7c8d9208e3f4bb93182aef1a0f upstream. + +list_del() leaves poison in the prev and next pointers. The next +list_empty() will compare those poisons, and say the list isn't empty. +Any list operations that assume the node is on a list because of such a +check will be fooled into dereferencing poison. One needs to INIT the +node after the del, and fortunately there's already a wrapper for that - +list_del_init(). + +Some of the dels are followed by deallocations, so can be ignored, and one +can be merged with an add to make a move. Apart from that, I erred on the +side of caution in making nodes list_empty()-queriable. + +Signed-off-by: Phil Carmody +Reviewed-by: Paul Menage +Cc: Li Zefan +Acked-by: Kirill A. Shutemov +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/cgroup.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +--- a/kernel/cgroup.c ++++ b/kernel/cgroup.c +@@ -1791,10 +1791,8 @@ int cgroup_attach_task(struct cgroup *cg + + /* Update the css_set linked lists if we're using them */ + write_lock(&css_set_lock); +- if (!list_empty(&tsk->cg_list)) { +- list_del(&tsk->cg_list); +- list_add(&tsk->cg_list, &newcg->tasks); +- } ++ if (!list_empty(&tsk->cg_list)) ++ list_move(&tsk->cg_list, &newcg->tasks); + write_unlock(&css_set_lock); + + for_each_subsys(root, ss) { +@@ -3630,12 +3628,12 @@ again: + spin_lock(&release_list_lock); + set_bit(CGRP_REMOVED, &cgrp->flags); + if (!list_empty(&cgrp->release_list)) +- list_del(&cgrp->release_list); ++ list_del_init(&cgrp->release_list); + spin_unlock(&release_list_lock); + + cgroup_lock_hierarchy(cgrp->root); + /* delete this cgroup from parent->children */ +- list_del(&cgrp->sibling); ++ list_del_init(&cgrp->sibling); + cgroup_unlock_hierarchy(cgrp->root); + + spin_lock(&cgrp->dentry->d_lock); +@@ -3856,7 +3854,7 @@ void cgroup_unload_subsys(struct cgroup_ + subsys[ss->subsys_id] = NULL; + + /* remove subsystem from rootnode's list of subsystems */ +- list_del(&ss->sibling); ++ list_del_init(&ss->sibling); + + /* + * disentangle the css from all css_sets attached to the dummytop. as +@@ -4230,7 +4228,7 @@ void cgroup_exit(struct task_struct *tsk + if (!list_empty(&tsk->cg_list)) { + write_lock(&css_set_lock); + if (!list_empty(&tsk->cg_list)) +- list_del(&tsk->cg_list); ++ list_del_init(&tsk->cg_list); + write_unlock(&css_set_lock); + } + diff --git a/queue-2.6.37/ethtool-compat-handling-for-struct-ethtool_rxnfc.patch b/queue-2.6.37/ethtool-compat-handling-for-struct-ethtool_rxnfc.patch new file mode 100644 index 00000000000..46a5db93dfb --- /dev/null +++ b/queue-2.6.37/ethtool-compat-handling-for-struct-ethtool_rxnfc.patch @@ -0,0 +1,206 @@ +From 3a7da39d165e0c363c294feec119db1427032afd Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Thu, 17 Mar 2011 07:34:32 +0000 +Subject: ethtool: Compat handling for struct ethtool_rxnfc + +From: Ben Hutchings + +commit 3a7da39d165e0c363c294feec119db1427032afd upstream. + +This structure was accidentally defined such that its layout can +differ between 32-bit and 64-bit processes. Add compat structure +definitions and an ioctl wrapper function. + +Signed-off-by: Ben Hutchings +Acked-by: Alexander Duyck +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/ethtool.h | 34 ++++++++++++++ + net/socket.c | 114 +++++++++++++++++++++++++++++++++++++++++++++--- + 2 files changed, 141 insertions(+), 7 deletions(-) + +--- a/include/linux/ethtool.h ++++ b/include/linux/ethtool.h +@@ -13,6 +13,9 @@ + #ifndef _LINUX_ETHTOOL_H + #define _LINUX_ETHTOOL_H + ++#ifdef __KERNEL__ ++#include ++#endif + #include + #include + +@@ -449,6 +452,37 @@ struct ethtool_rxnfc { + __u32 rule_locs[0]; + }; + ++#ifdef __KERNEL__ ++#ifdef CONFIG_COMPAT ++ ++struct compat_ethtool_rx_flow_spec { ++ u32 flow_type; ++ union { ++ struct ethtool_tcpip4_spec tcp_ip4_spec; ++ struct ethtool_tcpip4_spec udp_ip4_spec; ++ struct ethtool_tcpip4_spec sctp_ip4_spec; ++ struct ethtool_ah_espip4_spec ah_ip4_spec; ++ struct ethtool_ah_espip4_spec esp_ip4_spec; ++ struct ethtool_usrip4_spec usr_ip4_spec; ++ struct ethhdr ether_spec; ++ u8 hdata[72]; ++ } h_u, m_u; ++ compat_u64 ring_cookie; ++ u32 location; ++}; ++ ++struct compat_ethtool_rxnfc { ++ u32 cmd; ++ u32 flow_type; ++ compat_u64 data; ++ struct compat_ethtool_rx_flow_spec fs; ++ u32 rule_cnt; ++ u32 rule_locs[0]; ++}; ++ ++#endif /* CONFIG_COMPAT */ ++#endif /* __KERNEL__ */ ++ + /** + * struct ethtool_rxfh_indir - command to get or set RX flow hash indirection + * @cmd: Specific command number - %ETHTOOL_GRXFHINDIR or %ETHTOOL_SRXFHINDIR +--- a/net/socket.c ++++ b/net/socket.c +@@ -2566,23 +2566,123 @@ static int dev_ifconf(struct net *net, s + + static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) + { ++ struct compat_ethtool_rxnfc __user *compat_rxnfc; ++ bool convert_in = false, convert_out = false; ++ size_t buf_size = ALIGN(sizeof(struct ifreq), 8); ++ struct ethtool_rxnfc __user *rxnfc; + struct ifreq __user *ifr; ++ u32 rule_cnt = 0, actual_rule_cnt; ++ u32 ethcmd; + u32 data; +- void __user *datap; ++ int ret; + +- ifr = compat_alloc_user_space(sizeof(*ifr)); ++ if (get_user(data, &ifr32->ifr_ifru.ifru_data)) ++ return -EFAULT; + +- if (copy_in_user(&ifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ)) ++ compat_rxnfc = compat_ptr(data); ++ ++ if (get_user(ethcmd, &compat_rxnfc->cmd)) + return -EFAULT; + +- if (get_user(data, &ifr32->ifr_ifru.ifru_data)) ++ /* Most ethtool structures are defined without padding. ++ * Unfortunately struct ethtool_rxnfc is an exception. ++ */ ++ switch (ethcmd) { ++ default: ++ break; ++ case ETHTOOL_GRXCLSRLALL: ++ /* Buffer size is variable */ ++ if (get_user(rule_cnt, &compat_rxnfc->rule_cnt)) ++ return -EFAULT; ++ if (rule_cnt > KMALLOC_MAX_SIZE / sizeof(u32)) ++ return -ENOMEM; ++ buf_size += rule_cnt * sizeof(u32); ++ /* fall through */ ++ case ETHTOOL_GRXRINGS: ++ case ETHTOOL_GRXCLSRLCNT: ++ case ETHTOOL_GRXCLSRULE: ++ convert_out = true; ++ /* fall through */ ++ case ETHTOOL_SRXCLSRLDEL: ++ case ETHTOOL_SRXCLSRLINS: ++ buf_size += sizeof(struct ethtool_rxnfc); ++ convert_in = true; ++ break; ++ } ++ ++ ifr = compat_alloc_user_space(buf_size); ++ rxnfc = (void *)ifr + ALIGN(sizeof(struct ifreq), 8); ++ ++ if (copy_in_user(&ifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ)) + return -EFAULT; + +- datap = compat_ptr(data); +- if (put_user(datap, &ifr->ifr_ifru.ifru_data)) ++ if (put_user(convert_in ? rxnfc : compat_ptr(data), ++ &ifr->ifr_ifru.ifru_data)) + return -EFAULT; + +- return dev_ioctl(net, SIOCETHTOOL, ifr); ++ if (convert_in) { ++ /* We expect there to be holes between fs.m_u and ++ * fs.ring_cookie and at the end of fs, but nowhere else. ++ */ ++ BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_u) + ++ sizeof(compat_rxnfc->fs.m_u) != ++ offsetof(struct ethtool_rxnfc, fs.m_u) + ++ sizeof(rxnfc->fs.m_u)); ++ BUILD_BUG_ON( ++ offsetof(struct compat_ethtool_rxnfc, fs.location) - ++ offsetof(struct compat_ethtool_rxnfc, fs.ring_cookie) != ++ offsetof(struct ethtool_rxnfc, fs.location) - ++ offsetof(struct ethtool_rxnfc, fs.ring_cookie)); ++ ++ if (copy_in_user(rxnfc, compat_rxnfc, ++ (void *)(&rxnfc->fs.m_u + 1) - ++ (void *)rxnfc) || ++ copy_in_user(&rxnfc->fs.ring_cookie, ++ &compat_rxnfc->fs.ring_cookie, ++ (void *)(&rxnfc->fs.location + 1) - ++ (void *)&rxnfc->fs.ring_cookie) || ++ copy_in_user(&rxnfc->rule_cnt, &compat_rxnfc->rule_cnt, ++ sizeof(rxnfc->rule_cnt))) ++ return -EFAULT; ++ } ++ ++ ret = dev_ioctl(net, SIOCETHTOOL, ifr); ++ if (ret) ++ return ret; ++ ++ if (convert_out) { ++ if (copy_in_user(compat_rxnfc, rxnfc, ++ (const void *)(&rxnfc->fs.m_u + 1) - ++ (const void *)rxnfc) || ++ copy_in_user(&compat_rxnfc->fs.ring_cookie, ++ &rxnfc->fs.ring_cookie, ++ (const void *)(&rxnfc->fs.location + 1) - ++ (const void *)&rxnfc->fs.ring_cookie) || ++ copy_in_user(&compat_rxnfc->rule_cnt, &rxnfc->rule_cnt, ++ sizeof(rxnfc->rule_cnt))) ++ return -EFAULT; ++ ++ if (ethcmd == ETHTOOL_GRXCLSRLALL) { ++ /* As an optimisation, we only copy the actual ++ * number of rules that the underlying ++ * function returned. Since Mallory might ++ * change the rule count in user memory, we ++ * check that it is less than the rule count ++ * originally given (as the user buffer size), ++ * which has been range-checked. ++ */ ++ if (get_user(actual_rule_cnt, &rxnfc->rule_cnt)) ++ return -EFAULT; ++ if (actual_rule_cnt < rule_cnt) ++ rule_cnt = actual_rule_cnt; ++ if (copy_in_user(&compat_rxnfc->rule_locs[0], ++ &rxnfc->rule_locs[0], ++ rule_cnt * sizeof(u32))) ++ return -EFAULT; ++ } ++ } ++ ++ return 0; + } + + static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32) diff --git a/queue-2.6.37/mm-swap-unlock-swapfile-inode-mutex-before-closing-file-on-bad-swapfiles.patch b/queue-2.6.37/mm-swap-unlock-swapfile-inode-mutex-before-closing-file-on-bad-swapfiles.patch new file mode 100644 index 00000000000..0d1967b7524 --- /dev/null +++ b/queue-2.6.37/mm-swap-unlock-swapfile-inode-mutex-before-closing-file-on-bad-swapfiles.patch @@ -0,0 +1,82 @@ +From 52c50567d8ab0a0a87f12cceaa4194967854f0bd Mon Sep 17 00:00:00 2001 +From: Mel Gorman +Date: Tue, 22 Mar 2011 16:30:08 -0700 +Subject: mm: swap: unlock swapfile inode mutex before closing file on bad swapfiles + +From: Mel Gorman + +commit 52c50567d8ab0a0a87f12cceaa4194967854f0bd upstream. + +If an administrator tries to swapon a file backed by NFS, the inode mutex is +taken (as it is for any swapfile) but later identified to be a bad swapfile +due to the lack of bmap and tries to cleanup. During cleanup, an attempt is +made to close the file but with inode->i_mutex still held. Closing an NFS +file syncs it which tries to acquire the inode mutex leading to deadlock. If +lockdep is enabled the following appears on the console; + + ============================================= + [ INFO: possible recursive locking detected ] + 2.6.38-rc8-autobuild #1 + --------------------------------------------- + swapon/2192 is trying to acquire lock: + (&sb->s_type->i_mutex_key#13){+.+.+.}, at: vfs_fsync_range+0x47/0x7c + + but task is already holding lock: + (&sb->s_type->i_mutex_key#13){+.+.+.}, at: sys_swapon+0x28d/0xae7 + + other info that might help us debug this: + 1 lock held by swapon/2192: + #0: (&sb->s_type->i_mutex_key#13){+.+.+.}, at: sys_swapon+0x28d/0xae7 + + stack backtrace: + Pid: 2192, comm: swapon Not tainted 2.6.38-rc8-autobuild #1 + Call Trace: + __lock_acquire+0x2eb/0x1623 + find_get_pages_tag+0x14a/0x174 + pagevec_lookup_tag+0x25/0x2e + vfs_fsync_range+0x47/0x7c + lock_acquire+0xd3/0x100 + vfs_fsync_range+0x47/0x7c + nfs_flush_one+0x0/0xdf [nfs] + mutex_lock_nested+0x40/0x2b1 + vfs_fsync_range+0x47/0x7c + vfs_fsync_range+0x47/0x7c + vfs_fsync+0x1c/0x1e + nfs_file_flush+0x64/0x69 [nfs] + filp_close+0x43/0x72 + sys_swapon+0xa39/0xae7 + sysret_check+0x2e/0x69 + system_call_fastpath+0x16/0x1b + +This patch releases the mutex if its held before calling filep_close() +so swapon fails as expected without deadlock when the swapfile is backed +by NFS. If accepted for 2.6.39, it should also be considered a -stable +candidate for 2.6.38 and 2.6.37. + +Signed-off-by: Mel Gorman +Acked-by: Hugh Dickins +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/swapfile.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/mm/swapfile.c ++++ b/mm/swapfile.c +@@ -2146,8 +2146,13 @@ bad_swap_2: + p->flags = 0; + spin_unlock(&swap_lock); + vfree(swap_map); +- if (swap_file) ++ if (swap_file) { ++ if (did_down) { ++ mutex_unlock(&inode->i_mutex); ++ did_down = 0; ++ } + filp_close(swap_file, NULL); ++ } + out: + if (page && !IS_ERR(page)) { + kunmap(page); diff --git a/queue-2.6.37/oom-avoid-deferring-oom-killer-if-exiting-task-is-being-traced.patch b/queue-2.6.37/oom-avoid-deferring-oom-killer-if-exiting-task-is-being-traced.patch new file mode 100644 index 00000000000..357f0086499 --- /dev/null +++ b/queue-2.6.37/oom-avoid-deferring-oom-killer-if-exiting-task-is-being-traced.patch @@ -0,0 +1,106 @@ +From edd45544c6f09550df0a5491aa8a07af24767e73 Mon Sep 17 00:00:00 2001 +From: David Rientjes +Date: Tue, 22 Mar 2011 16:30:12 -0700 +Subject: oom: avoid deferring oom killer if exiting task is being traced + +From: David Rientjes + +commit edd45544c6f09550df0a5491aa8a07af24767e73 upstream. + +The oom killer naturally defers killing anything if it finds an eligible +task that is already exiting and has yet to detach its ->mm. This avoids +unnecessarily killing tasks when one is already in the exit path and may +free enough memory that the oom killer is no longer needed. This is +detected by PF_EXITING since threads that have already detached its ->mm +are no longer considered at all. + +The problem with always deferring when a thread is PF_EXITING, however, is +that it may never actually exit when being traced, specifically if another +task is tracing it with PTRACE_O_TRACEEXIT. The oom killer does not want +to defer in this case since there is no guarantee that thread will ever +exit without intervention. + +This patch will now only defer the oom killer when a thread is PF_EXITING +and no ptracer has stopped its progress in the exit path. It also ensures +that a child is sacrificed for the chosen parent only if it has a +different ->mm as the comment implies: this ensures that the thread group +leader is always targeted appropriately. + +Signed-off-by: David Rientjes +Reported-by: Oleg Nesterov +Cc: KOSAKI Motohiro +Cc: KAMEZAWA Hiroyuki +Cc: Hugh Dickins +Cc: Andrey Vagin +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/oom_kill.c | 40 +++++++++++++++++++++++++--------------- + 1 file changed, 25 insertions(+), 15 deletions(-) + +--- a/mm/oom_kill.c ++++ b/mm/oom_kill.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + int sysctl_panic_on_oom; + int sysctl_oom_kill_allocating_task; +@@ -316,22 +317,29 @@ static struct task_struct *select_bad_pr + if (test_tsk_thread_flag(p, TIF_MEMDIE)) + return ERR_PTR(-1UL); + +- /* +- * This is in the process of releasing memory so wait for it +- * to finish before killing some other task by mistake. +- * +- * However, if p is the current task, we allow the 'kill' to +- * go ahead if it is exiting: this will simply set TIF_MEMDIE, +- * which will allow it to gain access to memory reserves in +- * the process of exiting and releasing its resources. +- * Otherwise we could get an easy OOM deadlock. +- */ + if (p->flags & PF_EXITING) { +- if (p != current) +- return ERR_PTR(-1UL); +- +- chosen = p; +- *ppoints = 1000; ++ /* ++ * If p is the current task and is in the process of ++ * releasing memory, we allow the "kill" to set ++ * TIF_MEMDIE, which will allow it to gain access to ++ * memory reserves. Otherwise, it may stall forever. ++ * ++ * The loop isn't broken here, however, in case other ++ * threads are found to have already been oom killed. ++ */ ++ if (p == current) { ++ chosen = p; ++ *ppoints = 1000; ++ } else { ++ /* ++ * If this task is not being ptraced on exit, ++ * then wait for it to finish before killing ++ * some other task unnecessarily. ++ */ ++ if (!(task_ptrace(p->group_leader) & ++ PT_TRACE_EXIT)) ++ return ERR_PTR(-1UL); ++ } + } + + points = oom_badness(p, mem, nodemask, totalpages); +@@ -493,6 +501,8 @@ static int oom_kill_process(struct task_ + list_for_each_entry(child, &t->children, sibling) { + unsigned int child_points; + ++ if (child->mm == p->mm) ++ continue; + /* + * oom_badness() returns 0 if the thread is unkillable + */ diff --git a/queue-2.6.37/oom-prevent-unnecessary-oom-kills-or-kernel-panics.patch b/queue-2.6.37/oom-prevent-unnecessary-oom-kills-or-kernel-panics.patch new file mode 100644 index 00000000000..87a4b852379 --- /dev/null +++ b/queue-2.6.37/oom-prevent-unnecessary-oom-kills-or-kernel-panics.patch @@ -0,0 +1,92 @@ +From 3a5dda7a17cf3706f79b86293f29db02d61e0d48 Mon Sep 17 00:00:00 2001 +From: David Rientjes +Date: Tue, 22 Mar 2011 16:30:09 -0700 +Subject: oom: prevent unnecessary oom kills or kernel panics + +From: David Rientjes + +commit 3a5dda7a17cf3706f79b86293f29db02d61e0d48 upstream. + +This patch prevents unnecessary oom kills or kernel panics by reverting +two commits: + + 495789a5 (oom: make oom_score to per-process value) + cef1d352 (oom: multi threaded process coredump don't make deadlock) + +First, 495789a5 (oom: make oom_score to per-process value) ignores the +fact that all threads in a thread group do not necessarily exit at the +same time. + +It is imperative that select_bad_process() detect threads that are in the +exit path, specifically those with PF_EXITING set, to prevent needlessly +killing additional tasks. If a process is oom killed and the thread group +leader exits, select_bad_process() cannot detect the other threads that +are PF_EXITING by iterating over only processes. Thus, it currently +chooses another task unnecessarily for oom kill or panics the machine when +nothing else is eligible. + +By iterating over threads instead, it is possible to detect threads that +are exiting and nominate them for oom kill so they get access to memory +reserves. + +Second, cef1d352 (oom: multi threaded process coredump don't make +deadlock) erroneously avoids making the oom killer a no-op when an +eligible thread other than current isfound to be exiting. We want to +detect this situation so that we may allow that exiting thread time to +exit and free its memory; if it is able to exit on its own, that should +free memory so current is no loner oom. If it is not able to exit on its +own, the oom killer will nominate it for oom kill which, in this case, +only means it will get access to memory reserves. + +Without this change, it is easy for the oom killer to unnecessarily target +tasks when all threads of a victim don't exit before the thread group +leader or, in the worst case, panic the machine. + +Signed-off-by: David Rientjes +Cc: KOSAKI Motohiro +Cc: KAMEZAWA Hiroyuki +Cc: Oleg Nesterov +Cc: Hugh Dickins +Cc: Andrey Vagin +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/oom_kill.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/mm/oom_kill.c ++++ b/mm/oom_kill.c +@@ -292,11 +292,11 @@ static struct task_struct *select_bad_pr + unsigned long totalpages, struct mem_cgroup *mem, + const nodemask_t *nodemask) + { +- struct task_struct *p; ++ struct task_struct *g, *p; + struct task_struct *chosen = NULL; + *ppoints = 0; + +- for_each_process(p) { ++ do_each_thread(g, p) { + unsigned int points; + + if (oom_unkillable_task(p, mem, nodemask)) +@@ -324,7 +324,7 @@ static struct task_struct *select_bad_pr + * the process of exiting and releasing its resources. + * Otherwise we could get an easy OOM deadlock. + */ +- if (thread_group_empty(p) && (p->flags & PF_EXITING) && p->mm) { ++ if ((p->flags & PF_EXITING) && p->mm) { + if (p != current) + return ERR_PTR(-1UL); + +@@ -337,7 +337,7 @@ static struct task_struct *select_bad_pr + chosen = p; + *ppoints = points; + } +- } ++ } while_each_thread(g, p); + + return chosen; + } diff --git a/queue-2.6.37/oom-skip-zombies-when-iterating-tasklist.patch b/queue-2.6.37/oom-skip-zombies-when-iterating-tasklist.patch new file mode 100644 index 00000000000..b79bfd8584e --- /dev/null +++ b/queue-2.6.37/oom-skip-zombies-when-iterating-tasklist.patch @@ -0,0 +1,44 @@ +From 30e2b41f20b6238f51e7cffb879c7a0f0073f5fe Mon Sep 17 00:00:00 2001 +From: Andrey Vagin +Date: Tue, 22 Mar 2011 16:30:11 -0700 +Subject: oom: skip zombies when iterating tasklist + +From: Andrey Vagin + +commit 30e2b41f20b6238f51e7cffb879c7a0f0073f5fe upstream. + +We shouldn't defer oom killing if a thread has already detached its ->mm +and still has TIF_MEMDIE set. Memory needs to be freed, so find kill +other threads that pin the same ->mm or find another task to kill. + +Signed-off-by: Andrey Vagin +Signed-off-by: David Rientjes +Cc: KOSAKI Motohiro +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/oom_kill.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/mm/oom_kill.c ++++ b/mm/oom_kill.c +@@ -299,6 +299,8 @@ static struct task_struct *select_bad_pr + do_each_thread(g, p) { + unsigned int points; + ++ if (!p->mm) ++ continue; + if (oom_unkillable_task(p, mem, nodemask)) + continue; + +@@ -324,7 +326,7 @@ static struct task_struct *select_bad_pr + * the process of exiting and releasing its resources. + * Otherwise we could get an easy OOM deadlock. + */ +- if ((p->flags & PF_EXITING) && p->mm) { ++ if (p->flags & PF_EXITING) { + if (p != current) + return ERR_PTR(-1UL); + diff --git a/queue-2.6.37/revert-slab-fix-missing-debug_slab-last-user.patch b/queue-2.6.37/revert-slab-fix-missing-debug_slab-last-user.patch new file mode 100644 index 00000000000..773247552e9 --- /dev/null +++ b/queue-2.6.37/revert-slab-fix-missing-debug_slab-last-user.patch @@ -0,0 +1,78 @@ +From 3ff84a7f36554b257cd57325b1a7c1fa4b49fbe3 Mon Sep 17 00:00:00 2001 +From: Pekka Enberg +Date: Mon, 14 Feb 2011 17:46:21 +0200 +Subject: Revert "slab: Fix missing DEBUG_SLAB last user" + +From: Pekka Enberg + +commit 3ff84a7f36554b257cd57325b1a7c1fa4b49fbe3 upstream. + +This reverts commit 5c5e3b33b7cb959a401f823707bee006caadd76e. + +The commit breaks ARM thusly: + +| Mount-cache hash table entries: 512 +| slab error in verify_redzone_free(): cache `idr_layer_cache': memory outside object was overwritten +| Backtrace: +| [] (dump_backtrace+0x0/0x110) from [] (dump_stack+0x18/0x1c) +| [] (dump_stack+0x0/0x1c) from [] (__slab_error+0x28/0x30) +| [] (__slab_error+0x0/0x30) from [] (cache_free_debugcheck+0x1c0/0x2b8) +| [] (cache_free_debugcheck+0x0/0x2b8) from [] (kmem_cache_free+0x3c/0xc0) +| [] (kmem_cache_free+0x0/0xc0) from [] (ida_get_new_above+0x19c/0x1c0) +| [] (ida_get_new_above+0x0/0x1c0) from [] (alloc_vfsmnt+0x54/0x144) +| [] (alloc_vfsmnt+0x0/0x144) from [] (vfs_kern_mount+0x30/0xec) +| [] (vfs_kern_mount+0x0/0xec) from [] (kern_mount_data+0x1c/0x20) +| [] (kern_mount_data+0x0/0x20) from [] (sysfs_init+0x68/0xc8) +| [] (sysfs_init+0x0/0xc8) from [] (mnt_init+0x90/0x1b0) +| [] (mnt_init+0x0/0x1b0) from [] (vfs_caches_init+0x100/0x140) +| [] (vfs_caches_init+0x0/0x140) from [] (start_kernel+0x2e8/0x368) +| [] (start_kernel+0x0/0x368) from [] (__enable_mmu+0x0/0x2c) +| c0113268: redzone 1:0xd84156c5c032b3ac, redzone 2:0xd84156c5635688c0. +| slab error in cache_alloc_debugcheck_after(): cache `idr_layer_cache': double free, or memory outside object was overwritten +| ... +| c011307c: redzone 1:0x9f91102ffffffff, redzone 2:0x9f911029d74e35b +| slab: Internal list corruption detected in cache 'idr_layer_cache'(24), slabp c0113000(16). Hexdump: +| +| 000: 20 4f 10 c0 20 4f 10 c0 7c 00 00 00 7c 30 11 c0 +| 010: 10 00 00 00 10 00 00 00 00 00 c9 17 fe ff ff ff +| 020: fe ff ff ff fe ff ff ff fe ff ff ff fe ff ff ff +| 030: fe ff ff ff fe ff ff ff fe ff ff ff fe ff ff ff +| 040: fe ff ff ff fe ff ff ff fe ff ff ff fe ff ff ff +| 050: fe ff ff ff fe ff ff ff fe ff ff ff 11 00 00 00 +| 060: 12 00 00 00 13 00 00 00 14 00 00 00 15 00 00 00 +| 070: 16 00 00 00 17 00 00 00 c0 88 56 63 +| kernel BUG at /home/rmk/git/linux-2.6-rmk/mm/slab.c:2928! + +Reference: https://lkml.org/lkml/2011/2/7/238 +Reported-and-analyzed-by: Russell King +Signed-off-by: Pekka Enberg +Signed-off-by: Greg Kroah-Hartman + +--- + mm/slab.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/mm/slab.c ++++ b/mm/slab.c +@@ -2288,8 +2288,8 @@ kmem_cache_create (const char *name, siz + if (ralign < align) { + ralign = align; + } +- /* disable debug if not aligning with REDZONE_ALIGN */ +- if (ralign & (__alignof__(unsigned long long) - 1)) ++ /* disable debug if necessary */ ++ if (ralign > __alignof__(unsigned long long)) + flags &= ~(SLAB_RED_ZONE | SLAB_STORE_USER); + /* + * 4) Store it. +@@ -2315,8 +2315,8 @@ kmem_cache_create (const char *name, siz + */ + if (flags & SLAB_RED_ZONE) { + /* add space for red zone words */ +- cachep->obj_offset += align; +- size += align + sizeof(unsigned long long); ++ cachep->obj_offset += sizeof(unsigned long long); ++ size += 2 * sizeof(unsigned long long); + } + if (flags & SLAB_STORE_USER) { + /* user store requires one word storage behind the end of diff --git a/queue-2.6.37/series b/queue-2.6.37/series new file mode 100644 index 00000000000..0554bb388e6 --- /dev/null +++ b/queue-2.6.37/series @@ -0,0 +1,15 @@ +alsa-hda-via-fix-stereo-mixer-recording-no-sound-issue.patch +alsa-hda-via-fix-independent-headphone-no-sound-issue.patch +alsa-hda-via-add-missing-support-for-vt1718s-in-a-a-path.patch +alsa-hda-via-fix-invalid-a-a-path-volume-adjust-issue.patch +alsa-hda-via-fix-codec-type-for-vt1708bce-at-the-right-timing.patch +alsa-hda-via-fix-vt1708-can-t-build-up-headphone-control-issue.patch +ethtool-compat-handling-for-struct-ethtool_rxnfc.patch +revert-slab-fix-missing-debug_slab-last-user.patch +aio-wake-all-waiters-when-destroying-ctx.patch +cgroups-if-you-list_empty-a-head-then-don-t-list_del-it.patch +shmem-let-shared-anonymous-be-nonlinear-again.patch +mm-swap-unlock-swapfile-inode-mutex-before-closing-file-on-bad-swapfiles.patch +oom-prevent-unnecessary-oom-kills-or-kernel-panics.patch +oom-skip-zombies-when-iterating-tasklist.patch +oom-avoid-deferring-oom-killer-if-exiting-task-is-being-traced.patch diff --git a/queue-2.6.37/shmem-let-shared-anonymous-be-nonlinear-again.patch b/queue-2.6.37/shmem-let-shared-anonymous-be-nonlinear-again.patch new file mode 100644 index 00000000000..ce006fb1911 --- /dev/null +++ b/queue-2.6.37/shmem-let-shared-anonymous-be-nonlinear-again.patch @@ -0,0 +1,34 @@ +From bee4c36a5cf5c9f63ce1d7372aa62045fbd16d47 Mon Sep 17 00:00:00 2001 +From: Hugh Dickins +Date: Tue, 22 Mar 2011 16:33:43 -0700 +Subject: shmem: let shared anonymous be nonlinear again + +From: Hugh Dickins + +commit bee4c36a5cf5c9f63ce1d7372aa62045fbd16d47 upstream. + +Up to 2.6.22, you could use remap_file_pages(2) on a tmpfs file or a +shared mapping of /dev/zero or a shared anonymous mapping. In 2.6.23 we +disabled it by default, but set VM_CAN_NONLINEAR to enable it on safe +mappings. We made sure to set it in shmem_mmap() for tmpfs files, but +missed it in shmem_zero_setup() for the others. Fix that at last. + +Reported-by: Kenny Simpson +Signed-off-by: Hugh Dickins +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/shmem.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -2784,5 +2784,6 @@ int shmem_zero_setup(struct vm_area_stru + fput(vma->vm_file); + vma->vm_file = file; + vma->vm_ops = &shmem_vm_ops; ++ vma->vm_flags |= VM_CAN_NONLINEAR; + return 0; + }