aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-xp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/sgi-xp')
-rw-r--r--drivers/misc/sgi-xp/xp.h10
-rw-r--r--drivers/misc/sgi-xp/xpc.h39
-rw-r--r--drivers/misc/sgi-xp/xpc_main.c31
-rw-r--r--drivers/misc/sgi-xp/xpc_partition.c31
-rw-r--r--drivers/misc/sgi-xp/xpc_sn2.c88
5 files changed, 97 insertions, 102 deletions
diff --git a/drivers/misc/sgi-xp/xp.h b/drivers/misc/sgi-xp/xp.h
index 43bf2470850..955b5b91323 100644
--- a/drivers/misc/sgi-xp/xp.h
+++ b/drivers/misc/sgi-xp/xp.h
@@ -61,16 +61,6 @@
61#define XP_MAX_NPARTITIONS_UV 256 61#define XP_MAX_NPARTITIONS_UV 256
62 62
63/* 63/*
64 * Define the number of u64s required to represent all the C-brick nasids
65 * as a bitmap. The cross-partition kernel modules deal only with
66 * C-brick nasids, thus the need for bitmaps which don't account for
67 * odd-numbered (non C-brick) nasids.
68 */
69#define XP_MAX_PHYSNODE_ID (MAX_NUMALINK_NODES / 2)
70#define XP_NASID_MASK_BYTES ((XP_MAX_PHYSNODE_ID + 7) / 8)
71#define XP_NASID_MASK_WORDS ((XP_MAX_PHYSNODE_ID + 63) / 64)
72
73/*
74 * XPC establishes channel connections between the local partition and any 64 * XPC establishes channel connections between the local partition and any
75 * other partition that is currently up. Over these channels, kernel-level 65 * other partition that is currently up. Over these channels, kernel-level
76 * `users' can communicate with their counterparts on the other partitions. 66 * `users' can communicate with their counterparts on the other partitions.
diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h
index defd0888118..2111723553b 100644
--- a/drivers/misc/sgi-xp/xpc.h
+++ b/drivers/misc/sgi-xp/xpc.h
@@ -151,26 +151,6 @@ struct xpc_vars_sn2 {
151#define XPC_V_VERSION _XPC_VERSION(3, 1) /* version 3.1 of the cross vars */ 151#define XPC_V_VERSION _XPC_VERSION(3, 1) /* version 3.1 of the cross vars */
152 152
153/* 153/*
154 * The following pertains to ia64-sn2 only.
155 *
156 * Memory for XPC's amo variables is allocated by the MSPEC driver. These
157 * pages are located in the lowest granule. The lowest granule uses 4k pages
158 * for cached references and an alternate TLB handler to never provide a
159 * cacheable mapping for the entire region. This will prevent speculative
160 * reading of cached copies of our lines from being issued which will cause
161 * a PI FSB Protocol error to be generated by the SHUB. For XPC, we need 64
162 * amo variables (based on XP_MAX_NPARTITIONS_SN2) to identify the senders of
163 * NOTIFY IRQs, 128 amo variables (based on XP_NASID_MASK_WORDS) to identify
164 * the senders of ACTIVATE IRQs, 1 amo variable to identify which remote
165 * partitions (i.e., XPCs) consider themselves currently engaged with the
166 * local XPC and 1 amo variable to request partition deactivation.
167 */
168#define XPC_NOTIFY_IRQ_AMOS 0
169#define XPC_ACTIVATE_IRQ_AMOS (XPC_NOTIFY_IRQ_AMOS + XP_MAX_NPARTITIONS_SN2)
170#define XPC_ENGAGED_PARTITIONS_AMO (XPC_ACTIVATE_IRQ_AMOS + XP_NASID_MASK_WORDS)
171#define XPC_DEACTIVATE_REQUEST_AMO (XPC_ENGAGED_PARTITIONS_AMO + 1)
172
173/*
174 * The following structure describes the per partition specific variables. 154 * The following structure describes the per partition specific variables.
175 * 155 *
176 * An array of these structures, one per partition, will be defined. As a 156 * An array of these structures, one per partition, will be defined. As a
@@ -214,9 +194,10 @@ struct xpc_vars_part_sn2 {
214#define XPC_RP_VARS_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_vars_sn2)) 194#define XPC_RP_VARS_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_vars_sn2))
215 195
216#define XPC_RP_PART_NASIDS(_rp) ((u64 *)((u8 *)(_rp) + XPC_RP_HEADER_SIZE)) 196#define XPC_RP_PART_NASIDS(_rp) ((u64 *)((u8 *)(_rp) + XPC_RP_HEADER_SIZE))
217#define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + xp_nasid_mask_words) 197#define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + xpc_nasid_mask_words)
218#define XPC_RP_VARS(_rp) ((struct xpc_vars_sn2 *)(XPC_RP_MACH_NASIDS(_rp) + \ 198#define XPC_RP_VARS(_rp) ((struct xpc_vars_sn2 *) \
219 xp_nasid_mask_words)) 199 (XPC_RP_MACH_NASIDS(_rp) + \
200 xpc_nasid_mask_words))
220 201
221/* 202/*
222 * Functions registered by add_timer() or called by kernel_thread() only 203 * Functions registered by add_timer() or called by kernel_thread() only
@@ -225,11 +206,11 @@ struct xpc_vars_part_sn2 {
225 * the passed argument. 206 * the passed argument.
226 */ 207 */
227#define XPC_PACK_ARGS(_arg1, _arg2) \ 208#define XPC_PACK_ARGS(_arg1, _arg2) \
228 ((((u64) _arg1) & 0xffffffff) | \ 209 ((((u64)_arg1) & 0xffffffff) | \
229 ((((u64) _arg2) & 0xffffffff) << 32)) 210 ((((u64)_arg2) & 0xffffffff) << 32))
230 211
231#define XPC_UNPACK_ARG1(_args) (((u64) _args) & 0xffffffff) 212#define XPC_UNPACK_ARG1(_args) (((u64)_args) & 0xffffffff)
232#define XPC_UNPACK_ARG2(_args) ((((u64) _args) >> 32) & 0xffffffff) 213#define XPC_UNPACK_ARG2(_args) ((((u64)_args) >> 32) & 0xffffffff)
233 214
234/* 215/*
235 * Define a Get/Put value pair (pointers) used with a message queue. 216 * Define a Get/Put value pair (pointers) used with a message queue.
@@ -710,12 +691,10 @@ extern void xpc_exit_uv(void);
710 691
711/* found in xpc_partition.c */ 692/* found in xpc_partition.c */
712extern int xpc_exiting; 693extern int xpc_exiting;
713extern int xp_nasid_mask_words; 694extern int xpc_nasid_mask_words;
714extern struct xpc_rsvd_page *xpc_rsvd_page; 695extern struct xpc_rsvd_page *xpc_rsvd_page;
715extern u64 *xpc_mach_nasids; 696extern u64 *xpc_mach_nasids;
716extern struct xpc_partition *xpc_partitions; 697extern struct xpc_partition *xpc_partitions;
717extern char *xpc_remote_copy_buffer;
718extern void *xpc_remote_copy_buffer_base;
719extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **); 698extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **);
720extern struct xpc_rsvd_page *xpc_setup_rsvd_page(void); 699extern struct xpc_rsvd_page *xpc_setup_rsvd_page(void);
721extern int xpc_identify_activate_IRQ_sender(void); 700extern int xpc_identify_activate_IRQ_sender(void);
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c
index b5f3c5e59db..36dfccea524 100644
--- a/drivers/misc/sgi-xp/xpc_main.c
+++ b/drivers/misc/sgi-xp/xpc_main.c
@@ -877,7 +877,6 @@ xpc_do_exit(enum xp_retval reason)
877 unregister_sysctl_table(xpc_sysctl); 877 unregister_sysctl_table(xpc_sysctl);
878 878
879 kfree(xpc_partitions); 879 kfree(xpc_partitions);
880 kfree(xpc_remote_copy_buffer_base);
881 880
882 if (is_shub()) 881 if (is_shub())
883 xpc_exit_sn2(); 882 xpc_exit_sn2();
@@ -1031,7 +1030,9 @@ xpc_init(void)
1031 short partid; 1030 short partid;
1032 struct xpc_partition *part; 1031 struct xpc_partition *part;
1033 struct task_struct *kthread; 1032 struct task_struct *kthread;
1034 size_t buf_size; 1033
1034 snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part");
1035 snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan");
1035 1036
1036 if (is_shub()) { 1037 if (is_shub()) {
1037 /* 1038 /*
@@ -1054,26 +1055,12 @@ xpc_init(void)
1054 return -ENODEV; 1055 return -ENODEV;
1055 } 1056 }
1056 1057
1057 snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part");
1058 snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan");
1059
1060 buf_size = max(XPC_RP_VARS_SIZE,
1061 XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES);
1062 xpc_remote_copy_buffer = xpc_kmalloc_cacheline_aligned(buf_size,
1063 GFP_KERNEL,
1064 &xpc_remote_copy_buffer_base);
1065 if (xpc_remote_copy_buffer == NULL) {
1066 dev_err(xpc_part, "can't get memory for remote copy buffer\n");
1067 ret = -ENOMEM;
1068 goto out_1;
1069 }
1070
1071 xpc_partitions = kzalloc(sizeof(struct xpc_partition) * 1058 xpc_partitions = kzalloc(sizeof(struct xpc_partition) *
1072 xp_max_npartitions, GFP_KERNEL); 1059 xp_max_npartitions, GFP_KERNEL);
1073 if (xpc_partitions == NULL) { 1060 if (xpc_partitions == NULL) {
1074 dev_err(xpc_part, "can't get memory for partition structure\n"); 1061 dev_err(xpc_part, "can't get memory for partition structure\n");
1075 ret = -ENOMEM; 1062 ret = -ENOMEM;
1076 goto out_2; 1063 goto out_1;
1077 } 1064 }
1078 1065
1079 /* 1066 /*
@@ -1115,7 +1102,7 @@ xpc_init(void)
1115 if (xpc_rsvd_page == NULL) { 1102 if (xpc_rsvd_page == NULL) {
1116 dev_err(xpc_part, "can't setup our reserved page\n"); 1103 dev_err(xpc_part, "can't setup our reserved page\n");
1117 ret = -EBUSY; 1104 ret = -EBUSY;
1118 goto out_3; 1105 goto out_2;
1119 } 1106 }
1120 1107
1121 /* add ourselves to the reboot_notifier_list */ 1108 /* add ourselves to the reboot_notifier_list */
@@ -1136,7 +1123,7 @@ xpc_init(void)
1136 if (IS_ERR(kthread)) { 1123 if (IS_ERR(kthread)) {
1137 dev_err(xpc_part, "failed while forking hb check thread\n"); 1124 dev_err(xpc_part, "failed while forking hb check thread\n");
1138 ret = -EBUSY; 1125 ret = -EBUSY;
1139 goto out_4; 1126 goto out_3;
1140 } 1127 }
1141 1128
1142 /* 1129 /*
@@ -1164,18 +1151,16 @@ xpc_init(void)
1164 return 0; 1151 return 0;
1165 1152
1166 /* initialization was not successful */ 1153 /* initialization was not successful */
1167out_4: 1154out_3:
1168 /* indicate to others that our reserved page is uninitialized */ 1155 /* indicate to others that our reserved page is uninitialized */
1169 xpc_rsvd_page->stamp = 0; 1156 xpc_rsvd_page->stamp = 0;
1170 1157
1171 (void)unregister_die_notifier(&xpc_die_notifier); 1158 (void)unregister_die_notifier(&xpc_die_notifier);
1172 (void)unregister_reboot_notifier(&xpc_reboot_notifier); 1159 (void)unregister_reboot_notifier(&xpc_reboot_notifier);
1173out_3: 1160out_2:
1174 if (xpc_sysctl) 1161 if (xpc_sysctl)
1175 unregister_sysctl_table(xpc_sysctl); 1162 unregister_sysctl_table(xpc_sysctl);
1176 kfree(xpc_partitions); 1163 kfree(xpc_partitions);
1177out_2:
1178 kfree(xpc_remote_copy_buffer_base);
1179out_1: 1164out_1:
1180 if (is_shub()) 1165 if (is_shub())
1181 xpc_exit_sn2(); 1166 xpc_exit_sn2();
diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c
index c769ab8f74e..9f104450478 100644
--- a/drivers/misc/sgi-xp/xpc_partition.c
+++ b/drivers/misc/sgi-xp/xpc_partition.c
@@ -34,21 +34,12 @@ struct xpc_rsvd_page *xpc_rsvd_page;
34static u64 *xpc_part_nasids; 34static u64 *xpc_part_nasids;
35u64 *xpc_mach_nasids; 35u64 *xpc_mach_nasids;
36 36
37/* >>> next two variables should be 'xpc_' if they remain here */ 37static int xpc_sizeof_nasid_mask; /* actual size in bytes of nasid mask */
38static int xp_sizeof_nasid_mask; /* actual size in bytes of nasid mask */ 38int xpc_nasid_mask_words; /* actual size in words of nasid mask */
39int xp_nasid_mask_words; /* actual size in words of nasid mask */
40 39
41struct xpc_partition *xpc_partitions; 40struct xpc_partition *xpc_partitions;
42 41
43/* 42/*
44 * Generic buffer used to store a local copy of portions of a remote
45 * partition's reserved page (either its header and part_nasids mask,
46 * or its vars).
47 */
48char *xpc_remote_copy_buffer;
49void *xpc_remote_copy_buffer_base;
50
51/*
52 * Guarantee that the kmalloc'd memory is cacheline aligned. 43 * Guarantee that the kmalloc'd memory is cacheline aligned.
53 */ 44 */
54void * 45void *
@@ -176,9 +167,9 @@ xpc_setup_rsvd_page(void)
176 /* SAL_version 1 didn't set the nasids_size field */ 167 /* SAL_version 1 didn't set the nasids_size field */
177 rp->SAL_nasids_size = 128; 168 rp->SAL_nasids_size = 128;
178 } 169 }
179 xp_sizeof_nasid_mask = rp->SAL_nasids_size; 170 xpc_sizeof_nasid_mask = rp->SAL_nasids_size;
180 xp_nasid_mask_words = DIV_ROUND_UP(xp_sizeof_nasid_mask, 171 xpc_nasid_mask_words = DIV_ROUND_UP(xpc_sizeof_nasid_mask,
181 BYTES_PER_WORD); 172 BYTES_PER_WORD);
182 173
183 /* setup the pointers to the various items in the reserved page */ 174 /* setup the pointers to the various items in the reserved page */
184 xpc_part_nasids = XPC_RP_PART_NASIDS(rp); 175 xpc_part_nasids = XPC_RP_PART_NASIDS(rp);
@@ -222,14 +213,14 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
222 213
223 /* pull over the reserved page header and part_nasids mask */ 214 /* pull over the reserved page header and part_nasids mask */
224 ret = xp_remote_memcpy(remote_rp, (void *)*remote_rp_pa, 215 ret = xp_remote_memcpy(remote_rp, (void *)*remote_rp_pa,
225 XPC_RP_HEADER_SIZE + xp_sizeof_nasid_mask); 216 XPC_RP_HEADER_SIZE + xpc_sizeof_nasid_mask);
226 if (ret != xpSuccess) 217 if (ret != xpSuccess)
227 return ret; 218 return ret;
228 219
229 if (discovered_nasids != NULL) { 220 if (discovered_nasids != NULL) {
230 u64 *remote_part_nasids = XPC_RP_PART_NASIDS(remote_rp); 221 u64 *remote_part_nasids = XPC_RP_PART_NASIDS(remote_rp);
231 222
232 for (i = 0; i < xp_nasid_mask_words; i++) 223 for (i = 0; i < xpc_nasid_mask_words; i++)
233 discovered_nasids[i] |= remote_part_nasids[i]; 224 discovered_nasids[i] |= remote_part_nasids[i];
234 } 225 }
235 226
@@ -414,12 +405,12 @@ xpc_discovery(void)
414 enum xp_retval ret; 405 enum xp_retval ret;
415 406
416 remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE + 407 remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE +
417 xp_sizeof_nasid_mask, 408 xpc_sizeof_nasid_mask,
418 GFP_KERNEL, &remote_rp_base); 409 GFP_KERNEL, &remote_rp_base);
419 if (remote_rp == NULL) 410 if (remote_rp == NULL)
420 return; 411 return;
421 412
422 discovered_nasids = kzalloc(sizeof(u64) * xp_nasid_mask_words, 413 discovered_nasids = kzalloc(sizeof(u64) * xpc_nasid_mask_words,
423 GFP_KERNEL); 414 GFP_KERNEL);
424 if (discovered_nasids == NULL) { 415 if (discovered_nasids == NULL) {
425 kfree(remote_rp_base); 416 kfree(remote_rp_base);
@@ -521,10 +512,10 @@ xpc_initiate_partid_to_nasids(short partid, void *nasid_mask)
521 if (part->remote_rp_pa == 0) 512 if (part->remote_rp_pa == 0)
522 return xpPartitionDown; 513 return xpPartitionDown;
523 514
524 memset(nasid_mask, 0, XP_NASID_MASK_BYTES); 515 memset(nasid_mask, 0, xpc_sizeof_nasid_mask);
525 516
526 part_nasid_pa = (u64)XPC_RP_PART_NASIDS(part->remote_rp_pa); 517 part_nasid_pa = (u64)XPC_RP_PART_NASIDS(part->remote_rp_pa);
527 518
528 return xp_remote_memcpy(nasid_mask, (void *)part_nasid_pa, 519 return xp_remote_memcpy(nasid_mask, (void *)part_nasid_pa,
529 xp_sizeof_nasid_mask); 520 xpc_sizeof_nasid_mask);
530} 521}
diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c
index e5dc8c44c6f..9c0c29a2ac8 100644
--- a/drivers/misc/sgi-xp/xpc_sn2.c
+++ b/drivers/misc/sgi-xp/xpc_sn2.c
@@ -19,6 +19,43 @@
19#include <asm/sn/sn_sal.h> 19#include <asm/sn/sn_sal.h>
20#include "xpc.h" 20#include "xpc.h"
21 21
22/*
23 * Define the number of u64s required to represent all the C-brick nasids
24 * as a bitmap. The cross-partition kernel modules deal only with
25 * C-brick nasids, thus the need for bitmaps which don't account for
26 * odd-numbered (non C-brick) nasids.
27 */
28#define XPC_MAX_PHYSNODES_SN2 (MAX_NUMALINK_NODES / 2)
29#define XP_NASID_MASK_BYTES_SN2 ((XPC_MAX_PHYSNODES_SN2 + 7) / 8)
30#define XP_NASID_MASK_WORDS_SN2 ((XPC_MAX_PHYSNODES_SN2 + 63) / 64)
31
32/*
33 * Memory for XPC's amo variables is allocated by the MSPEC driver. These
34 * pages are located in the lowest granule. The lowest granule uses 4k pages
35 * for cached references and an alternate TLB handler to never provide a
36 * cacheable mapping for the entire region. This will prevent speculative
37 * reading of cached copies of our lines from being issued which will cause
38 * a PI FSB Protocol error to be generated by the SHUB. For XPC, we need 64
39 * amo variables (based on XP_MAX_NPARTITIONS_SN2) to identify the senders of
40 * NOTIFY IRQs, 128 amo variables (based on XP_NASID_MASK_WORDS_SN2) to identify
41 * the senders of ACTIVATE IRQs, 1 amo variable to identify which remote
42 * partitions (i.e., XPCs) consider themselves currently engaged with the
43 * local XPC and 1 amo variable to request partition deactivation.
44 */
45#define XPC_NOTIFY_IRQ_AMOS_SN2 0
46#define XPC_ACTIVATE_IRQ_AMOS_SN2 (XPC_NOTIFY_IRQ_AMOS_SN2 + \
47 XP_MAX_NPARTITIONS_SN2)
48#define XPC_ENGAGED_PARTITIONS_AMO_SN2 (XPC_ACTIVATE_IRQ_AMOS_SN2 + \
49 XP_NASID_MASK_WORDS_SN2)
50#define XPC_DEACTIVATE_REQUEST_AMO_SN2 (XPC_ENGAGED_PARTITIONS_AMO_SN2 + 1)
51
52/*
53 * Buffer used to store a local copy of portions of a remote partition's
54 * reserved page (either its header and part_nasids mask, or its vars).
55 */
56static char *xpc_remote_copy_buffer_sn2;
57static void *xpc_remote_copy_buffer_base_sn2;
58
22static struct xpc_vars_sn2 *xpc_vars; /* >>> Add _sn2 suffix? */ 59static struct xpc_vars_sn2 *xpc_vars; /* >>> Add _sn2 suffix? */
23static struct xpc_vars_part_sn2 *xpc_vars_part; /* >>> Add _sn2 suffix? */ 60static struct xpc_vars_part_sn2 *xpc_vars_part; /* >>> Add _sn2 suffix? */
24 61
@@ -176,7 +213,7 @@ xpc_send_activate_IRQ_sn2(u64 amos_page_pa, int from_nasid, int to_nasid,
176 int w_index = XPC_NASID_W_INDEX(from_nasid); 213 int w_index = XPC_NASID_W_INDEX(from_nasid);
177 int b_index = XPC_NASID_B_INDEX(from_nasid); 214 int b_index = XPC_NASID_B_INDEX(from_nasid);
178 struct amo *amos = (struct amo *)__va(amos_page_pa + 215 struct amo *amos = (struct amo *)__va(amos_page_pa +
179 (XPC_ACTIVATE_IRQ_AMOS * 216 (XPC_ACTIVATE_IRQ_AMOS_SN2 *
180 sizeof(struct amo))); 217 sizeof(struct amo)));
181 218
182 (void)xpc_send_IRQ_sn2(&amos[w_index], (1UL << b_index), to_nasid, 219 (void)xpc_send_IRQ_sn2(&amos[w_index], (1UL << b_index), to_nasid,
@@ -189,7 +226,7 @@ xpc_send_local_activate_IRQ_sn2(int from_nasid)
189 int w_index = XPC_NASID_W_INDEX(from_nasid); 226 int w_index = XPC_NASID_W_INDEX(from_nasid);
190 int b_index = XPC_NASID_B_INDEX(from_nasid); 227 int b_index = XPC_NASID_B_INDEX(from_nasid);
191 struct amo *amos = (struct amo *)__va(xpc_vars->amos_page_pa + 228 struct amo *amos = (struct amo *)__va(xpc_vars->amos_page_pa +
192 (XPC_ACTIVATE_IRQ_AMOS * 229 (XPC_ACTIVATE_IRQ_AMOS_SN2 *
193 sizeof(struct amo))); 230 sizeof(struct amo)));
194 231
195 /* fake the sending and receipt of an activate IRQ from remote nasid */ 232 /* fake the sending and receipt of an activate IRQ from remote nasid */
@@ -395,7 +432,7 @@ xpc_indicate_partition_engaged_sn2(struct xpc_partition *part)
395{ 432{
396 unsigned long irq_flags; 433 unsigned long irq_flags;
397 struct amo *amo = (struct amo *)__va(part->sn.sn2.remote_amos_page_pa + 434 struct amo *amo = (struct amo *)__va(part->sn.sn2.remote_amos_page_pa +
398 (XPC_ENGAGED_PARTITIONS_AMO * 435 (XPC_ENGAGED_PARTITIONS_AMO_SN2 *
399 sizeof(struct amo))); 436 sizeof(struct amo)));
400 437
401 local_irq_save(irq_flags); 438 local_irq_save(irq_flags);
@@ -422,7 +459,7 @@ xpc_indicate_partition_disengaged_sn2(struct xpc_partition *part)
422 struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2; 459 struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
423 unsigned long irq_flags; 460 unsigned long irq_flags;
424 struct amo *amo = (struct amo *)__va(part_sn2->remote_amos_page_pa + 461 struct amo *amo = (struct amo *)__va(part_sn2->remote_amos_page_pa +
425 (XPC_ENGAGED_PARTITIONS_AMO * 462 (XPC_ENGAGED_PARTITIONS_AMO_SN2 *
426 sizeof(struct amo))); 463 sizeof(struct amo)));
427 464
428 local_irq_save(irq_flags); 465 local_irq_save(irq_flags);
@@ -455,7 +492,7 @@ xpc_indicate_partition_disengaged_sn2(struct xpc_partition *part)
455static int 492static int
456xpc_partition_engaged_sn2(short partid) 493xpc_partition_engaged_sn2(short partid)
457{ 494{
458 struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO; 495 struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO_SN2;
459 496
460 /* our partition's amo variable ANDed with partid mask */ 497 /* our partition's amo variable ANDed with partid mask */
461 return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) & 498 return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
@@ -465,7 +502,7 @@ xpc_partition_engaged_sn2(short partid)
465static int 502static int
466xpc_any_partition_engaged_sn2(void) 503xpc_any_partition_engaged_sn2(void)
467{ 504{
468 struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO; 505 struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO_SN2;
469 506
470 /* our partition's amo variable */ 507 /* our partition's amo variable */
471 return FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) != 0; 508 return FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) != 0;
@@ -474,7 +511,7 @@ xpc_any_partition_engaged_sn2(void)
474static void 511static void
475xpc_assume_partition_disengaged_sn2(short partid) 512xpc_assume_partition_disengaged_sn2(short partid)
476{ 513{
477 struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO; 514 struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO_SN2;
478 515
479 /* clear bit(s) based on partid mask in our partition's amo */ 516 /* clear bit(s) based on partid mask in our partition's amo */
480 FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND, 517 FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
@@ -599,12 +636,12 @@ xpc_rsvd_page_init_sn2(struct xpc_rsvd_page *rp)
599 xp_max_npartitions); 636 xp_max_npartitions);
600 637
601 /* initialize the activate IRQ related amo variables */ 638 /* initialize the activate IRQ related amo variables */
602 for (i = 0; i < xp_nasid_mask_words; i++) 639 for (i = 0; i < xpc_nasid_mask_words; i++)
603 (void)xpc_init_IRQ_amo_sn2(XPC_ACTIVATE_IRQ_AMOS + i); 640 (void)xpc_init_IRQ_amo_sn2(XPC_ACTIVATE_IRQ_AMOS_SN2 + i);
604 641
605 /* initialize the engaged remote partitions related amo variables */ 642 /* initialize the engaged remote partitions related amo variables */
606 (void)xpc_init_IRQ_amo_sn2(XPC_ENGAGED_PARTITIONS_AMO); 643 (void)xpc_init_IRQ_amo_sn2(XPC_ENGAGED_PARTITIONS_AMO_SN2);
607 (void)xpc_init_IRQ_amo_sn2(XPC_DEACTIVATE_REQUEST_AMO); 644 (void)xpc_init_IRQ_amo_sn2(XPC_DEACTIVATE_REQUEST_AMO_SN2);
608 645
609 return xpSuccess; 646 return xpSuccess;
610} 647}
@@ -657,7 +694,7 @@ xpc_check_remote_hb_sn2(void)
657 short partid; 694 short partid;
658 enum xp_retval ret; 695 enum xp_retval ret;
659 696
660 remote_vars = (struct xpc_vars_sn2 *)xpc_remote_copy_buffer; 697 remote_vars = (struct xpc_vars_sn2 *)xpc_remote_copy_buffer_sn2;
661 698
662 for (partid = 0; partid < xp_max_npartitions; partid++) { 699 for (partid = 0; partid < xp_max_npartitions; partid++) {
663 700
@@ -749,7 +786,7 @@ xpc_request_partition_deactivation_sn2(struct xpc_partition *part)
749 struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2; 786 struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
750 unsigned long irq_flags; 787 unsigned long irq_flags;
751 struct amo *amo = (struct amo *)__va(part_sn2->remote_amos_page_pa + 788 struct amo *amo = (struct amo *)__va(part_sn2->remote_amos_page_pa +
752 (XPC_DEACTIVATE_REQUEST_AMO * 789 (XPC_DEACTIVATE_REQUEST_AMO_SN2 *
753 sizeof(struct amo))); 790 sizeof(struct amo)));
754 791
755 local_irq_save(irq_flags); 792 local_irq_save(irq_flags);
@@ -784,7 +821,7 @@ xpc_cancel_partition_deactivation_request_sn2(struct xpc_partition *part)
784{ 821{
785 unsigned long irq_flags; 822 unsigned long irq_flags;
786 struct amo *amo = (struct amo *)__va(part->sn.sn2.remote_amos_page_pa + 823 struct amo *amo = (struct amo *)__va(part->sn.sn2.remote_amos_page_pa +
787 (XPC_DEACTIVATE_REQUEST_AMO * 824 (XPC_DEACTIVATE_REQUEST_AMO_SN2 *
788 sizeof(struct amo))); 825 sizeof(struct amo)));
789 826
790 local_irq_save(irq_flags); 827 local_irq_save(irq_flags);
@@ -808,7 +845,7 @@ xpc_cancel_partition_deactivation_request_sn2(struct xpc_partition *part)
808static int 845static int
809xpc_partition_deactivation_requested_sn2(short partid) 846xpc_partition_deactivation_requested_sn2(short partid)
810{ 847{
811 struct amo *amo = xpc_vars->amos_page + XPC_DEACTIVATE_REQUEST_AMO; 848 struct amo *amo = xpc_vars->amos_page + XPC_DEACTIVATE_REQUEST_AMO_SN2;
812 849
813 /* our partition's amo variable ANDed with partid mask */ 850 /* our partition's amo variable ANDed with partid mask */
814 return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) & 851 return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
@@ -898,7 +935,7 @@ xpc_identify_activate_IRQ_req_sn2(int nasid)
898 935
899 /* pull over the reserved page structure */ 936 /* pull over the reserved page structure */
900 937
901 remote_rp = (struct xpc_rsvd_page *)xpc_remote_copy_buffer; 938 remote_rp = (struct xpc_rsvd_page *)xpc_remote_copy_buffer_sn2;
902 939
903 ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rp_pa); 940 ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rp_pa);
904 if (ret != xpSuccess) { 941 if (ret != xpSuccess) {
@@ -917,7 +954,7 @@ xpc_identify_activate_IRQ_req_sn2(int nasid)
917 954
918 /* pull over the cross partition variables */ 955 /* pull over the cross partition variables */
919 956
920 remote_vars = (struct xpc_vars_sn2 *)xpc_remote_copy_buffer; 957 remote_vars = (struct xpc_vars_sn2 *)xpc_remote_copy_buffer_sn2;
921 958
922 ret = xpc_get_remote_vars_sn2(remote_vars_pa, remote_vars); 959 ret = xpc_get_remote_vars_sn2(remote_vars_pa, remote_vars);
923 if (ret != xpSuccess) { 960 if (ret != xpSuccess) {
@@ -996,10 +1033,10 @@ xpc_identify_activate_IRQ_sender_sn2(void)
996 int n_IRQs_detected = 0; 1033 int n_IRQs_detected = 0;
997 struct amo *act_amos; 1034 struct amo *act_amos;
998 1035
999 act_amos = xpc_vars->amos_page + XPC_ACTIVATE_IRQ_AMOS; 1036 act_amos = xpc_vars->amos_page + XPC_ACTIVATE_IRQ_AMOS_SN2;
1000 1037
1001 /* scan through act amo variable looking for non-zero entries */ 1038 /* scan through act amo variable looking for non-zero entries */
1002 for (word = 0; word < xp_nasid_mask_words; word++) { 1039 for (word = 0; word < xpc_nasid_mask_words; word++) {
1003 1040
1004 if (xpc_exiting) 1041 if (xpc_exiting)
1005 break; 1042 break;
@@ -2334,6 +2371,7 @@ int
2334xpc_init_sn2(void) 2371xpc_init_sn2(void)
2335{ 2372{
2336 int ret; 2373 int ret;
2374 size_t buf_size;
2337 2375
2338 xpc_rsvd_page_init = xpc_rsvd_page_init_sn2; 2376 xpc_rsvd_page_init = xpc_rsvd_page_init_sn2;
2339 xpc_increment_heartbeat = xpc_increment_heartbeat_sn2; 2377 xpc_increment_heartbeat = xpc_increment_heartbeat_sn2;
@@ -2378,6 +2416,16 @@ xpc_init_sn2(void)
2378 xpc_send_msg = xpc_send_msg_sn2; 2416 xpc_send_msg = xpc_send_msg_sn2;
2379 xpc_received_msg = xpc_received_msg_sn2; 2417 xpc_received_msg = xpc_received_msg_sn2;
2380 2418
2419 buf_size = max(XPC_RP_VARS_SIZE,
2420 XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES_SN2);
2421 xpc_remote_copy_buffer_sn2 = xpc_kmalloc_cacheline_aligned(buf_size,
2422 GFP_KERNEL,
2423 &xpc_remote_copy_buffer_base_sn2);
2424 if (xpc_remote_copy_buffer_sn2 == NULL) {
2425 dev_err(xpc_part, "can't get memory for remote copy buffer\n");
2426 return -ENOMEM;
2427 }
2428
2381 /* open up protections for IPI and [potentially] amo operations */ 2429 /* open up protections for IPI and [potentially] amo operations */
2382 xpc_allow_IPI_ops_sn2(); 2430 xpc_allow_IPI_ops_sn2();
2383 xpc_allow_amo_ops_shub_wars_1_1_sn2(); 2431 xpc_allow_amo_ops_shub_wars_1_1_sn2();
@@ -2394,6 +2442,7 @@ xpc_init_sn2(void)
2394 dev_err(xpc_part, "can't register ACTIVATE IRQ handler, " 2442 dev_err(xpc_part, "can't register ACTIVATE IRQ handler, "
2395 "errno=%d\n", -ret); 2443 "errno=%d\n", -ret);
2396 xpc_disallow_IPI_ops_sn2(); 2444 xpc_disallow_IPI_ops_sn2();
2445 kfree(xpc_remote_copy_buffer_base_sn2);
2397 } 2446 }
2398 return ret; 2447 return ret;
2399} 2448}
@@ -2403,4 +2452,5 @@ xpc_exit_sn2(void)
2403{ 2452{
2404 free_irq(SGI_XPC_ACTIVATE, NULL); 2453 free_irq(SGI_XPC_ACTIVATE, NULL);
2405 xpc_disallow_IPI_ops_sn2(); 2454 xpc_disallow_IPI_ops_sn2();
2455 kfree(xpc_remote_copy_buffer_base_sn2);
2406} 2456}