--- /dev/null
+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;
+ }
+
--- /dev/null
+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),
--- /dev/null
+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);
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
--- /dev/null
+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);
--- /dev/null
+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
--- /dev/null
+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;
--- /dev/null
+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;
+ }
+
--- /dev/null
+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 = {
--- /dev/null
+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));