aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/tlb_uv.c
diff options
context:
space:
mode:
authorCliff Wickman <cpw@sgi.com>2009-04-16 08:53:09 -0400
committerIngo Molnar <mingo@elte.hu>2009-04-16 13:44:16 -0400
commit4ea3c51d5bd3bb4eea7d7d3a1f80d1a48c2a6f92 (patch)
tree025c060c7733bfc72a0614a60f745296070def69 /arch/x86/kernel/tlb_uv.c
parent94ca8e4852807fc42d2f64fcaf248aafc4f2e6a7 (diff)
x86: UV BAU distribution and payload MMRs
This patch correctly sets BAU memory mapped registers to point to the sending activation descriptor table and target payload table. The "Broadcast Assist Unit" is used for TLB shootdown in UV. The memory mapped registers that point to sending and receiving memory structures contain node numbers. In one case the __pa() function did not provide the node id of memory on blade zero in configurations where that id is nonzero. In another case, it was assumed that memory was allocated on the local node. That assumption is not true in a configuration in which the node has no memory. Tested on the UV hardware simulator. [ Impact: fix possible runtime crash due to incorrect TLB logic ] Signed-off-by: Cliff Wickman <cpw@sgi.com> LKML-Reference: <E1LuR5Z-0007An-B8@eag09.americas.sgi.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/tlb_uv.c')
-rw-r--r--arch/x86/kernel/tlb_uv.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c
index 98307f953492..78422336ddea 100644
--- a/arch/x86/kernel/tlb_uv.c
+++ b/arch/x86/kernel/tlb_uv.c
@@ -717,7 +717,7 @@ uv_activation_descriptor_init(int node, int pnode)
717 adp = (struct bau_desc *)kmalloc_node(16384, GFP_KERNEL, node); 717 adp = (struct bau_desc *)kmalloc_node(16384, GFP_KERNEL, node);
718 BUG_ON(!adp); 718 BUG_ON(!adp);
719 719
720 pa = __pa((unsigned long)adp); 720 pa = uv_gpa(adp); /* need the real nasid*/
721 n = pa >> uv_nshift; 721 n = pa >> uv_nshift;
722 m = pa & uv_mmask; 722 m = pa & uv_mmask;
723 723
@@ -754,6 +754,8 @@ static struct bau_payload_queue_entry * __init
754uv_payload_queue_init(int node, int pnode, struct bau_control *bau_tablesp) 754uv_payload_queue_init(int node, int pnode, struct bau_control *bau_tablesp)
755{ 755{
756 struct bau_payload_queue_entry *pqp; 756 struct bau_payload_queue_entry *pqp;
757 unsigned long pa;
758 int pn;
757 char *cp; 759 char *cp;
758 760
759 pqp = (struct bau_payload_queue_entry *) kmalloc_node( 761 pqp = (struct bau_payload_queue_entry *) kmalloc_node(
@@ -764,10 +766,14 @@ uv_payload_queue_init(int node, int pnode, struct bau_control *bau_tablesp)
764 cp = (char *)pqp + 31; 766 cp = (char *)pqp + 31;
765 pqp = (struct bau_payload_queue_entry *)(((unsigned long)cp >> 5) << 5); 767 pqp = (struct bau_payload_queue_entry *)(((unsigned long)cp >> 5) << 5);
766 bau_tablesp->va_queue_first = pqp; 768 bau_tablesp->va_queue_first = pqp;
769 /*
770 * need the pnode of where the memory was really allocated
771 */
772 pa = uv_gpa(pqp);
773 pn = pa >> uv_nshift;
767 uv_write_global_mmr64(pnode, 774 uv_write_global_mmr64(pnode,
768 UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST, 775 UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST,
769 ((unsigned long)pnode << 776 ((unsigned long)pn << UV_PAYLOADQ_PNODE_SHIFT) |
770 UV_PAYLOADQ_PNODE_SHIFT) |
771 uv_physnodeaddr(pqp)); 777 uv_physnodeaddr(pqp));
772 uv_write_global_mmr64(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL, 778 uv_write_global_mmr64(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL,
773 uv_physnodeaddr(pqp)); 779 uv_physnodeaddr(pqp));