]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.32 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Tue, 7 Dec 2010 22:04:13 +0000 (14:04 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 7 Dec 2010 22:04:13 +0000 (14:04 -0800)
queue-2.6.32/act_nat-use-stack-variable.patch [new file with mode: 0644]
queue-2.6.32/net-sched-fix-some-kernel-memory-leaks.patch [new file with mode: 0644]
queue-2.6.32/nmi-fix-clock-comparator-revalidation.patch [new file with mode: 0644]
queue-2.6.32/series
queue-2.6.32/uv-xpc-pass-nasid-instead-of-nid-to-gru_create_message_queue.patch [new file with mode: 0644]
queue-2.6.32/x86-uv-update-xpc-to-handle-updated-bios-interface.patch [new file with mode: 0644]
queue-2.6.32/x86-uv-xpc-needs-to-provide-an-abstraction-for-uv_gpa.patch [new file with mode: 0644]
queue-2.6.32/x86-uv-xpc-null-deref-when-mesq-becomes-empty.patch [new file with mode: 0644]
queue-2.6.32/x86-uv-xpc-receive-message-reuse-triggers-invalid-bug_on.patch [new file with mode: 0644]
queue-2.6.32/x86-uv-xpc_make_first_contact-hang-due-to-not-accepting-active-state.patch [new file with mode: 0644]

diff --git a/queue-2.6.32/act_nat-use-stack-variable.patch b/queue-2.6.32/act_nat-use-stack-variable.patch
new file mode 100644 (file)
index 0000000..34e2b6a
--- /dev/null
@@ -0,0 +1,75 @@
+From 504f85c9d05f7c605306e808f0d835fe11bfd18d Mon Sep 17 00:00:00 2001
+From: Changli Gao <xiaosuo@gmail.com>
+Date: Tue, 29 Jun 2010 23:07:09 +0000
+Subject: act_nat: use stack variable
+
+From: Changli Gao <xiaosuo@gmail.com>
+
+commit 504f85c9d05f7c605306e808f0d835fe11bfd18d upstream.
+
+act_nat: use stack variable
+
+structure tc_nat isn't too big for stack, so we can put it in stack.
+
+Signed-off-by: Changli Gao <xiaosuo@gmail.com>
+Cc: dann frazier <dannf@debian.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/sched/act_nat.c |   33 +++++++++++----------------------
+ 1 file changed, 11 insertions(+), 22 deletions(-)
+
+--- a/net/sched/act_nat.c
++++ b/net/sched/act_nat.c
+@@ -261,40 +261,29 @@ static int tcf_nat_dump(struct sk_buff *
+ {
+       unsigned char *b = skb_tail_pointer(skb);
+       struct tcf_nat *p = a->priv;
+-      struct tc_nat *opt;
++      struct tc_nat opt;
+       struct tcf_t t;
+-      int s;
+-      s = sizeof(*opt);
++      opt.old_addr = p->old_addr;
++      opt.new_addr = p->new_addr;
++      opt.mask = p->mask;
++      opt.flags = p->flags;
++
++      opt.index = p->tcf_index;
++      opt.action = p->tcf_action;
++      opt.refcnt = p->tcf_refcnt - ref;
++      opt.bindcnt = p->tcf_bindcnt - bind;
+-      /* netlink spinlocks held above us - must use ATOMIC */
+-      opt = kzalloc(s, GFP_ATOMIC);
+-      if (unlikely(!opt))
+-              return -ENOBUFS;
+-
+-      opt->old_addr = p->old_addr;
+-      opt->new_addr = p->new_addr;
+-      opt->mask = p->mask;
+-      opt->flags = p->flags;
+-
+-      opt->index = p->tcf_index;
+-      opt->action = p->tcf_action;
+-      opt->refcnt = p->tcf_refcnt - ref;
+-      opt->bindcnt = p->tcf_bindcnt - bind;
+-
+-      NLA_PUT(skb, TCA_NAT_PARMS, s, opt);
++      NLA_PUT(skb, TCA_NAT_PARMS, sizeof(opt), &opt);
+       t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install);
+       t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse);
+       t.expires = jiffies_to_clock_t(p->tcf_tm.expires);
+       NLA_PUT(skb, TCA_NAT_TM, sizeof(t), &t);
+-      kfree(opt);
+-
+       return skb->len;
+ nla_put_failure:
+       nlmsg_trim(skb, b);
+-      kfree(opt);
+       return -1;
+ }
diff --git a/queue-2.6.32/net-sched-fix-some-kernel-memory-leaks.patch b/queue-2.6.32/net-sched-fix-some-kernel-memory-leaks.patch
new file mode 100644 (file)
index 0000000..7e22537
--- /dev/null
@@ -0,0 +1,165 @@
+From 1c40be12f7d8ca1d387510d39787b12e512a7ce8 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <eric.dumazet@gmail.com>
+Date: Mon, 16 Aug 2010 20:04:22 +0000
+Subject: net sched: fix some kernel memory leaks
+
+From: Eric Dumazet <eric.dumazet@gmail.com>
+
+commit 1c40be12f7d8ca1d387510d39787b12e512a7ce8 upstream.
+
+We leak at least 32bits of kernel memory to user land in tc dump,
+because we dont init all fields (capab ?) of the dumped structure.
+
+Use C99 initializers so that holes and non explicit fields are zeroed.
+
+Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Cc: dann frazier <dannf@debian.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/sched/act_gact.c    |   21 ++++++++++++---------
+ net/sched/act_mirred.c  |   15 ++++++++-------
+ net/sched/act_nat.c     |   22 +++++++++++-----------
+ net/sched/act_simple.c  |   11 ++++++-----
+ net/sched/act_skbedit.c |   11 ++++++-----
+ 5 files changed, 43 insertions(+), 37 deletions(-)
+
+--- a/net/sched/act_gact.c
++++ b/net/sched/act_gact.c
+@@ -152,21 +152,24 @@ static int tcf_gact(struct sk_buff *skb,
+ static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
+ {
+       unsigned char *b = skb_tail_pointer(skb);
+-      struct tc_gact opt;
+       struct tcf_gact *gact = a->priv;
++      struct tc_gact opt = {
++              .index   = gact->tcf_index,
++              .refcnt  = gact->tcf_refcnt - ref,
++              .bindcnt = gact->tcf_bindcnt - bind,
++              .action  = gact->tcf_action,
++      };
+       struct tcf_t t;
+-      opt.index = gact->tcf_index;
+-      opt.refcnt = gact->tcf_refcnt - ref;
+-      opt.bindcnt = gact->tcf_bindcnt - bind;
+-      opt.action = gact->tcf_action;
+       NLA_PUT(skb, TCA_GACT_PARMS, sizeof(opt), &opt);
+ #ifdef CONFIG_GACT_PROB
+       if (gact->tcfg_ptype) {
+-              struct tc_gact_p p_opt;
+-              p_opt.paction = gact->tcfg_paction;
+-              p_opt.pval = gact->tcfg_pval;
+-              p_opt.ptype = gact->tcfg_ptype;
++              struct tc_gact_p p_opt = {
++                      .paction = gact->tcfg_paction,
++                      .pval    = gact->tcfg_pval,
++                      .ptype   = gact->tcfg_ptype,
++              };
++
+               NLA_PUT(skb, TCA_GACT_PROB, sizeof(p_opt), &p_opt);
+       }
+ #endif
+--- a/net/sched/act_mirred.c
++++ b/net/sched/act_mirred.c
+@@ -205,15 +205,16 @@ static int tcf_mirred_dump(struct sk_buf
+ {
+       unsigned char *b = skb_tail_pointer(skb);
+       struct tcf_mirred *m = a->priv;
+-      struct tc_mirred opt;
++      struct tc_mirred opt = {
++              .index   = m->tcf_index,
++              .action  = m->tcf_action,
++              .refcnt  = m->tcf_refcnt - ref,
++              .bindcnt = m->tcf_bindcnt - bind,
++              .eaction = m->tcfm_eaction,
++              .ifindex = m->tcfm_ifindex,
++      };
+       struct tcf_t t;
+-      opt.index = m->tcf_index;
+-      opt.action = m->tcf_action;
+-      opt.refcnt = m->tcf_refcnt - ref;
+-      opt.bindcnt = m->tcf_bindcnt - bind;
+-      opt.eaction = m->tcfm_eaction;
+-      opt.ifindex = m->tcfm_ifindex;
+       NLA_PUT(skb, TCA_MIRRED_PARMS, sizeof(opt), &opt);
+       t.install = jiffies_to_clock_t(jiffies - m->tcf_tm.install);
+       t.lastuse = jiffies_to_clock_t(jiffies - m->tcf_tm.lastuse);
+--- a/net/sched/act_nat.c
++++ b/net/sched/act_nat.c
+@@ -261,18 +261,18 @@ static int tcf_nat_dump(struct sk_buff *
+ {
+       unsigned char *b = skb_tail_pointer(skb);
+       struct tcf_nat *p = a->priv;
+-      struct tc_nat opt;
+-      struct tcf_t t;
+-
+-      opt.old_addr = p->old_addr;
+-      opt.new_addr = p->new_addr;
+-      opt.mask = p->mask;
+-      opt.flags = p->flags;
++      struct tc_nat opt = {
++              .old_addr = p->old_addr,
++              .new_addr = p->new_addr,
++              .mask     = p->mask,
++              .flags    = p->flags,
+-      opt.index = p->tcf_index;
+-      opt.action = p->tcf_action;
+-      opt.refcnt = p->tcf_refcnt - ref;
+-      opt.bindcnt = p->tcf_bindcnt - bind;
++              .index    = p->tcf_index,
++              .action   = p->tcf_action,
++              .refcnt   = p->tcf_refcnt - ref,
++              .bindcnt  = p->tcf_bindcnt - bind,
++      };
++      struct tcf_t t;
+       NLA_PUT(skb, TCA_NAT_PARMS, sizeof(opt), &opt);
+       t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install);
+--- a/net/sched/act_simple.c
++++ b/net/sched/act_simple.c
+@@ -163,13 +163,14 @@ static inline int tcf_simp_dump(struct s
+ {
+       unsigned char *b = skb_tail_pointer(skb);
+       struct tcf_defact *d = a->priv;
+-      struct tc_defact opt;
++      struct tc_defact opt = {
++              .index   = d->tcf_index,
++              .refcnt  = d->tcf_refcnt - ref,
++              .bindcnt = d->tcf_bindcnt - bind,
++              .action  = d->tcf_action,
++      };
+       struct tcf_t t;
+-      opt.index = d->tcf_index;
+-      opt.refcnt = d->tcf_refcnt - ref;
+-      opt.bindcnt = d->tcf_bindcnt - bind;
+-      opt.action = d->tcf_action;
+       NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt);
+       NLA_PUT_STRING(skb, TCA_DEF_DATA, d->tcfd_defdata);
+       t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install);
+--- a/net/sched/act_skbedit.c
++++ b/net/sched/act_skbedit.c
+@@ -147,13 +147,14 @@ static inline int tcf_skbedit_dump(struc
+ {
+       unsigned char *b = skb_tail_pointer(skb);
+       struct tcf_skbedit *d = a->priv;
+-      struct tc_skbedit opt;
++      struct tc_skbedit opt = {
++              .index   = d->tcf_index,
++              .refcnt  = d->tcf_refcnt - ref,
++              .bindcnt = d->tcf_bindcnt - bind,
++              .action  = d->tcf_action,
++      };
+       struct tcf_t t;
+-      opt.index = d->tcf_index;
+-      opt.refcnt = d->tcf_refcnt - ref;
+-      opt.bindcnt = d->tcf_bindcnt - bind;
+-      opt.action = d->tcf_action;
+       NLA_PUT(skb, TCA_SKBEDIT_PARMS, sizeof(opt), &opt);
+       if (d->flags & SKBEDIT_F_PRIORITY)
+               NLA_PUT(skb, TCA_SKBEDIT_PRIORITY, sizeof(d->priority),
diff --git a/queue-2.6.32/nmi-fix-clock-comparator-revalidation.patch b/queue-2.6.32/nmi-fix-clock-comparator-revalidation.patch
new file mode 100644 (file)
index 0000000..e2a14fc
--- /dev/null
@@ -0,0 +1,93 @@
+From e8129c642155616d9e2160a75f103e127c8c3708 Mon Sep 17 00:00:00 2001
+From: Heiko Carstens <heiko.carstens@de.ibm.com>
+Date: Thu, 25 Nov 2010 09:52:45 +0100
+Subject: [S390] nmi: fix clock comparator revalidation
+
+From: Heiko Carstens <heiko.carstens@de.ibm.com>
+
+commit e8129c642155616d9e2160a75f103e127c8c3708 upstream.
+
+On each machine check all registers are revalidated. The save area for
+the clock comparator however only contains the upper most seven bytes
+of the former contents, if valid.
+Therefore the machine check handler uses a store clock instruction to
+get the current time and writes that to the clock comparator register
+which in turn will generate an immediate timer interrupt.
+However within the lowcore the expected time of the next timer
+interrupt is stored. If the interrupt happens before that time the
+handler won't be called. In turn the clock comparator won't be
+reprogrammed and therefore the interrupt condition stays pending which
+causes an interrupt loop until the expected time is reached.
+
+On NOHZ machines this can result in unresponsive machines since the
+time of the next expected interrupted can be a couple of days in the
+future.
+
+To fix this just revalidate the clock comparator register with the
+expected value.
+In addition the special handling for udelay must be changed as well.
+
+Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/s390/kernel/nmi.c |   10 ++++------
+ arch/s390/lib/delay.c  |   14 +++++++++-----
+ 2 files changed, 13 insertions(+), 11 deletions(-)
+
+--- a/arch/s390/kernel/nmi.c
++++ b/arch/s390/kernel/nmi.c
+@@ -95,7 +95,6 @@ EXPORT_SYMBOL_GPL(s390_handle_mcck);
+ static int notrace s390_revalidate_registers(struct mci *mci)
+ {
+       int kill_task;
+-      u64 tmpclock;
+       u64 zero;
+       void *fpt_save_area, *fpt_creg_save_area;
+@@ -214,11 +213,10 @@ static int notrace s390_revalidate_regis
+                       : "0", "cc");
+ #endif
+       /* Revalidate clock comparator register */
+-      asm volatile(
+-              "       stck    0(%1)\n"
+-              "       sckc    0(%1)"
+-              : "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory");
+-
++      if (S390_lowcore.clock_comparator == -1)
++              set_clock_comparator(S390_lowcore.mcck_clock);
++      else
++              set_clock_comparator(S390_lowcore.clock_comparator);
+       /* Check if old PSW is valid */
+       if (!mci->wp)
+               /*
+--- a/arch/s390/lib/delay.c
++++ b/arch/s390/lib/delay.c
+@@ -29,17 +29,21 @@ static void __udelay_disabled(unsigned l
+ {
+       unsigned long mask, cr0, cr0_saved;
+       u64 clock_saved;
++      u64 end;
++      mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT;
++      end = get_clock() + (usecs << 12);
+       clock_saved = local_tick_disable();
+-      set_clock_comparator(get_clock() + (usecs << 12));
+       __ctl_store(cr0_saved, 0, 0);
+       cr0 = (cr0_saved & 0xffff00e0) | 0x00000800;
+       __ctl_load(cr0 , 0, 0);
+-      mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT;
+       lockdep_off();
+-      trace_hardirqs_on();
+-      __load_psw_mask(mask);
+-      local_irq_disable();
++      do {
++              set_clock_comparator(end);
++              trace_hardirqs_on();
++              __load_psw_mask(mask);
++              local_irq_disable();
++      } while (get_clock() < end);
+       lockdep_on();
+       __ctl_load(cr0_saved, 0, 0);
+       local_tick_enable(clock_saved);
index 94a3d190c4cc0e42e9ea54bc620db4249bc5edf0..58e34bd1cd4bee2a5a17eac9b083c19b5abf4379 100644 (file)
@@ -118,3 +118,12 @@ econet-fix-cve-2010-3850.patch
 rds-integer-overflow-in-rds-cmsg-handling.patch
 net-truncate-recvfrom-and-sendto-length-to-int_max.patch
 net-limit-socket-i-o-iovec-total-length-to-int_max.patch
+nmi-fix-clock-comparator-revalidation.patch
+act_nat-use-stack-variable.patch
+net-sched-fix-some-kernel-memory-leaks.patch
+uv-xpc-pass-nasid-instead-of-nid-to-gru_create_message_queue.patch
+x86-uv-xpc-receive-message-reuse-triggers-invalid-bug_on.patch
+x86-uv-xpc_make_first_contact-hang-due-to-not-accepting-active-state.patch
+x86-uv-xpc-null-deref-when-mesq-becomes-empty.patch
+x86-uv-update-xpc-to-handle-updated-bios-interface.patch
+x86-uv-xpc-needs-to-provide-an-abstraction-for-uv_gpa.patch
diff --git a/queue-2.6.32/uv-xpc-pass-nasid-instead-of-nid-to-gru_create_message_queue.patch b/queue-2.6.32/uv-xpc-pass-nasid-instead-of-nid-to-gru_create_message_queue.patch
new file mode 100644 (file)
index 0000000..747329a
--- /dev/null
@@ -0,0 +1,45 @@
+From 57e6d258b1e41cd7ceb26fa43ce116939d8440b1 Mon Sep 17 00:00:00 2001
+From: Robin Holt <holt@sgi.com>
+Date: Tue, 15 Dec 2009 16:48:00 -0800
+Subject: UV - XPC: pass nasid instead of nid to gru_create_message_queue
+
+From: Robin Holt <holt@sgi.com>
+
+commit 57e6d258b1e41cd7ceb26fa43ce116939d8440b1 upstream.
+
+Currently, the UV xpc code is passing nid to the gru_create_message_queue
+instead of nasid as it expects.
+
+Signed-off-by: Robin Holt <holt@sgi.com>
+Signed-off-by: Jack Steiner <steiner@sgi.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/misc/sgi-xp/xpc_uv.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/misc/sgi-xp/xpc_uv.c
++++ b/drivers/misc/sgi-xp/xpc_uv.c
+@@ -203,6 +203,7 @@ xpc_create_gru_mq_uv(unsigned int mq_siz
+       enum xp_retval xp_ret;
+       int ret;
+       int nid;
++      int nasid;
+       int pg_order;
+       struct page *page;
+       struct xpc_gru_mq_uv *mq;
+@@ -258,9 +259,11 @@ xpc_create_gru_mq_uv(unsigned int mq_siz
+               goto out_5;
+       }
++      nasid = UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpu));
++
+       mmr_value = (struct uv_IO_APIC_route_entry *)&mq->mmr_value;
+       ret = gru_create_message_queue(mq->gru_mq_desc, mq->address, mq_size,
+-                                     nid, mmr_value->vector, mmr_value->dest);
++                                   nasid, mmr_value->vector, mmr_value->dest);
+       if (ret != 0) {
+               dev_err(xpc_part, "gru_create_message_queue() returned "
+                       "error=%d\n", ret);
diff --git a/queue-2.6.32/x86-uv-update-xpc-to-handle-updated-bios-interface.patch b/queue-2.6.32/x86-uv-update-xpc-to-handle-updated-bios-interface.patch
new file mode 100644 (file)
index 0000000..bf9ee1c
--- /dev/null
@@ -0,0 +1,219 @@
+From c2c9f115741453715d6b4da1cd2de65af8c7ad86 Mon Sep 17 00:00:00 2001
+From: Robin Holt <holt@sgi.com>
+Date: Tue, 15 Dec 2009 16:47:56 -0800
+Subject: x86: uv: update XPC to handle updated BIOS interface
+
+From: Robin Holt <holt@sgi.com>
+
+commit c2c9f115741453715d6b4da1cd2de65af8c7ad86 upstream.
+
+The UV BIOS has moved the location of some of their pointers to the
+"partition reserved page" from memory into a uv hub MMR.  The GRU does not
+support bcopy operations from MMR space so we need to special case the MMR
+addresses using VLOAD operations.
+
+Additionally, the BIOS call for registering a message queue watchlist has
+removed the 'blade' value and eliminated the structure that was being
+passed in.  This is also reflected in this patch.
+
+Signed-off-by: Robin Holt <holt@sgi.com>
+Cc: Jack Steiner <steiner@sgi.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/include/asm/uv/bios.h      |   11 +----------
+ arch/x86/kernel/bios_uv.c           |    8 ++------
+ drivers/misc/sgi-xp/xp_uv.c         |   23 +++++++++++++++++++++++
+ drivers/misc/sgi-xp/xpc_partition.c |   13 +++++++++----
+ drivers/misc/sgi-xp/xpc_uv.c        |   27 +++++++++++++++------------
+ 5 files changed, 50 insertions(+), 32 deletions(-)
+
+--- a/arch/x86/include/asm/uv/bios.h
++++ b/arch/x86/include/asm/uv/bios.h
+@@ -76,15 +76,6 @@ union partition_info_u {
+       };
+ };
+-union uv_watchlist_u {
+-      u64     val;
+-      struct {
+-              u64     blade   : 16,
+-                      size    : 32,
+-                      filler  : 16;
+-      };
+-};
+-
+ enum uv_memprotect {
+       UV_MEMPROT_RESTRICT_ACCESS,
+       UV_MEMPROT_ALLOW_AMO,
+@@ -100,7 +91,7 @@ extern s64 uv_bios_call_reentrant(enum u
+ extern s64 uv_bios_get_sn_info(int, int *, long *, long *, long *);
+ extern s64 uv_bios_freq_base(u64, u64 *);
+-extern int uv_bios_mq_watchlist_alloc(int, unsigned long, unsigned int,
++extern int uv_bios_mq_watchlist_alloc(unsigned long, unsigned int,
+                                       unsigned long *);
+ extern int uv_bios_mq_watchlist_free(int, int);
+ extern s64 uv_bios_change_memprotect(u64, u64, enum uv_memprotect);
+--- a/arch/x86/kernel/bios_uv.c
++++ b/arch/x86/kernel/bios_uv.c
+@@ -101,21 +101,17 @@ s64 uv_bios_get_sn_info(int fc, int *uvt
+ }
+ int
+-uv_bios_mq_watchlist_alloc(int blade, unsigned long addr, unsigned int mq_size,
++uv_bios_mq_watchlist_alloc(unsigned long addr, unsigned int mq_size,
+                          unsigned long *intr_mmr_offset)
+ {
+-      union uv_watchlist_u size_blade;
+       u64 watchlist;
+       s64 ret;
+-      size_blade.size = mq_size;
+-      size_blade.blade = blade;
+-
+       /*
+        * bios returns watchlist number or negative error number.
+        */
+       ret = (int)uv_bios_call_irqsave(UV_BIOS_WATCHLIST_ALLOC, addr,
+-                      size_blade.val, (u64)intr_mmr_offset,
++                      mq_size, (u64)intr_mmr_offset,
+                       (u64)&watchlist, 0);
+       if (ret < BIOS_STATUS_SUCCESS)
+               return ret;
+--- a/drivers/misc/sgi-xp/xp_uv.c
++++ b/drivers/misc/sgi-xp/xp_uv.c
+@@ -33,11 +33,34 @@ xp_pa_uv(void *addr)
+ }
+ static enum xp_retval
++xp_remote_mmr_read(unsigned long dst_gpa, const unsigned long src_gpa,
++                 size_t len)
++{
++      int ret;
++      unsigned long *dst_va = __va(uv_gpa_to_soc_phys_ram(dst_gpa));
++
++      BUG_ON(!uv_gpa_in_mmr_space(src_gpa));
++      BUG_ON(len != 8);
++
++      ret = gru_read_gpa(dst_va, src_gpa);
++      if (ret == 0)
++              return xpSuccess;
++
++      dev_err(xp, "gru_read_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx "
++              "len=%ld\n", dst_gpa, src_gpa, len);
++      return xpGruCopyError;
++}
++
++
++static enum xp_retval
+ xp_remote_memcpy_uv(unsigned long dst_gpa, const unsigned long src_gpa,
+                   size_t len)
+ {
+       int ret;
++      if (uv_gpa_in_mmr_space(src_gpa))
++              return xp_remote_mmr_read(dst_gpa, src_gpa, len);
++
+       ret = gru_copy_gpa(dst_gpa, src_gpa, len);
+       if (ret == 0)
+               return xpSuccess;
+--- a/drivers/misc/sgi-xp/xpc_partition.c
++++ b/drivers/misc/sgi-xp/xpc_partition.c
+@@ -18,6 +18,7 @@
+ #include <linux/device.h>
+ #include <linux/hardirq.h>
+ #include "xpc.h"
++#include <asm/uv/uv_hub.h>
+ /* XPC is exiting flag */
+ int xpc_exiting;
+@@ -92,8 +93,12 @@ xpc_get_rsvd_page_pa(int nasid)
+                       break;
+               /* !!! L1_CACHE_ALIGN() is only a sn2-bte_copy requirement */
+-              if (L1_CACHE_ALIGN(len) > buf_len) {
+-                      kfree(buf_base);
++              if (is_shub())
++                      len = L1_CACHE_ALIGN(len);
++
++              if (len > buf_len) {
++                      if (buf_base != NULL)
++                              kfree(buf_base);
+                       buf_len = L1_CACHE_ALIGN(len);
+                       buf = xpc_kmalloc_cacheline_aligned(buf_len, GFP_KERNEL,
+                                                           &buf_base);
+@@ -105,7 +110,7 @@ xpc_get_rsvd_page_pa(int nasid)
+                       }
+               }
+-              ret = xp_remote_memcpy(xp_pa(buf), rp_pa, buf_len);
++              ret = xp_remote_memcpy(xp_pa(buf), rp_pa, len);
+               if (ret != xpSuccess) {
+                       dev_dbg(xpc_part, "xp_remote_memcpy failed %d\n", ret);
+                       break;
+@@ -143,7 +148,7 @@ xpc_setup_rsvd_page(void)
+               dev_err(xpc_part, "SAL failed to locate the reserved page\n");
+               return -ESRCH;
+       }
+-      rp = (struct xpc_rsvd_page *)__va(rp_pa);
++      rp = (struct xpc_rsvd_page *)__va(xp_socket_pa(rp_pa));
+       if (rp->SAL_version < 3) {
+               /* SAL_versions < 3 had a SAL_partid defined as a u8 */
+--- a/drivers/misc/sgi-xp/xpc_uv.c
++++ b/drivers/misc/sgi-xp/xpc_uv.c
+@@ -156,22 +156,24 @@ xpc_gru_mq_watchlist_alloc_uv(struct xpc
+ {
+       int ret;
+-#if defined CONFIG_X86_64
+-      ret = uv_bios_mq_watchlist_alloc(mq->mmr_blade, uv_gpa(mq->address),
+-                                       mq->order, &mq->mmr_offset);
+-      if (ret < 0) {
+-              dev_err(xpc_part, "uv_bios_mq_watchlist_alloc() failed, "
+-                      "ret=%d\n", ret);
+-              return ret;
+-      }
+-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+-      ret = sn_mq_watchlist_alloc(mq->mmr_blade, (void *)uv_gpa(mq->address),
++#if defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
++      int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
++
++      ret = sn_mq_watchlist_alloc(mmr_pnode, (void *)uv_gpa(mq->address),
+                                   mq->order, &mq->mmr_offset);
+       if (ret < 0) {
+               dev_err(xpc_part, "sn_mq_watchlist_alloc() failed, ret=%d\n",
+                       ret);
+               return -EBUSY;
+       }
++#elif defined CONFIG_X86_64
++      ret = uv_bios_mq_watchlist_alloc(uv_gpa(mq->address),
++                                       mq->order, &mq->mmr_offset);
++      if (ret < 0) {
++              dev_err(xpc_part, "uv_bios_mq_watchlist_alloc() failed, "
++                      "ret=%d\n", ret);
++              return ret;
++      }
+ #else
+       #error not a supported configuration
+ #endif
+@@ -184,12 +186,13 @@ static void
+ xpc_gru_mq_watchlist_free_uv(struct xpc_gru_mq_uv *mq)
+ {
+       int ret;
++      int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
+ #if defined CONFIG_X86_64
+-      ret = uv_bios_mq_watchlist_free(mq->mmr_blade, mq->watchlist_num);
++      ret = uv_bios_mq_watchlist_free(mmr_pnode, mq->watchlist_num);
+       BUG_ON(ret != BIOS_STATUS_SUCCESS);
+ #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+-      ret = sn_mq_watchlist_free(mq->mmr_blade, mq->watchlist_num);
++      ret = sn_mq_watchlist_free(mmr_pnode, mq->watchlist_num);
+       BUG_ON(ret != SALRET_OK);
+ #else
+       #error not a supported configuration
diff --git a/queue-2.6.32/x86-uv-xpc-needs-to-provide-an-abstraction-for-uv_gpa.patch b/queue-2.6.32/x86-uv-xpc-needs-to-provide-an-abstraction-for-uv_gpa.patch
new file mode 100644 (file)
index 0000000..47b6735
--- /dev/null
@@ -0,0 +1,100 @@
+From 682128939f546e3a9cdd9fef392b932dd9c41a65 Mon Sep 17 00:00:00 2001
+From: Robin Holt <holt@sgi.com>
+Date: Tue, 15 Dec 2009 16:47:53 -0800
+Subject: x86: uv: xpc needs to provide an abstraction for uv_gpa
+
+From: Robin Holt <holt@sgi.com>
+
+commit 682128939f546e3a9cdd9fef392b932dd9c41a65 upstream.
+
+Provide an SGI SN2/UV agnositic method for converting a global physical
+address into a socket physical address.
+
+Signed-off-by: Robin Holt <holt@sgi.com>
+Cc: Jack Steiner <steiner@sgi.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/misc/sgi-xp/xp.h      |    1 +
+ drivers/misc/sgi-xp/xp_main.c |    3 +++
+ drivers/misc/sgi-xp/xp_sn2.c  |   10 ++++++++++
+ drivers/misc/sgi-xp/xp_uv.c   |   10 ++++++++++
+ 4 files changed, 24 insertions(+)
+
+--- a/drivers/misc/sgi-xp/xp.h
++++ b/drivers/misc/sgi-xp/xp.h
+@@ -339,6 +339,7 @@ extern short xp_partition_id;
+ extern u8 xp_region_size;
+ extern unsigned long (*xp_pa) (void *);
++extern unsigned long (*xp_socket_pa) (unsigned long);
+ extern enum xp_retval (*xp_remote_memcpy) (unsigned long, const unsigned long,
+                      size_t);
+ extern int (*xp_cpu_to_nasid) (int);
+--- a/drivers/misc/sgi-xp/xp_main.c
++++ b/drivers/misc/sgi-xp/xp_main.c
+@@ -44,6 +44,9 @@ EXPORT_SYMBOL_GPL(xp_region_size);
+ unsigned long (*xp_pa) (void *addr);
+ EXPORT_SYMBOL_GPL(xp_pa);
++unsigned long (*xp_socket_pa) (unsigned long gpa);
++EXPORT_SYMBOL_GPL(xp_socket_pa);
++
+ enum xp_retval (*xp_remote_memcpy) (unsigned long dst_gpa,
+                                   const unsigned long src_gpa, size_t len);
+ EXPORT_SYMBOL_GPL(xp_remote_memcpy);
+--- a/drivers/misc/sgi-xp/xp_sn2.c
++++ b/drivers/misc/sgi-xp/xp_sn2.c
+@@ -84,6 +84,15 @@ xp_pa_sn2(void *addr)
+ }
+ /*
++ * Convert a global physical to a socket physical address.
++ */
++static unsigned long
++xp_socket_pa_sn2(unsigned long gpa)
++{
++      return gpa;
++}
++
++/*
+  * Wrapper for bte_copy().
+  *
+  *    dst_pa - physical address of the destination of the transfer.
+@@ -162,6 +171,7 @@ xp_init_sn2(void)
+       xp_region_size = sn_region_size;
+       xp_pa = xp_pa_sn2;
++      xp_socket_pa = xp_socket_pa_sn2;
+       xp_remote_memcpy = xp_remote_memcpy_sn2;
+       xp_cpu_to_nasid = xp_cpu_to_nasid_sn2;
+       xp_expand_memprotect = xp_expand_memprotect_sn2;
+--- a/drivers/misc/sgi-xp/xp_uv.c
++++ b/drivers/misc/sgi-xp/xp_uv.c
+@@ -32,6 +32,15 @@ xp_pa_uv(void *addr)
+       return uv_gpa(addr);
+ }
++/*
++ * Convert a global physical to socket physical address.
++ */
++static unsigned long
++xp_socket_pa_uv(unsigned long gpa)
++{
++      return uv_gpa_to_soc_phys_ram(gpa);
++}
++
+ static enum xp_retval
+ xp_remote_mmr_read(unsigned long dst_gpa, const unsigned long src_gpa,
+                  size_t len)
+@@ -146,6 +155,7 @@ xp_init_uv(void)
+       xp_region_size = sn_region_size;
+       xp_pa = xp_pa_uv;
++      xp_socket_pa = xp_socket_pa_uv;
+       xp_remote_memcpy = xp_remote_memcpy_uv;
+       xp_cpu_to_nasid = xp_cpu_to_nasid_uv;
+       xp_expand_memprotect = xp_expand_memprotect_uv;
diff --git a/queue-2.6.32/x86-uv-xpc-null-deref-when-mesq-becomes-empty.patch b/queue-2.6.32/x86-uv-xpc-null-deref-when-mesq-becomes-empty.patch
new file mode 100644 (file)
index 0000000..12df048
--- /dev/null
@@ -0,0 +1,43 @@
+From 15b87d67ff3dc042bee42f991858d6b121b3b3ca Mon Sep 17 00:00:00 2001
+From: Robin Holt <holt@sgi.com>
+Date: Tue, 15 Dec 2009 16:47:57 -0800
+Subject: x86: uv: xpc NULL deref when mesq becomes empty
+
+From: Robin Holt <holt@sgi.com>
+
+commit 15b87d67ff3dc042bee42f991858d6b121b3b3ca upstream.
+
+Under heavy load conditions, our set of xpc messages may become exhausted.
+ The code handles this correctly with the exception of the management code
+which hits a NULL pointer dereference.
+
+Signed-off-by: Robin Holt <holt@sgi.com>
+Cc: Jack Steiner <steiner@sgi.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/misc/sgi-xp/xpc_uv.c |    8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/misc/sgi-xp/xpc_uv.c
++++ b/drivers/misc/sgi-xp/xpc_uv.c
+@@ -965,11 +965,13 @@ xpc_get_fifo_entry_uv(struct xpc_fifo_he
+               head->first = first->next;
+               if (head->first == NULL)
+                       head->last = NULL;
++
++              head->n_entries--;
++              BUG_ON(head->n_entries < 0);
++
++              first->next = NULL;
+       }
+-      head->n_entries--;
+-      BUG_ON(head->n_entries < 0);
+       spin_unlock_irqrestore(&head->lock, irq_flags);
+-      first->next = NULL;
+       return first;
+ }
diff --git a/queue-2.6.32/x86-uv-xpc-receive-message-reuse-triggers-invalid-bug_on.patch b/queue-2.6.32/x86-uv-xpc-receive-message-reuse-triggers-invalid-bug_on.patch
new file mode 100644 (file)
index 0000000..c989ec5
--- /dev/null
@@ -0,0 +1,63 @@
+From 046d6c563b1c6226bbf0f84e5b2413ad8ab921a1 Mon Sep 17 00:00:00 2001
+From: Robin Holt <holt@sgi.com>
+Date: Tue, 15 Dec 2009 16:47:59 -0800
+Subject: x86: uv: XPC receive message reuse triggers invalid BUG_ON()
+
+From: Robin Holt <holt@sgi.com>
+
+commit 046d6c563b1c6226bbf0f84e5b2413ad8ab921a1 upstream.
+
+This was a difficult bug to trip.  XPC was in the middle of sending an
+acknowledgement for a received message.
+
+In xpc_received_payload_uv():
+.
+        ret = xpc_send_gru_msg(ch->sn.uv.cached_notify_gru_mq_desc, msg,
+                               sizeof(struct xpc_notify_mq_msghdr_uv));
+        if (ret != xpSuccess)
+                XPC_DEACTIVATE_PARTITION(&xpc_partitions[ch->partid], ret);
+
+        msg->hdr.msg_slot_number += ch->remote_nentries;
+
+at the point in xpc_send_gru_msg() where the hardware has dispatched the
+acknowledgement, the remote side is able to reuse the message structure
+and send a message with a different slot number.  This problem is made
+worse by interrupts.
+
+The adjustment of msg_slot_number and the BUG_ON in
+xpc_handle_notify_mq_msg_uv() which verifies the msg_slot_number is
+consistent are only used for debug purposes.  Since a fix for this that
+preserves the debug functionality would either have to infringe upon the
+payload or allocate another structure just for debug, I decided to remove
+it entirely.
+
+Signed-off-by: Robin Holt <holt@sgi.com>
+Cc: Jack Steiner <steiner@sgi.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/misc/sgi-xp/xpc_uv.c |    3 ---
+ 1 file changed, 3 deletions(-)
+
+--- a/drivers/misc/sgi-xp/xpc_uv.c
++++ b/drivers/misc/sgi-xp/xpc_uv.c
+@@ -1441,7 +1441,6 @@ xpc_handle_notify_mq_msg_uv(struct xpc_p
+       msg_slot = ch_uv->recv_msg_slots +
+           (msg->hdr.msg_slot_number % ch->remote_nentries) * ch->entry_size;
+-      BUG_ON(msg->hdr.msg_slot_number != msg_slot->hdr.msg_slot_number);
+       BUG_ON(msg_slot->hdr.size != 0);
+       memcpy(msg_slot, msg, msg->hdr.size);
+@@ -1665,8 +1664,6 @@ xpc_received_payload_uv(struct xpc_chann
+                              sizeof(struct xpc_notify_mq_msghdr_uv));
+       if (ret != xpSuccess)
+               XPC_DEACTIVATE_PARTITION(&xpc_partitions[ch->partid], ret);
+-
+-      msg->hdr.msg_slot_number += ch->remote_nentries;
+ }
+ static struct xpc_arch_operations xpc_arch_ops_uv = {
diff --git a/queue-2.6.32/x86-uv-xpc_make_first_contact-hang-due-to-not-accepting-active-state.patch b/queue-2.6.32/x86-uv-xpc_make_first_contact-hang-due-to-not-accepting-active-state.patch
new file mode 100644 (file)
index 0000000..279471f
--- /dev/null
@@ -0,0 +1,41 @@
+From dbd2918ec65c35f36bb102c88eafe87be0552f6f Mon Sep 17 00:00:00 2001
+From: Robin Holt <holt@sgi.com>
+Date: Tue, 15 Dec 2009 16:47:58 -0800
+Subject: X86: uv: xpc_make_first_contact hang due to not accepting ACTIVE state
+
+From: Robin Holt <holt@sgi.com>
+
+commit dbd2918ec65c35f36bb102c88eafe87be0552f6f upstream.
+
+Many times while the initial connection is being made, the contacted
+partition will send back both the ACTIVATING and the ACTIVE
+remote_act_state changes in very close succescion.  The 1/4 second delay
+in the make first contact loop is large enough to nearly always miss the
+ACTIVATING state change.
+
+Since either state indicates the remote partition has acknowledged our
+state change, accept either.
+
+Signed-off-by: Robin Holt <holt@sgi.com>
+Cc: Jack Steiner <steiner@sgi.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/misc/sgi-xp/xpc_uv.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/misc/sgi-xp/xpc_uv.c
++++ b/drivers/misc/sgi-xp/xpc_uv.c
+@@ -1038,7 +1038,8 @@ xpc_make_first_contact_uv(struct xpc_par
+       xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
+                                     XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV);
+-      while (part->sn.uv.remote_act_state != XPC_P_AS_ACTIVATING) {
++      while (!((part->sn.uv.remote_act_state == XPC_P_AS_ACTIVATING) ||
++               (part->sn.uv.remote_act_state == XPC_P_AS_ACTIVE))) {
+               dev_dbg(xpc_part, "waiting to make first contact with "
+                       "partition %d\n", XPC_PARTID(part));