diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-08-02 10:52:39 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-08-02 10:52:39 -0700 |
commit | 7cb1509433fdaa0c402a419be9b13f94c45831a7 (patch) | |
tree | 6ce31161d9549400bc573a49714a1d4cdd1520a9 | |
parent | 632d9a268e3192160c9de2941903c898f3dd86d3 (diff) | |
download | stable-queue-7cb1509433fdaa0c402a419be9b13f94c45831a7.tar.gz |
3.0 patches
24 files changed, 1791 insertions, 0 deletions
diff --git a/queue-3.0/alsa-hda-fix-duplicated-dac-assignments-for-realtek.patch b/queue-3.0/alsa-hda-fix-duplicated-dac-assignments-for-realtek.patch new file mode 100644 index 0000000000..31620fd491 --- /dev/null +++ b/queue-3.0/alsa-hda-fix-duplicated-dac-assignments-for-realtek.patch @@ -0,0 +1,48 @@ +From c48a8fb0d31d6147d8d76b8e2ad7f51a2fbb5c4d Mon Sep 17 00:00:00 2001 +From: Takashi Iwai <tiwai@suse.de> +Date: Wed, 27 Jul 2011 16:41:57 +0200 +Subject: ALSA: hda - Fix duplicated DAC assignments for Realtek + +From: Takashi Iwai <tiwai@suse.de> + +commit c48a8fb0d31d6147d8d76b8e2ad7f51a2fbb5c4d upstream. + +Copying hp_pins and speaker_pins from line_out_pins may confuse the +parser, and it can lead to duplicated initializations for the same pin +with a wrong DAC assignment. The problem appears in 3.0 kernel code. + +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + sound/pci/hda/patch_realtek.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -1578,13 +1578,15 @@ static void alc_init_auto_hp(struct hda_ + if (present == 3) + spec->automute_hp_lo = 1; /* both HP and LO automute */ + +- if (!cfg->speaker_pins[0]) { ++ if (!cfg->speaker_pins[0] && ++ cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { + memcpy(cfg->speaker_pins, cfg->line_out_pins, + sizeof(cfg->speaker_pins)); + cfg->speaker_outs = cfg->line_outs; + } + +- if (!cfg->hp_pins[0]) { ++ if (!cfg->hp_pins[0] && ++ cfg->line_out_type == AUTO_PIN_HP_OUT) { + memcpy(cfg->hp_pins, cfg->line_out_pins, + sizeof(cfg->hp_pins)); + cfg->hp_outs = cfg->line_outs; +@@ -1603,6 +1605,7 @@ static void alc_init_auto_hp(struct hda_ + spec->automute_mode = ALC_AUTOMUTE_PIN; + } + if (spec->automute && cfg->line_out_pins[0] && ++ cfg->speaker_pins[0] && + cfg->line_out_pins[0] != cfg->hp_pins[0] && + cfg->line_out_pins[0] != cfg->speaker_pins[0]) { + for (i = 0; i < cfg->line_outs; i++) { diff --git a/queue-3.0/alsa-virtuoso-fix-silent-analog-output-on-xonar-essence-st.patch b/queue-3.0/alsa-virtuoso-fix-silent-analog-output-on-xonar-essence-st.patch new file mode 100644 index 0000000000..975f4de134 --- /dev/null +++ b/queue-3.0/alsa-virtuoso-fix-silent-analog-output-on-xonar-essence-st.patch @@ -0,0 +1,46 @@ +From c81c6b356b52d3fcb4d531d149573fc100aad643 Mon Sep 17 00:00:00 2001 +From: Clemens Ladisch <clemens@ladisch.de> +Date: Sun, 17 Jul 2011 22:18:05 +0200 +Subject: ALSA: virtuoso: fix silent analog output on Xonar Essence ST + Deluxe + +From: Clemens Ladisch <clemens@ladisch.de> + +commit c81c6b356b52d3fcb4d531d149573fc100aad643 upstream. + +Commit dd203fa97bd5 (ALSA: virtuoso: remove non-working controls on +Essence ST Deluxe) made it impossible to adjust the volume after the +driver initialized it to muted. + +Ensure that those DACs that can be accessed with I2C are initialized +to the same volume that is the reset default of the DAC without I2C. + +Signed-off-by: Clemens Ladisch <clemens@ladisch.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + sound/pci/oxygen/xonar_pcm179x.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/sound/pci/oxygen/xonar_pcm179x.c ++++ b/sound/pci/oxygen/xonar_pcm179x.c +@@ -327,8 +327,10 @@ static void pcm1796_init(struct oxygen * + { + struct xonar_pcm179x *data = chip->model_data; + +- data->pcm1796_regs[0][18 - PCM1796_REG_BASE] = PCM1796_MUTE | ++ data->pcm1796_regs[0][18 - PCM1796_REG_BASE] = + PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD; ++ if (!data->broken_i2c) ++ data->pcm1796_regs[0][18 - PCM1796_REG_BASE] |= PCM1796_MUTE; + data->pcm1796_regs[0][19 - PCM1796_REG_BASE] = + PCM1796_FLT_SHARP | PCM1796_ATS_1; + data->pcm1796_regs[0][20 - PCM1796_REG_BASE] = +@@ -1123,6 +1125,7 @@ int __devinit get_xonar_pcm179x_model(st + chip->model.control_filter = xonar_st_h6_control_filter; + chip->model.dac_channels_pcm = 8; + chip->model.dac_channels_mixer = 8; ++ chip->model.dac_volume_min = 255; + chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128); + break; + } diff --git a/queue-3.0/blacklist-traxdata-cdr4120-and-iomega-zip-drive-to-avoid-lock-ups.patch b/queue-3.0/blacklist-traxdata-cdr4120-and-iomega-zip-drive-to-avoid-lock-ups.patch new file mode 100644 index 0000000000..7f78bf94e2 --- /dev/null +++ b/queue-3.0/blacklist-traxdata-cdr4120-and-iomega-zip-drive-to-avoid-lock-ups.patch @@ -0,0 +1,40 @@ +From 82103978189e9731658cd32da5eb85ab7b8542b8 Mon Sep 17 00:00:00 2001 +From: Werner Fink <werner@novell.com> +Date: Thu, 9 Jun 2011 10:54:24 +0530 +Subject: [SCSI] Blacklist Traxdata CDR4120 and IOMEGA Zip drive to avoid lock ups. + +From: Werner Fink <werner@novell.com> + +commit 82103978189e9731658cd32da5eb85ab7b8542b8 upstream. + +This patch resulted from the discussion at +https://bugzilla.novell.com/show_bug.cgi?id=679277, +https://bugzilla.novell.com/show_bug.cgi?id=681840 . + +Signed-off-by: Werner Fink <werner@novell.com> +Signed-off-by: Ankit Jain <jankit@suse.de> +Signed-off-by: James Bottomley <JBottomley@Parallels.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/scsi/scsi_devinfo.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/scsi/scsi_devinfo.c ++++ b/drivers/scsi/scsi_devinfo.c +@@ -197,6 +197,7 @@ static struct { + {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, + {"IBM", "2105", NULL, BLIST_RETRY_HWERROR}, + {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN}, ++ {"IOMEGA", "ZIP", NULL, BLIST_NOTQ | BLIST_NOLUN}, + {"IOMEGA", "Io20S *F", NULL, BLIST_KEY}, + {"INSITE", "Floptical F*8I", NULL, BLIST_KEY}, + {"INSITE", "I325VM", NULL, BLIST_KEY}, +@@ -243,6 +244,7 @@ static struct { + {"Tornado-", "F4", "*", BLIST_NOREPORTLUN}, + {"TOSHIBA", "CDROM", NULL, BLIST_ISROM}, + {"TOSHIBA", "CD-ROM", NULL, BLIST_ISROM}, ++ {"Traxdata", "CDR4120", NULL, BLIST_NOLUN}, /* locks up */ + {"USB2.0", "SMARTMEDIA/XD", NULL, BLIST_FORCELUN | BLIST_INQUIRY_36}, + {"WangDAT", "Model 2600", "01.7", BLIST_SELECT_NO_ATN}, + {"WangDAT", "Model 3200", "02.2", BLIST_SELECT_NO_ATN}, diff --git a/queue-3.0/drm-radeon-kms-add-missing-vddci-setting-on-ni.patch b/queue-3.0/drm-radeon-kms-add-missing-vddci-setting-on-ni.patch new file mode 100644 index 0000000000..cace4d2059 --- /dev/null +++ b/queue-3.0/drm-radeon-kms-add-missing-vddci-setting-on-ni.patch @@ -0,0 +1,35 @@ +From 4639dd21e759e32125adc7171abf6cb8140d54cf Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Mon, 25 Jul 2011 18:50:08 -0400 +Subject: drm/radeon/kms: add missing vddci setting on NI+ + +From: Alex Deucher <alexander.deucher@amd.com> + +commit 4639dd21e759e32125adc7171abf6cb8140d54cf upstream. + +Need to add vddci setting to pm init as well as +resume. Fixes hangs on load on some boards. + +Fixes: +https://bugs.freedesktop.org/show_bug.cgi?id=38754 + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Dave Airlie <airlied@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/radeon/radeon_pm.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/gpu/drm/radeon/radeon_pm.c ++++ b/drivers/gpu/drm/radeon/radeon_pm.c +@@ -594,6 +594,9 @@ int radeon_pm_init(struct radeon_device + if (rdev->pm.default_vddc) + radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, + SET_VOLTAGE_TYPE_ASIC_VDDC); ++ if (rdev->pm.default_vddci) ++ radeon_atom_set_voltage(rdev, rdev->pm.default_vddci, ++ SET_VOLTAGE_TYPE_ASIC_VDDCI); + if (rdev->pm.default_sclk) + radeon_set_engine_clock(rdev, rdev->pm.default_sclk); + if (rdev->pm.default_mclk) diff --git a/queue-3.0/drm-radeon-kms-fix-dp-training-for-dpencoderservice.patch b/queue-3.0/drm-radeon-kms-fix-dp-training-for-dpencoderservice.patch new file mode 100644 index 0000000000..7ee7c36ba7 --- /dev/null +++ b/queue-3.0/drm-radeon-kms-fix-dp-training-for-dpencoderservice.patch @@ -0,0 +1,89 @@ +From 5a96a899bbdee86024ab9ea6d02b9e242faacbed Mon Sep 17 00:00:00 2001 +From: Jerome Glisse <jglisse@redhat.com> +Date: Mon, 25 Jul 2011 11:57:43 -0400 +Subject: drm/radeon/kms: fix DP training for DPEncoderService + revision bigger than 1.1 + +From: Jerome Glisse <jglisse@redhat.com> + +commit 5a96a899bbdee86024ab9ea6d02b9e242faacbed upstream. + +DPEncoderService newer than 1.1 can't properly program the DP (display port) +link training. When facing such version use the DIGxEncoderControl method +instead. Fix DP link training on some R7XX. + +Signed-off-by: Jerome Glisse <jglisse@redhat.com> +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Dave Airlie <airlied@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/radeon/atombios_dp.c | 22 ++++++++++++++++++---- + 1 file changed, 18 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/radeon/atombios_dp.c ++++ b/drivers/gpu/drm/radeon/atombios_dp.c +@@ -627,6 +627,7 @@ struct radeon_dp_link_train_info { + u8 train_set[4]; + u8 link_status[DP_LINK_STATUS_SIZE]; + u8 tries; ++ bool use_dpencoder; + }; + + static void radeon_dp_update_vs_emph(struct radeon_dp_link_train_info *dp_info) +@@ -646,7 +647,7 @@ static void radeon_dp_set_tp(struct rade + int rtp = 0; + + /* set training pattern on the source */ +- if (ASIC_IS_DCE4(dp_info->rdev)) { ++ if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) { + switch (tp) { + case DP_TRAINING_PATTERN_1: + rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1; +@@ -706,7 +707,7 @@ static int radeon_dp_link_train_init(str + radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LINK_BW_SET, tmp); + + /* start training on the source */ +- if (ASIC_IS_DCE4(dp_info->rdev)) ++ if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) + atombios_dig_encoder_setup(dp_info->encoder, + ATOM_ENCODER_CMD_DP_LINK_TRAINING_START, 0); + else +@@ -731,7 +732,7 @@ static int radeon_dp_link_train_finish(s + DP_TRAINING_PATTERN_DISABLE); + + /* disable the training pattern on the source */ +- if (ASIC_IS_DCE4(dp_info->rdev)) ++ if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) + atombios_dig_encoder_setup(dp_info->encoder, + ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE, 0); + else +@@ -869,7 +870,8 @@ void radeon_dp_link_train(struct drm_enc + struct radeon_connector *radeon_connector; + struct radeon_connector_atom_dig *dig_connector; + struct radeon_dp_link_train_info dp_info; +- u8 tmp; ++ int index; ++ u8 tmp, frev, crev; + + if (!radeon_encoder->enc_priv) + return; +@@ -884,6 +886,18 @@ void radeon_dp_link_train(struct drm_enc + (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_eDP)) + return; + ++ /* DPEncoderService newer than 1.1 can't program properly the ++ * training pattern. When facing such version use the ++ * DIGXEncoderControl (X== 1 | 2) ++ */ ++ dp_info.use_dpencoder = true; ++ index = GetIndexIntoMasterTable(COMMAND, DPEncoderService); ++ if (atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) { ++ if (crev > 1) { ++ dp_info.use_dpencoder = false; ++ } ++ } ++ + dp_info.enc_id = 0; + if (dig->dig_encoder) + dp_info.enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; diff --git a/queue-3.0/drm-radeon-kms-fix-i2c-map-for-rv250-280.patch b/queue-3.0/drm-radeon-kms-fix-i2c-map-for-rv250-280.patch new file mode 100644 index 0000000000..f327b76a7f --- /dev/null +++ b/queue-3.0/drm-radeon-kms-fix-i2c-map-for-rv250-280.patch @@ -0,0 +1,34 @@ +From 6dd666333ddee39903d86f870d5c40d9f100e0cc Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Sat, 23 Jul 2011 18:02:04 +0000 +Subject: drm/radeon/kms: fix i2c map for rv250/280 + +From: Alex Deucher <alexander.deucher@amd.com> + +commit 6dd666333ddee39903d86f870d5c40d9f100e0cc upstream. + +Those chips have crt2_ddc bus. + +Fixes: +https://bugzilla.kernel.org/show_bug.cgi?id=39672 + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Dave Airlie <airlied@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/radeon/radeon_combios.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/radeon/radeon_combios.c ++++ b/drivers/gpu/drm/radeon/radeon_combios.c +@@ -779,7 +779,8 @@ void radeon_combios_i2c_init(struct rade + } + } + } +- } else if (rdev->family >= CHIP_R200) { ++ } else if ((rdev->family == CHIP_R200) || ++ (rdev->family >= CHIP_R300)) { + /* 0x68 */ + i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); + rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); diff --git a/queue-3.0/fix-crash-in-scsi_dispatch_cmd.patch b/queue-3.0/fix-crash-in-scsi_dispatch_cmd.patch new file mode 100644 index 0000000000..151369cd58 --- /dev/null +++ b/queue-3.0/fix-crash-in-scsi_dispatch_cmd.patch @@ -0,0 +1,71 @@ +From bfe159a51203c15d23cb3158fffdc25ec4b4dda1 Mon Sep 17 00:00:00 2001 +From: James Bottomley <James.Bottomley@HansenPartnership.com> +Date: Thu, 7 Jul 2011 15:45:40 -0500 +Subject: [SCSI] fix crash in scsi_dispatch_cmd() + +From: James Bottomley <James.Bottomley@HansenPartnership.com> + +commit bfe159a51203c15d23cb3158fffdc25ec4b4dda1 upstream. + +USB surprise removal of sr is triggering an oops in +scsi_dispatch_command(). What seems to be happening is that USB is +hanging on to a queue reference until the last close of the upper +device, so the crash is caused by surprise remove of a mounted CD +followed by attempted unmount. + +The problem is that USB doesn't issue its final commands as part of +the SCSI teardown path, but on last close when the block queue is long +gone. The long term fix is probably to make sr do the teardown in the +same way as sd (so remove all the lower bits on ejection, but keep the +upper disk alive until last close of user space). However, the +current oops can be simply fixed by not allowing any commands to be +sent to a dead queue. + +Signed-off-by: James Bottomley <JBottomley@Parallels.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + block/blk-core.c | 3 +++ + block/blk-exec.c | 7 +++++++ + drivers/scsi/scsi_lib.c | 2 ++ + 3 files changed, 12 insertions(+) + +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -839,6 +839,9 @@ struct request *blk_get_request(struct r + { + struct request *rq; + ++ if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) ++ return NULL; ++ + BUG_ON(rw != READ && rw != WRITE); + + spin_lock_irq(q->queue_lock); +--- a/block/blk-exec.c ++++ b/block/blk-exec.c +@@ -50,6 +50,13 @@ void blk_execute_rq_nowait(struct reques + { + int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK; + ++ if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) { ++ rq->errors = -ENXIO; ++ if (rq->end_io) ++ rq->end_io(rq, rq->errors); ++ return; ++ } ++ + rq->rq_disk = bd_disk; + rq->end_io = done; + WARN_ON(irqs_disabled()); +--- a/drivers/scsi/scsi_lib.c ++++ b/drivers/scsi/scsi_lib.c +@@ -213,6 +213,8 @@ int scsi_execute(struct scsi_device *sde + int ret = DRIVER_ERROR << 24; + + req = blk_get_request(sdev->request_queue, write, __GFP_WAIT); ++ if (!req) ++ return ret; + + if (bufflen && blk_rq_map_kern(sdev->request_queue, req, + buffer, bufflen, __GFP_WAIT)) diff --git a/queue-3.0/hpsa-do-not-attempt-to-read-from-a-write-only.patch b/queue-3.0/hpsa-do-not-attempt-to-read-from-a-write-only.patch new file mode 100644 index 0000000000..64de31b110 --- /dev/null +++ b/queue-3.0/hpsa-do-not-attempt-to-read-from-a-write-only.patch @@ -0,0 +1,32 @@ +From fec62c368b9c8b05d5124ca6c3b8336b537f26f3 Mon Sep 17 00:00:00 2001 +From: "Stephen M. Cameron" <scameron@beardog.cce.hp.com> +Date: Thu, 21 Jul 2011 13:16:05 -0500 +Subject: [SCSI] hpsa: do not attempt to read from a write-only register + +From: "Stephen M. Cameron" <scameron@beardog.cce.hp.com> + +commit fec62c368b9c8b05d5124ca6c3b8336b537f26f3 upstream. + +Most smartarrays tolerate it, but a few new ones don't. +Without this change some newer Smart Arrays will lock up +and i/o will grind to a halt. + +Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com> +Signed-off-by: James Bottomley <JBottomley@Parallels.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/scsi/hpsa.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/hpsa.h ++++ b/drivers/scsi/hpsa.h +@@ -214,7 +214,7 @@ static void SA5_submit_command(struct ct + dev_dbg(&h->pdev->dev, "Sending %x, tag = %x\n", c->busaddr, + c->Header.Tag.lower); + writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); +- (void) readl(h->vaddr + SA5_REQUEST_PORT_OFFSET); ++ (void) readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); + h->commands_outstanding++; + if (h->commands_outstanding > h->max_outstanding) + h->max_outstanding = h->commands_outstanding; diff --git a/queue-3.0/irq_work-alpha-fix-up-arch-hooks.patch b/queue-3.0/irq_work-alpha-fix-up-arch-hooks.patch new file mode 100644 index 0000000000..9a26748a9c --- /dev/null +++ b/queue-3.0/irq_work-alpha-fix-up-arch-hooks.patch @@ -0,0 +1,34 @@ +From 0f933625e7b6c3d91878ae95e341bf1984db7eaf Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra <a.p.zijlstra@chello.nl> +Date: Tue, 28 Jun 2011 12:15:51 +0200 +Subject: irq_work, alpha: Fix up arch hooks + +From: Peter Zijlstra <a.p.zijlstra@chello.nl> + +commit 0f933625e7b6c3d91878ae95e341bf1984db7eaf upstream. + +Commit e360adbe29 ("irq_work: Add generic hardirq context +callbacks") fouled up the Alpha bit, not properly naming the +arch specific function that raises the 'self-IPI'. + +Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> +Cc: Michael Cree <mcree@orcon.net.nz> +Link: http://lkml.kernel.org/n/tip-gukh0txmql2l4thgrekzzbfy@git.kernel.org +Signed-off-by: Ingo Molnar <mingo@elte.hu> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + arch/alpha/kernel/time.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/alpha/kernel/time.c ++++ b/arch/alpha/kernel/time.c +@@ -91,7 +91,7 @@ DEFINE_PER_CPU(u8, irq_work_pending); + #define test_irq_work_pending() __get_cpu_var(irq_work_pending) + #define clear_irq_work_pending() __get_cpu_var(irq_work_pending) = 0 + +-void set_irq_work_pending(void) ++void arch_irq_work_raise(void) + { + set_irq_work_pending_flag(); + } diff --git a/queue-3.0/kexec-x86-fix-incorrect-jump-back-address-if-not.patch b/queue-3.0/kexec-x86-fix-incorrect-jump-back-address-if-not.patch new file mode 100644 index 0000000000..7fc843102c --- /dev/null +++ b/queue-3.0/kexec-x86-fix-incorrect-jump-back-address-if-not.patch @@ -0,0 +1,57 @@ +From 050438ed5a05b25cdf287f5691e56a58c2606997 Mon Sep 17 00:00:00 2001 +From: Huang Ying <ying.huang@intel.com> +Date: Thu, 14 Jul 2011 09:34:37 +0800 +Subject: kexec, x86: Fix incorrect jump back address if not + preserving context + +From: Huang Ying <ying.huang@intel.com> + +commit 050438ed5a05b25cdf287f5691e56a58c2606997 upstream. + +In kexec jump support, jump back address passed to the kexeced +kernel via function calling ABI, that is, the function call +return address is the jump back entry. + +Furthermore, jump back entry == 0 should be used to signal that +the jump back or preserve context is not enabled in the original +kernel. + +But in the current implementation the stack position used for +function call return address is not cleared context +preservation is disabled. The patch fixes this bug. + +Reported-and-tested-by: Yin Kangkai <kangkai.yin@intel.com> +Signed-off-by: Huang Ying <ying.huang@intel.com> +Cc: Eric W. Biederman <ebiederm@xmission.com> +Cc: Vivek Goyal <vgoyal@redhat.com> +Link: http://lkml.kernel.org/r/1310607277-25029-1-git-send-email-ying.huang@intel.com +Signed-off-by: Ingo Molnar <mingo@elte.hu> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + arch/x86/kernel/relocate_kernel_32.S | 2 ++ + arch/x86/kernel/relocate_kernel_64.S | 2 ++ + 2 files changed, 4 insertions(+) + +--- a/arch/x86/kernel/relocate_kernel_32.S ++++ b/arch/x86/kernel/relocate_kernel_32.S +@@ -97,6 +97,8 @@ relocate_kernel: + ret + + identity_mapped: ++ /* set return address to 0 if not preserving context */ ++ pushl $0 + /* store the start address on the stack */ + pushl %edx + +--- a/arch/x86/kernel/relocate_kernel_64.S ++++ b/arch/x86/kernel/relocate_kernel_64.S +@@ -100,6 +100,8 @@ relocate_kernel: + ret + + identity_mapped: ++ /* set return address to 0 if not preserving context */ ++ pushq $0 + /* store the start address on the stack */ + pushq %rdx + diff --git a/queue-3.0/oprofile-x86-fix-nmi-unsafe-callgraph-support.patch b/queue-3.0/oprofile-x86-fix-nmi-unsafe-callgraph-support.patch new file mode 100644 index 0000000000..45b675f4a5 --- /dev/null +++ b/queue-3.0/oprofile-x86-fix-nmi-unsafe-callgraph-support.patch @@ -0,0 +1,165 @@ +From a0e3e70243f5b270bc3eca718f0a9fa5e6b8262e Mon Sep 17 00:00:00 2001 +From: Robert Richter <robert.richter@amd.com> +Date: Fri, 3 Jun 2011 16:37:47 +0200 +Subject: oprofile, x86: Fix nmi-unsafe callgraph support + +From: Robert Richter <robert.richter@amd.com> + +commit a0e3e70243f5b270bc3eca718f0a9fa5e6b8262e upstream. + +Current oprofile's x86 callgraph support may trigger page faults +throwing the BUG_ON(in_nmi()) message below. This patch fixes this by +using the same nmi-safe copy-from-user code as in perf. + +------------[ cut here ]------------ +kernel BUG at .../arch/x86/kernel/traps.c:436! +invalid opcode: 0000 [#1] SMP +last sysfs file: /sys/devices/pci0000:00/0000:00:0a.0/0000:07:00.0/0000:08:04.0/net/eth0/broadcast +CPU 5 +Modules linked in: + +Pid: 8611, comm: opcontrol Not tainted 2.6.39-00007-gfe47ae7 #1 Advanced Micro Device Anaheim/Anaheim +RIP: 0010:[<ffffffff813e8e35>] [<ffffffff813e8e35>] do_nmi+0x22/0x1ee +RSP: 0000:ffff88042fd47f28 EFLAGS: 00010002 +RAX: ffff88042c0a7fd8 RBX: 0000000000000001 RCX: 00000000c0000101 +RDX: 00000000ffff8804 RSI: ffffffffffffffff RDI: ffff88042fd47f58 +RBP: ffff88042fd47f48 R08: 0000000000000004 R09: 0000000000001484 +R10: 0000000000000001 R11: 0000000000000000 R12: ffff88042fd47f58 +R13: 0000000000000000 R14: ffff88042fd47d98 R15: 0000000000000020 +FS: 00007fca25e56700(0000) GS:ffff88042fd40000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000000000074 CR3: 000000042d28b000 CR4: 00000000000006e0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 +Process opcontrol (pid: 8611, threadinfo ffff88042c0a6000, task ffff88042c532310) +Stack: + 0000000000000000 0000000000000001 ffff88042c0a7fd8 0000000000000000 + ffff88042fd47de8 ffffffff813e897a 0000000000000020 ffff88042fd47d98 + 0000000000000000 ffff88042c0a7fd8 ffff88042fd47de8 0000000000000074 +Call Trace: + <NMI> + [<ffffffff813e897a>] nmi+0x1a/0x20 + [<ffffffff813f08ab>] ? bad_to_user+0x25/0x771 + <<EOE>> +Code: ff 59 5b 41 5c 41 5d c9 c3 55 65 48 8b 04 25 88 b5 00 00 48 89 e5 41 55 41 54 49 89 fc 53 48 83 ec 08 f6 80 47 e0 ff ff 04 74 04 <0f> 0b eb fe 81 80 44 e0 ff ff 00 00 01 04 65 ff 04 25 c4 0f 01 +RIP [<ffffffff813e8e35>] do_nmi+0x22/0x1ee + RSP <ffff88042fd47f28> +---[ end trace ed6752185092104b ]--- +Kernel panic - not syncing: Fatal exception in interrupt +Pid: 8611, comm: opcontrol Tainted: G D 2.6.39-00007-gfe47ae7 #1 +Call Trace: + <NMI> [<ffffffff813e5e0a>] panic+0x8c/0x188 + [<ffffffff813e915c>] oops_end+0x81/0x8e + [<ffffffff8100403d>] die+0x55/0x5e + [<ffffffff813e8c45>] do_trap+0x11c/0x12b + [<ffffffff810023c8>] do_invalid_op+0x91/0x9a + [<ffffffff813e8e35>] ? do_nmi+0x22/0x1ee + [<ffffffff8131e6fa>] ? oprofile_add_sample+0x83/0x95 + [<ffffffff81321670>] ? op_amd_check_ctrs+0x4f/0x2cf + [<ffffffff813ee4d5>] invalid_op+0x15/0x20 + [<ffffffff813e8e35>] ? do_nmi+0x22/0x1ee + [<ffffffff813e8e7a>] ? do_nmi+0x67/0x1ee + [<ffffffff813e897a>] nmi+0x1a/0x20 + [<ffffffff813f08ab>] ? bad_to_user+0x25/0x771 + <<EOE>> + +Cc: John Lumby <johnlumby@hotmail.com> +Cc: Maynard Johnson <maynardj@us.ibm.com> +Signed-off-by: Robert Richter <robert.richter@amd.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + arch/x86/oprofile/backtrace.c | 56 +++++++++++++++++++++++++++++++++++------- + 1 file changed, 47 insertions(+), 9 deletions(-) + +--- a/arch/x86/oprofile/backtrace.c ++++ b/arch/x86/oprofile/backtrace.c +@@ -11,10 +11,12 @@ + #include <linux/oprofile.h> + #include <linux/sched.h> + #include <linux/mm.h> ++#include <linux/compat.h> ++#include <linux/highmem.h> ++ + #include <asm/ptrace.h> + #include <asm/uaccess.h> + #include <asm/stacktrace.h> +-#include <linux/compat.h> + + static int backtrace_stack(void *data, char *name) + { +@@ -36,17 +38,53 @@ static struct stacktrace_ops backtrace_o + .walk_stack = print_context_stack, + }; + ++/* from arch/x86/kernel/cpu/perf_event.c: */ ++ ++/* ++ * best effort, GUP based copy_from_user() that assumes IRQ or NMI context ++ */ ++static unsigned long ++copy_from_user_nmi(void *to, const void __user *from, unsigned long n) ++{ ++ unsigned long offset, addr = (unsigned long)from; ++ unsigned long size, len = 0; ++ struct page *page; ++ void *map; ++ int ret; ++ ++ do { ++ ret = __get_user_pages_fast(addr, 1, 0, &page); ++ if (!ret) ++ break; ++ ++ offset = addr & (PAGE_SIZE - 1); ++ size = min(PAGE_SIZE - offset, n - len); ++ ++ map = kmap_atomic(page); ++ memcpy(to, map+offset, size); ++ kunmap_atomic(map); ++ put_page(page); ++ ++ len += size; ++ to += size; ++ addr += size; ++ ++ } while (len < n); ++ ++ return len; ++} ++ + #ifdef CONFIG_COMPAT + static struct stack_frame_ia32 * + dump_user_backtrace_32(struct stack_frame_ia32 *head) + { ++ /* Also check accessibility of one struct frame_head beyond: */ + struct stack_frame_ia32 bufhead[2]; + struct stack_frame_ia32 *fp; ++ unsigned long bytes; + +- /* Also check accessibility of one struct frame_head beyond */ +- if (!access_ok(VERIFY_READ, head, sizeof(bufhead))) +- return NULL; +- if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead))) ++ bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead)); ++ if (bytes != sizeof(bufhead)) + return NULL; + + fp = (struct stack_frame_ia32 *) compat_ptr(bufhead[0].next_frame); +@@ -87,12 +125,12 @@ x86_backtrace_32(struct pt_regs * const + + static struct stack_frame *dump_user_backtrace(struct stack_frame *head) + { ++ /* Also check accessibility of one struct frame_head beyond: */ + struct stack_frame bufhead[2]; ++ unsigned long bytes; + +- /* Also check accessibility of one struct stack_frame beyond */ +- if (!access_ok(VERIFY_READ, head, sizeof(bufhead))) +- return NULL; +- if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead))) ++ bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead)); ++ if (bytes != sizeof(bufhead)) + return NULL; + + oprofile_add_trace(bufhead[0].return_address); diff --git a/queue-3.0/pci-ari-is-a-pcie-v2-feature.patch b/queue-3.0/pci-ari-is-a-pcie-v2-feature.patch new file mode 100644 index 0000000000..6b27425571 --- /dev/null +++ b/queue-3.0/pci-ari-is-a-pcie-v2-feature.patch @@ -0,0 +1,50 @@ +From 864d296cf948aef0fa32b81407541572583f7572 Mon Sep 17 00:00:00 2001 +From: Chris Wright <chrisw@sous-sol.org> +Date: Wed, 13 Jul 2011 10:14:33 -0700 +Subject: PCI: ARI is a PCIe v2 feature + +From: Chris Wright <chrisw@sous-sol.org> + +commit 864d296cf948aef0fa32b81407541572583f7572 upstream. + +The function pci_enable_ari() may mistakenly set the downstream port +of a v1 PCIe switch in ARI Forwarding mode. This is a PCIe v2 feature, +and with an SR-IOV device on that switch port believing the switch above +is ARI capable it may attempt to use functions 8-255, translating into +invalid (non-zero) device numbers for that bus. This has been seen +to cause Completion Timeouts and general misbehaviour including hangs +and panics. + +Acked-by: Don Dutile <ddutile@redhat.com> +Tested-by: Don Dutile <ddutile@redhat.com> +Signed-off-by: Chris Wright <chrisw@sous-sol.org> +Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/pci/pci.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -1905,7 +1905,7 @@ void pci_enable_ari(struct pci_dev *dev) + { + int pos; + u32 cap; +- u16 ctrl; ++ u16 flags, ctrl; + struct pci_dev *bridge; + + if (!pci_is_pcie(dev) || dev->devfn) +@@ -1923,6 +1923,11 @@ void pci_enable_ari(struct pci_dev *dev) + if (!pos) + return; + ++ /* ARI is a PCIe v2 feature */ ++ pci_read_config_word(bridge, pos + PCI_EXP_FLAGS, &flags); ++ if ((flags & PCI_EXP_FLAGS_VERS) < 2) ++ return; ++ + pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap); + if (!(cap & PCI_EXP_DEVCAP2_ARI)) + return; diff --git a/queue-3.0/pmcraid-reject-negative-request-size.patch b/queue-3.0/pmcraid-reject-negative-request-size.patch new file mode 100644 index 0000000000..9e57c7fead --- /dev/null +++ b/queue-3.0/pmcraid-reject-negative-request-size.patch @@ -0,0 +1,52 @@ +From b5b515445f4f5a905c5dd27e6e682868ccd6c09d Mon Sep 17 00:00:00 2001 +From: Dan Rosenberg <drosenberg@vsecurity.com> +Date: Mon, 11 Jul 2011 14:08:23 -0700 +Subject: [SCSI] pmcraid: reject negative request size + +From: Dan Rosenberg <drosenberg@vsecurity.com> + +commit b5b515445f4f5a905c5dd27e6e682868ccd6c09d upstream. + +There's a code path in pmcraid that can be reached via device ioctl that +causes all sorts of ugliness, including heap corruption or triggering the +OOM killer due to consecutive allocation of large numbers of pages. + +First, the user can call pmcraid_chr_ioctl(), with a type +PMCRAID_PASSTHROUGH_IOCTL. This calls through to +pmcraid_ioctl_passthrough(). Next, a pmcraid_passthrough_ioctl_buffer +is copied in, and the request_size variable is set to +buffer->ioarcb.data_transfer_length, which is an arbitrary 32-bit +signed value provided by the user. If a negative value is provided +here, bad things can happen. For example, +pmcraid_build_passthrough_ioadls() is called with this request_size, +which immediately calls pmcraid_alloc_sglist() with a negative size. +The resulting math on allocating a scatter list can result in an +overflow in the kzalloc() call (if num_elem is 0, the sglist will be +smaller than expected), or if num_elem is unexpectedly large the +subsequent loop will call alloc_pages() repeatedly, a high number of +pages will be allocated and the OOM killer might be invoked. + +It looks like preventing this value from being negative in +pmcraid_ioctl_passthrough() would be sufficient. + +Signed-off-by: Dan Rosenberg <drosenberg@vsecurity.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: James Bottomley <JBottomley@Parallels.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/scsi/pmcraid.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/scsi/pmcraid.c ++++ b/drivers/scsi/pmcraid.c +@@ -3871,6 +3871,9 @@ static long pmcraid_ioctl_passthrough( + pmcraid_err("couldn't build passthrough ioadls\n"); + goto out_free_buffer; + } ++ } else if (request_size < 0) { ++ rc = -EINVAL; ++ goto out_free_buffer; + } + + /* If data is being written into the device, copy the data from user diff --git a/queue-3.0/pnfs-let-layoutcommit-handle-a-list-of-lseg.patch b/queue-3.0/pnfs-let-layoutcommit-handle-a-list-of-lseg.patch new file mode 100644 index 0000000000..b010402686 --- /dev/null +++ b/queue-3.0/pnfs-let-layoutcommit-handle-a-list-of-lseg.patch @@ -0,0 +1,160 @@ +From a9bae5666d0510ad69bdb437371c9a3e6b770705 Mon Sep 17 00:00:00 2001 +From: Peng Tao <peng_tao@emc.com> +Date: Sat, 30 Jul 2011 20:52:33 -0400 +Subject: pnfs: let layoutcommit handle a list of lseg + +From: Peng Tao <peng_tao@emc.com> + +commit a9bae5666d0510ad69bdb437371c9a3e6b770705 upstream. + +There can be multiple lseg per file, so layoutcommit should be +able to handle it. + +[Needed in v3.0] +Signed-off-by: Peng Tao <peng_tao@emc.com> +Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> +Signed-off-by: Jim Rees <rees@umich.edu> +Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + fs/nfs/nfs4proc.c | 8 +++++++- + fs/nfs/pnfs.c | 32 ++++++++++++++++---------------- + fs/nfs/pnfs.h | 2 ++ + include/linux/nfs_xdr.h | 2 +- + 4 files changed, 26 insertions(+), 18 deletions(-) + +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -5850,9 +5850,15 @@ nfs4_layoutcommit_done(struct rpc_task * + static void nfs4_layoutcommit_release(void *calldata) + { + struct nfs4_layoutcommit_data *data = calldata; ++ struct pnfs_layout_segment *lseg, *tmp; + + /* Matched by references in pnfs_set_layoutcommit */ +- put_lseg(data->lseg); ++ list_for_each_entry_safe(lseg, tmp, &data->lseg_list, pls_lc_list) { ++ list_del_init(&lseg->pls_lc_list); ++ if (test_and_clear_bit(NFS_LSEG_LAYOUTCOMMIT, ++ &lseg->pls_flags)) ++ put_lseg(lseg); ++ } + put_rpccred(data->cred); + kfree(data); + } +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -224,6 +224,7 @@ static void + init_lseg(struct pnfs_layout_hdr *lo, struct pnfs_layout_segment *lseg) + { + INIT_LIST_HEAD(&lseg->pls_list); ++ INIT_LIST_HEAD(&lseg->pls_lc_list); + atomic_set(&lseg->pls_refcount, 1); + smp_mb(); + set_bit(NFS_LSEG_VALID, &lseg->pls_flags); +@@ -1201,16 +1202,17 @@ pnfs_try_to_read_data(struct nfs_read_da + } + + /* +- * Currently there is only one (whole file) write lseg. ++ * There can be multiple RW segments. + */ +-static struct pnfs_layout_segment *pnfs_list_write_lseg(struct inode *inode) ++static void pnfs_list_write_lseg(struct inode *inode, struct list_head *listp) + { +- struct pnfs_layout_segment *lseg, *rv = NULL; ++ struct pnfs_layout_segment *lseg; + +- list_for_each_entry(lseg, &NFS_I(inode)->layout->plh_segs, pls_list) +- if (lseg->pls_range.iomode == IOMODE_RW) +- rv = lseg; +- return rv; ++ list_for_each_entry(lseg, &NFS_I(inode)->layout->plh_segs, pls_list) { ++ if (lseg->pls_range.iomode == IOMODE_RW && ++ test_bit(NFS_LSEG_LAYOUTCOMMIT, &lseg->pls_flags)) ++ list_add(&lseg->pls_lc_list, listp); ++ } + } + + void +@@ -1222,12 +1224,14 @@ pnfs_set_layoutcommit(struct nfs_write_d + + spin_lock(&nfsi->vfs_inode.i_lock); + if (!test_and_set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) { +- /* references matched in nfs4_layoutcommit_release */ +- get_lseg(wdata->lseg); + mark_as_dirty = true; + dprintk("%s: Set layoutcommit for inode %lu ", + __func__, wdata->inode->i_ino); + } ++ if (!test_and_set_bit(NFS_LSEG_LAYOUTCOMMIT, &wdata->lseg->pls_flags)) { ++ /* references matched in nfs4_layoutcommit_release */ ++ get_lseg(wdata->lseg); ++ } + if (end_pos > nfsi->layout->plh_lwb) + nfsi->layout->plh_lwb = end_pos; + spin_unlock(&nfsi->vfs_inode.i_lock); +@@ -1254,7 +1258,6 @@ pnfs_layoutcommit_inode(struct inode *in + { + struct nfs4_layoutcommit_data *data; + struct nfs_inode *nfsi = NFS_I(inode); +- struct pnfs_layout_segment *lseg; + loff_t end_pos; + int status = 0; + +@@ -1271,17 +1274,15 @@ pnfs_layoutcommit_inode(struct inode *in + goto out; + } + ++ INIT_LIST_HEAD(&data->lseg_list); + spin_lock(&inode->i_lock); + if (!test_and_clear_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) { + spin_unlock(&inode->i_lock); + kfree(data); + goto out; + } +- /* +- * Currently only one (whole file) write lseg which is referenced +- * in pnfs_set_layoutcommit and will be found. +- */ +- lseg = pnfs_list_write_lseg(inode); ++ ++ pnfs_list_write_lseg(inode, &data->lseg_list); + + end_pos = nfsi->layout->plh_lwb; + nfsi->layout->plh_lwb = 0; +@@ -1291,7 +1292,6 @@ pnfs_layoutcommit_inode(struct inode *in + spin_unlock(&inode->i_lock); + + data->args.inode = inode; +- data->lseg = lseg; + data->cred = get_rpccred(nfsi->layout->plh_lc_cred); + nfs_fattr_init(&data->fattr); + data->args.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask; +--- a/fs/nfs/pnfs.h ++++ b/fs/nfs/pnfs.h +@@ -36,10 +36,12 @@ + enum { + NFS_LSEG_VALID = 0, /* cleared when lseg is recalled/returned */ + NFS_LSEG_ROC, /* roc bit received from server */ ++ NFS_LSEG_LAYOUTCOMMIT, /* layoutcommit bit set for layoutcommit */ + }; + + struct pnfs_layout_segment { + struct list_head pls_list; ++ struct list_head pls_lc_list; + struct pnfs_layout_range pls_range; + atomic_t pls_refcount; + unsigned long pls_flags; +--- a/include/linux/nfs_xdr.h ++++ b/include/linux/nfs_xdr.h +@@ -262,7 +262,7 @@ struct nfs4_layoutcommit_res { + struct nfs4_layoutcommit_data { + struct rpc_task task; + struct nfs_fattr fattr; +- struct pnfs_layout_segment *lseg; ++ struct list_head lseg_list; + struct rpc_cred *cred; + struct nfs4_layoutcommit_args args; + struct nfs4_layoutcommit_res res; diff --git a/queue-3.0/pnfs-save-layoutcommit-cred-at-layout-header-init.patch b/queue-3.0/pnfs-save-layoutcommit-cred-at-layout-header-init.patch new file mode 100644 index 0000000000..c6d6667df9 --- /dev/null +++ b/queue-3.0/pnfs-save-layoutcommit-cred-at-layout-header-init.patch @@ -0,0 +1,133 @@ +From 9fa4075878a5faac872a63f4a97ce79c776264e9 Mon Sep 17 00:00:00 2001 +From: Peng Tao <bergwolf@gmail.com> +Date: Sat, 30 Jul 2011 20:52:32 -0400 +Subject: pnfs: save layoutcommit cred at layout header init + +From: Peng Tao <bergwolf@gmail.com> + +commit 9fa4075878a5faac872a63f4a97ce79c776264e9 upstream. + +No need to save it for every lseg. +No need to save it at every pnfs_set_layoutcommit. + +[Needed in v3.0] +Signed-off-by: Peng Tao <peng_tao@emc.com> +Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> +Signed-off-by: Jim Rees <rees@umich.edu> +Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + fs/nfs/pnfs.c | 21 +++++++++++---------- + fs/nfs/pnfs.h | 2 +- + 2 files changed, 12 insertions(+), 11 deletions(-) + +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -189,6 +189,7 @@ static void + pnfs_free_layout_hdr(struct pnfs_layout_hdr *lo) + { + struct pnfs_layoutdriver_type *ld = NFS_SERVER(lo->plh_inode)->pnfs_curr_ld; ++ put_rpccred(lo->plh_lc_cred); + return ld->alloc_layout_hdr ? ld->free_layout_hdr(lo) : kfree(lo); + } + +@@ -805,7 +806,9 @@ out: + } + + static struct pnfs_layout_hdr * +-alloc_init_layout_hdr(struct inode *ino, gfp_t gfp_flags) ++alloc_init_layout_hdr(struct inode *ino, ++ struct nfs_open_context *ctx, ++ gfp_t gfp_flags) + { + struct pnfs_layout_hdr *lo; + +@@ -817,11 +820,14 @@ alloc_init_layout_hdr(struct inode *ino, + INIT_LIST_HEAD(&lo->plh_segs); + INIT_LIST_HEAD(&lo->plh_bulk_recall); + lo->plh_inode = ino; ++ lo->plh_lc_cred = get_rpccred(ctx->state->owner->so_cred); + return lo; + } + + static struct pnfs_layout_hdr * +-pnfs_find_alloc_layout(struct inode *ino, gfp_t gfp_flags) ++pnfs_find_alloc_layout(struct inode *ino, ++ struct nfs_open_context *ctx, ++ gfp_t gfp_flags) + { + struct nfs_inode *nfsi = NFS_I(ino); + struct pnfs_layout_hdr *new = NULL; +@@ -836,7 +842,7 @@ pnfs_find_alloc_layout(struct inode *ino + return nfsi->layout; + } + spin_unlock(&ino->i_lock); +- new = alloc_init_layout_hdr(ino, gfp_flags); ++ new = alloc_init_layout_hdr(ino, ctx, gfp_flags); + spin_lock(&ino->i_lock); + + if (likely(nfsi->layout == NULL)) /* Won the race? */ +@@ -928,7 +934,7 @@ pnfs_update_layout(struct inode *ino, + if (!pnfs_enabled_sb(NFS_SERVER(ino))) + return NULL; + spin_lock(&ino->i_lock); +- lo = pnfs_find_alloc_layout(ino, gfp_flags); ++ lo = pnfs_find_alloc_layout(ino, ctx, gfp_flags); + if (lo == NULL) { + dprintk("%s ERROR: can't get pnfs_layout_hdr\n", __func__); + goto out_unlock; +@@ -1218,8 +1224,6 @@ pnfs_set_layoutcommit(struct nfs_write_d + if (!test_and_set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) { + /* references matched in nfs4_layoutcommit_release */ + get_lseg(wdata->lseg); +- wdata->lseg->pls_lc_cred = +- get_rpccred(wdata->args.context->state->owner->so_cred); + mark_as_dirty = true; + dprintk("%s: Set layoutcommit for inode %lu ", + __func__, wdata->inode->i_ino); +@@ -1251,7 +1255,6 @@ pnfs_layoutcommit_inode(struct inode *in + struct nfs4_layoutcommit_data *data; + struct nfs_inode *nfsi = NFS_I(inode); + struct pnfs_layout_segment *lseg; +- struct rpc_cred *cred; + loff_t end_pos; + int status = 0; + +@@ -1281,9 +1284,7 @@ pnfs_layoutcommit_inode(struct inode *in + lseg = pnfs_list_write_lseg(inode); + + end_pos = nfsi->layout->plh_lwb; +- cred = lseg->pls_lc_cred; + nfsi->layout->plh_lwb = 0; +- lseg->pls_lc_cred = NULL; + + memcpy(&data->args.stateid.data, nfsi->layout->plh_stateid.data, + sizeof(nfsi->layout->plh_stateid.data)); +@@ -1291,7 +1292,7 @@ pnfs_layoutcommit_inode(struct inode *in + + data->args.inode = inode; + data->lseg = lseg; +- data->cred = cred; ++ data->cred = get_rpccred(nfsi->layout->plh_lc_cred); + nfs_fattr_init(&data->fattr); + data->args.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask; + data->res.fattr = &data->fattr; +--- a/fs/nfs/pnfs.h ++++ b/fs/nfs/pnfs.h +@@ -44,7 +44,6 @@ struct pnfs_layout_segment { + atomic_t pls_refcount; + unsigned long pls_flags; + struct pnfs_layout_hdr *pls_layout; +- struct rpc_cred *pls_lc_cred; /* LAYOUTCOMMIT credential */ + }; + + enum pnfs_try_status { +@@ -124,6 +123,7 @@ struct pnfs_layout_hdr { + u32 plh_barrier; /* ignore lower seqids */ + unsigned long plh_flags; + loff_t plh_lwb; /* last write byte for layoutcommit */ ++ struct rpc_cred *plh_lc_cred; /* layoutcommit cred */ + struct inode *plh_inode; + }; + diff --git a/queue-3.0/pnfs-save-layoutcommit-lwb-at-layout-header.patch b/queue-3.0/pnfs-save-layoutcommit-lwb-at-layout-header.patch new file mode 100644 index 0000000000..16cff1b700 --- /dev/null +++ b/queue-3.0/pnfs-save-layoutcommit-lwb-at-layout-header.patch @@ -0,0 +1,80 @@ +From acff5880539fe33897d016c0f3dcf062e67c61b6 Mon Sep 17 00:00:00 2001 +From: Peng Tao <bergwolf@gmail.com> +Date: Sat, 30 Jul 2011 20:52:31 -0400 +Subject: pnfs: save layoutcommit lwb at layout header + +From: Peng Tao <bergwolf@gmail.com> + +commit acff5880539fe33897d016c0f3dcf062e67c61b6 upstream. + +No need to save it for every lseg. + +[Needed in v3.0] +Signed-off-by: Peng Tao <peng_tao@emc.com> +Signed-off-by: Jim Rees <rees@umich.edu> +Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + fs/nfs/nfs4filelayout.c | 2 +- + fs/nfs/pnfs.c | 10 ++++++---- + fs/nfs/pnfs.h | 2 +- + 3 files changed, 8 insertions(+), 6 deletions(-) + +--- a/fs/nfs/nfs4filelayout.c ++++ b/fs/nfs/nfs4filelayout.c +@@ -170,7 +170,7 @@ filelayout_set_layoutcommit(struct nfs_w + + pnfs_set_layoutcommit(wdata); + dprintk("%s ionde %lu pls_end_pos %lu\n", __func__, wdata->inode->i_ino, +- (unsigned long) wdata->lseg->pls_end_pos); ++ (unsigned long) NFS_I(wdata->inode)->layout->plh_lwb); + } + + /* +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -1224,9 +1224,11 @@ pnfs_set_layoutcommit(struct nfs_write_d + dprintk("%s: Set layoutcommit for inode %lu ", + __func__, wdata->inode->i_ino); + } +- if (end_pos > wdata->lseg->pls_end_pos) +- wdata->lseg->pls_end_pos = end_pos; ++ if (end_pos > nfsi->layout->plh_lwb) ++ nfsi->layout->plh_lwb = end_pos; + spin_unlock(&nfsi->vfs_inode.i_lock); ++ dprintk("%s: lseg %p end_pos %llu\n", ++ __func__, wdata->lseg, nfsi->layout->plh_lwb); + + /* if pnfs_layoutcommit_inode() runs between inode locks, the next one + * will be a noop because NFS_INO_LAYOUTCOMMIT will not be set */ +@@ -1278,9 +1280,9 @@ pnfs_layoutcommit_inode(struct inode *in + */ + lseg = pnfs_list_write_lseg(inode); + +- end_pos = lseg->pls_end_pos; ++ end_pos = nfsi->layout->plh_lwb; + cred = lseg->pls_lc_cred; +- lseg->pls_end_pos = 0; ++ nfsi->layout->plh_lwb = 0; + lseg->pls_lc_cred = NULL; + + memcpy(&data->args.stateid.data, nfsi->layout->plh_stateid.data, +--- a/fs/nfs/pnfs.h ++++ b/fs/nfs/pnfs.h +@@ -45,7 +45,6 @@ struct pnfs_layout_segment { + unsigned long pls_flags; + struct pnfs_layout_hdr *pls_layout; + struct rpc_cred *pls_lc_cred; /* LAYOUTCOMMIT credential */ +- loff_t pls_end_pos; /* LAYOUTCOMMIT write end */ + }; + + enum pnfs_try_status { +@@ -124,6 +123,7 @@ struct pnfs_layout_hdr { + unsigned long plh_block_lgets; /* block LAYOUTGET if >0 */ + u32 plh_barrier; /* ignore lower seqids */ + unsigned long plh_flags; ++ loff_t plh_lwb; /* last write byte for layoutcommit */ + struct inode *plh_inode; + }; + diff --git a/queue-3.0/pnfs-use-lwb-as-layoutcommit-length.patch b/queue-3.0/pnfs-use-lwb-as-layoutcommit-length.patch new file mode 100644 index 0000000000..95b16c2fd9 --- /dev/null +++ b/queue-3.0/pnfs-use-lwb-as-layoutcommit-length.patch @@ -0,0 +1,32 @@ +From 3557c6c3be5b2ca0b11365db7f8a813253eb520b Mon Sep 17 00:00:00 2001 +From: Peng Tao <bergwolf@gmail.com> +Date: Sat, 30 Jul 2011 20:52:34 -0400 +Subject: pnfs: use lwb as layoutcommit length + +From: Peng Tao <bergwolf@gmail.com> + +commit 3557c6c3be5b2ca0b11365db7f8a813253eb520b upstream. + +Using NFS4_MAX_UINT64 will break current protocol. + +[Needed in v3.0] +Signed-off-by: Peng Tao <peng_tao@emc.com> +Signed-off-by: Jim Rees <rees@umich.edu> +Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + fs/nfs/nfs4xdr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfs/nfs4xdr.c ++++ b/fs/nfs/nfs4xdr.c +@@ -1888,7 +1888,7 @@ encode_layoutcommit(struct xdr_stream *x + *p++ = cpu_to_be32(OP_LAYOUTCOMMIT); + /* Only whole file layouts */ + p = xdr_encode_hyper(p, 0); /* offset */ +- p = xdr_encode_hyper(p, NFS4_MAX_UINT64); /* length */ ++ p = xdr_encode_hyper(p, args->lastbytewritten + 1); /* length */ + *p++ = cpu_to_be32(0); /* reclaim */ + p = xdr_encode_opaque_fixed(p, args->stateid.data, NFS4_STATEID_SIZE); + *p++ = cpu_to_be32(1); /* newoffset = TRUE */ diff --git a/queue-3.0/powerpc-kdump-fix-timeout-in-crash_kexec_wait_realmode.patch b/queue-3.0/powerpc-kdump-fix-timeout-in-crash_kexec_wait_realmode.patch new file mode 100644 index 0000000000..989fc97280 --- /dev/null +++ b/queue-3.0/powerpc-kdump-fix-timeout-in-crash_kexec_wait_realmode.patch @@ -0,0 +1,43 @@ +From 63f21a56f1cc0b800a4c00349c59448f82473d19 Mon Sep 17 00:00:00 2001 +From: Michael Neuling <mikey@neuling.org> +Date: Mon, 4 Jul 2011 20:40:10 +0000 +Subject: powerpc/kdump: Fix timeout in crash_kexec_wait_realmode + +From: Michael Neuling <mikey@neuling.org> + +commit 63f21a56f1cc0b800a4c00349c59448f82473d19 upstream. + +The existing code it pretty ugly. How about we clean it up even more +like this? + +From: Anton Blanchard <anton@samba.org> + +We check for timeout expiry in the outer loop, but we also need to +check it in the inner loop or we can lock up forever waiting for a +CPU to hit real mode. + +Signed-off-by: Anton Blanchard <anton@samba.org> +Signed-off-by: Michael Neuling <mikey@neuling.org> +Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + arch/powerpc/kernel/crash.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +--- a/arch/powerpc/kernel/crash.c ++++ b/arch/powerpc/kernel/crash.c +@@ -242,12 +242,8 @@ static void crash_kexec_wait_realmode(in + + while (paca[i].kexec_state < KEXEC_STATE_REAL_MODE) { + barrier(); +- if (!cpu_possible(i)) { ++ if (!cpu_possible(i) || !cpu_online(i) || (msecs <= 0)) + break; +- } +- if (!cpu_online(i)) { +- break; +- } + msecs--; + mdelay(1); + } diff --git a/queue-3.0/series b/queue-3.0/series index 6816640230..e1e0d80af6 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -38,3 +38,26 @@ perf-tools-x86-fix-32-bit-compile-on-64-bit-system.patch perf-tools-fix-endian-conversion-reading-event-attr-from.patch x86-intel-power-initialize-msr_ia32_energy_perf_bias.patch perf-fix-software-event-overflow.patch +blacklist-traxdata-cdr4120-and-iomega-zip-drive-to-avoid-lock-ups.patch +sr-check_events-ignore-get_event-when-tur-says-otherwise.patch +ses-requesting-a-fault-indication.patch +fix-crash-in-scsi_dispatch_cmd.patch +pmcraid-reject-negative-request-size.patch +hpsa-do-not-attempt-to-read-from-a-write-only.patch +drm-radeon-kms-fix-i2c-map-for-rv250-280.patch +drm-radeon-kms-fix-dp-training-for-dpencoderservice.patch +drm-radeon-kms-add-missing-vddci-setting-on-ni.patch +alsa-virtuoso-fix-silent-analog-output-on-xonar-essence-st.patch +alsa-hda-fix-duplicated-dac-assignments-for-realtek.patch +pnfs-save-layoutcommit-lwb-at-layout-header.patch +pnfs-save-layoutcommit-cred-at-layout-header-init.patch +pnfs-let-layoutcommit-handle-a-list-of-lseg.patch +pnfs-use-lwb-as-layoutcommit-length.patch +kexec-x86-fix-incorrect-jump-back-address-if-not.patch +oprofile-x86-fix-nmi-unsafe-callgraph-support.patch +powerpc-kdump-fix-timeout-in-crash_kexec_wait_realmode.patch +irq_work-alpha-fix-up-arch-hooks.patch +tracing-fix-bug-when-reading-system-filters-on-module.patch +tracing-have-enable-file-use-refcounts-like-the-filter.patch +xz-fix-missing-linux-kernel.h-include.patch +pci-ari-is-a-pcie-v2-feature.patch diff --git a/queue-3.0/ses-requesting-a-fault-indication.patch b/queue-3.0/ses-requesting-a-fault-indication.patch new file mode 100644 index 0000000000..eeb7de3d7e --- /dev/null +++ b/queue-3.0/ses-requesting-a-fault-indication.patch @@ -0,0 +1,54 @@ +From 2a350cab9daf9a46322d83b091bb05cf54ccf6ab Mon Sep 17 00:00:00 2001 +From: Douglas Gilbert <dgilbert@interlog.com> +Date: Thu, 9 Jun 2011 00:27:07 -0400 +Subject: [SCSI] ses: requesting a fault indication + +From: Douglas Gilbert <dgilbert@interlog.com> + +commit 2a350cab9daf9a46322d83b091bb05cf54ccf6ab upstream. + +Noticed that when the sysfs interface of the SCSI SES +driver was used to request a fault indication the LED +flashed but the buzzer didn't sound. So it was doing +what REQUEST IDENT (locate) should do. + +Changelog: + - fix the setting of REQUEST FAULT for the device slot + and array device slot elements in the enclosure control + diagnostic page + - note the potentially defective code that reads the + FAULT SENSED and FAULT REQUESTED bits from the enclosure + status diagnostic page + +The attached patch is against git/scsi-misc-2.6 + +Signed-off-by: Douglas Gilbert <dgilbert@interlog.com> +Signed-off-by: James Bottomley <JBottomley@Parallels.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/scsi/ses.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/ses.c ++++ b/drivers/scsi/ses.c +@@ -160,6 +160,10 @@ static unsigned char *ses_get_page2_desc + return NULL; + } + ++/* For device slot and array device slot elements, byte 3 bit 6 ++ * is "fault sensed" while byte 3 bit 5 is "fault reqstd". As this ++ * code stands these bits are shifted 4 positions right so in ++ * sysfs they will appear as bits 2 and 1 respectively. Strange. */ + static void ses_get_fault(struct enclosure_device *edev, + struct enclosure_component *ecomp) + { +@@ -181,7 +185,7 @@ static int ses_set_fault(struct enclosur + /* zero is disabled */ + break; + case ENCLOSURE_SETTING_ENABLED: +- desc[2] = 0x02; ++ desc[3] = 0x20; + break; + default: + /* SES doesn't do the SGPIO blink settings */ diff --git a/queue-3.0/sr-check_events-ignore-get_event-when-tur-says-otherwise.patch b/queue-3.0/sr-check_events-ignore-get_event-when-tur-says-otherwise.patch new file mode 100644 index 0000000000..c858825500 --- /dev/null +++ b/queue-3.0/sr-check_events-ignore-get_event-when-tur-says-otherwise.patch @@ -0,0 +1,137 @@ +From 79b9677d885d1a792bc103f2febb06f91f92de43 Mon Sep 17 00:00:00 2001 +From: Kay Sievers <kay.sievers@vrfy.org> +Date: Thu, 30 Jun 2011 15:03:48 +0200 +Subject: [SCSI] sr: check_events() ignore GET_EVENT when TUR says otherwise + +From: Kay Sievers <kay.sievers@vrfy.org> + +commit 79b9677d885d1a792bc103f2febb06f91f92de43 upstream. + +Some broken devices indicates that media has changed on every +GET_EVENT_STATUS_NOTIFICATION. This translates into MEDIA_CHANGE +uevent on every open() which lets udev run into a loop. + +Verify GET_EVENT result against TUR and if it generates spurious +events for several times in a row, ignore the GET_EVENT events, and +trust only the TUR status. + +This is the log of a USB stick with a (broken) fake CDROM drive: + + scsi 5:0:0:0: Direct-Access SanDisk U3 Cruzer Micro 8.02 PQ: 0 ANSI: 0 CCS + sd 5:0:0:0: Attached scsi generic sg3 type 0 + scsi 5:0:0:1: CD-ROM SanDisk U3 Cruzer Micro 8.02 PQ: 0 ANSI: 0 + sd 5:0:0:0: [sdb] Attached SCSI removable disk + sr2: scsi3-mmc drive: 48x/48x tray + sr 5:0:0:1: Attached scsi CD-ROM sr2 + sr 5:0:0:1: Attached scsi generic sg4 type 5 + sr2: GET_EVENT and TUR disagree continuously, suppress GET_EVENT events + sd 5:0:0:0: [sdb] 31777279 512-byte logical blocks: (16.2 GB/15.1 GiB) + sd 5:0:0:0: [sdb] No Caching mode page present + sd 5:0:0:0: [sdb] Assuming drive cache: write through + sd 5:0:0:0: [sdb] No Caching mode page present + sd 5:0:0:0: [sdb] Assuming drive cache: write through + sdb: sdb1 + +-tj: Updated to consider only spurious GET_EVENT events among + different types of disagreement and allow using TUR for kernel + event polling after GET_EVENT is ignored. + +Reported-By: Markus Rathgeb maggu2810@googlemail.com +Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> +Signed-off-by: Tejun Heo <tj@kernel.org> +Signed-off-by: James Bottomley <JBottomley@Parallels.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/scsi/sr.c | 46 ++++++++++++++++++++++++++++++++++++++++++---- + drivers/scsi/sr.h | 7 +++++++ + 2 files changed, 49 insertions(+), 4 deletions(-) + +--- a/drivers/scsi/sr.c ++++ b/drivers/scsi/sr.c +@@ -221,14 +221,33 @@ static unsigned int sr_check_events(stru + return 0; + + events = sr_get_events(cd->device); ++ cd->get_event_changed |= events & DISK_EVENT_MEDIA_CHANGE; ++ ++ /* ++ * If earlier GET_EVENT_STATUS_NOTIFICATION and TUR did not agree ++ * for several times in a row. We rely on TUR only for this likely ++ * broken device, to prevent generating incorrect media changed ++ * events for every open(). ++ */ ++ if (cd->ignore_get_event) { ++ events &= ~DISK_EVENT_MEDIA_CHANGE; ++ goto do_tur; ++ } ++ + /* + * GET_EVENT_STATUS_NOTIFICATION is enough unless MEDIA_CHANGE + * is being cleared. Note that there are devices which hang + * if asked to execute TUR repeatedly. + */ +- if (!(clearing & DISK_EVENT_MEDIA_CHANGE)) +- goto skip_tur; ++ if (cd->device->changed) { ++ events |= DISK_EVENT_MEDIA_CHANGE; ++ cd->device->changed = 0; ++ cd->tur_changed = true; ++ } + ++ if (!(clearing & DISK_EVENT_MEDIA_CHANGE)) ++ return events; ++do_tur: + /* let's see whether the media is there with TUR */ + last_present = cd->media_present; + ret = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr); +@@ -242,12 +261,31 @@ static unsigned int sr_check_events(stru + (scsi_sense_valid(&sshdr) && sshdr.asc != 0x3a); + + if (last_present != cd->media_present) +- events |= DISK_EVENT_MEDIA_CHANGE; +-skip_tur: ++ cd->device->changed = 1; ++ + if (cd->device->changed) { + events |= DISK_EVENT_MEDIA_CHANGE; + cd->device->changed = 0; ++ cd->tur_changed = true; ++ } ++ ++ if (cd->ignore_get_event) ++ return events; ++ ++ /* check whether GET_EVENT is reporting spurious MEDIA_CHANGE */ ++ if (!cd->tur_changed) { ++ if (cd->get_event_changed) { ++ if (cd->tur_mismatch++ > 8) { ++ sdev_printk(KERN_WARNING, cd->device, ++ "GET_EVENT and TUR disagree continuously, suppress GET_EVENT events\n"); ++ cd->ignore_get_event = true; ++ } ++ } else { ++ cd->tur_mismatch = 0; ++ } + } ++ cd->tur_changed = false; ++ cd->get_event_changed = false; + + return events; + } +--- a/drivers/scsi/sr.h ++++ b/drivers/scsi/sr.h +@@ -41,6 +41,13 @@ typedef struct scsi_cd { + unsigned readcd_known:1; /* drive supports READ_CD (0xbe) */ + unsigned readcd_cdda:1; /* reading audio data using READ_CD */ + unsigned media_present:1; /* media is present */ ++ ++ /* GET_EVENT spurious event handling, blk layer guarantees exclusion */ ++ int tur_mismatch; /* nr of get_event TUR mismatches */ ++ bool tur_changed:1; /* changed according to TUR */ ++ bool get_event_changed:1; /* changed according to GET_EVENT */ ++ bool ignore_get_event:1; /* GET_EVENT is unreliable, use TUR */ ++ + struct cdrom_device_info cdi; + /* We hold gendisk and scsi_device references on probe and use + * the refs on this kref to decide when to release them */ diff --git a/queue-3.0/tracing-fix-bug-when-reading-system-filters-on-module.patch b/queue-3.0/tracing-fix-bug-when-reading-system-filters-on-module.patch new file mode 100644 index 0000000000..f375385907 --- /dev/null +++ b/queue-3.0/tracing-fix-bug-when-reading-system-filters-on-module.patch @@ -0,0 +1,203 @@ +From e9dbfae53eeb9fc3d4bb7da3df87fa9875f5da02 Mon Sep 17 00:00:00 2001 +From: Steven Rostedt <srostedt@redhat.com> +Date: Tue, 5 Jul 2011 11:36:06 -0400 +Subject: tracing: Fix bug when reading system filters on module + removal + +From: Steven Rostedt <srostedt@redhat.com> + +commit e9dbfae53eeb9fc3d4bb7da3df87fa9875f5da02 upstream. + +The event system is freed when its nr_events is set to zero. This happens +when a module created an event system and then later the module is +removed. Modules may share systems, so the system is allocated when +it is created and freed when the modules are unloaded and all the +events under the system are removed (nr_events set to zero). + +The problem arises when a task opened the "filter" file for the +system. If the module is unloaded and it removed the last event for +that system, the system structure is freed. If the task that opened +the filter file accesses the "filter" file after the system has +been freed, the system will access an invalid pointer. + +By adding a ref_count, and using it to keep track of what +is using the event system, we can free it after all users +are finished with the event system. + +Reported-by: Johannes Berg <johannes.berg@intel.com> +Signed-off-by: Steven Rostedt <rostedt@goodmis.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + kernel/trace/trace.h | 1 + kernel/trace/trace_events.c | 86 ++++++++++++++++++++++++++++++++----- + kernel/trace/trace_events_filter.c | 6 ++ + 3 files changed, 82 insertions(+), 11 deletions(-) + +--- a/kernel/trace/trace.h ++++ b/kernel/trace/trace.h +@@ -677,6 +677,7 @@ struct event_subsystem { + struct dentry *entry; + struct event_filter *filter; + int nr_events; ++ int ref_count; + }; + + #define FILTER_PRED_INVALID ((unsigned short)-1) +--- a/kernel/trace/trace_events.c ++++ b/kernel/trace/trace_events.c +@@ -244,6 +244,35 @@ static void ftrace_clear_events(void) + mutex_unlock(&event_mutex); + } + ++static void __put_system(struct event_subsystem *system) ++{ ++ struct event_filter *filter = system->filter; ++ ++ WARN_ON_ONCE(system->ref_count == 0); ++ if (--system->ref_count) ++ return; ++ ++ if (filter) { ++ kfree(filter->filter_string); ++ kfree(filter); ++ } ++ kfree(system->name); ++ kfree(system); ++} ++ ++static void __get_system(struct event_subsystem *system) ++{ ++ WARN_ON_ONCE(system->ref_count == 0); ++ system->ref_count++; ++} ++ ++static void put_system(struct event_subsystem *system) ++{ ++ mutex_lock(&event_mutex); ++ __put_system(system); ++ mutex_unlock(&event_mutex); ++} ++ + /* + * __ftrace_set_clr_event(NULL, NULL, NULL, set) will set/unset all events. + */ +@@ -826,6 +855,47 @@ event_filter_write(struct file *filp, co + return cnt; + } + ++static LIST_HEAD(event_subsystems); ++ ++static int subsystem_open(struct inode *inode, struct file *filp) ++{ ++ struct event_subsystem *system = NULL; ++ int ret; ++ ++ /* Make sure the system still exists */ ++ mutex_lock(&event_mutex); ++ list_for_each_entry(system, &event_subsystems, list) { ++ if (system == inode->i_private) { ++ /* Don't open systems with no events */ ++ if (!system->nr_events) { ++ system = NULL; ++ break; ++ } ++ __get_system(system); ++ break; ++ } ++ } ++ mutex_unlock(&event_mutex); ++ ++ if (system != inode->i_private) ++ return -ENODEV; ++ ++ ret = tracing_open_generic(inode, filp); ++ if (ret < 0) ++ put_system(system); ++ ++ return ret; ++} ++ ++static int subsystem_release(struct inode *inode, struct file *file) ++{ ++ struct event_subsystem *system = inode->i_private; ++ ++ put_system(system); ++ ++ return 0; ++} ++ + static ssize_t + subsystem_filter_read(struct file *filp, char __user *ubuf, size_t cnt, + loff_t *ppos) +@@ -963,10 +1033,11 @@ static const struct file_operations ftra + }; + + static const struct file_operations ftrace_subsystem_filter_fops = { +- .open = tracing_open_generic, ++ .open = subsystem_open, + .read = subsystem_filter_read, + .write = subsystem_filter_write, + .llseek = default_llseek, ++ .release = subsystem_release, + }; + + static const struct file_operations ftrace_system_enable_fops = { +@@ -1002,8 +1073,6 @@ static struct dentry *event_trace_events + return d_events; + } + +-static LIST_HEAD(event_subsystems); +- + static struct dentry * + event_subsystem_dir(const char *name, struct dentry *d_events) + { +@@ -1013,6 +1082,7 @@ event_subsystem_dir(const char *name, st + /* First see if we did not already create this dir */ + list_for_each_entry(system, &event_subsystems, list) { + if (strcmp(system->name, name) == 0) { ++ __get_system(system); + system->nr_events++; + return system->entry; + } +@@ -1035,6 +1105,7 @@ event_subsystem_dir(const char *name, st + } + + system->nr_events = 1; ++ system->ref_count = 1; + system->name = kstrdup(name, GFP_KERNEL); + if (!system->name) { + debugfs_remove(system->entry); +@@ -1184,16 +1255,9 @@ static void remove_subsystem_dir(const c + list_for_each_entry(system, &event_subsystems, list) { + if (strcmp(system->name, name) == 0) { + if (!--system->nr_events) { +- struct event_filter *filter = system->filter; +- + debugfs_remove_recursive(system->entry); + list_del(&system->list); +- if (filter) { +- kfree(filter->filter_string); +- kfree(filter); +- } +- kfree(system->name); +- kfree(system); ++ __put_system(system); + } + break; + } +--- a/kernel/trace/trace_events_filter.c ++++ b/kernel/trace/trace_events_filter.c +@@ -1886,6 +1886,12 @@ int apply_subsystem_event_filter(struct + + mutex_lock(&event_mutex); + ++ /* Make sure the system still has events */ ++ if (!system->nr_events) { ++ err = -ENODEV; ++ goto out_unlock; ++ } ++ + if (!strcmp(strstrip(filter_string), "0")) { + filter_free_subsystem_preds(system); + remove_filter_string(system->filter); diff --git a/queue-3.0/tracing-have-enable-file-use-refcounts-like-the-filter.patch b/queue-3.0/tracing-have-enable-file-use-refcounts-like-the-filter.patch new file mode 100644 index 0000000000..5d7be8d25c --- /dev/null +++ b/queue-3.0/tracing-have-enable-file-use-refcounts-like-the-filter.patch @@ -0,0 +1,137 @@ +From 40ee4dffff061399eb9358e0c8fcfbaf8de4c8fe Mon Sep 17 00:00:00 2001 +From: Steven Rostedt <srostedt@redhat.com> +Date: Tue, 5 Jul 2011 14:32:51 -0400 +Subject: tracing: Have "enable" file use refcounts like the "filter" + file + +From: Steven Rostedt <srostedt@redhat.com> + +commit 40ee4dffff061399eb9358e0c8fcfbaf8de4c8fe upstream. + +The "enable" file for the event system can be removed when a module +is unloaded and the event system only has events from that module. +As the event system nr_events count goes to zero, it may be freed +if its ref_count is also set to zero. + +Like the "filter" file, the "enable" file may be opened by a task and +referenced later, after a module has been unloaded and the events for +that event system have been removed. + +Although the "filter" file referenced the event system structure, +the "enable" file only references a pointer to the event system +name. Since the name is freed when the event system is removed, +it is possible that an access to the "enable" file may reference +a freed pointer. + +Update the "enable" file to use the subsystem_open() routine that +the "filter" file uses, to keep a reference to the event system +structure while the "enable" file is opened. + +Reported-by: Johannes Berg <johannes.berg@intel.com> +Signed-off-by: Steven Rostedt <rostedt@goodmis.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + kernel/trace/trace_events.c | 31 ++++++++++++++++++++++--------- + 1 file changed, 22 insertions(+), 9 deletions(-) + +--- a/kernel/trace/trace_events.c ++++ b/kernel/trace/trace_events.c +@@ -557,7 +557,7 @@ system_enable_read(struct file *filp, ch + loff_t *ppos) + { + const char set_to_char[4] = { '?', '0', '1', 'X' }; +- const char *system = filp->private_data; ++ struct event_subsystem *system = filp->private_data; + struct ftrace_event_call *call; + char buf[2]; + int set = 0; +@@ -568,7 +568,7 @@ system_enable_read(struct file *filp, ch + if (!call->name || !call->class || !call->class->reg) + continue; + +- if (system && strcmp(call->class->system, system) != 0) ++ if (system && strcmp(call->class->system, system->name) != 0) + continue; + + /* +@@ -598,7 +598,8 @@ static ssize_t + system_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, + loff_t *ppos) + { +- const char *system = filp->private_data; ++ struct event_subsystem *system = filp->private_data; ++ const char *name = NULL; + unsigned long val; + char buf[64]; + ssize_t ret; +@@ -622,7 +623,14 @@ system_enable_write(struct file *filp, c + if (val != 0 && val != 1) + return -EINVAL; + +- ret = __ftrace_set_clr_event(NULL, system, NULL, val); ++ /* ++ * Opening of "enable" adds a ref count to system, ++ * so the name is safe to use. ++ */ ++ if (system) ++ name = system->name; ++ ++ ret = __ftrace_set_clr_event(NULL, name, NULL, val); + if (ret) + goto out; + +@@ -862,6 +870,9 @@ static int subsystem_open(struct inode * + struct event_subsystem *system = NULL; + int ret; + ++ if (!inode->i_private) ++ goto skip_search; ++ + /* Make sure the system still exists */ + mutex_lock(&event_mutex); + list_for_each_entry(system, &event_subsystems, list) { +@@ -880,8 +891,9 @@ static int subsystem_open(struct inode * + if (system != inode->i_private) + return -ENODEV; + ++ skip_search: + ret = tracing_open_generic(inode, filp); +- if (ret < 0) ++ if (ret < 0 && system) + put_system(system); + + return ret; +@@ -891,7 +903,8 @@ static int subsystem_release(struct inod + { + struct event_subsystem *system = inode->i_private; + +- put_system(system); ++ if (system) ++ put_system(system); + + return 0; + } +@@ -1041,10 +1054,11 @@ static const struct file_operations ftra + }; + + static const struct file_operations ftrace_system_enable_fops = { +- .open = tracing_open_generic, ++ .open = subsystem_open, + .read = system_enable_read, + .write = system_enable_write, + .llseek = default_llseek, ++ .release = subsystem_release, + }; + + static const struct file_operations ftrace_show_header_fops = { +@@ -1133,8 +1147,7 @@ event_subsystem_dir(const char *name, st + "'%s/filter' entry\n", name); + } + +- trace_create_file("enable", 0644, system->entry, +- (void *)system->name, ++ trace_create_file("enable", 0644, system->entry, system, + &ftrace_system_enable_fops); + + return system->entry; diff --git a/queue-3.0/xz-fix-missing-linux-kernel.h-include.patch b/queue-3.0/xz-fix-missing-linux-kernel.h-include.patch new file mode 100644 index 0000000000..d8d592eb46 --- /dev/null +++ b/queue-3.0/xz-fix-missing-linux-kernel.h-include.patch @@ -0,0 +1,36 @@ +From 81d67439855a7f928d90965d832aa4f2fb677342 Mon Sep 17 00:00:00 2001 +From: Lasse Collin <lasse.collin@tukaani.org> +Date: Sun, 24 Jul 2011 19:54:25 +0300 +Subject: XZ: Fix missing <linux/kernel.h> include + +From: Lasse Collin <lasse.collin@tukaani.org> + +commit 81d67439855a7f928d90965d832aa4f2fb677342 upstream. + +<linux/kernel.h> is needed for min_t. The old version +happened to work on x86 because <asm/unaligned.h> +indirectly includes <linux/kernel.h>, but it didn't +work on ARM. + +<linux/kernel.h> includes <asm/byteorder.h> so it's +not necessary to include it explicitly anymore. + +Signed-off-by: Lasse Collin <lasse.collin@tukaani.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + lib/xz/xz_private.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/lib/xz/xz_private.h ++++ b/lib/xz/xz_private.h +@@ -12,7 +12,7 @@ + + #ifdef __KERNEL__ + # include <linux/xz.h> +-# include <asm/byteorder.h> ++# include <linux/kernel.h> + # include <asm/unaligned.h> + /* XZ_PREBOOT may be defined only via decompress_unxz.c. */ + # ifndef XZ_PREBOOT |