From: Greg Kroah-Hartman Date: Wed, 28 Jul 2010 00:24:16 +0000 (-0700) Subject: .34 patches X-Git-Tag: v2.6.27.49~32 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a81d4be70b791543e5233befd85b0b5a7b546c79;p=thirdparty%2Fkernel%2Fstable-queue.git .34 patches --- diff --git a/queue-2.6.34/amd64-agp-probe-unknown-agp-devices-the-right-way.patch b/queue-2.6.34/amd64-agp-probe-unknown-agp-devices-the-right-way.patch new file mode 100644 index 00000000000..5399a57841b --- /dev/null +++ b/queue-2.6.34/amd64-agp-probe-unknown-agp-devices-the-right-way.patch @@ -0,0 +1,90 @@ +From 6fd024893911dcb51b4a0aa71971db5ba38f7071 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Wed, 24 Mar 2010 03:36:31 +0000 +Subject: amd64-agp: Probe unknown AGP devices the right way + +From: Ben Hutchings + +commit 6fd024893911dcb51b4a0aa71971db5ba38f7071 upstream. + +The current initialisation code probes 'unsupported' AGP devices +simply by calling its own probe function. It does not lock these +devices or even check whether another driver is already bound to +them. + +We must use the device core to manage this. So if the specific +device id table didn't match anything and agp_try_unsupported=1, +switch the device id table and call driver_attach() again. + +Signed-off-by: Ben Hutchings +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/agp/amd64-agp.c | 27 +++++++++++++++------------ + 1 file changed, 15 insertions(+), 12 deletions(-) + +--- a/drivers/char/agp/amd64-agp.c ++++ b/drivers/char/agp/amd64-agp.c +@@ -499,6 +499,10 @@ static int __devinit agp_amd64_probe(str + u8 cap_ptr; + int err; + ++ /* The Highlander principle */ ++ if (agp_bridges_found) ++ return -ENODEV; ++ + cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); + if (!cap_ptr) + return -ENODEV; +@@ -562,6 +566,8 @@ static void __devexit agp_amd64_remove(s + amd64_aperture_sizes[bridge->aperture_size_idx].size); + agp_remove_bridge(bridge); + agp_put_bridge(bridge); ++ ++ agp_bridges_found--; + } + + #ifdef CONFIG_PM +@@ -709,6 +715,11 @@ static struct pci_device_id agp_amd64_pc + + MODULE_DEVICE_TABLE(pci, agp_amd64_pci_table); + ++static DEFINE_PCI_DEVICE_TABLE(agp_amd64_pci_promisc_table) = { ++ { PCI_DEVICE_CLASS(0, 0) }, ++ { } ++}; ++ + static struct pci_driver agp_amd64_pci_driver = { + .name = "agpgart-amd64", + .id_table = agp_amd64_pci_table, +@@ -734,7 +745,6 @@ int __init agp_amd64_init(void) + return err; + + if (agp_bridges_found == 0) { +- struct pci_dev *dev; + if (!agp_try_unsupported && !agp_try_unsupported_boot) { + printk(KERN_INFO PFX "No supported AGP bridge found.\n"); + #ifdef MODULE +@@ -750,17 +760,10 @@ int __init agp_amd64_init(void) + return -ENODEV; + + /* Look for any AGP bridge */ +- dev = NULL; +- err = -ENODEV; +- for_each_pci_dev(dev) { +- if (!pci_find_capability(dev, PCI_CAP_ID_AGP)) +- continue; +- /* Only one bridge supported right now */ +- if (agp_amd64_probe(dev, NULL) == 0) { +- err = 0; +- break; +- } +- } ++ agp_amd64_pci_driver.id_table = agp_amd64_pci_promisc_table; ++ err = driver_attach(&agp_amd64_pci_driver.driver); ++ if (err == 0 && agp_bridges_found == 0) ++ err = -ENODEV; + } + return err; + } diff --git a/queue-2.6.34/amd64_edac-fix-syndrome-calculation-on-k8.patch b/queue-2.6.34/amd64_edac-fix-syndrome-calculation-on-k8.patch new file mode 100644 index 00000000000..a52cecfdaa4 --- /dev/null +++ b/queue-2.6.34/amd64_edac-fix-syndrome-calculation-on-k8.patch @@ -0,0 +1,60 @@ +From 41c310447fe06bcedc22b75752c18b60e0b9521b Mon Sep 17 00:00:00 2001 +From: Borislav Petkov +Date: Fri, 2 Jul 2010 17:02:43 +0200 +Subject: amd64_edac: Fix syndrome calculation on K8 + +From: Borislav Petkov + +commit 41c310447fe06bcedc22b75752c18b60e0b9521b upstream. + +When calculating the DCT channel from the syndrome we need to know the +syndrome type (x4 vs x8). On F10h, this is read out from extended PCI +cfg space register F3x180 while on K8 we only support x4 syndromes and +don't have extended PCI config space anyway. + +Make the code accessing F3x180 F10h only and fall back to x4 syndromes +on everything else. + +Reported-by: Jeffrey Merkey +Signed-off-by: Borislav Petkov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/edac/amd64_edac.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +--- a/drivers/edac/amd64_edac.c ++++ b/drivers/edac/amd64_edac.c +@@ -1958,20 +1958,20 @@ static int get_channel_from_ecc_syndrome + u32 value = 0; + int err_sym = 0; + +- amd64_read_pci_cfg(pvt->misc_f3_ctl, 0x180, &value); ++ if (boot_cpu_data.x86 == 0x10) { + +- /* F3x180[EccSymbolSize]=1, x8 symbols */ +- if (boot_cpu_data.x86 == 0x10 && +- boot_cpu_data.x86_model > 7 && +- value & BIT(25)) { +- err_sym = decode_syndrome(syndrome, x8_vectors, +- ARRAY_SIZE(x8_vectors), 8); +- return map_err_sym_to_channel(err_sym, 8); +- } else { +- err_sym = decode_syndrome(syndrome, x4_vectors, +- ARRAY_SIZE(x4_vectors), 4); +- return map_err_sym_to_channel(err_sym, 4); ++ amd64_read_pci_cfg(pvt->misc_f3_ctl, 0x180, &value); ++ ++ /* F3x180[EccSymbolSize]=1 => x8 symbols */ ++ if (boot_cpu_data.x86_model > 7 && ++ value & BIT(25)) { ++ err_sym = decode_syndrome(syndrome, x8_vectors, ++ ARRAY_SIZE(x8_vectors), 8); ++ return map_err_sym_to_channel(err_sym, 8); ++ } + } ++ err_sym = decode_syndrome(syndrome, x4_vectors, ARRAY_SIZE(x4_vectors), 4); ++ return map_err_sym_to_channel(err_sym, 4); + } + + /* diff --git a/queue-2.6.34/arm-6205-1-perf-ensure-counter-delta-is-treated-as-unsigned.patch b/queue-2.6.34/arm-6205-1-perf-ensure-counter-delta-is-treated-as-unsigned.patch new file mode 100644 index 00000000000..c627241e09c --- /dev/null +++ b/queue-2.6.34/arm-6205-1-perf-ensure-counter-delta-is-treated-as-unsigned.patch @@ -0,0 +1,50 @@ +From 446a5a8b1eb91a6990e5c8fe29f14e7a95b69132 Mon Sep 17 00:00:00 2001 +From: Will Deacon +Date: Fri, 2 Jul 2010 16:41:52 +0100 +Subject: ARM: 6205/1: perf: ensure counter delta is treated as unsigned + +From: Will Deacon + +commit 446a5a8b1eb91a6990e5c8fe29f14e7a95b69132 upstream. + +Hardware performance counters on ARM are 32-bits wide but atomic64_t +variables are used to represent counter data in the hw_perf_event structure. + +The armpmu_event_update function right-shifts a signed 64-bit delta variable +and adds the result to the event count. This can lead to shifting in sign-bits +if the MSB of the 32-bit counter value is set. This results in perf output +such as: + + Performance counter stats for 'sleep 20': + + 18446744073460670464 cycles <-- 0xFFFFFFFFF12A6000 + 7783773 instructions # 0.000 IPC + 465 context-switches + 161 page-faults + 1172393 branches + + 20.154242147 seconds time elapsed + +This patch ensures that the delta value is treated as unsigned so that the +right shift sets the upper bits to zero. + +Acked-by: Jamie Iles +Signed-off-by: Will Deacon +Signed-off-by: Russell King +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/kernel/perf_event.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/kernel/perf_event.c ++++ b/arch/arm/kernel/perf_event.c +@@ -165,7 +165,7 @@ armpmu_event_update(struct perf_event *e + { + int shift = 64 - 32; + s64 prev_raw_count, new_raw_count; +- s64 delta; ++ u64 delta; + + again: + prev_raw_count = atomic64_read(&hwc->prev_count); diff --git a/queue-2.6.34/cfq-don-t-allow-queue-merges-for-queues-that-have-no-process-references.patch b/queue-2.6.34/cfq-don-t-allow-queue-merges-for-queues-that-have-no-process-references.patch new file mode 100644 index 00000000000..d9083618f47 --- /dev/null +++ b/queue-2.6.34/cfq-don-t-allow-queue-merges-for-queues-that-have-no-process-references.patch @@ -0,0 +1,171 @@ +From c10b61f0910466b4b99c266a7d76ac4390743fb5 Mon Sep 17 00:00:00 2001 +From: Jeff Moyer +Date: Thu, 17 Jun 2010 10:19:11 -0400 +Subject: cfq: Don't allow queue merges for queues that have no process references + +From: Jeff Moyer + +commit c10b61f0910466b4b99c266a7d76ac4390743fb5 upstream. + +Hi, + +A user reported a kernel bug when running a particular program that did +the following: + +created 32 threads +- each thread took a mutex, grabbed a global offset, added a buffer size + to that offset, released the lock +- read from the given offset in the file +- created a new thread to do the same +- exited + +The result is that cfq's close cooperator logic would trigger, as the +threads were issuing I/O within the mean seek distance of one another. +This workload managed to routinely trigger a use after free bug when +walking the list of merge candidates for a particular cfqq +(cfqq->new_cfqq). The logic used for merging queues looks like this: + +static void cfq_setup_merge(struct cfq_queue *cfqq, struct cfq_queue *new_cfqq) +{ + int process_refs, new_process_refs; + struct cfq_queue *__cfqq; + + /* Avoid a circular list and skip interim queue merges */ + while ((__cfqq = new_cfqq->new_cfqq)) { + if (__cfqq == cfqq) + return; + new_cfqq = __cfqq; + } + + process_refs = cfqq_process_refs(cfqq); + /* + * If the process for the cfqq has gone away, there is no + * sense in merging the queues. + */ + if (process_refs == 0) + return; + + /* + * Merge in the direction of the lesser amount of work. + */ + new_process_refs = cfqq_process_refs(new_cfqq); + if (new_process_refs >= process_refs) { + cfqq->new_cfqq = new_cfqq; + atomic_add(process_refs, &new_cfqq->ref); + } else { + new_cfqq->new_cfqq = cfqq; + atomic_add(new_process_refs, &cfqq->ref); + } +} + +When a merge candidate is found, we add the process references for the +queue with less references to the queue with more. The actual merging +of queues happens when a new request is issued for a given cfqq. In the +case of the test program, it only does a single pread call to read in +1MB, so the actual merge never happens. + +Normally, this is fine, as when the queue exits, we simply drop the +references we took on the other cfqqs in the merge chain: + + /* + * If this queue was scheduled to merge with another queue, be + * sure to drop the reference taken on that queue (and others in + * the merge chain). See cfq_setup_merge and cfq_merge_cfqqs. + */ + __cfqq = cfqq->new_cfqq; + while (__cfqq) { + if (__cfqq == cfqq) { + WARN(1, "cfqq->new_cfqq loop detected\n"); + break; + } + next = __cfqq->new_cfqq; + cfq_put_queue(__cfqq); + __cfqq = next; + } + +However, there is a hole in this logic. Consider the following (and +keep in mind that each I/O keeps a reference to the cfqq): + +q1->new_cfqq = q2 // q2 now has 2 process references +q3->new_cfqq = q2 // q2 now has 3 process references + +// the process associated with q2 exits +// q2 now has 2 process references + +// queue 1 exits, drops its reference on q2 +// q2 now has 1 process reference + +// q3 exits, so has 0 process references, and hence drops its references +// to q2, which leaves q2 also with 0 process references + +q4 comes along and wants to merge with q3 + +q3->new_cfqq still points at q2! We follow that link and end up at an +already freed cfqq. + +So, the fix is to not follow a merge chain if the top-most queue does +not have a process reference, otherwise any queue in the chain could be +already freed. I also changed the logic to disallow merging with a +queue that does not have any process references. Previously, we did +this check for one of the merge candidates, but not the other. That +doesn't really make sense. + +Without the attached patch, my system would BUG within a couple of +seconds of running the reproducer program. With the patch applied, my +system ran the program for over an hour without issues. + +This addresses the following bugzilla: + https://bugzilla.kernel.org/show_bug.cgi?id=16217 + +Thanks a ton to Phil Carns for providing the bug report and an excellent +reproducer. + +[ Note for stable: this applies to 2.6.32/33/34 ]. + +Signed-off-by: Jeff Moyer +Reported-by: Phil Carns +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/cfq-iosched.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/block/cfq-iosched.c ++++ b/block/cfq-iosched.c +@@ -1930,6 +1930,15 @@ static void cfq_setup_merge(struct cfq_q + int process_refs, new_process_refs; + struct cfq_queue *__cfqq; + ++ /* ++ * If there are no process references on the new_cfqq, then it is ++ * unsafe to follow the ->new_cfqq chain as other cfqq's in the ++ * chain may have dropped their last reference (not just their ++ * last process reference). ++ */ ++ if (!cfqq_process_refs(new_cfqq)) ++ return; ++ + /* Avoid a circular list and skip interim queue merges */ + while ((__cfqq = new_cfqq->new_cfqq)) { + if (__cfqq == cfqq) +@@ -1938,17 +1947,17 @@ static void cfq_setup_merge(struct cfq_q + } + + process_refs = cfqq_process_refs(cfqq); ++ new_process_refs = cfqq_process_refs(new_cfqq); + /* + * If the process for the cfqq has gone away, there is no + * sense in merging the queues. + */ +- if (process_refs == 0) ++ if (process_refs == 0 || new_process_refs == 0) + return; + + /* + * Merge in the direction of the lesser amount of work. + */ +- new_process_refs = cfqq_process_refs(new_cfqq); + if (new_process_refs >= process_refs) { + cfqq->new_cfqq = new_cfqq; + atomic_add(process_refs, &new_cfqq->ref); diff --git a/queue-2.6.34/genirq-deal-with-desc-set_type-changing-desc-chip.patch b/queue-2.6.34/genirq-deal-with-desc-set_type-changing-desc-chip.patch new file mode 100644 index 00000000000..ffb12ca0c0b --- /dev/null +++ b/queue-2.6.34/genirq-deal-with-desc-set_type-changing-desc-chip.patch @@ -0,0 +1,54 @@ +From 4673247562e39a17e09440fa1400819522ccd446 Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Mon, 7 Jun 2010 17:53:51 +0200 +Subject: genirq: Deal with desc->set_type() changing desc->chip + +From: Thomas Gleixner + +commit 4673247562e39a17e09440fa1400819522ccd446 upstream. + +The set_type() function can change the chip implementation when the +trigger mode changes. That might result in using an non-initialized +irq chip when called from __setup_irq() or when called via +set_irq_type() on an already enabled irq. + +The set_irq_type() function should not be called on an enabled irq, +but because we forgot to put a check into it, we have a bunch of users +which grew the habit of doing that and it never blew up as the +function is serialized via desc->lock against all users of desc->chip +and they never hit the non-initialized irq chip issue. + +The easy fix for the __setup_irq() issue would be to move the +irq_chip_set_defaults(desc->chip) call after the trigger setting to +make sure that a chip change is covered. + +But as we have already users, which do the type setting after +request_irq(), the safe fix for now is to call irq_chip_set_defaults() +from __irq_set_trigger() when desc->set_type() changed the irq chip. + +It needs a deeper analysis whether we should refuse to change the chip +on an already enabled irq, but that'd be a large scale change to fix +all the existing users. So that's neither stable nor 2.6.35 material. + +Reported-by: Esben Haabendal +Signed-off-by: Thomas Gleixner +Cc: Benjamin Herrenschmidt +Cc: linuxppc-dev +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/irq/manage.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/kernel/irq/manage.c ++++ b/kernel/irq/manage.c +@@ -440,6 +440,9 @@ int __irq_set_trigger(struct irq_desc *d + /* note that IRQF_TRIGGER_MASK == IRQ_TYPE_SENSE_MASK */ + desc->status &= ~(IRQ_LEVEL | IRQ_TYPE_SENSE_MASK); + desc->status |= flags; ++ ++ if (chip != desc->chip) ++ irq_chip_set_defaults(desc->chip); + } + + return ret; diff --git a/queue-2.6.34/ipmi-set-schedule_timeout_wait-value-back-to-one.patch b/queue-2.6.34/ipmi-set-schedule_timeout_wait-value-back-to-one.patch new file mode 100644 index 00000000000..fabbc39988e --- /dev/null +++ b/queue-2.6.34/ipmi-set-schedule_timeout_wait-value-back-to-one.patch @@ -0,0 +1,41 @@ +From 8d1f66dc9b4f80a1441bc1c33efa98aca99e8813 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 29 Jun 2010 15:05:31 -0700 +Subject: ipmi: set schedule_timeout_wait() value back to one + +From: Martin Wilck + +commit 8d1f66dc9b4f80a1441bc1c33efa98aca99e8813 upstream. + +Fix a regression introduced by ae74e823cb7d ("ipmi: add parameter to limit +CPU usage in kipmid"). + +Some systems were seeing CPU usage go up dramatically with the recent +changes to try to reduce timer usage in the IPMI driver. This was traced +down to schedule_timeout_interruptible(1) being changed to +schedule_timeout_interruptbile(0). Revert that part of the change. + +Addresses https://bugzilla.kernel.org/show_bug.cgi?id=16147 + +Reported-by: Thomas Jarosch +Signed-off-by: Corey Minyard +Tested-by: Thomas Jarosch +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/ipmi/ipmi_si_intf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/char/ipmi/ipmi_si_intf.c ++++ b/drivers/char/ipmi/ipmi_si_intf.c +@@ -1003,7 +1003,7 @@ static int ipmi_thread(void *data) + else if (smi_result == SI_SM_CALL_WITH_DELAY && busy_wait) + schedule(); + else +- schedule_timeout_interruptible(0); ++ schedule_timeout_interruptible(1); + } + return 0; + } diff --git a/queue-2.6.34/ipv6-fix-null-reference-in-proxy-neighbor-discovery.patch b/queue-2.6.34/ipv6-fix-null-reference-in-proxy-neighbor-discovery.patch new file mode 100644 index 00000000000..25bb3402d43 --- /dev/null +++ b/queue-2.6.34/ipv6-fix-null-reference-in-proxy-neighbor-discovery.patch @@ -0,0 +1,48 @@ +From 9f888160bdcccf0565dd2774956b8d9456e610be Mon Sep 17 00:00:00 2001 +From: stephen hemminger +Date: Mon, 21 Jun 2010 11:00:13 +0000 +Subject: ipv6: fix NULL reference in proxy neighbor discovery + +From: stephen hemminger + +commit 9f888160bdcccf0565dd2774956b8d9456e610be upstream. + +The addition of TLLAO option created a kernel OOPS regression +for the case where neighbor advertisement is being sent via +proxy path. When using proxy, ipv6_get_ifaddr() returns NULL +causing the NULL dereference. + +Change causing the bug was: +commit f7734fdf61ec6bb848e0bafc1fb8bad2c124bb50 +Author: Octavian Purdila +Date: Fri Oct 2 11:39:15 2009 +0000 + + make TLLAO option for NA packets configurable + +Signed-off-by: Stephen Hemminger +Acked-by: YOSHIFUJI Hideaki +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv6/ndisc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv6/ndisc.c ++++ b/net/ipv6/ndisc.c +@@ -586,6 +586,7 @@ static void ndisc_send_na(struct net_dev + src_addr = solicited_addr; + if (ifp->flags & IFA_F_OPTIMISTIC) + override = 0; ++ inc_opt |= ifp->idev->cnf.force_tllao; + in6_ifa_put(ifp); + } else { + if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr, +@@ -599,7 +600,6 @@ static void ndisc_send_na(struct net_dev + icmp6h.icmp6_solicited = solicited; + icmp6h.icmp6_override = override; + +- inc_opt |= ifp->idev->cnf.force_tllao; + __ndisc_send(dev, neigh, daddr, src_addr, + &icmp6h, solicited_addr, + inc_opt ? ND_OPT_TARGET_LL_ADDR : 0); diff --git a/queue-2.6.34/ipv6-keep-route-for-tentative-address.patch b/queue-2.6.34/ipv6-keep-route-for-tentative-address.patch new file mode 100644 index 00000000000..abf81344f08 --- /dev/null +++ b/queue-2.6.34/ipv6-keep-route-for-tentative-address.patch @@ -0,0 +1,37 @@ +From shemminger@vyatta.com Tue Jul 27 16:56:59 2010 +From: Stephen Hemminger +Date: Mon, 24 May 2010 11:31:18 -0700 +Subject: IPv6: keep route for tentative address +To: Emil S Tantilov +Cc: NetDev , stable@kernel.org, Greg KH , "David S. Miller" , "Tantilov, Emil S" +Message-ID: <20100524113118.47cc9852@nehalam> + +From: Stephen Hemminger + +(cherry picked from commit 93fa159abe50d3c55c7f83622d3f5c09b6e06f4b) + +Recent changes preserve IPv6 address when link goes down (good). +But would cause address to point to dead dst entry (bad). +The simplest fix is to just not delete route if address is +being held for later use. + +Signed-off-by: Stephen Hemminger +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv6/addrconf.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -4047,7 +4047,8 @@ static void __ipv6_ifa_notify(int event, + addrconf_leave_anycast(ifp); + addrconf_leave_solict(ifp->idev, &ifp->addr); + dst_hold(&ifp->rt->u.dst); +- if (ip6_del_rt(ifp->rt)) ++ ++ if (ifp->dead && ip6_del_rt(ifp->rt)) + dst_free(&ifp->rt->u.dst); + break; + } diff --git a/queue-2.6.34/ipv6-only-notify-protocols-if-address-is-completely-gone.patch b/queue-2.6.34/ipv6-only-notify-protocols-if-address-is-completely-gone.patch new file mode 100644 index 00000000000..24c59a2a599 --- /dev/null +++ b/queue-2.6.34/ipv6-only-notify-protocols-if-address-is-completely-gone.patch @@ -0,0 +1,38 @@ +From shemminger@vyatta.com Tue Jul 27 16:57:29 2010 +From: Stephen Hemminger +Date: Mon, 24 May 2010 11:33:00 -0700 +Subject: IPv6: only notify protocols if address is completely gone +To: Emil S Tantilov , "David S. Miller" , Greg KH +Cc: NetDev , "Tantilov, Emil S" , stable@kernel.org +Message-ID: <20100524113300.2ef38e12@nehalam> + +From: Stephen Hemminger + +(cherry picked from commit 8595805aafc8b077e01804c9a3668e9aa3510e89) + +The notifier for address down should only be called if address is completely +gone, not just being marked as tentative on link transition. The code +in net-next would case bonding/sctp/s390 to see address disappear on link +down, but they would never see it reappear on link up. + +Signed-off-by: Stephen Hemminger +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv6/addrconf.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -2729,7 +2729,9 @@ static int addrconf_ifdown(struct net_de + write_unlock_bh(&idev->lock); + + __ipv6_ifa_notify(RTM_DELADDR, ifa); +- atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa); ++ if (ifa->dead) ++ atomic_notifier_call_chain(&inet6addr_chain, ++ NETDEV_DOWN, ifa); + in6_ifa_put(ifa); + + write_lock_bh(&idev->lock); diff --git a/queue-2.6.34/ipvs-add-missing-locking-during-connection-table-hashing-and-unhashing.patch b/queue-2.6.34/ipvs-add-missing-locking-during-connection-table-hashing-and-unhashing.patch new file mode 100644 index 00000000000..518909d710f --- /dev/null +++ b/queue-2.6.34/ipvs-add-missing-locking-during-connection-table-hashing-and-unhashing.patch @@ -0,0 +1,126 @@ +From aea9d711f3d68c656ad31ab578ecfb0bb5cd7f97 Mon Sep 17 00:00:00 2001 +From: Sven Wegener +Date: Wed, 9 Jun 2010 16:10:57 +0200 +Subject: ipvs: Add missing locking during connection table hashing and unhashing + +From: Sven Wegener + +commit aea9d711f3d68c656ad31ab578ecfb0bb5cd7f97 upstream. + +The code that hashes and unhashes connections from the connection table +is missing locking of the connection being modified, which opens up a +race condition and results in memory corruption when this race condition +is hit. + +Here is what happens in pretty verbose form: + +CPU 0 CPU 1 +------------ ------------ +An active connection is terminated and +we schedule ip_vs_conn_expire() on this +CPU to expire this connection. + + IRQ assignment is changed to this CPU, + but the expire timer stays scheduled on + the other CPU. + + New connection from same ip:port comes + in right before the timer expires, we + find the inactive connection in our + connection table and get a reference to + it. We proper lock the connection in + tcp_state_transition() and read the + connection flags in set_tcp_state(). + +ip_vs_conn_expire() gets called, we +unhash the connection from our +connection table and remove the hashed +flag in ip_vs_conn_unhash(), without +proper locking! + + While still holding proper locks we + write the connection flags in + set_tcp_state() and this sets the hashed + flag again. + +ip_vs_conn_expire() fails to expire the +connection, because the other CPU has +incremented the reference count. We try +to re-insert the connection into our +connection table, but this fails in +ip_vs_conn_hash(), because the hashed +flag has been set by the other CPU. We +re-schedule execution of +ip_vs_conn_expire(). Now this connection +has the hashed flag set, but isn't +actually hashed in our connection table +and has a dangling list_head. + + We drop the reference we held on the + connection and schedule the expire timer + for timeouting the connection on this + CPU. Further packets won't be able to + find this connection in our connection + table. + + ip_vs_conn_expire() gets called again, + we think it's already hashed, but the + list_head is dangling and while removing + the connection from our connection table + we write to the memory location where + this list_head points to. + +The result will probably be a kernel oops at some other point in time. + +This race condition is pretty subtle, but it can be triggered remotely. +It needs the IRQ assignment change or another circumstance where packets +coming from the same ip:port for the same service are being processed on +different CPUs. And it involves hitting the exact time at which +ip_vs_conn_expire() gets called. It can be avoided by making sure that +all packets from one connection are always processed on the same CPU and +can be made harder to exploit by changing the connection timeouts to +some custom values. + +Signed-off-by: Sven Wegener +Acked-by: Simon Horman +Signed-off-by: Patrick McHardy +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/ipvs/ip_vs_conn.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/netfilter/ipvs/ip_vs_conn.c ++++ b/net/netfilter/ipvs/ip_vs_conn.c +@@ -162,6 +162,7 @@ static inline int ip_vs_conn_hash(struct + hash = ip_vs_conn_hashkey(cp->af, cp->protocol, &cp->caddr, cp->cport); + + ct_write_lock(hash); ++ spin_lock(&cp->lock); + + if (!(cp->flags & IP_VS_CONN_F_HASHED)) { + list_add(&cp->c_list, &ip_vs_conn_tab[hash]); +@@ -174,6 +175,7 @@ static inline int ip_vs_conn_hash(struct + ret = 0; + } + ++ spin_unlock(&cp->lock); + ct_write_unlock(hash); + + return ret; +@@ -193,6 +195,7 @@ static inline int ip_vs_conn_unhash(stru + hash = ip_vs_conn_hashkey(cp->af, cp->protocol, &cp->caddr, cp->cport); + + ct_write_lock(hash); ++ spin_lock(&cp->lock); + + if (cp->flags & IP_VS_CONN_F_HASHED) { + list_del(&cp->c_list); +@@ -202,6 +205,7 @@ static inline int ip_vs_conn_unhash(stru + } else + ret = 0; + ++ spin_unlock(&cp->lock); + ct_write_unlock(hash); + + return ret; diff --git a/queue-2.6.34/md-raid10-fix-null-pointer-dereference-in-fix_read_error.patch b/queue-2.6.34/md-raid10-fix-null-pointer-dereference-in-fix_read_error.patch new file mode 100644 index 00000000000..f998b9ebbe1 --- /dev/null +++ b/queue-2.6.34/md-raid10-fix-null-pointer-dereference-in-fix_read_error.patch @@ -0,0 +1,70 @@ +From 0544a21db02c1d8883158fd6f323364f830a120a Mon Sep 17 00:00:00 2001 +From: Prasanna S. Panchamukhi +Date: Thu, 24 Jun 2010 13:31:03 +1000 +Subject: md: raid10: Fix null pointer dereference in fix_read_error() + +From: Prasanna S. Panchamukhi + +commit 0544a21db02c1d8883158fd6f323364f830a120a upstream. + +Such NULL pointer dereference can occur when the driver was fixing the +read errors/bad blocks and the disk was physically removed +causing a system crash. This patch check if the +rcu_dereference() returns valid rdev before accessing it in fix_read_error(). + +Signed-off-by: Prasanna S. Panchamukhi +Signed-off-by: Rob Becker +Signed-off-by: NeilBrown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/raid10.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -1487,14 +1487,14 @@ static void fix_read_error(conf_t *conf, + int sectors = r10_bio->sectors; + mdk_rdev_t*rdev; + int max_read_errors = atomic_read(&mddev->max_corr_read_errors); ++ int d = r10_bio->devs[r10_bio->read_slot].devnum; + + rcu_read_lock(); +- { +- int d = r10_bio->devs[r10_bio->read_slot].devnum; ++ rdev = rcu_dereference(conf->mirrors[d].rdev); ++ if (rdev) { /* If rdev is not NULL */ + char b[BDEVNAME_SIZE]; + int cur_read_error_count = 0; + +- rdev = rcu_dereference(conf->mirrors[d].rdev); + bdevname(rdev->bdev, b); + + if (test_bit(Faulty, &rdev->flags)) { +@@ -1534,7 +1534,7 @@ static void fix_read_error(conf_t *conf, + + rcu_read_lock(); + do { +- int d = r10_bio->devs[sl].devnum; ++ d = r10_bio->devs[sl].devnum; + rdev = rcu_dereference(conf->mirrors[d].rdev); + if (rdev && + test_bit(In_sync, &rdev->flags)) { +@@ -1568,7 +1568,7 @@ static void fix_read_error(conf_t *conf, + rcu_read_lock(); + while (sl != r10_bio->read_slot) { + char b[BDEVNAME_SIZE]; +- int d; ++ + if (sl==0) + sl = conf->copies; + sl--; +@@ -1604,7 +1604,7 @@ static void fix_read_error(conf_t *conf, + } + sl = start; + while (sl != r10_bio->read_slot) { +- int d; ++ + if (sl==0) + sl = conf->copies; + sl--; diff --git a/queue-2.6.34/netfilter-ip6t_reject-fix-a-dst-leak-in-ipv6-reject.patch b/queue-2.6.34/netfilter-ip6t_reject-fix-a-dst-leak-in-ipv6-reject.patch new file mode 100644 index 00000000000..9366a35b9b6 --- /dev/null +++ b/queue-2.6.34/netfilter-ip6t_reject-fix-a-dst-leak-in-ipv6-reject.patch @@ -0,0 +1,38 @@ +From 499031ac8a3df6738f6186ded9da853e8ea18253 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 2 Jul 2010 10:05:01 +0200 +Subject: netfilter: ip6t_REJECT: fix a dst leak in ipv6 REJECT + +From: Eric Dumazet + +commit 499031ac8a3df6738f6186ded9da853e8ea18253 upstream. + +We should release dst if dst->error is set. + +Bug introduced in 2.6.14 by commit e104411b82f5c +([XFRM]: Always release dst_entry on error in xfrm_lookup) + +Signed-off-by: Eric Dumazet +Signed-off-by: Patrick McHardy +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv6/netfilter/ip6t_REJECT.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/net/ipv6/netfilter/ip6t_REJECT.c ++++ b/net/ipv6/netfilter/ip6t_REJECT.c +@@ -96,9 +96,11 @@ static void send_reset(struct net *net, + fl.fl_ip_dport = otcph.source; + security_skb_classify_flow(oldskb, &fl); + dst = ip6_route_output(net, NULL, &fl); +- if (dst == NULL) ++ if (dst == NULL || dst->error) { ++ dst_release(dst); + return; +- if (dst->error || xfrm_lookup(net, &dst, &fl, NULL, 0)) ++ } ++ if (xfrm_lookup(net, &dst, &fl, NULL, 0)) + return; + + hh_len = (dst->dev->hard_header_len + 15)&~15; diff --git a/queue-2.6.34/perf-resurrect-flat-callchains.patch b/queue-2.6.34/perf-resurrect-flat-callchains.patch new file mode 100644 index 00000000000..3b4a8cc4326 --- /dev/null +++ b/queue-2.6.34/perf-resurrect-flat-callchains.patch @@ -0,0 +1,45 @@ +From 97aa1052739c6a06cb6b0467dbf410613d20bc97 Mon Sep 17 00:00:00 2001 +From: Frederic Weisbecker +Date: Thu, 8 Jul 2010 06:06:17 +0200 +Subject: perf: Resurrect flat callchains + +From: Frederic Weisbecker + +commit 97aa1052739c6a06cb6b0467dbf410613d20bc97 upstream. + +Initialize the callchain radix tree root correctly. + +When we walk through the parents, we must stop after the root, but +since it wasn't well initialized, its parent pointer was random. + +Also the number of hits was random because uninitialized, hence it +was part of the callchain while the root doesn't contain anything. + +This fixes segfaults and percentages followed by empty callchains +while running: + + perf report -g flat + +Reported-by: Ingo Molnar +Signed-off-by: Frederic Weisbecker +Cc: Peter Zijlstra +Cc: Arnaldo Carvalho de Melo +Cc: Paul Mackerras +Signed-off-by: Greg Kroah-Hartman + +--- + tools/perf/util/callchain.h | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/tools/perf/util/callchain.h ++++ b/tools/perf/util/callchain.h +@@ -48,6 +48,9 @@ static inline void callchain_init(struct + INIT_LIST_HEAD(&node->brothers); + INIT_LIST_HEAD(&node->children); + INIT_LIST_HEAD(&node->val); ++ ++ node->parent = NULL; ++ node->hit = 0; + } + + static inline u64 cumul_hits(struct callchain_node *node) diff --git a/queue-2.6.34/perf-x86-fix-incorrect-branches-event-on-amd-cpus.patch b/queue-2.6.34/perf-x86-fix-incorrect-branches-event-on-amd-cpus.patch new file mode 100644 index 00000000000..fd54538263b --- /dev/null +++ b/queue-2.6.34/perf-x86-fix-incorrect-branches-event-on-amd-cpus.patch @@ -0,0 +1,43 @@ +From f287d332ce835f77a4f5077d2c0ef1e3f9ea42d2 Mon Sep 17 00:00:00 2001 +From: Vince Weaver +Date: Thu, 1 Jul 2010 15:30:16 -0400 +Subject: perf, x86: Fix incorrect branches event on AMD CPUs + +From: Vince Weaver + +commit f287d332ce835f77a4f5077d2c0ef1e3f9ea42d2 upstream. + +While doing some performance counter validation tests on some +assembly language programs I noticed that the "branches:u" +count was very wrong on AMD machines. + +It looks like the wrong event was selected. + +Signed-off-by: Vince Weaver +Acked-by: Peter Zijlstra +Cc: Paul Mackerras +Cc: Arnaldo Carvalho de Melo +Cc: Robert Richter +Cc: Borislav Petkov +Cc: Frederic Weisbecker +LKML-Reference: +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/cpu/perf_event_amd.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/x86/kernel/cpu/perf_event_amd.c ++++ b/arch/x86/kernel/cpu/perf_event_amd.c +@@ -102,8 +102,8 @@ static const u64 amd_perfmon_event_map[] + [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, + [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0080, + [PERF_COUNT_HW_CACHE_MISSES] = 0x0081, +- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4, +- [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5, ++ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2, ++ [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3, + }; + + static u64 amd_pmu_event_map(int hw_event) diff --git a/queue-2.6.34/sched-fix-over-scheduling-bug.patch b/queue-2.6.34/sched-fix-over-scheduling-bug.patch new file mode 100644 index 00000000000..7939d68ffa4 --- /dev/null +++ b/queue-2.6.34/sched-fix-over-scheduling-bug.patch @@ -0,0 +1,64 @@ +From 3c93717cfa51316e4dbb471e7c0f9d243359d5f8 Mon Sep 17 00:00:00 2001 +From: Alex,Shi +Date: Thu, 17 Jun 2010 14:08:13 +0800 +Subject: sched: Fix over-scheduling bug + +From: Alex,Shi + +commit 3c93717cfa51316e4dbb471e7c0f9d243359d5f8 upstream. + +Commit e70971591 ("sched: Optimize unused cgroup configuration") introduced +an imbalanced scheduling bug. + +If we do not use CGROUP, function update_h_load won't update h_load. When the +system has a large number of tasks far more than logical CPU number, the +incorrect cfs_rq[cpu]->h_load value will cause load_balance() to pull too +many tasks to the local CPU from the busiest CPU. So the busiest CPU keeps +going in a round robin. That will hurt performance. + +The issue was found originally by a scientific calculation workload that +developed by Yanmin. With that commit, the workload performance drops +about 40%. + + CPU before after + + 00 : 2 : 7 + 01 : 1 : 7 + 02 : 11 : 6 + 03 : 12 : 7 + 04 : 6 : 6 + 05 : 11 : 7 + 06 : 10 : 6 + 07 : 12 : 7 + 08 : 11 : 6 + 09 : 12 : 6 + 10 : 1 : 6 + 11 : 1 : 6 + 12 : 6 : 6 + 13 : 2 : 6 + 14 : 2 : 6 + 15 : 1 : 6 + +Reviewed-by: Yanmin zhang +Signed-off-by: Alex Shi +Signed-off-by: Peter Zijlstra +LKML-Reference: <1276754893.9452.5442.camel@debian> +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/sched.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/kernel/sched.c ++++ b/kernel/sched.c +@@ -1675,9 +1675,6 @@ static void update_shares(struct sched_d + + static void update_h_load(long cpu) + { +- if (root_task_group_empty()) +- return; +- + walk_tg_tree(tg_load_down, tg_nop, (void *)cpu); + } + diff --git a/queue-2.6.34/sched-prevent-compiler-from-optimising-the-sched_avg_update-loop.patch b/queue-2.6.34/sched-prevent-compiler-from-optimising-the-sched_avg_update-loop.patch new file mode 100644 index 00000000000..cb73370be11 --- /dev/null +++ b/queue-2.6.34/sched-prevent-compiler-from-optimising-the-sched_avg_update-loop.patch @@ -0,0 +1,49 @@ +From 0d98bb2656e9bd2dfda2d089db1fe1dbdab41504 Mon Sep 17 00:00:00 2001 +From: Will Deacon +Date: Mon, 24 May 2010 12:11:43 -0700 +Subject: sched: Prevent compiler from optimising the sched_avg_update() loop + +From: Will Deacon + +commit 0d98bb2656e9bd2dfda2d089db1fe1dbdab41504 upstream. + +GCC 4.4.1 on ARM has been observed to replace the while loop in +sched_avg_update with a call to uldivmod, resulting in the +following build failure at link-time: + +kernel/built-in.o: In function `sched_avg_update': + kernel/sched.c:1261: undefined reference to `__aeabi_uldivmod' + kernel/sched.c:1261: undefined reference to `__aeabi_uldivmod' +make: *** [.tmp_vmlinux1] Error 1 + +This patch introduces a fake data hazard to the loop body to +prevent the compiler optimising the loop away. + +Signed-off-by: Will Deacon +Signed-off-by: Andrew Morton +Acked-by: Peter Zijlstra +Cc: Catalin Marinas +Cc: Russell King +Cc: Linus Torvalds +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/sched.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/kernel/sched.c ++++ b/kernel/sched.c +@@ -1251,6 +1251,12 @@ static void sched_avg_update(struct rq * + s64 period = sched_avg_period(); + + while ((s64)(rq->clock - rq->age_stamp) > period) { ++ /* ++ * Inline assembly required to prevent the compiler ++ * optimising this loop into a divmod call. ++ * See __iter_div_u64_rem() for another example of this. ++ */ ++ asm("" : "+rm" (rq->age_stamp)); + rq->age_stamp += period; + rq->rt_avg /= 2; + } diff --git a/queue-2.6.34/scsi-aacraid-eliminate-use-after-free.patch b/queue-2.6.34/scsi-aacraid-eliminate-use-after-free.patch new file mode 100644 index 00000000000..2d7acbb7415 --- /dev/null +++ b/queue-2.6.34/scsi-aacraid-eliminate-use-after-free.patch @@ -0,0 +1,56 @@ +From 8a52da632ceb9d8b776494563df579e87b7b586b Mon Sep 17 00:00:00 2001 +From: Julia Lawall +Date: Sat, 15 May 2010 11:46:12 +0200 +Subject: SCSI: aacraid: Eliminate use after free + +From: Julia Lawall + +commit 8a52da632ceb9d8b776494563df579e87b7b586b upstream. + +The debugging code using the freed structure is moved before the kfree. + +A simplified version of the semantic match that finds this problem is as +follows: (http://coccinelle.lip6.fr/) + +// +@free@ +expression E; +position p; +@@ +kfree@p(E) + +@@ +expression free.E, subE<=free.E, E1; +position free.p; +@@ + + kfree@p(E) + ... +( + subE = E1 +| +* E +) +// + +Signed-off-by: Julia Lawall +Signed-off-by: James Bottomley + +--- + drivers/scsi/aacraid/commctrl.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/aacraid/commctrl.c ++++ b/drivers/scsi/aacraid/commctrl.c +@@ -655,9 +655,9 @@ static int aac_send_raw_srb(struct aac_d + /* Does this really need to be GFP_DMA? */ + p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); + if(!p) { +- kfree (usg); +- dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", ++ dprintk((KERN_DEBUG "aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", + usg->sg[i].count,i,usg->count)); ++ kfree(usg); + rcode = -ENOMEM; + goto cleanup; + } diff --git a/queue-2.6.34/serial-cpm_uart-implement-the-cpm_uart_early_write-function-for-console-poll.patch b/queue-2.6.34/serial-cpm_uart-implement-the-cpm_uart_early_write-function-for-console-poll.patch new file mode 100644 index 00000000000..117fd3ee5ea --- /dev/null +++ b/queue-2.6.34/serial-cpm_uart-implement-the-cpm_uart_early_write-function-for-console-poll.patch @@ -0,0 +1,196 @@ +From 8cd774ad30c22b9d89823f1f05d845f4cdaba9e8 Mon Sep 17 00:00:00 2001 +From: Dongdong Deng +Date: Thu, 17 Jun 2010 11:13:40 +0800 +Subject: serial: cpm_uart: implement the cpm_uart_early_write() function for console poll + +From: Dongdong Deng + +commit 8cd774ad30c22b9d89823f1f05d845f4cdaba9e8 upstream. + +The cpm_uart_early_write() function which was used for console poll +isn't implemented in the cpm uart driver. + +Implementing this function both fixes the build when CONFIG_CONSOLE_POLL +is set and allows kgdboc to work via the cpm uart. + +Signed-off-by: Dongdong Deng +Reviewed-by: Bruce Ashfield +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/serial/cpm_uart/cpm_uart_core.c | 143 +++++++++++++++++--------------- + 1 file changed, 79 insertions(+), 64 deletions(-) + +--- a/drivers/serial/cpm_uart/cpm_uart_core.c ++++ b/drivers/serial/cpm_uart/cpm_uart_core.c +@@ -930,6 +930,83 @@ static void cpm_uart_config_port(struct + } + } + ++#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_CPM_CONSOLE) ++/* ++ * Write a string to the serial port ++ * Note that this is called with interrupts already disabled ++ */ ++static void cpm_uart_early_write(struct uart_cpm_port *pinfo, ++ const char *string, u_int count) ++{ ++ unsigned int i; ++ cbd_t __iomem *bdp, *bdbase; ++ unsigned char *cpm_outp_addr; ++ ++ /* Get the address of the host memory buffer. ++ */ ++ bdp = pinfo->tx_cur; ++ bdbase = pinfo->tx_bd_base; ++ ++ /* ++ * Now, do each character. This is not as bad as it looks ++ * since this is a holding FIFO and not a transmitting FIFO. ++ * We could add the complexity of filling the entire transmit ++ * buffer, but we would just wait longer between accesses...... ++ */ ++ for (i = 0; i < count; i++, string++) { ++ /* Wait for transmitter fifo to empty. ++ * Ready indicates output is ready, and xmt is doing ++ * that, not that it is ready for us to send. ++ */ ++ while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) ++ ; ++ ++ /* Send the character out. ++ * If the buffer address is in the CPM DPRAM, don't ++ * convert it. ++ */ ++ cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), ++ pinfo); ++ *cpm_outp_addr = *string; ++ ++ out_be16(&bdp->cbd_datlen, 1); ++ setbits16(&bdp->cbd_sc, BD_SC_READY); ++ ++ if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) ++ bdp = bdbase; ++ else ++ bdp++; ++ ++ /* if a LF, also do CR... */ ++ if (*string == 10) { ++ while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) ++ ; ++ ++ cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), ++ pinfo); ++ *cpm_outp_addr = 13; ++ ++ out_be16(&bdp->cbd_datlen, 1); ++ setbits16(&bdp->cbd_sc, BD_SC_READY); ++ ++ if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) ++ bdp = bdbase; ++ else ++ bdp++; ++ } ++ } ++ ++ /* ++ * Finally, Wait for transmitter & holding register to empty ++ * and restore the IER ++ */ ++ while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) ++ ; ++ ++ pinfo->tx_cur = bdp; ++} ++#endif ++ + #ifdef CONFIG_CONSOLE_POLL + /* Serial polling routines for writing and reading from the uart while + * in an interrupt or debug context. +@@ -999,7 +1076,7 @@ static void cpm_put_poll_char(struct uar + static char ch[2]; + + ch[0] = (char)c; +- cpm_uart_early_write(pinfo->port.line, ch, 1); ++ cpm_uart_early_write(pinfo, ch, 1); + } + #endif /* CONFIG_CONSOLE_POLL */ + +@@ -1130,9 +1207,6 @@ static void cpm_uart_console_write(struc + u_int count) + { + struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; +- unsigned int i; +- cbd_t __iomem *bdp, *bdbase; +- unsigned char *cp; + unsigned long flags; + int nolock = oops_in_progress; + +@@ -1142,66 +1216,7 @@ static void cpm_uart_console_write(struc + spin_lock_irqsave(&pinfo->port.lock, flags); + } + +- /* Get the address of the host memory buffer. +- */ +- bdp = pinfo->tx_cur; +- bdbase = pinfo->tx_bd_base; +- +- /* +- * Now, do each character. This is not as bad as it looks +- * since this is a holding FIFO and not a transmitting FIFO. +- * We could add the complexity of filling the entire transmit +- * buffer, but we would just wait longer between accesses...... +- */ +- for (i = 0; i < count; i++, s++) { +- /* Wait for transmitter fifo to empty. +- * Ready indicates output is ready, and xmt is doing +- * that, not that it is ready for us to send. +- */ +- while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) +- ; +- +- /* Send the character out. +- * If the buffer address is in the CPM DPRAM, don't +- * convert it. +- */ +- cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); +- *cp = *s; +- +- out_be16(&bdp->cbd_datlen, 1); +- setbits16(&bdp->cbd_sc, BD_SC_READY); +- +- if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) +- bdp = bdbase; +- else +- bdp++; +- +- /* if a LF, also do CR... */ +- if (*s == 10) { +- while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) +- ; +- +- cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); +- *cp = 13; +- +- out_be16(&bdp->cbd_datlen, 1); +- setbits16(&bdp->cbd_sc, BD_SC_READY); +- +- if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) +- bdp = bdbase; +- else +- bdp++; +- } +- } +- +- /* +- * Finally, Wait for transmitter & holding register to empty +- * and restore the IER +- */ +- while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) +- ; +- +- pinfo->tx_cur = bdp; ++ cpm_uart_early_write(pinfo, s, count); + + if (unlikely(nolock)) { + local_irq_restore(flags); diff --git a/queue-2.6.34/series b/queue-2.6.34/series index a018e03916f..29b1154d2d1 100644 --- a/queue-2.6.34/series +++ b/queue-2.6.34/series @@ -68,3 +68,27 @@ drm-radeon-kms-fix-possible-mis-detection-of-sideport-on-rs690-rs740.patch drm-radeon-kms-fix-legacy-lvds-dpms-sequence.patch drm-radeon-kms-fix-legacy-tv-out-pal-mode.patch tpm_tis-fix-subsequent-suspend-failures.patch +ipv6-keep-route-for-tentative-address.patch +ipv6-only-notify-protocols-if-address-is-completely-gone.patch +ipvs-add-missing-locking-during-connection-table-hashing-and-unhashing.patch +ipv6-fix-null-reference-in-proxy-neighbor-discovery.patch +netfilter-ip6t_reject-fix-a-dst-leak-in-ipv6-reject.patch +scsi-aacraid-eliminate-use-after-free.patch +md-raid10-fix-null-pointer-dereference-in-fix_read_error.patch +amd64-agp-probe-unknown-agp-devices-the-right-way.patch +amd64_edac-fix-syndrome-calculation-on-k8.patch +perf-x86-fix-incorrect-branches-event-on-amd-cpus.patch +arm-6205-1-perf-ensure-counter-delta-is-treated-as-unsigned.patch +perf-resurrect-flat-callchains.patch +x86-send-a-sigtrap-for-user-icebp-traps.patch +x86-fix-vsyscall-on-gcc-4.5-with-os.patch +x86-calgary-increase-max-phb-number.patch +x86-calgary-limit-the-max-phb-number-to-256.patch +sched-prevent-compiler-from-optimising-the-sched_avg_update-loop.patch +ipmi-set-schedule_timeout_wait-value-back-to-one.patch +sched-fix-over-scheduling-bug.patch +genirq-deal-with-desc-set_type-changing-desc-chip.patch +cfq-don-t-allow-queue-merges-for-queues-that-have-no-process-references.patch +sysvfs-fix-null-deref.-when-allocating-new-inode.patch +serial-cpm_uart-implement-the-cpm_uart_early_write-function-for-console-poll.patch +um-os-linux-mem.c-needs-sys-stat.h.patch diff --git a/queue-2.6.34/sysvfs-fix-null-deref.-when-allocating-new-inode.patch b/queue-2.6.34/sysvfs-fix-null-deref.-when-allocating-new-inode.patch new file mode 100644 index 00000000000..a5e611f3787 --- /dev/null +++ b/queue-2.6.34/sysvfs-fix-null-deref.-when-allocating-new-inode.patch @@ -0,0 +1,54 @@ +From 46c23d7f520e315dde86881b38ba92ebdf34ced5 Mon Sep 17 00:00:00 2001 +From: Lubomir Rintel +Date: Tue, 29 Jun 2010 15:05:38 -0700 +Subject: sysvfs: fix NULL deref. when allocating new inode + +From: Lubomir Rintel + +commit 46c23d7f520e315dde86881b38ba92ebdf34ced5 upstream. + +A call to sysv_write_inode() in sysv_new_inode() to its new interface that +replaced wait flag with writeback structure. This was broken by +a9185b41a4f84971b930c519f0c63bd450c4810d ("pass writeback_control to +->write_inode"). + +Signed-off-by: Lubomir Rintel +Cc: Christoph Hellwig +Cc: Al Viro +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/sysv/ialloc.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/fs/sysv/ialloc.c ++++ b/fs/sysv/ialloc.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include "sysv.h" + + /* We don't trust the value of +@@ -139,6 +140,9 @@ struct inode * sysv_new_inode(const stru + struct inode *inode; + sysv_ino_t ino; + unsigned count; ++ struct writeback_control wbc = { ++ .sync_mode = WB_SYNC_NONE ++ }; + + inode = new_inode(sb); + if (!inode) +@@ -177,7 +181,7 @@ struct inode * sysv_new_inode(const stru + mark_inode_dirty(inode); + + inode->i_mode = mode; /* for sysv_write_inode() */ +- sysv_write_inode(inode, 0); /* ensure inode not allocated again */ ++ sysv_write_inode(inode, &wbc); /* ensure inode not allocated again */ + mark_inode_dirty(inode); /* cleared by sysv_write_inode() */ + /* That's it. */ + unlock_super(sb); diff --git a/queue-2.6.34/um-os-linux-mem.c-needs-sys-stat.h.patch b/queue-2.6.34/um-os-linux-mem.c-needs-sys-stat.h.patch new file mode 100644 index 00000000000..f78b7c26f1c --- /dev/null +++ b/queue-2.6.34/um-os-linux-mem.c-needs-sys-stat.h.patch @@ -0,0 +1,33 @@ +From fb967ecc584c20c74a007de749ca597068b0fcac Mon Sep 17 00:00:00 2001 +From: Liu Aleaxander +Date: Tue, 29 Jun 2010 15:05:40 -0700 +Subject: um: os-linux/mem.c needs sys/stat.h + +From: Liu Aleaxander + +commit fb967ecc584c20c74a007de749ca597068b0fcac upstream. + +The os-linux/mem.c file calls fchmod function, which is declared in sys/stat.h +header file, so include it. Fixes build breakage under FC13. + +Signed-off-by: Liu Aleaxander +Acked-by: Boaz Harrosh +Cc: Jeff Dike +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + arch/um/os-Linux/mem.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/um/os-Linux/mem.c ++++ b/arch/um/os-Linux/mem.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + #include "init.h" diff --git a/queue-2.6.34/x86-calgary-increase-max-phb-number.patch b/queue-2.6.34/x86-calgary-increase-max-phb-number.patch new file mode 100644 index 00000000000..f0125264663 --- /dev/null +++ b/queue-2.6.34/x86-calgary-increase-max-phb-number.patch @@ -0,0 +1,49 @@ +From 499a00e92dd9a75395081f595e681629eb1eebad Mon Sep 17 00:00:00 2001 +From: Darrick J. Wong +Date: Thu, 24 Jun 2010 14:26:47 -0700 +Subject: x86, Calgary: Increase max PHB number + +From: Darrick J. Wong + +commit 499a00e92dd9a75395081f595e681629eb1eebad upstream. + +Newer systems (x3950M2) can have 48 PHBs per chassis and 8 +chassis, so bump the limits up and provide an explanation +of the requirements for each class. + +Signed-off-by: Darrick J. Wong +Acked-by: Muli Ben-Yehuda +Cc: Corinna Schultz +LKML-Reference: <20100624212647.GI15515@tux1.beaverton.ibm.com> +[ v2: Fixed build bug, added back PHBS_PER_CALGARY == 4 ] +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/pci-calgary_64.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +--- a/arch/x86/kernel/pci-calgary_64.c ++++ b/arch/x86/kernel/pci-calgary_64.c +@@ -103,11 +103,16 @@ int use_calgary __read_mostly = 0; + #define PMR_SOFTSTOPFAULT 0x40000000 + #define PMR_HARDSTOP 0x20000000 + +-#define MAX_NUM_OF_PHBS 8 /* how many PHBs in total? */ +-#define MAX_NUM_CHASSIS 8 /* max number of chassis */ +-/* MAX_PHB_BUS_NUM is the maximal possible dev->bus->number */ +-#define MAX_PHB_BUS_NUM (MAX_NUM_OF_PHBS * MAX_NUM_CHASSIS * 2) +-#define PHBS_PER_CALGARY 4 ++/* ++ * The maximum PHB bus number. ++ * x3950M2 (rare): 8 chassis, 48 PHBs per chassis = 384 ++ * x3950M2: 4 chassis, 48 PHBs per chassis = 192 ++ * x3950 (PCIE): 8 chassis, 32 PHBs per chassis = 256 ++ * x3950 (PCIX): 8 chassis, 16 PHBs per chassis = 128 ++ */ ++#define MAX_PHB_BUS_NUM 384 ++ ++#define PHBS_PER_CALGARY 4 + + /* register offsets in Calgary's internal register space */ + static const unsigned long tar_offsets[] = { diff --git a/queue-2.6.34/x86-calgary-limit-the-max-phb-number-to-256.patch b/queue-2.6.34/x86-calgary-limit-the-max-phb-number-to-256.patch new file mode 100644 index 00000000000..da1bb63034e --- /dev/null +++ b/queue-2.6.34/x86-calgary-limit-the-max-phb-number-to-256.patch @@ -0,0 +1,42 @@ +From d596043d71ff0d7b3d0bead19b1d68c55f003093 Mon Sep 17 00:00:00 2001 +From: Darrick J. Wong +Date: Wed, 30 Jun 2010 17:45:19 -0700 +Subject: x86, Calgary: Limit the max PHB number to 256 + +From: Darrick J. Wong + +commit d596043d71ff0d7b3d0bead19b1d68c55f003093 upstream. + +The x3950 family can have as many as 256 PCI buses in a single system, so +change the limits to the maximum. Since there can only be 256 PCI buses in one +domain, we no longer need the BUG_ON check. + +Signed-off-by: Darrick J. Wong +LKML-Reference: <20100701004519.GQ15515@tux1.beaverton.ibm.com> +Signed-off-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/pci-calgary_64.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/arch/x86/kernel/pci-calgary_64.c ++++ b/arch/x86/kernel/pci-calgary_64.c +@@ -110,7 +110,7 @@ int use_calgary __read_mostly = 0; + * x3950 (PCIE): 8 chassis, 32 PHBs per chassis = 256 + * x3950 (PCIX): 8 chassis, 16 PHBs per chassis = 128 + */ +-#define MAX_PHB_BUS_NUM 384 ++#define MAX_PHB_BUS_NUM 256 + + #define PHBS_PER_CALGARY 4 + +@@ -1056,8 +1056,6 @@ static int __init calgary_init_one(struc + struct iommu_table *tbl; + int ret; + +- BUG_ON(dev->bus->number >= MAX_PHB_BUS_NUM); +- + bbar = busno_to_bbar(dev->bus->number); + ret = calgary_setup_tar(dev, bbar); + if (ret) diff --git a/queue-2.6.34/x86-fix-vsyscall-on-gcc-4.5-with-os.patch b/queue-2.6.34/x86-fix-vsyscall-on-gcc-4.5-with-os.patch new file mode 100644 index 00000000000..ac27ee6224f --- /dev/null +++ b/queue-2.6.34/x86-fix-vsyscall-on-gcc-4.5-with-os.patch @@ -0,0 +1,36 @@ +From 124482935fb7fb9303c8a8ab930149c6a93d9910 Mon Sep 17 00:00:00 2001 +From: Andi Kleen +Date: Fri, 18 Jun 2010 23:09:00 +0200 +Subject: x86: Fix vsyscall on gcc 4.5 with -Os + +From: Andi Kleen + +commit 124482935fb7fb9303c8a8ab930149c6a93d9910 upstream. + +This fixes the -Os breaks with gcc 4.5 bug. rdtsc_barrier needs to be +force inlined, otherwise user space will jump into kernel space and +kill init. + +This also addresses http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44129 +I believe. + +Signed-off-by: Andi Kleen +LKML-Reference: <20100618210859.GA10913@basil.fritz.box> +Signed-off-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/system.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/include/asm/system.h ++++ b/arch/x86/include/asm/system.h +@@ -451,7 +451,7 @@ void stop_this_cpu(void *dummy); + * + * (Could use an alternative three way for this if there was one.) + */ +-static inline void rdtsc_barrier(void) ++static __always_inline void rdtsc_barrier(void) + { + alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC); + alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); diff --git a/queue-2.6.34/x86-send-a-sigtrap-for-user-icebp-traps.patch b/queue-2.6.34/x86-send-a-sigtrap-for-user-icebp-traps.patch new file mode 100644 index 00000000000..e4bf0fbb5e7 --- /dev/null +++ b/queue-2.6.34/x86-send-a-sigtrap-for-user-icebp-traps.patch @@ -0,0 +1,82 @@ +From a1e80fafc9f0742a1776a0490258cb64912411b0 Mon Sep 17 00:00:00 2001 +From: Frederic Weisbecker +Date: Wed, 30 Jun 2010 15:09:06 +0200 +Subject: x86: Send a SIGTRAP for user icebp traps + +From: Frederic Weisbecker + +commit a1e80fafc9f0742a1776a0490258cb64912411b0 upstream. + +Before we had a generic breakpoint layer, x86 used to send a +sigtrap for any debug event that happened in userspace, +except if it was caused by lazy dr7 switches. + +Currently we only send such signal for single step or breakpoint +events. + +However, there are three other kind of debug exceptions: + +- debug register access detected: trigger an exception if the + next instruction touches the debug registers. We don't use + it. +- task switch, but we don't use tss. +- icebp/int01 trap. This instruction (0xf1) is undocumented and + generates an int 1 exception. Unlike single step through TF + flag, it doesn't set the single step origin of the exception + in dr6. + +icebp then used to be reported in userspace using trap signals +but this have been incidentally broken with the new breakpoint +code. Reenable this. Since this is the only debug event that +doesn't set anything in dr6, this is all we have to check. + +This fixes a regression in Wine where World Of Warcraft got broken +as it uses this for software protection checks purposes. And +probably other apps do. + +Reported-and-tested-by: Alexandre Julliard +Signed-off-by: Frederic Weisbecker +Cc: Ingo Molnar +Cc: H. Peter Anvin +Cc: Thomas Gleixner +Cc: Prasad +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/traps.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/arch/x86/kernel/traps.c ++++ b/arch/x86/kernel/traps.c +@@ -529,6 +529,7 @@ asmlinkage __kprobes struct pt_regs *syn + dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) + { + struct task_struct *tsk = current; ++ int user_icebp = 0; + unsigned long dr6; + int si_code; + +@@ -537,6 +538,14 @@ dotraplinkage void __kprobes do_debug(st + /* Filter out all the reserved bits which are preset to 1 */ + dr6 &= ~DR6_RESERVED; + ++ /* ++ * If dr6 has no reason to give us about the origin of this trap, ++ * then it's very likely the result of an icebp/int01 trap. ++ * User wants a sigtrap for that. ++ */ ++ if (!dr6 && user_mode(regs)) ++ user_icebp = 1; ++ + /* Catch kmemcheck conditions first of all! */ + if ((dr6 & DR_STEP) && kmemcheck_trap(regs)) + return; +@@ -578,7 +587,7 @@ dotraplinkage void __kprobes do_debug(st + regs->flags &= ~X86_EFLAGS_TF; + } + si_code = get_si_code(tsk->thread.debugreg6); +- if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS)) ++ if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS) || user_icebp) + send_sigtrap(tsk, regs, error_code, si_code); + preempt_conditional_cli(regs); +