From: Greg Kroah-Hartman Date: Thu, 26 Jan 2012 18:20:05 +0000 (-0800) Subject: 3.2-stable patches X-Git-Tag: v3.0.19~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=098d1aae1c667911a65e817ccad6c2b4fd5c8878;p=thirdparty%2Fkernel%2Fstable-queue.git 3.2-stable patches added patches: alsa-hda-fix-buffer-alignment-regression-with-nvidia-hdmi.patch alsa-hda-fix-silent-outputs-from-docking-station-jacks-of-dell-laptops.patch drm-fix-authentication-kernel-crash.patch drm-radeon-kms-add-an-msi-quirk-for-dell-rs690.patch drm-radeon-kms-move-panel-mode-setup-into-encoder-mode-set.patch drm-radeon-kms-rework-modeset-sequence-for-dce41-and-dce5.patch ecryptfs-check-inode-changes-in-setattr.patch ecryptfs-fix-oops-when-printing-debug-info-in-extent-crypto-functions.patch ecryptfs-improve-metadata-read-failure-logging.patch ecryptfs-make-truncate-path-killable.patch ecryptfs-sanitize-write-counts-of-dev-ecryptfs.patch xfs-fix-missing-xfs_iunlock-on-error-recovery-path-in-xfs_readlink.patch --- diff --git a/queue-3.2/alsa-hda-fix-buffer-alignment-regression-with-nvidia-hdmi.patch b/queue-3.2/alsa-hda-fix-buffer-alignment-regression-with-nvidia-hdmi.patch new file mode 100644 index 00000000000..f1b2c167cc6 --- /dev/null +++ b/queue-3.2/alsa-hda-fix-buffer-alignment-regression-with-nvidia-hdmi.patch @@ -0,0 +1,59 @@ +From 52409aa6a0e96337da137c069856298f4dd825a0 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 23 Jan 2012 17:10:24 +0100 +Subject: ALSA: hda - Fix buffer-alignment regression with Nvidia HDMI + +From: Takashi Iwai + +commit 52409aa6a0e96337da137c069856298f4dd825a0 upstream. + +The commit 2ae66c26550cd94b0e2606a9275eb0ab7070ad0e + ALSA: hda: option to enable arbitrary buffer/period sizes +introduced a regression on machines with Intel controller and Nvidia +HDMI. The reason is that the driver modifies the global variable +align_buffer_size when an Intel controller is found, and the Nvidia +HDMI controller is probed after Intel although Nvidia chips require +the aligned buffers. + +This patch fixes the problem by moving the flag into the local struct +so that it's not affected by other controllers. + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=42567 + +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/hda_intel.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -461,6 +461,7 @@ struct azx { + unsigned int irq_pending_warned :1; + unsigned int probing :1; /* codec probing phase */ + unsigned int snoop:1; ++ unsigned int align_buffer_size:1; + + /* for debugging */ + unsigned int last_cmd[AZX_MAX_CODECS]; +@@ -1697,7 +1698,7 @@ static int azx_pcm_open(struct snd_pcm_s + runtime->hw.rates = hinfo->rates; + snd_pcm_limit_hw_rates(runtime); + snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); +- if (align_buffer_size) ++ if (chip->align_buffer_size) + /* constrain buffer sizes to be multiple of 128 + bytes. This is more efficient in terms of memory + access but isn't required by the HDA spec and +@@ -2753,8 +2754,9 @@ static int __devinit azx_create(struct s + } + + /* disable buffer size rounding to 128-byte multiples if supported */ ++ chip->align_buffer_size = align_buffer_size; + if (chip->driver_caps & AZX_DCAPS_BUFSIZE) +- align_buffer_size = 0; ++ chip->align_buffer_size = 0; + + /* allow 64bit DMA address if supported by H/W */ + if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) diff --git a/queue-3.2/alsa-hda-fix-silent-outputs-from-docking-station-jacks-of-dell-laptops.patch b/queue-3.2/alsa-hda-fix-silent-outputs-from-docking-station-jacks-of-dell-laptops.patch new file mode 100644 index 00000000000..e73dbfa1263 --- /dev/null +++ b/queue-3.2/alsa-hda-fix-silent-outputs-from-docking-station-jacks-of-dell-laptops.patch @@ -0,0 +1,61 @@ +From b4ead019afc201f71c39cd0dfcaafed4a97b3dd2 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 23 Jan 2012 18:23:36 +0100 +Subject: ALSA: hda - Fix silent outputs from docking-station jacks of Dell laptops + +From: Takashi Iwai + +commit b4ead019afc201f71c39cd0dfcaafed4a97b3dd2 upstream. + +The recent change of the power-widget handling for IDT codecs caused +the silent output from the docking-station line-out jack. This was +partially fixed by the commit f2cbba7602383cd9cdd21f0a5d0b8bd1aad47b33 +"ALSA: hda - Fix the lost power-setup of seconary pins after PM resume". +But the line-out on the docking-station is still silent when booted +with the jack plugged even by this fix. + +The remainig bug is that the power-widget is set off in stac92xx_init() +because the pins in cfg->line_out_pins[] aren't checked there properly +but only hp_pins[] are checked in is_nid_hp_pin(). + +This patch fixes the problem by checking both HP and line-out pins +and leaving the power-map correctly. + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=42637 + +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_sigmatel.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/sound/pci/hda/patch_sigmatel.c ++++ b/sound/pci/hda/patch_sigmatel.c +@@ -4253,13 +4253,15 @@ static int enable_pin_detect(struct hda_ + return 1; + } + +-static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) ++static int is_nid_out_jack_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) + { + int i; + for (i = 0; i < cfg->hp_outs; i++) + if (cfg->hp_pins[i] == nid) + return 1; /* nid is a HP-Out */ +- ++ for (i = 0; i < cfg->line_outs; i++) ++ if (cfg->line_out_pins[i] == nid) ++ return 1; /* nid is a line-Out */ + return 0; /* nid is not a HP-Out */ + }; + +@@ -4465,7 +4467,7 @@ static int stac92xx_init(struct hda_code + continue; + } + +- if (is_nid_hp_pin(cfg, nid)) ++ if (is_nid_out_jack_pin(cfg, nid)) + continue; /* already has an unsol event */ + + pinctl = snd_hda_codec_read(codec, nid, 0, diff --git a/queue-3.2/drm-fix-authentication-kernel-crash.patch b/queue-3.2/drm-fix-authentication-kernel-crash.patch new file mode 100644 index 00000000000..06a91c817aa --- /dev/null +++ b/queue-3.2/drm-fix-authentication-kernel-crash.patch @@ -0,0 +1,85 @@ +From 598781d71119827b454fd75d46f84755bca6f0c6 Mon Sep 17 00:00:00 2001 +From: Thomas Hellstrom +Date: Tue, 24 Jan 2012 18:54:21 +0100 +Subject: drm: Fix authentication kernel crash + +From: Thomas Hellstrom + +commit 598781d71119827b454fd75d46f84755bca6f0c6 upstream. + +If the master tries to authenticate a client using drm_authmagic and +that client has already closed its drm file descriptor, +either wilfully or because it was terminated, the +call to drm_authmagic will dereference a stale pointer into kmalloc'ed memory +and corrupt it. + +Typically this results in a hard system hang. + +This patch fixes that problem by removing any authentication tokens +(struct drm_magic_entry) open for a file descriptor when that file +descriptor is closed. + +Signed-off-by: Thomas Hellstrom +Reviewed-by: Daniel Vetter +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/drm_auth.c | 6 +++++- + drivers/gpu/drm/drm_fops.c | 5 +++++ + include/drm/drmP.h | 1 + + 3 files changed, 11 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/drm_auth.c ++++ b/drivers/gpu/drm/drm_auth.c +@@ -101,7 +101,7 @@ static int drm_add_magic(struct drm_mast + * Searches and unlinks the entry in drm_device::magiclist with the magic + * number hash key, while holding the drm_device::struct_mutex lock. + */ +-static int drm_remove_magic(struct drm_master *master, drm_magic_t magic) ++int drm_remove_magic(struct drm_master *master, drm_magic_t magic) + { + struct drm_magic_entry *pt; + struct drm_hash_item *hash; +@@ -136,6 +136,8 @@ static int drm_remove_magic(struct drm_m + * If there is a magic number in drm_file::magic then use it, otherwise + * searches an unique non-zero magic number and add it associating it with \p + * file_priv. ++ * This ioctl needs protection by the drm_global_mutex, which protects ++ * struct drm_file::magic and struct drm_magic_entry::priv. + */ + int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) + { +@@ -173,6 +175,8 @@ int drm_getmagic(struct drm_device *dev, + * \return zero if authentication successed, or a negative number otherwise. + * + * Checks if \p file_priv is associated with the magic number passed in \arg. ++ * This ioctl needs protection by the drm_global_mutex, which protects ++ * struct drm_file::magic and struct drm_magic_entry::priv. + */ + int drm_authmagic(struct drm_device *dev, void *data, + struct drm_file *file_priv) +--- a/drivers/gpu/drm/drm_fops.c ++++ b/drivers/gpu/drm/drm_fops.c +@@ -487,6 +487,11 @@ int drm_release(struct inode *inode, str + (long)old_encode_dev(file_priv->minor->device), + dev->open_count); + ++ /* Release any auth tokens that might point to this file_priv, ++ (do that under the drm_global_mutex) */ ++ if (file_priv->magic) ++ (void) drm_remove_magic(file_priv->master, file_priv->magic); ++ + /* if the master has gone away we can't do anything with the lock */ + if (file_priv->minor->master) + drm_master_release(dev, filp); +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1328,6 +1328,7 @@ extern int drm_getmagic(struct drm_devic + struct drm_file *file_priv); + extern int drm_authmagic(struct drm_device *dev, void *data, + struct drm_file *file_priv); ++extern int drm_remove_magic(struct drm_master *master, drm_magic_t magic); + + /* Cache management (drm_cache.c) */ + void drm_clflush_pages(struct page *pages[], unsigned long num_pages); diff --git a/queue-3.2/drm-radeon-kms-add-an-msi-quirk-for-dell-rs690.patch b/queue-3.2/drm-radeon-kms-add-an-msi-quirk-for-dell-rs690.patch new file mode 100644 index 00000000000..47f7806fafd --- /dev/null +++ b/queue-3.2/drm-radeon-kms-add-an-msi-quirk-for-dell-rs690.patch @@ -0,0 +1,36 @@ +From 44517c44496062180a6376cc704b33129441ce60 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Sun, 15 Jan 2012 08:51:12 -0500 +Subject: drm/radeon/kms: Add an MSI quirk for Dell RS690 + +From: Alex Deucher + +commit 44517c44496062180a6376cc704b33129441ce60 upstream. + +Interrupts only work with MSIs. +https://bugs.freedesktop.org/show_bug.cgi?id=37679 + +Reported-by: Dmitry Podgorny +Signed-off-by: Alex Deucher +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_irq_kms.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c ++++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c +@@ -134,6 +134,12 @@ static bool radeon_msi_ok(struct radeon_ + /* Dell RS690 only seems to work with MSIs. */ + if ((rdev->pdev->device == 0x791f) && + (rdev->pdev->subsystem_vendor == 0x1028) && ++ (rdev->pdev->subsystem_device == 0x01fc)) ++ return true; ++ ++ /* Dell RS690 only seems to work with MSIs. */ ++ if ((rdev->pdev->device == 0x791f) && ++ (rdev->pdev->subsystem_vendor == 0x1028) && + (rdev->pdev->subsystem_device == 0x01fd)) + return true; + diff --git a/queue-3.2/drm-radeon-kms-move-panel-mode-setup-into-encoder-mode-set.patch b/queue-3.2/drm-radeon-kms-move-panel-mode-setup-into-encoder-mode-set.patch new file mode 100644 index 00000000000..c7478f8366d --- /dev/null +++ b/queue-3.2/drm-radeon-kms-move-panel-mode-setup-into-encoder-mode-set.patch @@ -0,0 +1,123 @@ +From 386d4d751e8e0b4b693bb724f09aae064ee5297d Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Fri, 20 Jan 2012 15:01:29 -0500 +Subject: drm/radeon/kms: move panel mode setup into encoder mode set + +From: Alex Deucher + +commit 386d4d751e8e0b4b693bb724f09aae064ee5297d upstream. + +Needs to happen earlier in the mode set. + +Signed-off-by: Alex Deucher +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/atombios_dp.c | 22 ++++++++++------------ + drivers/gpu/drm/radeon/atombios_encoders.c | 11 +++++++++++ + drivers/gpu/drm/radeon/radeon_mode.h | 3 +++ + 3 files changed, 24 insertions(+), 12 deletions(-) + +--- a/drivers/gpu/drm/radeon/atombios_dp.c ++++ b/drivers/gpu/drm/radeon/atombios_dp.c +@@ -549,8 +549,8 @@ bool radeon_dp_getdpcd(struct radeon_con + return false; + } + +-static void radeon_dp_set_panel_mode(struct drm_encoder *encoder, +- struct drm_connector *connector) ++int radeon_dp_get_panel_mode(struct drm_encoder *encoder, ++ struct drm_connector *connector) + { + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; +@@ -558,7 +558,7 @@ static void radeon_dp_set_panel_mode(str + int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; + + if (!ASIC_IS_DCE4(rdev)) +- return; ++ return panel_mode; + + if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == + ENCODER_OBJECT_ID_NUTMEG) +@@ -572,14 +572,7 @@ static void radeon_dp_set_panel_mode(str + panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; + } + +- atombios_dig_encoder_setup(encoder, +- ATOM_ENCODER_CMD_SETUP_PANEL_MODE, +- panel_mode); +- +- if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) && +- (panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) { +- radeon_write_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_SET, 1); +- } ++ return panel_mode; + } + + void radeon_dp_set_link_config(struct drm_connector *connector, +@@ -717,6 +710,8 @@ static void radeon_dp_set_tp(struct rade + + static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) + { ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(dp_info->encoder); ++ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + u8 tmp; + + /* power up the sink */ +@@ -732,7 +727,10 @@ static int radeon_dp_link_train_init(str + radeon_write_dpcd_reg(dp_info->radeon_connector, + DP_DOWNSPREAD_CTRL, 0); + +- radeon_dp_set_panel_mode(dp_info->encoder, dp_info->connector); ++ if ((dp_info->connector->connector_type == DRM_MODE_CONNECTOR_eDP) && ++ (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) { ++ radeon_write_dpcd_reg(dp_info->radeon_connector, DP_EDP_CONFIGURATION_SET, 1); ++ } + + /* set the lane count on the sink */ + tmp = dp_info->dp_lane_count; +--- a/drivers/gpu/drm/radeon/atombios_encoders.c ++++ b/drivers/gpu/drm/radeon/atombios_encoders.c +@@ -1822,10 +1822,21 @@ radeon_atom_encoder_mode_set(struct drm_ + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: + if (ASIC_IS_DCE4(rdev)) { ++ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); ++ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; ++ ++ if (!connector) ++ dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; ++ else ++ dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector); ++ + /* disable the transmitter */ + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); + /* setup and enable the encoder */ + atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); ++ atombios_dig_encoder_setup(encoder, ++ ATOM_ENCODER_CMD_SETUP_PANEL_MODE, ++ dig->panel_mode); + + /* enable the transmitter */ + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); +--- a/drivers/gpu/drm/radeon/radeon_mode.h ++++ b/drivers/gpu/drm/radeon/radeon_mode.h +@@ -362,6 +362,7 @@ struct radeon_encoder_atom_dig { + struct backlight_device *bl_dev; + int dpms_mode; + uint8_t backlight_level; ++ int panel_mode; + }; + + struct radeon_encoder_atom_dac { +@@ -482,6 +483,8 @@ extern void radeon_dp_link_train(struct + extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); + extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); + extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); ++extern int radeon_dp_get_panel_mode(struct drm_encoder *encoder, ++ struct drm_connector *connector); + extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode); + extern void radeon_atom_encoder_init(struct radeon_device *rdev); + extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, diff --git a/queue-3.2/drm-radeon-kms-rework-modeset-sequence-for-dce41-and-dce5.patch b/queue-3.2/drm-radeon-kms-rework-modeset-sequence-for-dce41-and-dce5.patch new file mode 100644 index 00000000000..ffaec2207e0 --- /dev/null +++ b/queue-3.2/drm-radeon-kms-rework-modeset-sequence-for-dce41-and-dce5.patch @@ -0,0 +1,84 @@ +From 3a47824d85eeca122895646f027dc63480994199 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Fri, 20 Jan 2012 15:01:30 -0500 +Subject: drm/radeon/kms: rework modeset sequence for DCE41 and DCE5 + +From: Alex Deucher + +commit 3a47824d85eeca122895646f027dc63480994199 upstream. + +dig transmitter control table only has ENABLE/DISABLE actions +on DCE4.1/DCE5. + +Fixes: +https://bugs.freedesktop.org/show_bug.cgi?id=44955 + +Signed-off-by: Alex Deucher +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/atombios_encoders.c | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +--- a/drivers/gpu/drm/radeon/atombios_encoders.c ++++ b/drivers/gpu/drm/radeon/atombios_encoders.c +@@ -1352,7 +1352,8 @@ radeon_atom_encoder_dpms_dig(struct drm_ + switch (mode) { + case DRM_MODE_DPMS_ON: + /* some early dce3.2 boards have a bug in their transmitter control table */ +- if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730)) ++ if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) || ++ ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); + else + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); +@@ -1362,8 +1363,6 @@ radeon_atom_encoder_dpms_dig(struct drm_ + ATOM_TRANSMITTER_ACTION_POWER_ON); + radeon_dig_connector->edp_on = true; + } +- if (ASIC_IS_DCE4(rdev)) +- atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); + radeon_dp_link_train(encoder, connector); + if (ASIC_IS_DCE4(rdev)) + atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); +@@ -1374,7 +1373,10 @@ radeon_atom_encoder_dpms_dig(struct drm_ + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + case DRM_MODE_DPMS_OFF: +- atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); ++ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) ++ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); ++ else ++ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); + if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { + if (ASIC_IS_DCE4(rdev)) + atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); +@@ -1821,7 +1823,7 @@ radeon_atom_encoder_mode_set(struct drm_ + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: +- if (ASIC_IS_DCE4(rdev)) { ++ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { + struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + +@@ -1830,13 +1832,16 @@ radeon_atom_encoder_mode_set(struct drm_ + else + dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector); + +- /* disable the transmitter */ +- atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); + /* setup and enable the encoder */ + atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); + atombios_dig_encoder_setup(encoder, + ATOM_ENCODER_CMD_SETUP_PANEL_MODE, + dig->panel_mode); ++ } else if (ASIC_IS_DCE4(rdev)) { ++ /* disable the transmitter */ ++ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); ++ /* setup and enable the encoder */ ++ atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); + + /* enable the transmitter */ + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); diff --git a/queue-3.2/ecryptfs-check-inode-changes-in-setattr.patch b/queue-3.2/ecryptfs-check-inode-changes-in-setattr.patch new file mode 100644 index 00000000000..10e957888eb --- /dev/null +++ b/queue-3.2/ecryptfs-check-inode-changes-in-setattr.patch @@ -0,0 +1,120 @@ +From a261a03904849c3df50bd0300efb7fb3f865137d Mon Sep 17 00:00:00 2001 +From: Tyler Hicks +Date: Thu, 19 Jan 2012 20:33:44 -0600 +Subject: eCryptfs: Check inode changes in setattr + +From: Tyler Hicks + +commit a261a03904849c3df50bd0300efb7fb3f865137d upstream. + +Most filesystems call inode_change_ok() very early in ->setattr(), but +eCryptfs didn't call it at all. It allowed the lower filesystem to make +the call in its ->setattr() function. Then, eCryptfs would copy the +appropriate inode attributes from the lower inode to the eCryptfs inode. + +This patch changes that and actually calls inode_change_ok() on the +eCryptfs inode, fairly early in ecryptfs_setattr(). Ideally, the call +would happen earlier in ecryptfs_setattr(), but there are some possible +inode initialization steps that must happen first. + +Since the call was already being made on the lower inode, the change in +functionality should be minimal, except for the case of a file extending +truncate call. In that case, inode_newsize_ok() was never being +called on the eCryptfs inode. Rather than inode_newsize_ok() catching +maximum file size errors early on, eCryptfs would encrypt zeroed pages +and write them to the lower filesystem until the lower filesystem's +write path caught the error in generic_write_checks(). This patch +introduces a new function, called ecryptfs_inode_newsize_ok(), which +checks if the new lower file size is within the appropriate limits when +the truncate operation will be growing the lower file. + +In summary this change prevents eCryptfs truncate operations (and the +resulting page encryptions), which would exceed the lower filesystem +limits or FSIZE rlimits, from ever starting. + +Signed-off-by: Tyler Hicks +Reviewed-by: Li Wang +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ecryptfs/inode.c | 48 ++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 36 insertions(+), 12 deletions(-) + +--- a/fs/ecryptfs/inode.c ++++ b/fs/ecryptfs/inode.c +@@ -841,18 +841,6 @@ static int truncate_upper(struct dentry + size_t num_zeros = (PAGE_CACHE_SIZE + - (ia->ia_size & ~PAGE_CACHE_MASK)); + +- +- /* +- * XXX(truncate) this should really happen at the begginning +- * of ->setattr. But the code is too messy to that as part +- * of a larger patch. ecryptfs is also totally missing out +- * on the inode_change_ok check at the beginning of +- * ->setattr while would include this. +- */ +- rc = inode_newsize_ok(inode, ia->ia_size); +- if (rc) +- goto out; +- + if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { + truncate_setsize(inode, ia->ia_size); + lower_ia->ia_size = ia->ia_size; +@@ -902,6 +890,28 @@ out: + return rc; + } + ++static int ecryptfs_inode_newsize_ok(struct inode *inode, loff_t offset) ++{ ++ struct ecryptfs_crypt_stat *crypt_stat; ++ loff_t lower_oldsize, lower_newsize; ++ ++ crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; ++ lower_oldsize = upper_size_to_lower_size(crypt_stat, ++ i_size_read(inode)); ++ lower_newsize = upper_size_to_lower_size(crypt_stat, offset); ++ if (lower_newsize > lower_oldsize) { ++ /* ++ * The eCryptfs inode and the new *lower* size are mixed here ++ * because we may not have the lower i_mutex held and/or it may ++ * not be appropriate to call inode_newsize_ok() with inodes ++ * from other filesystems. ++ */ ++ return inode_newsize_ok(inode, lower_newsize); ++ } ++ ++ return 0; ++} ++ + /** + * ecryptfs_truncate + * @dentry: The ecryptfs layer dentry +@@ -918,6 +928,10 @@ int ecryptfs_truncate(struct dentry *den + struct iattr lower_ia = { .ia_valid = 0 }; + int rc; + ++ rc = ecryptfs_inode_newsize_ok(dentry->d_inode, new_length); ++ if (rc) ++ return rc; ++ + rc = truncate_upper(dentry, &ia, &lower_ia); + if (!rc && lower_ia.ia_valid & ATTR_SIZE) { + struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); +@@ -997,6 +1011,16 @@ static int ecryptfs_setattr(struct dentr + } + } + mutex_unlock(&crypt_stat->cs_mutex); ++ ++ rc = inode_change_ok(inode, ia); ++ if (rc) ++ goto out; ++ if (ia->ia_valid & ATTR_SIZE) { ++ rc = ecryptfs_inode_newsize_ok(inode, ia->ia_size); ++ if (rc) ++ goto out; ++ } ++ + if (S_ISREG(inode->i_mode)) { + rc = filemap_write_and_wait(inode->i_mapping); + if (rc) diff --git a/queue-3.2/ecryptfs-fix-oops-when-printing-debug-info-in-extent-crypto-functions.patch b/queue-3.2/ecryptfs-fix-oops-when-printing-debug-info-in-extent-crypto-functions.patch new file mode 100644 index 00000000000..f2ba8d69231 --- /dev/null +++ b/queue-3.2/ecryptfs-fix-oops-when-printing-debug-info-in-extent-crypto-functions.patch @@ -0,0 +1,101 @@ +From 58ded24f0fcb85bddb665baba75892f6ad0f4b8a Mon Sep 17 00:00:00 2001 +From: Tyler Hicks +Date: Tue, 24 Jan 2012 10:02:22 -0600 +Subject: eCryptfs: Fix oops when printing debug info in extent crypto functions + +From: Tyler Hicks + +commit 58ded24f0fcb85bddb665baba75892f6ad0f4b8a upstream. + +If pages passed to the eCryptfs extent-based crypto functions are not +mapped and the module parameter ecryptfs_verbosity=1 was specified at +loading time, a NULL pointer dereference will occur. + +Note that this wouldn't happen on a production system, as you wouldn't +pass ecryptfs_verbosity=1 on a production system. It leaks private +information to the system logs and is for debugging only. + +The debugging info printed in these messages is no longer very useful +and rather than doing a kmap() in these debugging paths, it will be +better to simply remove the debugging paths completely. + +https://launchpad.net/bugs/913651 + +Signed-off-by: Tyler Hicks +Reported-by: Daniel DeFreez +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ecryptfs/crypto.c | 40 ---------------------------------------- + 1 file changed, 40 deletions(-) + +--- a/fs/ecryptfs/crypto.c ++++ b/fs/ecryptfs/crypto.c +@@ -417,17 +417,6 @@ static int ecryptfs_encrypt_extent(struc + (unsigned long long)(extent_base + extent_offset), rc); + goto out; + } +- if (unlikely(ecryptfs_verbosity > 0)) { +- ecryptfs_printk(KERN_DEBUG, "Encrypting extent " +- "with iv:\n"); +- ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes); +- ecryptfs_printk(KERN_DEBUG, "First 8 bytes before " +- "encryption:\n"); +- ecryptfs_dump_hex((char *) +- (page_address(page) +- + (extent_offset * crypt_stat->extent_size)), +- 8); +- } + rc = ecryptfs_encrypt_page_offset(crypt_stat, enc_extent_page, 0, + page, (extent_offset + * crypt_stat->extent_size), +@@ -440,14 +429,6 @@ static int ecryptfs_encrypt_extent(struc + goto out; + } + rc = 0; +- if (unlikely(ecryptfs_verbosity > 0)) { +- ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16llx]; " +- "rc = [%d]\n", +- (unsigned long long)(extent_base + extent_offset), rc); +- ecryptfs_printk(KERN_DEBUG, "First 8 bytes after " +- "encryption:\n"); +- ecryptfs_dump_hex((char *)(page_address(enc_extent_page)), 8); +- } + out: + return rc; + } +@@ -543,17 +524,6 @@ static int ecryptfs_decrypt_extent(struc + (unsigned long long)(extent_base + extent_offset), rc); + goto out; + } +- if (unlikely(ecryptfs_verbosity > 0)) { +- ecryptfs_printk(KERN_DEBUG, "Decrypting extent " +- "with iv:\n"); +- ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes); +- ecryptfs_printk(KERN_DEBUG, "First 8 bytes before " +- "decryption:\n"); +- ecryptfs_dump_hex((char *) +- (page_address(enc_extent_page) +- + (extent_offset * crypt_stat->extent_size)), +- 8); +- } + rc = ecryptfs_decrypt_page_offset(crypt_stat, page, + (extent_offset + * crypt_stat->extent_size), +@@ -567,16 +537,6 @@ static int ecryptfs_decrypt_extent(struc + goto out; + } + rc = 0; +- if (unlikely(ecryptfs_verbosity > 0)) { +- ecryptfs_printk(KERN_DEBUG, "Decrypt extent [0x%.16llx]; " +- "rc = [%d]\n", +- (unsigned long long)(extent_base + extent_offset), rc); +- ecryptfs_printk(KERN_DEBUG, "First 8 bytes after " +- "decryption:\n"); +- ecryptfs_dump_hex((char *)(page_address(page) +- + (extent_offset +- * crypt_stat->extent_size)), 8); +- } + out: + return rc; + } diff --git a/queue-3.2/ecryptfs-improve-metadata-read-failure-logging.patch b/queue-3.2/ecryptfs-improve-metadata-read-failure-logging.patch new file mode 100644 index 00000000000..d30eb132370 --- /dev/null +++ b/queue-3.2/ecryptfs-improve-metadata-read-failure-logging.patch @@ -0,0 +1,56 @@ +From 30373dc0c87ffef68d5628e77d56ffb1fa22e1ee Mon Sep 17 00:00:00 2001 +From: Tim Gardner +Date: Thu, 12 Jan 2012 16:31:55 +0100 +Subject: ecryptfs: Improve metadata read failure logging + +From: Tim Gardner + +commit 30373dc0c87ffef68d5628e77d56ffb1fa22e1ee upstream. + +Print inode on metadata read failure. The only real +way of dealing with metadata read failures is to delete +the underlying file system file. Having the inode +allows one to 'find . -inum INODE`. + +[tyhicks@canonical.com: Removed some minor not-for-stable parts] +Signed-off-by: Tim Gardner +Reviewed-by: Kees Cook +Signed-off-by: Tyler Hicks +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ecryptfs/crypto.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/fs/ecryptfs/crypto.c ++++ b/fs/ecryptfs/crypto.c +@@ -1620,7 +1620,8 @@ int ecryptfs_read_metadata(struct dentry + rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode); + if (rc) { + printk(KERN_DEBUG "Valid eCryptfs headers not found in " +- "file header region or xattr region\n"); ++ "file header region or xattr region, inode %lu\n", ++ ecryptfs_inode->i_ino); + rc = -EINVAL; + goto out; + } +@@ -1629,7 +1630,8 @@ int ecryptfs_read_metadata(struct dentry + ECRYPTFS_DONT_VALIDATE_HEADER_SIZE); + if (rc) { + printk(KERN_DEBUG "Valid eCryptfs headers not found in " +- "file xattr region either\n"); ++ "file xattr region either, inode %lu\n", ++ ecryptfs_inode->i_ino); + rc = -EINVAL; + } + if (crypt_stat->mount_crypt_stat->flags +@@ -1640,7 +1642,8 @@ int ecryptfs_read_metadata(struct dentry + "crypto metadata only in the extended attribute " + "region, but eCryptfs was mounted without " + "xattr support enabled. eCryptfs will not treat " +- "this like an encrypted file.\n"); ++ "this like an encrypted file, inode %lu\n", ++ ecryptfs_inode->i_ino); + rc = -EINVAL; + } + } diff --git a/queue-3.2/ecryptfs-make-truncate-path-killable.patch b/queue-3.2/ecryptfs-make-truncate-path-killable.patch new file mode 100644 index 00000000000..ac2e3f59ecd --- /dev/null +++ b/queue-3.2/ecryptfs-make-truncate-path-killable.patch @@ -0,0 +1,69 @@ +From 5e6f0d769017cc49207ef56996e42363ec26c1f0 Mon Sep 17 00:00:00 2001 +From: Tyler Hicks +Date: Wed, 18 Jan 2012 18:30:04 -0600 +Subject: eCryptfs: Make truncate path killable + +From: Tyler Hicks + +commit 5e6f0d769017cc49207ef56996e42363ec26c1f0 upstream. + +ecryptfs_write() handles the truncation of eCryptfs inodes. It grabs a +page, zeroes out the appropriate portions, and then encrypts the page +before writing it to the lower filesystem. It was unkillable and due to +the lack of sparse file support could result in tying up a large portion +of system resources, while encrypting pages of zeros, with no way for +the truncate operation to be stopped from userspace. + +This patch adds the ability for ecryptfs_write() to detect a pending +fatal signal and return as gracefully as possible. The intent is to +leave the lower file in a useable state, while still allowing a user to +break out of the encryption loop. If a pending fatal signal is detected, +the eCryptfs inode size is updated to reflect the modified inode size +and then -EINTR is returned. + +Signed-off-by: Tyler Hicks +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ecryptfs/read_write.c | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +--- a/fs/ecryptfs/read_write.c ++++ b/fs/ecryptfs/read_write.c +@@ -132,6 +132,11 @@ int ecryptfs_write(struct inode *ecryptf + size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page); + size_t total_remaining_bytes = ((offset + size) - pos); + ++ if (fatal_signal_pending(current)) { ++ rc = -EINTR; ++ break; ++ } ++ + if (num_bytes > total_remaining_bytes) + num_bytes = total_remaining_bytes; + if (pos < offset) { +@@ -193,15 +198,19 @@ int ecryptfs_write(struct inode *ecryptf + } + pos += num_bytes; + } +- if ((offset + size) > ecryptfs_file_size) { +- i_size_write(ecryptfs_inode, (offset + size)); ++ if (pos > ecryptfs_file_size) { ++ i_size_write(ecryptfs_inode, pos); + if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) { +- rc = ecryptfs_write_inode_size_to_metadata( ++ int rc2; ++ ++ rc2 = ecryptfs_write_inode_size_to_metadata( + ecryptfs_inode); +- if (rc) { ++ if (rc2) { + printk(KERN_ERR "Problem with " + "ecryptfs_write_inode_size_to_metadata; " +- "rc = [%d]\n", rc); ++ "rc = [%d]\n", rc2); ++ if (!rc) ++ rc = rc2; + goto out; + } + } diff --git a/queue-3.2/ecryptfs-sanitize-write-counts-of-dev-ecryptfs.patch b/queue-3.2/ecryptfs-sanitize-write-counts-of-dev-ecryptfs.patch new file mode 100644 index 00000000000..3e20654f583 --- /dev/null +++ b/queue-3.2/ecryptfs-sanitize-write-counts-of-dev-ecryptfs.patch @@ -0,0 +1,101 @@ +From db10e556518eb9d21ee92ff944530d84349684f4 Mon Sep 17 00:00:00 2001 +From: Tyler Hicks +Date: Thu, 12 Jan 2012 11:30:44 +0100 +Subject: eCryptfs: Sanitize write counts of /dev/ecryptfs + +From: Tyler Hicks + +commit db10e556518eb9d21ee92ff944530d84349684f4 upstream. + +A malicious count value specified when writing to /dev/ecryptfs may +result in a a very large kernel memory allocation. + +This patch peeks at the specified packet payload size, adds that to the +size of the packet headers and compares the result with the write count +value. The resulting maximum memory allocation size is approximately 532 +bytes. + +Signed-off-by: Tyler Hicks +Reported-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ecryptfs/miscdev.c | 56 +++++++++++++++++++++++++++++++++----------------- + 1 file changed, 38 insertions(+), 18 deletions(-) + +--- a/fs/ecryptfs/miscdev.c ++++ b/fs/ecryptfs/miscdev.c +@@ -409,11 +409,47 @@ ecryptfs_miscdev_write(struct file *file + ssize_t sz = 0; + char *data; + uid_t euid = current_euid(); ++ unsigned char packet_size_peek[3]; + int rc; + +- if (count == 0) ++ if (count == 0) { + goto out; ++ } else if (count == (1 + 4)) { ++ /* Likely a harmless MSG_HELO or MSG_QUIT - no packet length */ ++ goto memdup; ++ } else if (count < (1 + 4 + 1) ++ || count > (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4 ++ + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES)) { ++ printk(KERN_WARNING "%s: Acceptable packet size range is " ++ "[%d-%lu], but amount of data written is [%zu].", ++ __func__, (1 + 4 + 1), ++ (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4 ++ + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES), count); ++ return -EINVAL; ++ } ++ ++ if (copy_from_user(packet_size_peek, (buf + 1 + 4), ++ sizeof(packet_size_peek))) { ++ printk(KERN_WARNING "%s: Error while inspecting packet size\n", ++ __func__); ++ return -EFAULT; ++ } + ++ rc = ecryptfs_parse_packet_length(packet_size_peek, &packet_size, ++ &packet_size_length); ++ if (rc) { ++ printk(KERN_WARNING "%s: Error parsing packet length; " ++ "rc = [%d]\n", __func__, rc); ++ return rc; ++ } ++ ++ if ((1 + 4 + packet_size_length + packet_size) != count) { ++ printk(KERN_WARNING "%s: Invalid packet size [%zu]\n", __func__, ++ packet_size); ++ return -EINVAL; ++ } ++ ++memdup: + data = memdup_user(buf, count); + if (IS_ERR(data)) { + printk(KERN_ERR "%s: memdup_user returned error [%ld]\n", +@@ -435,23 +471,7 @@ ecryptfs_miscdev_write(struct file *file + } + memcpy(&counter_nbo, &data[i], 4); + seq = be32_to_cpu(counter_nbo); +- i += 4; +- rc = ecryptfs_parse_packet_length(&data[i], &packet_size, +- &packet_size_length); +- if (rc) { +- printk(KERN_WARNING "%s: Error parsing packet length; " +- "rc = [%d]\n", __func__, rc); +- goto out_free; +- } +- i += packet_size_length; +- if ((1 + 4 + packet_size_length + packet_size) != count) { +- printk(KERN_WARNING "%s: (1 + packet_size_length([%zd])" +- " + packet_size([%zd]))([%zd]) != " +- "count([%zd]). Invalid packet format.\n", +- __func__, packet_size_length, packet_size, +- (1 + packet_size_length + packet_size), count); +- goto out_free; +- } ++ i += 4 + packet_size_length; + rc = ecryptfs_miscdev_response(&data[i], packet_size, + euid, current_user_ns(), + task_pid(current), seq); diff --git a/queue-3.2/series b/queue-3.2/series new file mode 100644 index 00000000000..06a70214821 --- /dev/null +++ b/queue-3.2/series @@ -0,0 +1,12 @@ +alsa-hda-fix-buffer-alignment-regression-with-nvidia-hdmi.patch +alsa-hda-fix-silent-outputs-from-docking-station-jacks-of-dell-laptops.patch +ecryptfs-sanitize-write-counts-of-dev-ecryptfs.patch +ecryptfs-improve-metadata-read-failure-logging.patch +ecryptfs-make-truncate-path-killable.patch +ecryptfs-check-inode-changes-in-setattr.patch +ecryptfs-fix-oops-when-printing-debug-info-in-extent-crypto-functions.patch +drm-radeon-kms-add-an-msi-quirk-for-dell-rs690.patch +drm-radeon-kms-move-panel-mode-setup-into-encoder-mode-set.patch +drm-radeon-kms-rework-modeset-sequence-for-dce41-and-dce5.patch +drm-fix-authentication-kernel-crash.patch +xfs-fix-missing-xfs_iunlock-on-error-recovery-path-in-xfs_readlink.patch diff --git a/queue-3.2/xfs-fix-missing-xfs_iunlock-on-error-recovery-path-in-xfs_readlink.patch b/queue-3.2/xfs-fix-missing-xfs_iunlock-on-error-recovery-path-in-xfs_readlink.patch new file mode 100644 index 00000000000..cfb4b977eaf --- /dev/null +++ b/queue-3.2/xfs-fix-missing-xfs_iunlock-on-error-recovery-path-in-xfs_readlink.patch @@ -0,0 +1,35 @@ +From 9b025eb3a89e041bab6698e3858706be2385d692 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Wed, 11 Jan 2012 18:52:10 +0000 +Subject: xfs: Fix missing xfs_iunlock() on error recovery path in xfs_readlink() + +From: Jan Kara + +commit 9b025eb3a89e041bab6698e3858706be2385d692 upstream. + +Commit b52a360b forgot to call xfs_iunlock() when it detected corrupted +symplink and bailed out. Fix it by jumping to 'out' instead of doing return. + +CC: Carlos Maiolino +Signed-off-by: Jan Kara +Reviewed-by: Alex Elder +Reviewed-by: Dave Chinner +Signed-off-by: Ben Myers +Signed-off-by: Greg Kroah-Hartman + +--- + fs/xfs/xfs_vnodeops.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/xfs/xfs_vnodeops.c ++++ b/fs/xfs/xfs_vnodeops.c +@@ -131,7 +131,8 @@ xfs_readlink( + __func__, (unsigned long long) ip->i_ino, + (long long) pathlen); + ASSERT(0); +- return XFS_ERROR(EFSCORRUPTED); ++ error = XFS_ERROR(EFSCORRUPTED); ++ goto out; + } + +