From 7ea459d67e1bb5b8dc0bd0a1adbe08270a29728e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 29 Jan 2010 11:37:47 -0800 Subject: [PATCH] more .32 patches --- ...d-acpi-opregion-support-for-ironlake.patch | 213 +++++++++++++++ ...dd-display-hotplug-event-on-ironlake.patch | 120 +++++++++ ...oad-hangcheck-timer-too-for-ironlake.patch | 30 +++ ...-don-t-use-small-hardware-rx-buffers.patch | 111 ++++++++ ...000-enhance-frame-fragment-detection.patch | 76 ++++++ ...00e-enhance-frame-fragment-detection.patch | 94 +++++++ ...n-markings-when-creating-nommu-stack.patch | 105 ++++++++ .../fix-a-leak-in-affs_fill_super.patch | 27 ++ queue-2.6.32/fix-affs-parse_options.patch | 68 +++++ .../fix-failure-exit-in-ipathfs.patch | 33 +++ .../fix-failure-exits-in-bfs_fill_super.patch | 136 ++++++++++ .../fix-leak-in-romfs_fill_super.patch | 26 ++ ...fix-oops-in-fs-9p-late-mount-failure.patch | 31 +++ ...-races-with-symlink-handling-in-affs.patch | 134 ++++++++++ .../input-winbond-cir-remove-dmesg-spam.patch | 32 +++ ...igratetype-bug-which-slowed-swapping.patch | 55 ++++ queue-2.6.32/series | 19 ++ .../sparc-tif_abi_pending-bit-removal.patch | 86 ++++++ ...it-flush_old_exec-into-two-functions.patch | 245 ++++++++++++++++++ ...id-of-the-insane-tif_abi_pending-bit.patch | 117 +++++++++ 20 files changed, 1758 insertions(+) create mode 100644 queue-2.6.32/drm-i915-add-acpi-opregion-support-for-ironlake.patch create mode 100644 queue-2.6.32/drm-i915-add-display-hotplug-event-on-ironlake.patch create mode 100644 queue-2.6.32/drm-i915-reload-hangcheck-timer-too-for-ironlake.patch create mode 100644 queue-2.6.32/e1000-e1000e-don-t-use-small-hardware-rx-buffers.patch create mode 100644 queue-2.6.32/e1000-enhance-frame-fragment-detection.patch create mode 100644 queue-2.6.32/e1000e-enhance-frame-fragment-detection.patch create mode 100644 queue-2.6.32/fdpic-respect-pt_gnu_stack-exec-protection-markings-when-creating-nommu-stack.patch create mode 100644 queue-2.6.32/fix-a-leak-in-affs_fill_super.patch create mode 100644 queue-2.6.32/fix-affs-parse_options.patch create mode 100644 queue-2.6.32/fix-failure-exit-in-ipathfs.patch create mode 100644 queue-2.6.32/fix-failure-exits-in-bfs_fill_super.patch create mode 100644 queue-2.6.32/fix-leak-in-romfs_fill_super.patch create mode 100644 queue-2.6.32/fix-oops-in-fs-9p-late-mount-failure.patch create mode 100644 queue-2.6.32/fix-remount-races-with-symlink-handling-in-affs.patch create mode 100644 queue-2.6.32/input-winbond-cir-remove-dmesg-spam.patch create mode 100644 queue-2.6.32/mm-fix-migratetype-bug-which-slowed-swapping.patch create mode 100644 queue-2.6.32/sparc-tif_abi_pending-bit-removal.patch create mode 100644 queue-2.6.32/split-flush_old_exec-into-two-functions.patch create mode 100644 queue-2.6.32/x86-get-rid-of-the-insane-tif_abi_pending-bit.patch diff --git a/queue-2.6.32/drm-i915-add-acpi-opregion-support-for-ironlake.patch b/queue-2.6.32/drm-i915-add-acpi-opregion-support-for-ironlake.patch new file mode 100644 index 00000000000..2f059a4c7d6 --- /dev/null +++ b/queue-2.6.32/drm-i915-add-acpi-opregion-support-for-ironlake.patch @@ -0,0 +1,213 @@ +From sconklin@canonical.com Fri Jan 29 11:11:00 2010 +From: Steve Conklin +Date: Fri, 29 Jan 2010 12:55:46 -0600 +Subject: drm/i915: Add ACPI OpRegion support for Ironlake +To: stable@kernel.org +Cc: Zhao Yakui , Eric Anholt , Steve Conklin , Zhenyu Wang +Message-ID: <1264791346-8113-1-git-send-email-sconklin@canonical.com> + + +commit 01c66889c14aa163c49355b3be2ccfb214500599 upstream + +Add the support of ACPI opregion on Ironlake so that the backlight +brightness can be adjusted by using ACPI interface + >/sys/class/backlight/acpi_video0/brightness + +Signed-off-by: Zhao Yakui +Signed-off-by: Zhenyu Wang +Signed-off-by: Eric Anholt +Signed-off-by: Steve Conklin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/i915/i915_dma.c | 7 --- + drivers/gpu/drm/i915/i915_drv.h | 3 + + drivers/gpu/drm/i915/i915_irq.c | 19 ++++++++ + drivers/gpu/drm/i915/i915_opregion.c | 74 ++++++++++++++++++++++++++++++++++- + 4 files changed, 95 insertions(+), 8 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1490,9 +1490,7 @@ int i915_driver_load(struct drm_device * + } + + /* Must be done after probing outputs */ +- /* FIXME: verify on IGDNG */ +- if (!IS_IGDNG(dev)) +- intel_opregion_init(dev, 0); ++ intel_opregion_init(dev, 0); + + setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, + (unsigned long) dev); +@@ -1536,8 +1534,7 @@ int i915_driver_unload(struct drm_device + if (dev_priv->regs != NULL) + iounmap(dev_priv->regs); + +- if (!IS_IGDNG(dev)) +- intel_opregion_free(dev, 0); ++ intel_opregion_free(dev, 0); + + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + intel_modeset_cleanup(dev); +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -739,6 +739,7 @@ i915_enable_pipestat(drm_i915_private_t + void + i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); + ++void intel_enable_asle (struct drm_device *dev); + + /* i915_mem.c */ + extern int i915_mem_alloc(struct drm_device *dev, void *data, +@@ -864,11 +865,13 @@ extern int i915_restore_state(struct drm + extern int intel_opregion_init(struct drm_device *dev, int resume); + extern void intel_opregion_free(struct drm_device *dev, int suspend); + extern void opregion_asle_intr(struct drm_device *dev); ++extern void ironlake_opregion_gse_intr(struct drm_device *dev); + extern void opregion_enable_asle(struct drm_device *dev); + #else + static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; } + static inline void intel_opregion_free(struct drm_device *dev, int suspend) { return; } + static inline void opregion_asle_intr(struct drm_device *dev) { return; } ++static inline void ironlake_opregion_gse_intr(struct drm_device *dev) { return; } + static inline void opregion_enable_asle(struct drm_device *dev) { return; } + #endif + +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -157,6 +157,20 @@ i915_disable_pipestat(drm_i915_private_t + } + + /** ++ * intel_enable_asle - enable ASLE interrupt for OpRegion ++ */ ++void intel_enable_asle (struct drm_device *dev) ++{ ++ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; ++ ++ if (IS_IGDNG(dev)) ++ igdng_enable_display_irq(dev_priv, DE_GSE); ++ else ++ i915_enable_pipestat(dev_priv, 1, ++ I915_LEGACY_BLC_EVENT_ENABLE); ++} ++ ++/** + * i915_pipe_enabled - check if a pipe is enabled + * @dev: DRM device + * @pipe: pipe to check +@@ -286,6 +300,9 @@ irqreturn_t igdng_irq_handler(struct drm + mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); + } + ++ if (de_iir & DE_GSE) ++ ironlake_opregion_gse_intr(dev); ++ + I915_WRITE(GTIIR, gt_iir); + I915_WRITE(DEIIR, de_iir); + +@@ -993,7 +1010,7 @@ static int igdng_irq_postinstall(struct + { + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + /* enable kind of interrupts always enabled */ +- u32 display_mask = DE_MASTER_IRQ_CONTROL /*| DE_PCH_EVENT */; ++ u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE /*| DE_PCH_EVENT */; + u32 render_mask = GT_USER_INTERRUPT; + + dev_priv->irq_mask_reg = ~display_mask; +--- a/drivers/gpu/drm/i915/i915_opregion.c ++++ b/drivers/gpu/drm/i915/i915_opregion.c +@@ -118,6 +118,10 @@ struct opregion_asle { + #define ASLE_BACKLIGHT_FAIL (2<<12) + #define ASLE_PFIT_FAIL (2<<14) + #define ASLE_PWM_FREQ_FAIL (2<<16) ++#define ASLE_ALS_ILLUM_FAILED (1<<10) ++#define ASLE_BACKLIGHT_FAILED (1<<12) ++#define ASLE_PFIT_FAILED (1<<14) ++#define ASLE_PWM_FREQ_FAILED (1<<16) + + /* ASLE backlight brightness to set */ + #define ASLE_BCLP_VALID (1<<31) +@@ -243,6 +247,73 @@ void opregion_asle_intr(struct drm_devic + asle->aslc = asle_stat; + } + ++static u32 asle_set_backlight_ironlake(struct drm_device *dev, u32 bclp) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct opregion_asle *asle = dev_priv->opregion.asle; ++ u32 cpu_pwm_ctl, pch_pwm_ctl2; ++ u32 max_backlight, level; ++ ++ if (!(bclp & ASLE_BCLP_VALID)) ++ return ASLE_BACKLIGHT_FAILED; ++ ++ bclp &= ASLE_BCLP_MSK; ++ if (bclp < 0 || bclp > 255) ++ return ASLE_BACKLIGHT_FAILED; ++ ++ cpu_pwm_ctl = I915_READ(BLC_PWM_CPU_CTL); ++ pch_pwm_ctl2 = I915_READ(BLC_PWM_PCH_CTL2); ++ /* get the max PWM frequency */ ++ max_backlight = (pch_pwm_ctl2 >> 16) & BACKLIGHT_DUTY_CYCLE_MASK; ++ /* calculate the expected PMW frequency */ ++ level = (bclp * max_backlight) / 255; ++ /* reserve the high 16 bits */ ++ cpu_pwm_ctl &= ~(BACKLIGHT_DUTY_CYCLE_MASK); ++ /* write the updated PWM frequency */ ++ I915_WRITE(BLC_PWM_CPU_CTL, cpu_pwm_ctl | level); ++ ++ asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID; ++ ++ return 0; ++} ++ ++void ironlake_opregion_gse_intr(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct opregion_asle *asle = dev_priv->opregion.asle; ++ u32 asle_stat = 0; ++ u32 asle_req; ++ ++ if (!asle) ++ return; ++ ++ asle_req = asle->aslc & ASLE_REQ_MSK; ++ ++ if (!asle_req) { ++ DRM_DEBUG_DRIVER("non asle set request??\n"); ++ return; ++ } ++ ++ if (asle_req & ASLE_SET_ALS_ILLUM) { ++ DRM_DEBUG_DRIVER("Illum is not supported\n"); ++ asle_stat |= ASLE_ALS_ILLUM_FAILED; ++ } ++ ++ if (asle_req & ASLE_SET_BACKLIGHT) ++ asle_stat |= asle_set_backlight_ironlake(dev, asle->bclp); ++ ++ if (asle_req & ASLE_SET_PFIT) { ++ DRM_DEBUG_DRIVER("Pfit is not supported\n"); ++ asle_stat |= ASLE_PFIT_FAILED; ++ } ++ ++ if (asle_req & ASLE_SET_PWM_FREQ) { ++ DRM_DEBUG_DRIVER("PWM freq is not supported\n"); ++ asle_stat |= ASLE_PWM_FREQ_FAILED; ++ } ++ ++ asle->aslc = asle_stat; ++} + #define ASLE_ALS_EN (1<<0) + #define ASLE_BLC_EN (1<<1) + #define ASLE_PFIT_EN (1<<2) +@@ -258,8 +329,7 @@ void opregion_enable_asle(struct drm_dev + unsigned long irqflags; + + spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); +- i915_enable_pipestat(dev_priv, 1, +- I915_LEGACY_BLC_EVENT_ENABLE); ++ intel_enable_asle(dev); + spin_unlock_irqrestore(&dev_priv->user_irq_lock, + irqflags); + } diff --git a/queue-2.6.32/drm-i915-add-display-hotplug-event-on-ironlake.patch b/queue-2.6.32/drm-i915-add-display-hotplug-event-on-ironlake.patch new file mode 100644 index 00000000000..369ea993076 --- /dev/null +++ b/queue-2.6.32/drm-i915-add-display-hotplug-event-on-ironlake.patch @@ -0,0 +1,120 @@ +From sconklin@canonical.com Fri Jan 29 11:32:08 2010 +From: Steve Conklin +Date: Fri, 29 Jan 2010 12:56:45 -0600 +Subject: drm/i915: Add display hotplug event on Ironlake +To: stable@kernel.org +Cc: Steve Conklin , Eric Anholt , Zhenyu Wang +Message-ID: <1264791405-8169-1-git-send-email-sconklin@canonical.com> + + +commit c650156af34bffa3d3a62c9fe26eee595aab3fd1 upstream + +Enable display hotplug irqs from Ibex Peak (PCH). + +Signed-off-by: Zhenyu Wang +Signed-off-by: Eric Anholt +Signed-off-by: Steve Conklin +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_drv.h | 2 ++ + drivers/gpu/drm/i915/i915_irq.c | 30 +++++++++++++++++++++++++++--- + drivers/gpu/drm/i915/i915_reg.h | 1 + + 3 files changed, 30 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -211,6 +211,8 @@ typedef struct drm_i915_private { + u32 gt_irq_mask_reg; + u32 gt_irq_enable_reg; + u32 de_irq_enable_reg; ++ u32 pch_irq_mask_reg; ++ u32 pch_irq_enable_reg; + + u32 hotplug_supported_mask; + struct work_struct hotplug_work; +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -268,7 +268,7 @@ irqreturn_t igdng_irq_handler(struct drm + { + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + int ret = IRQ_NONE; +- u32 de_iir, gt_iir, de_ier; ++ u32 de_iir, gt_iir, de_ier, pch_iir; + struct drm_i915_master_private *master_priv; + + /* disable master interrupt before clearing iir */ +@@ -278,8 +278,9 @@ irqreturn_t igdng_irq_handler(struct drm + + de_iir = I915_READ(DEIIR); + gt_iir = I915_READ(GTIIR); ++ pch_iir = I915_READ(SDEIIR); + +- if (de_iir == 0 && gt_iir == 0) ++ if (de_iir == 0 && gt_iir == 0 && pch_iir == 0) + goto done; + + ret = IRQ_HANDLED; +@@ -303,6 +304,14 @@ irqreturn_t igdng_irq_handler(struct drm + if (de_iir & DE_GSE) + ironlake_opregion_gse_intr(dev); + ++ /* check event from PCH */ ++ if ((de_iir & DE_PCH_EVENT) && ++ (pch_iir & SDE_HOTPLUG_MASK)) { ++ queue_work(dev_priv->wq, &dev_priv->hotplug_work); ++ } ++ ++ /* should clear PCH hotplug event before clear CPU irq */ ++ I915_WRITE(SDEIIR, pch_iir); + I915_WRITE(GTIIR, gt_iir); + I915_WRITE(DEIIR, de_iir); + +@@ -1004,14 +1013,21 @@ static void igdng_irq_preinstall(struct + I915_WRITE(GTIMR, 0xffffffff); + I915_WRITE(GTIER, 0x0); + (void) I915_READ(GTIER); ++ ++ /* south display irq */ ++ I915_WRITE(SDEIMR, 0xffffffff); ++ I915_WRITE(SDEIER, 0x0); ++ (void) I915_READ(SDEIER); + } + + static int igdng_irq_postinstall(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + /* enable kind of interrupts always enabled */ +- u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE /*| DE_PCH_EVENT */; ++ u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT; + u32 render_mask = GT_USER_INTERRUPT; ++ u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | ++ SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; + + dev_priv->irq_mask_reg = ~display_mask; + dev_priv->de_irq_enable_reg = display_mask; +@@ -1031,6 +1047,14 @@ static int igdng_irq_postinstall(struct + I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); + (void) I915_READ(GTIER); + ++ dev_priv->pch_irq_mask_reg = ~hotplug_mask; ++ dev_priv->pch_irq_enable_reg = hotplug_mask; ++ ++ I915_WRITE(SDEIIR, I915_READ(SDEIIR)); ++ I915_WRITE(SDEIMR, dev_priv->pch_irq_mask_reg); ++ I915_WRITE(SDEIER, dev_priv->pch_irq_enable_reg); ++ (void) I915_READ(SDEIER); ++ + return 0; + } + +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -2121,6 +2121,7 @@ + #define SDE_PORTC_HOTPLUG (1 << 9) + #define SDE_PORTB_HOTPLUG (1 << 8) + #define SDE_SDVOB_HOTPLUG (1 << 6) ++#define SDE_HOTPLUG_MASK (0xf << 8) + + #define SDEISR 0xc4000 + #define SDEIMR 0xc4004 diff --git a/queue-2.6.32/drm-i915-reload-hangcheck-timer-too-for-ironlake.patch b/queue-2.6.32/drm-i915-reload-hangcheck-timer-too-for-ironlake.patch new file mode 100644 index 00000000000..d5747835a5c --- /dev/null +++ b/queue-2.6.32/drm-i915-reload-hangcheck-timer-too-for-ironlake.patch @@ -0,0 +1,30 @@ +From c566ec49159b806db95a90fd8f37448376cd0ad2 Mon Sep 17 00:00:00 2001 +From: Zhenyu Wang +Date: Thu, 17 Dec 2009 16:12:56 +0800 +Subject: drm/i915: Reload hangcheck timer too for Ironlake + +From: Zhenyu Wang + +commit c566ec49159b806db95a90fd8f37448376cd0ad2 upstream. + +Make sure hangcheck timer won't beat us unexpectedly on Ironlake. + +Signed-off-by: Zhenyu Wang +Signed-off-by: Eric Anholt +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_irq.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -282,6 +282,8 @@ irqreturn_t igdng_irq_handler(struct drm + dev_priv->mm.irq_gem_seqno = seqno; + trace_i915_gem_request_complete(dev, seqno); + DRM_WAKEUP(&dev_priv->irq_queue); ++ dev_priv->hangcheck_count = 0; ++ mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); + } + + I915_WRITE(GTIIR, gt_iir); diff --git a/queue-2.6.32/e1000-e1000e-don-t-use-small-hardware-rx-buffers.patch b/queue-2.6.32/e1000-e1000e-don-t-use-small-hardware-rx-buffers.patch new file mode 100644 index 00000000000..d1058893089 --- /dev/null +++ b/queue-2.6.32/e1000-e1000e-don-t-use-small-hardware-rx-buffers.patch @@ -0,0 +1,111 @@ +From 9926146b15fd96d78a4f7c32e7a26d50639369f4 Mon Sep 17 00:00:00 2001 +From: Jesse Brandeburg +Date: Fri, 22 Jan 2010 22:56:16 +0000 +Subject: e1000/e1000e: don't use small hardware rx buffers + +From: Jesse Brandeburg + +commit 9926146b15fd96d78a4f7c32e7a26d50639369f4 upstream. + +When testing the "e1000: enhance frame fragment detection" (and e1000e) +patches we found some bugs with reducing the MTU size. The 1024 byte +descriptor used with the 1000 mtu test also (re) introduced the +(originally) reported bug, and causes us to need the e1000_clean_tx_irq +"enhance frame fragment detection" fix. + +So what has occured here is that 2.6.32 is only vulnerable for mtu < +1500 due to the jumbo specific routines in both e1000 and e1000e. +So, 2.6.32 needs the 2kB buffer len fix for those smaller MTUs, but +is not vulnerable to the original issue reported. It has been pointed +out that this vulnerability needs to be patched in older kernels that +don't have the e1000 jumbo routine. Without the jumbo routines, we +need the "enhance frame fragment detection" fix the e1000, old +e1000e is only vulnerable for < 1500 mtu, and needs a similar +fix. We split the patches up to provide easy backport paths. + +There is only a slight bit of extra code when this fix and the +original "enhance frame fragment detection" fixes are applied, so +please apply both, even though it is a bit of overkill. + +Signed-off-by: Jesse Brandeburg +Signed-off-by: Jeff Kirsher +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/e1000/e1000_main.c | 20 +------------------- + drivers/net/e1000e/netdev.c | 20 +------------------- + 2 files changed, 2 insertions(+), 38 deletions(-) + +--- a/drivers/net/e1000/e1000_main.c ++++ b/drivers/net/e1000/e1000_main.c +@@ -1698,18 +1698,6 @@ static void e1000_setup_rctl(struct e100 + rctl &= ~E1000_RCTL_SZ_4096; + rctl |= E1000_RCTL_BSEX; + switch (adapter->rx_buffer_len) { +- case E1000_RXBUFFER_256: +- rctl |= E1000_RCTL_SZ_256; +- rctl &= ~E1000_RCTL_BSEX; +- break; +- case E1000_RXBUFFER_512: +- rctl |= E1000_RCTL_SZ_512; +- rctl &= ~E1000_RCTL_BSEX; +- break; +- case E1000_RXBUFFER_1024: +- rctl |= E1000_RCTL_SZ_1024; +- rctl &= ~E1000_RCTL_BSEX; +- break; + case E1000_RXBUFFER_2048: + default: + rctl |= E1000_RCTL_SZ_2048; +@@ -3154,13 +3142,7 @@ static int e1000_change_mtu(struct net_d + * however with the new *_jumbo_rx* routines, jumbo receives will use + * fragmented skbs */ + +- if (max_frame <= E1000_RXBUFFER_256) +- adapter->rx_buffer_len = E1000_RXBUFFER_256; +- else if (max_frame <= E1000_RXBUFFER_512) +- adapter->rx_buffer_len = E1000_RXBUFFER_512; +- else if (max_frame <= E1000_RXBUFFER_1024) +- adapter->rx_buffer_len = E1000_RXBUFFER_1024; +- else if (max_frame <= E1000_RXBUFFER_2048) ++ if (max_frame <= E1000_RXBUFFER_2048) + adapter->rx_buffer_len = E1000_RXBUFFER_2048; + else + #if (PAGE_SIZE >= E1000_RXBUFFER_16384) +--- a/drivers/net/e1000e/netdev.c ++++ b/drivers/net/e1000e/netdev.c +@@ -2347,18 +2347,6 @@ static void e1000_setup_rctl(struct e100 + rctl &= ~E1000_RCTL_SZ_4096; + rctl |= E1000_RCTL_BSEX; + switch (adapter->rx_buffer_len) { +- case 256: +- rctl |= E1000_RCTL_SZ_256; +- rctl &= ~E1000_RCTL_BSEX; +- break; +- case 512: +- rctl |= E1000_RCTL_SZ_512; +- rctl &= ~E1000_RCTL_BSEX; +- break; +- case 1024: +- rctl |= E1000_RCTL_SZ_1024; +- rctl &= ~E1000_RCTL_BSEX; +- break; + case 2048: + default: + rctl |= E1000_RCTL_SZ_2048; +@@ -4338,13 +4326,7 @@ static int e1000_change_mtu(struct net_d + * fragmented skbs + */ + +- if (max_frame <= 256) +- adapter->rx_buffer_len = 256; +- else if (max_frame <= 512) +- adapter->rx_buffer_len = 512; +- else if (max_frame <= 1024) +- adapter->rx_buffer_len = 1024; +- else if (max_frame <= 2048) ++ if (max_frame <= 2048) + adapter->rx_buffer_len = 2048; + else + adapter->rx_buffer_len = 4096; diff --git a/queue-2.6.32/e1000-enhance-frame-fragment-detection.patch b/queue-2.6.32/e1000-enhance-frame-fragment-detection.patch new file mode 100644 index 00000000000..2e46351ddca --- /dev/null +++ b/queue-2.6.32/e1000-enhance-frame-fragment-detection.patch @@ -0,0 +1,76 @@ +From 40a14deaf411592b57cb0720f0e8004293ab9865 Mon Sep 17 00:00:00 2001 +From: Jesse Brandeburg +Date: Tue, 19 Jan 2010 14:15:38 +0000 +Subject: e1000: enhance frame fragment detection + +From: Jesse Brandeburg + +commit 40a14deaf411592b57cb0720f0e8004293ab9865 upstream. + +Originally From: Neil Horman +Modified by: Jesse Brandeburg + +Hey all- + A security discussion was recently given: +http://events.ccc.de/congress/2009/Fahrplan//events/3596.en.html +And a patch that I submitted awhile back was brought up. Apparently some of +their testing revealed that they were able to force a buffer fragment in e1000 +in which the trailing fragment was greater than 4 bytes. As a result the +fragment check I introduced failed to detect the fragement and a partial +invalid frame was passed up into the network stack. I've written this patch +to correct it. I'm in the process of testing it now, but it makes good +logical sense to me. Effectively it maintains a per-adapter state variable +which detects a non-EOP frame, and discards it and subsequent non-EOP frames +leading up to _and_ _including_ the next positive-EOP frame (as it is by +definition the last fragment). This should prevent any and all partial frames +from entering the network stack from e1000. + +Signed-off-by: Jesse Brandeburg +Acked-by: Neil Horman +Signed-off-by: Jeff Kirsher +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/e1000/e1000.h | 2 ++ + drivers/net/e1000/e1000_main.c | 13 +++++++++++-- + 2 files changed, 13 insertions(+), 2 deletions(-) + +--- a/drivers/net/e1000/e1000.h ++++ b/drivers/net/e1000/e1000.h +@@ -326,6 +326,8 @@ struct e1000_adapter { + /* for ioport free */ + int bars; + int need_ioport; ++ ++ bool discarding; + }; + + enum e1000_state_t { +--- a/drivers/net/e1000/e1000_main.c ++++ b/drivers/net/e1000/e1000_main.c +@@ -3827,13 +3827,22 @@ static bool e1000_clean_rx_irq(struct e1 + + length = le16_to_cpu(rx_desc->length); + /* !EOP means multiple descriptors were used to store a single +- * packet, also make sure the frame isn't just CRC only */ +- if (unlikely(!(status & E1000_RXD_STAT_EOP) || (length <= 4))) { ++ * packet, if thats the case we need to toss it. In fact, we ++ * to toss every packet with the EOP bit clear and the next ++ * frame that _does_ have the EOP bit set, as it is by ++ * definition only a frame fragment ++ */ ++ if (unlikely(!(status & E1000_RXD_STAT_EOP))) ++ adapter->discarding = true; ++ ++ if (adapter->discarding) { + /* All receives must fit into a single buffer */ + E1000_DBG("%s: Receive packet consumed multiple" + " buffers\n", netdev->name); + /* recycle */ + buffer_info->skb = skb; ++ if (status & E1000_RXD_STAT_EOP) ++ adapter->discarding = false; + goto next_desc; + } + diff --git a/queue-2.6.32/e1000e-enhance-frame-fragment-detection.patch b/queue-2.6.32/e1000e-enhance-frame-fragment-detection.patch new file mode 100644 index 00000000000..2f4c4f9cb3c --- /dev/null +++ b/queue-2.6.32/e1000e-enhance-frame-fragment-detection.patch @@ -0,0 +1,94 @@ +From b94b50289622e816adc9f94111cfc2679c80177c Mon Sep 17 00:00:00 2001 +From: Jesse Brandeburg +Date: Tue, 19 Jan 2010 14:15:59 +0000 +Subject: e1000e: enhance frame fragment detection + +From: Jesse Brandeburg + +commit b94b50289622e816adc9f94111cfc2679c80177c upstream. + +Originally patched by Neil Horman + +e1000e could with a jumbo frame enabled interface, and packet split disabled, +receive a packet that would overflow a single rx buffer. While in practice +very hard to craft a packet that could abuse this, it is possible. + +this is related to CVE-2009-4538 + +Signed-off-by: Jesse Brandeburg +CC: Neil Horman +Signed-off-by: Jeff Kirsher +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/e1000e/e1000.h | 1 + + drivers/net/e1000e/netdev.c | 25 +++++++++++++++++++++---- + 2 files changed, 22 insertions(+), 4 deletions(-) + +--- a/drivers/net/e1000e/e1000.h ++++ b/drivers/net/e1000e/e1000.h +@@ -417,6 +417,7 @@ struct e1000_info { + /* CRC Stripping defines */ + #define FLAG2_CRC_STRIPPING (1 << 0) + #define FLAG2_HAS_PHY_WAKEUP (1 << 1) ++#define FLAG2_IS_DISCARDING (1 << 2) + + #define E1000_RX_DESC_PS(R, i) \ + (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) +--- a/drivers/net/e1000e/netdev.c ++++ b/drivers/net/e1000e/netdev.c +@@ -482,14 +482,24 @@ static bool e1000_clean_rx_irq(struct e1 + + length = le16_to_cpu(rx_desc->length); + +- /* !EOP means multiple descriptors were used to store a single +- * packet, also make sure the frame isn't just CRC only */ +- if (!(status & E1000_RXD_STAT_EOP) || (length <= 4)) { ++ /* ++ * !EOP means multiple descriptors were used to store a single ++ * packet, if that's the case we need to toss it. In fact, we ++ * need to toss every packet with the EOP bit clear and the ++ * next frame that _does_ have the EOP bit set, as it is by ++ * definition only a frame fragment ++ */ ++ if (unlikely(!(status & E1000_RXD_STAT_EOP))) ++ adapter->flags2 |= FLAG2_IS_DISCARDING; ++ ++ if (adapter->flags2 & FLAG2_IS_DISCARDING) { + /* All receives must fit into a single buffer */ + e_dbg("%s: Receive packet consumed multiple buffers\n", + netdev->name); + /* recycle */ + buffer_info->skb = skb; ++ if (status & E1000_RXD_STAT_EOP) ++ adapter->flags2 &= ~FLAG2_IS_DISCARDING; + goto next_desc; + } + +@@ -747,10 +757,16 @@ static bool e1000_clean_rx_irq_ps(struct + PCI_DMA_FROMDEVICE); + buffer_info->dma = 0; + +- if (!(staterr & E1000_RXD_STAT_EOP)) { ++ /* see !EOP comment in other rx routine */ ++ if (!(staterr & E1000_RXD_STAT_EOP)) ++ adapter->flags2 |= FLAG2_IS_DISCARDING; ++ ++ if (adapter->flags2 & FLAG2_IS_DISCARDING) { + e_dbg("%s: Packet Split buffers didn't pick up the " + "full packet\n", netdev->name); + dev_kfree_skb_irq(skb); ++ if (staterr & E1000_RXD_STAT_EOP) ++ adapter->flags2 &= ~FLAG2_IS_DISCARDING; + goto next_desc; + } + +@@ -1120,6 +1136,7 @@ static void e1000_clean_rx_ring(struct e + + rx_ring->next_to_clean = 0; + rx_ring->next_to_use = 0; ++ adapter->flags2 &= ~FLAG2_IS_DISCARDING; + + writel(0, adapter->hw.hw_addr + rx_ring->head); + writel(0, adapter->hw.hw_addr + rx_ring->tail); diff --git a/queue-2.6.32/fdpic-respect-pt_gnu_stack-exec-protection-markings-when-creating-nommu-stack.patch b/queue-2.6.32/fdpic-respect-pt_gnu_stack-exec-protection-markings-when-creating-nommu-stack.patch new file mode 100644 index 00000000000..ba5e8844a0a --- /dev/null +++ b/queue-2.6.32/fdpic-respect-pt_gnu_stack-exec-protection-markings-when-creating-nommu-stack.patch @@ -0,0 +1,105 @@ +From 04e4f2b18c8de1389d1e00fef0f42a8099910daf Mon Sep 17 00:00:00 2001 +From: Mike Frysinger +Date: Wed, 6 Jan 2010 17:23:17 +0000 +Subject: FDPIC: Respect PT_GNU_STACK exec protection markings when creating NOMMU stack + +From: Mike Frysinger + +commit 04e4f2b18c8de1389d1e00fef0f42a8099910daf upstream. + +The current code will load the stack size and protection markings, but +then only use the markings in the MMU code path. The NOMMU code path +always passes PROT_EXEC to the mmap() call. While this doesn't matter +to most people whilst the code is running, it will cause a pointless +icache flush when starting every FDPIC application. Typically this +icache flush will be of a region on the order of 128KB in size, or may +be the entire icache, depending on the facilities available on the CPU. + +In the case where the arch default behaviour seems to be desired +(EXSTACK_DEFAULT), we probe VM_STACK_FLAGS for VM_EXEC to determine +whether we should be setting PROT_EXEC or not. + +For arches that support an MPU (Memory Protection Unit - an MMU without +the virtual mapping capability), setting PROT_EXEC or not will make an +important difference. + +It should be noted that this change also affects the executability of +the brk region, since ELF-FDPIC has that share with the stack. However, +this is probably irrelevant as NOMMU programs aren't likely to use the +brk region, preferring instead allocation via mmap(). + +Signed-off-by: Mike Frysinger +Signed-off-by: David Howells +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + arch/blackfin/include/asm/page.h | 5 +++++ + arch/frv/include/asm/page.h | 2 -- + fs/binfmt_elf_fdpic.c | 13 +++++++++++-- + 3 files changed, 16 insertions(+), 4 deletions(-) + +--- a/arch/blackfin/include/asm/page.h ++++ b/arch/blackfin/include/asm/page.h +@@ -10,4 +10,9 @@ + #include + #define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT) + ++#define VM_DATA_DEFAULT_FLAGS \ ++ (VM_READ | VM_WRITE | \ ++ ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ ++ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) ++ + #endif +--- a/arch/frv/include/asm/page.h ++++ b/arch/frv/include/asm/page.h +@@ -63,12 +63,10 @@ extern unsigned long max_pfn; + #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) + + +-#ifdef CONFIG_MMU + #define VM_DATA_DEFAULT_FLAGS \ + (VM_READ | VM_WRITE | \ + ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +-#endif + + #endif /* __ASSEMBLY__ */ + +--- a/fs/binfmt_elf_fdpic.c ++++ b/fs/binfmt_elf_fdpic.c +@@ -171,6 +171,9 @@ static int load_elf_fdpic_binary(struct + #ifdef ELF_FDPIC_PLAT_INIT + unsigned long dynaddr; + #endif ++#ifndef CONFIG_MMU ++ unsigned long stack_prot; ++#endif + struct file *interpreter = NULL; /* to shut gcc up */ + char *interpreter_name = NULL; + int executable_stack; +@@ -316,6 +319,8 @@ static int load_elf_fdpic_binary(struct + * defunct, deceased, etc. after this point we have to exit via + * error_kill */ + set_personality(PER_LINUX_FDPIC); ++ if (elf_read_implies_exec(&exec_params.hdr, executable_stack)) ++ current->personality |= READ_IMPLIES_EXEC; + set_binfmt(&elf_fdpic_format); + + current->mm->start_code = 0; +@@ -377,9 +382,13 @@ static int load_elf_fdpic_binary(struct + if (stack_size < PAGE_SIZE * 2) + stack_size = PAGE_SIZE * 2; + ++ stack_prot = PROT_READ | PROT_WRITE; ++ if (executable_stack == EXSTACK_ENABLE_X || ++ (executable_stack == EXSTACK_DEFAULT && VM_STACK_FLAGS & VM_EXEC)) ++ stack_prot |= PROT_EXEC; ++ + down_write(¤t->mm->mmap_sem); +- current->mm->start_brk = do_mmap(NULL, 0, stack_size, +- PROT_READ | PROT_WRITE | PROT_EXEC, ++ current->mm->start_brk = do_mmap(NULL, 0, stack_size, stack_prot, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN, + 0); + diff --git a/queue-2.6.32/fix-a-leak-in-affs_fill_super.patch b/queue-2.6.32/fix-a-leak-in-affs_fill_super.patch new file mode 100644 index 00000000000..1a62ba8681b --- /dev/null +++ b/queue-2.6.32/fix-a-leak-in-affs_fill_super.patch @@ -0,0 +1,27 @@ +From afc70ed05a07bfe171f7a5b8fdc80bdb073d314f Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Sat, 23 Jan 2010 23:38:27 -0500 +Subject: Fix a leak in affs_fill_super() + +From: Al Viro + +commit afc70ed05a07bfe171f7a5b8fdc80bdb073d314f upstream. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/affs/super.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/affs/super.c ++++ b/fs/affs/super.c +@@ -316,6 +316,8 @@ static int affs_fill_super(struct super_ + &blocksize,&sbi->s_prefix, + sbi->s_volume, &mount_flags)) { + printk(KERN_ERR "AFFS: Error parsing options\n"); ++ kfree(sbi->s_prefix); ++ kfree(sbi); + return -EINVAL; + } + /* N.B. after this point s_prefix must be released */ diff --git a/queue-2.6.32/fix-affs-parse_options.patch b/queue-2.6.32/fix-affs-parse_options.patch new file mode 100644 index 00000000000..87b4967134e --- /dev/null +++ b/queue-2.6.32/fix-affs-parse_options.patch @@ -0,0 +1,68 @@ +From 217686e98321a4ff4c1a6cc535e511e37c5d2dbf Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Sun, 24 Jan 2010 00:06:22 -0500 +Subject: fix affs parse_options() + +From: Al Viro + +commit 217686e98321a4ff4c1a6cc535e511e37c5d2dbf upstream. + +Error handling in that sucker got broken back in 2003. If function +returns 0 on failure, it's not nice to add return -EINVAL into it. +Adding return 1 on other failure exits is also not a good thing (and +yes, original success exits with 1 and some of failure exits with 0 +are still there; so's the original logics in callers). + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/affs/super.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/fs/affs/super.c ++++ b/fs/affs/super.c +@@ -203,7 +203,7 @@ parse_options(char *options, uid_t *uid, + switch (token) { + case Opt_bs: + if (match_int(&args[0], &n)) +- return -EINVAL; ++ return 0; + if (n != 512 && n != 1024 && n != 2048 + && n != 4096) { + printk ("AFFS: Invalid blocksize (512, 1024, 2048, 4096 allowed)\n"); +@@ -213,7 +213,7 @@ parse_options(char *options, uid_t *uid, + break; + case Opt_mode: + if (match_octal(&args[0], &option)) +- return 1; ++ return 0; + *mode = option & 0777; + *mount_opts |= SF_SETMODE; + break; +@@ -231,21 +231,21 @@ parse_options(char *options, uid_t *uid, + break; + case Opt_reserved: + if (match_int(&args[0], reserved)) +- return 1; ++ return 0; + break; + case Opt_root: + if (match_int(&args[0], root)) +- return 1; ++ return 0; + break; + case Opt_setgid: + if (match_int(&args[0], &option)) +- return 1; ++ return 0; + *gid = option; + *mount_opts |= SF_SETGID; + break; + case Opt_setuid: + if (match_int(&args[0], &option)) +- return -EINVAL; ++ return 0; + *uid = option; + *mount_opts |= SF_SETUID; + break; diff --git a/queue-2.6.32/fix-failure-exit-in-ipathfs.patch b/queue-2.6.32/fix-failure-exit-in-ipathfs.patch new file mode 100644 index 00000000000..50fa443ed98 --- /dev/null +++ b/queue-2.6.32/fix-failure-exit-in-ipathfs.patch @@ -0,0 +1,33 @@ +From 12e9a45609054fb83d4a8b716a5265cc1a393e10 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Mon, 25 Jan 2010 18:44:58 -0500 +Subject: Fix failure exit in ipathfs + +From: Al Viro + +commit 12e9a45609054fb83d4a8b716a5265cc1a393e10 upstream. + +deactivate_locked_super() will be done by caller of fill_super, doing +it there as well is b0rken. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/ipath/ipath_fs.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/infiniband/hw/ipath/ipath_fs.c ++++ b/drivers/infiniband/hw/ipath/ipath_fs.c +@@ -346,10 +346,8 @@ static int ipathfs_fill_super(struct sup + list_for_each_entry_safe(dd, tmp, &ipath_dev_list, ipath_list) { + spin_unlock_irqrestore(&ipath_devs_lock, flags); + ret = create_device_files(sb, dd); +- if (ret) { +- deactivate_locked_super(sb); ++ if (ret) + goto bail; +- } + spin_lock_irqsave(&ipath_devs_lock, flags); + } + diff --git a/queue-2.6.32/fix-failure-exits-in-bfs_fill_super.patch b/queue-2.6.32/fix-failure-exits-in-bfs_fill_super.patch new file mode 100644 index 00000000000..7eccbb5a131 --- /dev/null +++ b/queue-2.6.32/fix-failure-exits-in-bfs_fill_super.patch @@ -0,0 +1,136 @@ +From 5998649f779b7148a8a0c10c46cfa99e27d34dfe Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Sun, 24 Jan 2010 00:52:22 -0500 +Subject: Fix failure exits in bfs_fill_super() + +From: Al Viro + +commit 5998649f779b7148a8a0c10c46cfa99e27d34dfe upstream. + +double iput(), leaks... + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/bfs/inode.c | 43 +++++++++++++++++++++---------------------- + 1 file changed, 21 insertions(+), 22 deletions(-) + +--- a/fs/bfs/inode.c ++++ b/fs/bfs/inode.c +@@ -353,35 +353,35 @@ static int bfs_fill_super(struct super_b + struct inode *inode; + unsigned i, imap_len; + struct bfs_sb_info *info; +- long ret = -EINVAL; ++ int ret = -EINVAL; + unsigned long i_sblock, i_eblock, i_eoff, s_size; + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; ++ mutex_init(&info->bfs_lock); + s->s_fs_info = info; + + sb_set_blocksize(s, BFS_BSIZE); + +- bh = sb_bread(s, 0); +- if(!bh) ++ info->si_sbh = sb_bread(s, 0); ++ if (!info->si_sbh) + goto out; +- bfs_sb = (struct bfs_super_block *)bh->b_data; ++ bfs_sb = (struct bfs_super_block *)info->si_sbh->b_data; + if (le32_to_cpu(bfs_sb->s_magic) != BFS_MAGIC) { + if (!silent) + printf("No BFS filesystem on %s (magic=%08x)\n", + s->s_id, le32_to_cpu(bfs_sb->s_magic)); +- goto out; ++ goto out1; + } + if (BFS_UNCLEAN(bfs_sb, s) && !silent) + printf("%s is unclean, continuing\n", s->s_id); + + s->s_magic = BFS_MAGIC; +- info->si_sbh = bh; + + if (le32_to_cpu(bfs_sb->s_start) > le32_to_cpu(bfs_sb->s_end)) { + printf("Superblock is corrupted\n"); +- goto out; ++ goto out1; + } + + info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE) / +@@ -390,7 +390,7 @@ static int bfs_fill_super(struct super_b + imap_len = (info->si_lasti / 8) + 1; + info->si_imap = kzalloc(imap_len, GFP_KERNEL); + if (!info->si_imap) +- goto out; ++ goto out1; + for (i = 0; i < BFS_ROOT_INO; i++) + set_bit(i, info->si_imap); + +@@ -398,15 +398,13 @@ static int bfs_fill_super(struct super_b + inode = bfs_iget(s, BFS_ROOT_INO); + if (IS_ERR(inode)) { + ret = PTR_ERR(inode); +- kfree(info->si_imap); +- goto out; ++ goto out2; + } + s->s_root = d_alloc_root(inode); + if (!s->s_root) { + iput(inode); + ret = -ENOMEM; +- kfree(info->si_imap); +- goto out; ++ goto out2; + } + + info->si_blocks = (le32_to_cpu(bfs_sb->s_end) + 1) >> BFS_BSIZE_BITS; +@@ -419,10 +417,8 @@ static int bfs_fill_super(struct super_b + bh = sb_bread(s, info->si_blocks - 1); + if (!bh) { + printf("Last block not available: %lu\n", info->si_blocks - 1); +- iput(inode); + ret = -EIO; +- kfree(info->si_imap); +- goto out; ++ goto out3; + } + brelse(bh); + +@@ -459,11 +455,8 @@ static int bfs_fill_super(struct super_b + printf("Inode 0x%08x corrupted\n", i); + + brelse(bh); +- s->s_root = NULL; +- kfree(info->si_imap); +- kfree(info); +- s->s_fs_info = NULL; +- return -EIO; ++ ret = -EIO; ++ goto out3; + } + + if (!di->i_ino) { +@@ -483,11 +476,17 @@ static int bfs_fill_super(struct super_b + s->s_dirt = 1; + } + dump_imap("read_super", s); +- mutex_init(&info->bfs_lock); + return 0; + ++out3: ++ dput(s->s_root); ++ s->s_root = NULL; ++out2: ++ kfree(info->si_imap); ++out1: ++ brelse(info->si_sbh); + out: +- brelse(bh); ++ mutex_destroy(&info->bfs_lock); + kfree(info); + s->s_fs_info = NULL; + return ret; diff --git a/queue-2.6.32/fix-leak-in-romfs_fill_super.patch b/queue-2.6.32/fix-leak-in-romfs_fill_super.patch new file mode 100644 index 00000000000..8e9a98760b5 --- /dev/null +++ b/queue-2.6.32/fix-leak-in-romfs_fill_super.patch @@ -0,0 +1,26 @@ +From 7e32b7bb734047c5e3cecf2e896b9cf8fc35d1e8 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Mon, 25 Jan 2010 06:05:54 -0500 +Subject: fix leak in romfs_fill_super() + +From: Al Viro + +commit 7e32b7bb734047c5e3cecf2e896b9cf8fc35d1e8 upstream. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/romfs/super.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/romfs/super.c ++++ b/fs/romfs/super.c +@@ -544,6 +544,7 @@ error: + error_rsb_inval: + ret = -EINVAL; + error_rsb: ++ kfree(rsb); + return ret; + } + diff --git a/queue-2.6.32/fix-oops-in-fs-9p-late-mount-failure.patch b/queue-2.6.32/fix-oops-in-fs-9p-late-mount-failure.patch new file mode 100644 index 00000000000..afb9972275b --- /dev/null +++ b/queue-2.6.32/fix-oops-in-fs-9p-late-mount-failure.patch @@ -0,0 +1,31 @@ +From 083c73c253c23c20359a344dfe1198ea628e6259 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Mon, 25 Jan 2010 06:16:19 -0500 +Subject: fix oops in fs/9p late mount failure + +From: Al Viro + +commit 083c73c253c23c20359a344dfe1198ea628e6259 upstream. + +if 9P ->get_sb() fails late (at root inode or root dentry +allocation), we'll hit its ->kill_sb() with NULL ->s_root + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/9p/vfs_super.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/9p/vfs_super.c ++++ b/fs/9p/vfs_super.c +@@ -188,7 +188,8 @@ static void v9fs_kill_super(struct super + + P9_DPRINTK(P9_DEBUG_VFS, " %p\n", s); + +- v9fs_dentry_release(s->s_root); /* clunk root */ ++ if (s->s_root) ++ v9fs_dentry_release(s->s_root); /* clunk root */ + + kill_anon_super(s); + diff --git a/queue-2.6.32/fix-remount-races-with-symlink-handling-in-affs.patch b/queue-2.6.32/fix-remount-races-with-symlink-handling-in-affs.patch new file mode 100644 index 00000000000..636da0f0ecd --- /dev/null +++ b/queue-2.6.32/fix-remount-races-with-symlink-handling-in-affs.patch @@ -0,0 +1,134 @@ +From 29333920a5a46edcc9b728e2cf0134d5a9b516ee Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Sun, 24 Jan 2010 00:04:07 -0500 +Subject: Fix remount races with symlink handling in affs + +From: Al Viro + +commit 29333920a5a46edcc9b728e2cf0134d5a9b516ee upstream. + +A couple of fields in affs_sb_info is used in follow_link() and +symlink() for handling AFFS "absolute" symlinks. Need locking +against affs_remount() updates. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/affs/affs.h | 2 +- + fs/affs/namei.c | 7 +++++-- + fs/affs/super.c | 17 ++++++++++++++--- + fs/affs/symlink.c | 7 +++++-- + 4 files changed, 25 insertions(+), 8 deletions(-) + +--- a/fs/affs/affs.h ++++ b/fs/affs/affs.h +@@ -106,8 +106,8 @@ struct affs_sb_info { + u32 s_last_bmap; + struct buffer_head *s_bmap_bh; + char *s_prefix; /* Prefix for volumes and assigns. */ +- int s_prefix_len; /* Length of prefix. */ + char s_volume[32]; /* Volume prefix for absolute symlinks. */ ++ spinlock_t symlink_lock; /* protects the previous two */ + }; + + #define SF_INTL 0x0001 /* International filesystem. */ +--- a/fs/affs/namei.c ++++ b/fs/affs/namei.c +@@ -341,10 +341,13 @@ affs_symlink(struct inode *dir, struct d + p = (char *)AFFS_HEAD(bh)->table; + lc = '/'; + if (*symname == '/') { ++ struct affs_sb_info *sbi = AFFS_SB(sb); + while (*symname == '/') + symname++; +- while (AFFS_SB(sb)->s_volume[i]) /* Cannot overflow */ +- *p++ = AFFS_SB(sb)->s_volume[i++]; ++ spin_lock(&sbi->symlink_lock); ++ while (sbi->s_volume[i]) /* Cannot overflow */ ++ *p++ = sbi->s_volume[i++]; ++ spin_unlock(&sbi->symlink_lock); + } + while (i < maxlen && (c = *symname++)) { + if (c == '.' && lc == '/' && *symname == '.' && symname[1] == '/') { +--- a/fs/affs/super.c ++++ b/fs/affs/super.c +@@ -221,8 +221,6 @@ parse_options(char *options, uid_t *uid, + *mount_opts |= SF_MUFS; + break; + case Opt_prefix: +- /* Free any previous prefix */ +- kfree(*prefix); + *prefix = match_strdup(&args[0]); + if (!*prefix) + return 0; +@@ -311,6 +309,7 @@ static int affs_fill_super(struct super_ + return -ENOMEM; + sb->s_fs_info = sbi; + mutex_init(&sbi->s_bmlock); ++ spin_lock_init(&sbi->symlink_lock); + + if (!parse_options(data,&uid,&gid,&i,&reserved,&root_block, + &blocksize,&sbi->s_prefix, +@@ -518,14 +517,18 @@ affs_remount(struct super_block *sb, int + unsigned long mount_flags; + int res = 0; + char *new_opts = kstrdup(data, GFP_KERNEL); ++ char volume[32]; ++ char *prefix = NULL; + + pr_debug("AFFS: remount(flags=0x%x,opts=\"%s\")\n",*flags,data); + + *flags |= MS_NODIRATIME; + ++ memcpy(volume, sbi->s_volume, 32); + if (!parse_options(data, &uid, &gid, &mode, &reserved, &root_block, +- &blocksize, &sbi->s_prefix, sbi->s_volume, ++ &blocksize, &prefix, volume, + &mount_flags)) { ++ kfree(prefix); + kfree(new_opts); + return -EINVAL; + } +@@ -536,6 +539,14 @@ affs_remount(struct super_block *sb, int + sbi->s_mode = mode; + sbi->s_uid = uid; + sbi->s_gid = gid; ++ /* protect against readers */ ++ spin_lock(&sbi->symlink_lock); ++ if (prefix) { ++ kfree(sbi->s_prefix); ++ sbi->s_prefix = prefix; ++ } ++ memcpy(sbi->s_volume, volume, 32); ++ spin_unlock(&sbi->symlink_lock); + + if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { + unlock_kernel(); +--- a/fs/affs/symlink.c ++++ b/fs/affs/symlink.c +@@ -20,7 +20,6 @@ static int affs_symlink_readpage(struct + int i, j; + char c; + char lc; +- char *pf; + + pr_debug("AFFS: follow_link(ino=%lu)\n",inode->i_ino); + +@@ -32,11 +31,15 @@ static int affs_symlink_readpage(struct + j = 0; + lf = (struct slink_front *)bh->b_data; + lc = 0; +- pf = AFFS_SB(inode->i_sb)->s_prefix ? AFFS_SB(inode->i_sb)->s_prefix : "/"; + + if (strchr(lf->symname,':')) { /* Handle assign or volume name */ ++ struct affs_sb_info *sbi = AFFS_SB(inode->i_sb); ++ char *pf; ++ spin_lock(&sbi->symlink_lock); ++ pf = sbi->s_prefix ? sbi->s_prefix : "/"; + while (i < 1023 && (c = pf[i])) + link[i++] = c; ++ spin_unlock(&sbi->symlink_lock); + while (i < 1023 && lf->symname[j] != ':') + link[i++] = lf->symname[j++]; + if (i < 1023) diff --git a/queue-2.6.32/input-winbond-cir-remove-dmesg-spam.patch b/queue-2.6.32/input-winbond-cir-remove-dmesg-spam.patch new file mode 100644 index 00000000000..3fa2d4820c2 --- /dev/null +++ b/queue-2.6.32/input-winbond-cir-remove-dmesg-spam.patch @@ -0,0 +1,32 @@ +From 93fb84b50fe03aabca8d9dea5d3ba521a07e8571 Mon Sep 17 00:00:00 2001 +From: David Härdeman +Date: Thu, 28 Jan 2010 22:28:27 -0800 +Subject: Input: winbond-cir - remove dmesg spam + +From: David Härdeman + +commit 93fb84b50fe03aabca8d9dea5d3ba521a07e8571 upstream. + +I missed converting one dev_info call to deb_dbg before submitting the driver. +Without this change, a message will be printed to dmesg for each button press +if a RC6 remote is used. + +Signed-off-by: David Härdeman +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/misc/winbond-cir.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/input/misc/winbond-cir.c ++++ b/drivers/input/misc/winbond-cir.c +@@ -768,7 +768,7 @@ wbcir_parse_rc6(struct device *dev, stru + return; + } + +- dev_info(dev, "IR-RC6 ad 0x%02X cm 0x%02X cu 0x%04X " ++ dev_dbg(dev, "IR-RC6 ad 0x%02X cm 0x%02X cu 0x%04X " + "toggle %u mode %u scan 0x%08X\n", + address, + command, diff --git a/queue-2.6.32/mm-fix-migratetype-bug-which-slowed-swapping.patch b/queue-2.6.32/mm-fix-migratetype-bug-which-slowed-swapping.patch new file mode 100644 index 00000000000..6b8290a35a7 --- /dev/null +++ b/queue-2.6.32/mm-fix-migratetype-bug-which-slowed-swapping.patch @@ -0,0 +1,55 @@ +From a7016235a61d520e6806f38129001d935c4b6661 Mon Sep 17 00:00:00 2001 +From: Hugh Dickins +Date: Fri, 29 Jan 2010 17:46:34 +0000 +Subject: mm: fix migratetype bug which slowed swapping + +From: Hugh Dickins + +commit a7016235a61d520e6806f38129001d935c4b6661 upstream. + +After memory pressure has forced it to dip into the reserves, 2.6.32's +5f8dcc21211a3d4e3a7a5ca366b469fb88117f61 "page-allocator: split per-cpu +list into one-list-per-migrate-type" has been returning MIGRATE_RESERVE +pages to the MIGRATE_MOVABLE free_list: in some sense depleting reserves. + +Fix that in the most straightforward way (which, considering the overheads +of alternative approaches, is Mel's preference): the right migratetype is +already in page_private(page), but free_pcppages_bulk() wasn't using it. + +How did this bug show up? As a 20% slowdown in my tmpfs loop kbuild +swapping tests, on PowerMac G5 with SLUB allocator. Bisecting to that +commit was easy, but explaining the magnitude of the slowdown not easy. + +The same effect appears, but much less markedly, with SLAB, and even +less markedly on other machines (the PowerMac divides into fewer zones +than x86, I think that may be a factor). We guess that lumpy reclaim +of short-lived high-order pages is implicated in some way, and probably +this bug has been tickling a poor decision somewhere in page reclaim. + +But instrumentation hasn't told me much, I've run out of time and +imagination to determine exactly what's going on, and shouldn't hold up +the fix any longer: it's valid, and might even fix other misbehaviours. + +Signed-off-by: Hugh Dickins +Acked-by: Mel Gorman +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/page_alloc.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -559,8 +559,9 @@ static void free_pcppages_bulk(struct zo + page = list_entry(list->prev, struct page, lru); + /* must delete as __free_one_page list manipulates */ + list_del(&page->lru); +- __free_one_page(page, zone, 0, migratetype); +- trace_mm_page_pcpu_drain(page, 0, migratetype); ++ /* MIGRATE_MOVABLE list may include MIGRATE_RESERVEs */ ++ __free_one_page(page, zone, 0, page_private(page)); ++ trace_mm_page_pcpu_drain(page, 0, page_private(page)); + } while (--count && --batch_free && !list_empty(list)); + } + spin_unlock(&zone->lock); diff --git a/queue-2.6.32/series b/queue-2.6.32/series index 43258a15fe6..54501972a85 100644 --- a/queue-2.6.32/series +++ b/queue-2.6.32/series @@ -14,3 +14,22 @@ acpi-add-platform-wide-_osc-support.patch acpi-fix-osc-regression-that-caused-aer-and-pciehp-not-to-load.patch acpi-advertise-to-bios-in-_osc-_ost-on-_ppc-changes.patch ubi-fix-volume-creation-input-checking.patch +e1000-enhance-frame-fragment-detection.patch +e1000e-enhance-frame-fragment-detection.patch +e1000-e1000e-don-t-use-small-hardware-rx-buffers.patch +drm-i915-reload-hangcheck-timer-too-for-ironlake.patch +drm-i915-add-acpi-opregion-support-for-ironlake.patch +fix-a-leak-in-affs_fill_super.patch +fix-failure-exits-in-bfs_fill_super.patch +fix-oops-in-fs-9p-late-mount-failure.patch +fix-leak-in-romfs_fill_super.patch +fix-remount-races-with-symlink-handling-in-affs.patch +fix-affs-parse_options.patch +fix-failure-exit-in-ipathfs.patch +mm-fix-migratetype-bug-which-slowed-swapping.patch +fdpic-respect-pt_gnu_stack-exec-protection-markings-when-creating-nommu-stack.patch +split-flush_old_exec-into-two-functions.patch +sparc-tif_abi_pending-bit-removal.patch +x86-get-rid-of-the-insane-tif_abi_pending-bit.patch +drm-i915-add-display-hotplug-event-on-ironlake.patch +input-winbond-cir-remove-dmesg-spam.patch diff --git a/queue-2.6.32/sparc-tif_abi_pending-bit-removal.patch b/queue-2.6.32/sparc-tif_abi_pending-bit-removal.patch new file mode 100644 index 00000000000..a3e6dc34a23 --- /dev/null +++ b/queue-2.6.32/sparc-tif_abi_pending-bit-removal.patch @@ -0,0 +1,86 @@ +From 94673e968cbcce07fa78dac4b0ae05d24b5816e1 Mon Sep 17 00:00:00 2001 +From: David Miller +Date: Thu, 28 Jan 2010 21:42:02 -0800 +Subject: sparc: TIF_ABI_PENDING bit removal + +From: David Miller + +commit 94673e968cbcce07fa78dac4b0ae05d24b5816e1 upstream. + +Here are the sparc bits to remove TIF_ABI_PENDING now that +set_personality() is called at the appropriate place in exec. + +Signed-off-by: David S. Miller +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + arch/sparc/include/asm/elf_64.h | 13 +++---------- + arch/sparc/include/asm/thread_info_64.h | 4 +--- + arch/sparc/kernel/process_64.c | 8 -------- + 3 files changed, 4 insertions(+), 21 deletions(-) + +--- a/arch/sparc/include/asm/elf_64.h ++++ b/arch/sparc/include/asm/elf_64.h +@@ -196,17 +196,10 @@ static inline unsigned int sparc64_elf_h + #define ELF_PLATFORM (NULL) + + #define SET_PERSONALITY(ex) \ +-do { unsigned long new_flags = current_thread_info()->flags; \ +- new_flags &= _TIF_32BIT; \ +- if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ +- new_flags |= _TIF_32BIT; \ ++do { if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ ++ set_thread_flag(TIF_32BIT); \ + else \ +- new_flags &= ~_TIF_32BIT; \ +- if ((current_thread_info()->flags & _TIF_32BIT) \ +- != new_flags) \ +- set_thread_flag(TIF_ABI_PENDING); \ +- else \ +- clear_thread_flag(TIF_ABI_PENDING); \ ++ clear_thread_flag(TIF_32BIT); \ + /* flush_thread will update pgd cache */ \ + if (personality(current->personality) != PER_LINUX32) \ + set_personality(PER_LINUX | \ +--- a/arch/sparc/include/asm/thread_info_64.h ++++ b/arch/sparc/include/asm/thread_info_64.h +@@ -227,12 +227,11 @@ register struct thread_info *current_thr + /* flag bit 8 is available */ + #define TIF_SECCOMP 9 /* secure computing */ + #define TIF_SYSCALL_AUDIT 10 /* syscall auditing active */ +-/* flag bit 11 is available */ + /* NOTE: Thread flags >= 12 should be ones we have no interest + * in using in assembly, else we can't use the mask as + * an immediate value in instructions such as andcc. + */ +-#define TIF_ABI_PENDING 12 ++/* flag bit 12 is available */ + #define TIF_MEMDIE 13 + #define TIF_POLLING_NRFLAG 14 + #define TIF_FREEZE 15 /* is freezing for suspend */ +@@ -246,7 +245,6 @@ register struct thread_info *current_thr + #define _TIF_32BIT (1<task->mm; + if (mm) + tsb_context_switch(mm); diff --git a/queue-2.6.32/split-flush_old_exec-into-two-functions.patch b/queue-2.6.32/split-flush_old_exec-into-two-functions.patch new file mode 100644 index 00000000000..8794a49a472 --- /dev/null +++ b/queue-2.6.32/split-flush_old_exec-into-two-functions.patch @@ -0,0 +1,245 @@ +From 221af7f87b97431e3ee21ce4b0e77d5411cf1549 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Thu, 28 Jan 2010 22:14:42 -0800 +Subject: Split 'flush_old_exec' into two functions + +From: Linus Torvalds + +commit 221af7f87b97431e3ee21ce4b0e77d5411cf1549 upstream. + +'flush_old_exec()' is the point of no return when doing an execve(), and +it is pretty badly misnamed. It doesn't just flush the old executable +environment, it also starts up the new one. + +Which is very inconvenient for things like setting up the new +personality, because we want the new personality to affect the starting +of the new environment, but at the same time we do _not_ want the new +personality to take effect if flushing the old one fails. + +As a result, the x86-64 '32-bit' personality is actually done using this +insane "I'm going to change the ABI, but I haven't done it yet" bit +(TIF_ABI_PENDING), with SET_PERSONALITY() not actually setting the +personality, but just the "pending" bit, so that "flush_thread()" can do +the actual personality magic. + +This patch in no way changes any of that insanity, but it does split the +'flush_old_exec()' function up into a preparatory part that can fail +(still called flush_old_exec()), and a new part that will actually set +up the new exec environment (setup_new_exec()). All callers are changed +to trivially comply with the new world order. + +Signed-off-by: H. Peter Anvin +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + arch/sh/kernel/process_64.c | 2 +- + arch/x86/ia32/ia32_aout.c | 10 ++++++---- + fs/binfmt_aout.c | 1 + + fs/binfmt_elf.c | 27 ++------------------------- + fs/binfmt_elf_fdpic.c | 3 +++ + fs/binfmt_flat.c | 1 + + fs/binfmt_som.c | 1 + + fs/exec.c | 26 ++++++++++++++++---------- + include/linux/binfmts.h | 1 + + include/linux/sched.h | 2 +- + 10 files changed, 33 insertions(+), 41 deletions(-) + +--- a/arch/sh/kernel/process_64.c ++++ b/arch/sh/kernel/process_64.c +@@ -367,7 +367,7 @@ void exit_thread(void) + void flush_thread(void) + { + +- /* Called by fs/exec.c (flush_old_exec) to remove traces of a ++ /* Called by fs/exec.c (setup_new_exec) to remove traces of a + * previously running executable. */ + #ifdef CONFIG_SH_FPU + if (last_task_used_math == current) { +--- a/arch/x86/ia32/ia32_aout.c ++++ b/arch/x86/ia32/ia32_aout.c +@@ -308,15 +308,17 @@ static int load_aout_binary(struct linux + if (retval) + return retval; + +- regs->cs = __USER32_CS; +- regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 = +- regs->r13 = regs->r14 = regs->r15 = 0; +- + /* OK, This is the point of no return */ + set_personality(PER_LINUX); + set_thread_flag(TIF_IA32); + clear_thread_flag(TIF_ABI_PENDING); + ++ setup_new_exec(bprm); ++ ++ regs->cs = __USER32_CS; ++ regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 = ++ regs->r13 = regs->r14 = regs->r15 = 0; ++ + current->mm->end_code = ex.a_text + + (current->mm->start_code = N_TXTADDR(ex)); + current->mm->end_data = ex.a_data + +--- a/fs/binfmt_aout.c ++++ b/fs/binfmt_aout.c +@@ -263,6 +263,7 @@ static int load_aout_binary(struct linux + #else + set_personality(PER_LINUX); + #endif ++ setup_new_exec(bprm); + + current->mm->end_code = ex.a_text + + (current->mm->start_code = N_TXTADDR(ex)); +--- a/fs/binfmt_elf.c ++++ b/fs/binfmt_elf.c +@@ -662,27 +662,6 @@ static int load_elf_binary(struct linux_ + if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0') + goto out_free_interp; + +- /* +- * The early SET_PERSONALITY here is so that the lookup +- * for the interpreter happens in the namespace of the +- * to-be-execed image. SET_PERSONALITY can select an +- * alternate root. +- * +- * However, SET_PERSONALITY is NOT allowed to switch +- * this task into the new images's memory mapping +- * policy - that is, TASK_SIZE must still evaluate to +- * that which is appropriate to the execing application. +- * This is because exit_mmap() needs to have TASK_SIZE +- * evaluate to the size of the old image. +- * +- * So if (say) a 64-bit application is execing a 32-bit +- * application it is the architecture's responsibility +- * to defer changing the value of TASK_SIZE until the +- * switch really is going to happen - do this in +- * flush_thread(). - akpm +- */ +- SET_PERSONALITY(loc->elf_ex); +- + interpreter = open_exec(elf_interpreter); + retval = PTR_ERR(interpreter); + if (IS_ERR(interpreter)) +@@ -730,9 +709,6 @@ static int load_elf_binary(struct linux_ + /* Verify the interpreter has a valid arch */ + if (!elf_check_arch(&loc->interp_elf_ex)) + goto out_free_dentry; +- } else { +- /* Executables without an interpreter also need a personality */ +- SET_PERSONALITY(loc->elf_ex); + } + + /* Flush all traces of the currently running executable */ +@@ -752,7 +728,8 @@ static int load_elf_binary(struct linux_ + + if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) + current->flags |= PF_RANDOMIZE; +- arch_pick_mmap_layout(current->mm); ++ ++ setup_new_exec(bprm); + + /* Do this so that we can load the interpreter, if need be. We will + change some of these later */ +--- a/fs/binfmt_elf_fdpic.c ++++ b/fs/binfmt_elf_fdpic.c +@@ -321,6 +321,9 @@ static int load_elf_fdpic_binary(struct + set_personality(PER_LINUX_FDPIC); + if (elf_read_implies_exec(&exec_params.hdr, executable_stack)) + current->personality |= READ_IMPLIES_EXEC; ++ ++ setup_new_exec(bprm); ++ + set_binfmt(&elf_fdpic_format); + + current->mm->start_code = 0; +--- a/fs/binfmt_flat.c ++++ b/fs/binfmt_flat.c +@@ -519,6 +519,7 @@ static int load_flat_file(struct linux_b + + /* OK, This is the point of no return */ + set_personality(PER_LINUX_32BIT); ++ setup_new_exec(bprm); + } + + /* +--- a/fs/binfmt_som.c ++++ b/fs/binfmt_som.c +@@ -227,6 +227,7 @@ load_som_binary(struct linux_binprm * bp + /* OK, This is the point of no return */ + current->flags &= ~PF_FORKNOEXEC; + current->personality = PER_HPUX; ++ setup_new_exec(bprm); + + /* Set the task size for HP-UX processes such that + * the gateway page is outside the address space. +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -931,9 +931,7 @@ void set_task_comm(struct task_struct *t + + int flush_old_exec(struct linux_binprm * bprm) + { +- char * name; +- int i, ch, retval; +- char tcomm[sizeof(current->comm)]; ++ int retval; + + /* + * Make sure we have a private signal table and that +@@ -953,6 +951,20 @@ int flush_old_exec(struct linux_binprm * + goto out; + + bprm->mm = NULL; /* We're using it now */ ++ return 0; ++ ++out: ++ return retval; ++} ++EXPORT_SYMBOL(flush_old_exec); ++ ++void setup_new_exec(struct linux_binprm * bprm) ++{ ++ int i, ch; ++ char * name; ++ char tcomm[sizeof(current->comm)]; ++ ++ arch_pick_mmap_layout(current->mm); + + /* This is the point of no return */ + current->sas_ss_sp = current->sas_ss_size = 0; +@@ -1009,14 +1021,8 @@ int flush_old_exec(struct linux_binprm * + + flush_signal_handlers(current, 0); + flush_old_files(current->files); +- +- return 0; +- +-out: +- return retval; + } +- +-EXPORT_SYMBOL(flush_old_exec); ++EXPORT_SYMBOL(setup_new_exec); + + /* + * Prepare credentials and lock ->cred_guard_mutex. +--- a/include/linux/binfmts.h ++++ b/include/linux/binfmts.h +@@ -101,6 +101,7 @@ extern int prepare_binprm(struct linux_b + extern int __must_check remove_arg_zero(struct linux_binprm *); + extern int search_binary_handler(struct linux_binprm *,struct pt_regs *); + extern int flush_old_exec(struct linux_binprm * bprm); ++extern void setup_new_exec(struct linux_binprm * bprm); + + extern int suid_dumpable; + #define SUID_DUMP_DISABLE 0 /* No setuid dumping */ +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -1354,7 +1354,7 @@ struct task_struct { + char comm[TASK_COMM_LEN]; /* executable name excluding path + - access with [gs]et_task_comm (which lock + it with task_lock()) +- - initialized normally by flush_old_exec */ ++ - initialized normally by setup_new_exec */ + /* file system info */ + int link_count, total_link_count; + #ifdef CONFIG_SYSVIPC diff --git a/queue-2.6.32/x86-get-rid-of-the-insane-tif_abi_pending-bit.patch b/queue-2.6.32/x86-get-rid-of-the-insane-tif_abi_pending-bit.patch new file mode 100644 index 00000000000..bf0a3faca78 --- /dev/null +++ b/queue-2.6.32/x86-get-rid-of-the-insane-tif_abi_pending-bit.patch @@ -0,0 +1,117 @@ +From 05d43ed8a89c159ff641d472f970e3f1baa66318 Mon Sep 17 00:00:00 2001 +From: H. Peter Anvin +Date: Thu, 28 Jan 2010 22:14:43 -0800 +Subject: x86: get rid of the insane TIF_ABI_PENDING bit + +From: H. Peter Anvin + +commit 05d43ed8a89c159ff641d472f970e3f1baa66318 upstream. + +Now that the previous commit made it possible to do the personality +setting at the point of no return, we do just that for ELF binaries. +And suddenly all the reasons for that insane TIF_ABI_PENDING bit go +away, and we can just make SET_PERSONALITY() just do the obvious thing +for a 32-bit compat process. + +Everything becomes much more straightforward this way. + +Signed-off-by: H. Peter Anvin +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/ia32/ia32_aout.c | 1 - + arch/x86/include/asm/elf.h | 10 ++-------- + arch/x86/include/asm/thread_info.h | 2 -- + arch/x86/kernel/process.c | 12 ------------ + arch/x86/kernel/process_64.c | 11 +++++++++++ + 5 files changed, 13 insertions(+), 23 deletions(-) + +--- a/arch/x86/ia32/ia32_aout.c ++++ b/arch/x86/ia32/ia32_aout.c +@@ -311,7 +311,6 @@ static int load_aout_binary(struct linux + /* OK, This is the point of no return */ + set_personality(PER_LINUX); + set_thread_flag(TIF_IA32); +- clear_thread_flag(TIF_ABI_PENDING); + + setup_new_exec(bprm); + +--- a/arch/x86/include/asm/elf.h ++++ b/arch/x86/include/asm/elf.h +@@ -197,14 +197,8 @@ do { \ + set_fs(USER_DS); \ + } while (0) + +-#define COMPAT_SET_PERSONALITY(ex) \ +-do { \ +- if (test_thread_flag(TIF_IA32)) \ +- clear_thread_flag(TIF_ABI_PENDING); \ +- else \ +- set_thread_flag(TIF_ABI_PENDING); \ +- current->personality |= force_personality32; \ +-} while (0) ++void set_personality_ia32(void); ++#define COMPAT_SET_PERSONALITY(ex) set_personality_ia32() + + #define COMPAT_ELF_PLATFORM ("i686") + +--- a/arch/x86/include/asm/thread_info.h ++++ b/arch/x86/include/asm/thread_info.h +@@ -86,7 +86,6 @@ struct thread_info { + #define TIF_NOTSC 16 /* TSC is not accessible in userland */ + #define TIF_IA32 17 /* 32bit process */ + #define TIF_FORK 18 /* ret_from_fork */ +-#define TIF_ABI_PENDING 19 + #define TIF_MEMDIE 20 + #define TIF_DEBUG 21 /* uses debug registers */ + #define TIF_IO_BITMAP 22 /* uses I/O bitmap */ +@@ -110,7 +109,6 @@ struct thread_info { + #define _TIF_NOTSC (1 << TIF_NOTSC) + #define _TIF_IA32 (1 << TIF_IA32) + #define _TIF_FORK (1 << TIF_FORK) +-#define _TIF_ABI_PENDING (1 << TIF_ABI_PENDING) + #define _TIF_DEBUG (1 << TIF_DEBUG) + #define _TIF_IO_BITMAP (1 << TIF_IO_BITMAP) + #define _TIF_FREEZE (1 << TIF_FREEZE) +--- a/arch/x86/kernel/process_64.c ++++ b/arch/x86/kernel/process_64.c +@@ -540,6 +540,17 @@ sys_clone(unsigned long clone_flags, uns + return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); + } + ++void set_personality_ia32(void) ++{ ++ /* inherit personality from parent */ ++ ++ /* Make sure to be in 32bit mode */ ++ set_thread_flag(TIF_IA32); ++ ++ /* Prepare the first "return" to user space */ ++ current_thread_info()->status |= TS_COMPAT; ++} ++ + unsigned long get_wchan(struct task_struct *p) + { + unsigned long stack; +--- a/arch/x86/kernel/process.c ++++ b/arch/x86/kernel/process.c +@@ -91,18 +91,6 @@ void flush_thread(void) + { + struct task_struct *tsk = current; + +-#ifdef CONFIG_X86_64 +- if (test_tsk_thread_flag(tsk, TIF_ABI_PENDING)) { +- clear_tsk_thread_flag(tsk, TIF_ABI_PENDING); +- if (test_tsk_thread_flag(tsk, TIF_IA32)) { +- clear_tsk_thread_flag(tsk, TIF_IA32); +- } else { +- set_tsk_thread_flag(tsk, TIF_IA32); +- current_thread_info()->status |= TS_COMPAT; +- } +- } +-#endif +- + clear_tsk_thread_flag(tsk, TIF_DEBUG); + + tsk->thread.debugreg0 = 0; -- 2.47.3