diff options
Diffstat (limited to 'drivers/misc/sgi-xp/xpc_partition.c')
-rw-r--r-- | drivers/misc/sgi-xp/xpc_partition.c | 99 |
1 files changed, 43 insertions, 56 deletions
diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c index 57f1d0b3ac26..27e200ec5826 100644 --- a/drivers/misc/sgi-xp/xpc_partition.c +++ b/drivers/misc/sgi-xp/xpc_partition.c | |||
@@ -75,19 +75,19 @@ xpc_kmalloc_cacheline_aligned(size_t size, gfp_t flags, void **base) | |||
75 | { | 75 | { |
76 | /* see if kmalloc will give us cachline aligned memory by default */ | 76 | /* see if kmalloc will give us cachline aligned memory by default */ |
77 | *base = kmalloc(size, flags); | 77 | *base = kmalloc(size, flags); |
78 | if (*base == NULL) { | 78 | if (*base == NULL) |
79 | return NULL; | 79 | return NULL; |
80 | } | 80 | |
81 | if ((u64)*base == L1_CACHE_ALIGN((u64)*base)) { | 81 | if ((u64)*base == L1_CACHE_ALIGN((u64)*base)) |
82 | return *base; | 82 | return *base; |
83 | } | 83 | |
84 | kfree(*base); | 84 | kfree(*base); |
85 | 85 | ||
86 | /* nope, we'll have to do it ourselves */ | 86 | /* nope, we'll have to do it ourselves */ |
87 | *base = kmalloc(size + L1_CACHE_BYTES, flags); | 87 | *base = kmalloc(size + L1_CACHE_BYTES, flags); |
88 | if (*base == NULL) { | 88 | if (*base == NULL) |
89 | return NULL; | 89 | return NULL; |
90 | } | 90 | |
91 | return (void *)L1_CACHE_ALIGN((u64)*base); | 91 | return (void *)L1_CACHE_ALIGN((u64)*base); |
92 | } | 92 | } |
93 | 93 | ||
@@ -116,9 +116,8 @@ xpc_get_rsvd_page_pa(int nasid) | |||
116 | "0x%016lx, address=0x%016lx, len=0x%016lx\n", | 116 | "0x%016lx, address=0x%016lx, len=0x%016lx\n", |
117 | status, cookie, rp_pa, len); | 117 | status, cookie, rp_pa, len); |
118 | 118 | ||
119 | if (status != SALRET_MORE_PASSES) { | 119 | if (status != SALRET_MORE_PASSES) |
120 | break; | 120 | break; |
121 | } | ||
122 | 121 | ||
123 | if (L1_CACHE_ALIGN(len) > buf_len) { | 122 | if (L1_CACHE_ALIGN(len) > buf_len) { |
124 | kfree(buf_base); | 123 | kfree(buf_base); |
@@ -145,9 +144,9 @@ xpc_get_rsvd_page_pa(int nasid) | |||
145 | 144 | ||
146 | kfree(buf_base); | 145 | kfree(buf_base); |
147 | 146 | ||
148 | if (status != SALRET_OK) { | 147 | if (status != SALRET_OK) |
149 | rp_pa = 0; | 148 | rp_pa = 0; |
150 | } | 149 | |
151 | dev_dbg(xpc_part, "reserved page at phys address 0x%016lx\n", rp_pa); | 150 | dev_dbg(xpc_part, "reserved page at phys address 0x%016lx\n", rp_pa); |
152 | return rp_pa; | 151 | return rp_pa; |
153 | } | 152 | } |
@@ -210,7 +209,8 @@ xpc_rsvd_page_init(void) | |||
210 | * on subsequent loads of XPC. This AMO page is never freed, and its | 209 | * on subsequent loads of XPC. This AMO page is never freed, and its |
211 | * memory protections are never restricted. | 210 | * memory protections are never restricted. |
212 | */ | 211 | */ |
213 | if ((amos_page = xpc_vars->amos_page) == NULL) { | 212 | amos_page = xpc_vars->amos_page; |
213 | if (amos_page == NULL) { | ||
214 | amos_page = (AMO_t *)TO_AMO(uncached_alloc_page(0)); | 214 | amos_page = (AMO_t *)TO_AMO(uncached_alloc_page(0)); |
215 | if (amos_page == NULL) { | 215 | if (amos_page == NULL) { |
216 | dev_err(xpc_part, "can't allocate page of AMOs\n"); | 216 | dev_err(xpc_part, "can't allocate page of AMOs\n"); |
@@ -264,9 +264,8 @@ xpc_rsvd_page_init(void) | |||
264 | XP_MAX_PARTITIONS); | 264 | XP_MAX_PARTITIONS); |
265 | 265 | ||
266 | /* initialize the activate IRQ related AMO variables */ | 266 | /* initialize the activate IRQ related AMO variables */ |
267 | for (i = 0; i < xp_nasid_mask_words; i++) { | 267 | for (i = 0; i < xp_nasid_mask_words; i++) |
268 | (void)xpc_IPI_init(XPC_ACTIVATE_IRQ_AMOS + i); | 268 | (void)xpc_IPI_init(XPC_ACTIVATE_IRQ_AMOS + i); |
269 | } | ||
270 | 269 | ||
271 | /* initialize the engaged remote partitions related AMO variables */ | 270 | /* initialize the engaged remote partitions related AMO variables */ |
272 | (void)xpc_IPI_init(XPC_ENGAGED_PARTITIONS_AMO); | 271 | (void)xpc_IPI_init(XPC_ENGAGED_PARTITIONS_AMO); |
@@ -294,7 +293,7 @@ xpc_allow_IPI_ops(void) | |||
294 | int node; | 293 | int node; |
295 | int nasid; | 294 | int nasid; |
296 | 295 | ||
297 | // >>> Change SH_IPI_ACCESS code to use SAL call once it is available. | 296 | /* >>> Change SH_IPI_ACCESS code to use SAL call once it is available */ |
298 | 297 | ||
299 | if (is_shub2()) { | 298 | if (is_shub2()) { |
300 | xpc_sh2_IPI_access0 = | 299 | xpc_sh2_IPI_access0 = |
@@ -336,14 +335,14 @@ xpc_allow_IPI_ops(void) | |||
336 | xpc_prot_vec[node] = (u64)HUB_L((u64 *) | 335 | xpc_prot_vec[node] = (u64)HUB_L((u64 *) |
337 | GLOBAL_MMR_ADDR | 336 | GLOBAL_MMR_ADDR |
338 | (nasid, | 337 | (nasid, |
339 | SH1_MD_DQLP_MMR_DIR_PRIVEC0)); | 338 | SH1_MD_DQLP_MMR_DIR_PRIVEC0)); |
340 | HUB_S((u64 *) | 339 | HUB_S((u64 *) |
341 | GLOBAL_MMR_ADDR(nasid, | 340 | GLOBAL_MMR_ADDR(nasid, |
342 | SH1_MD_DQLP_MMR_DIR_PRIVEC0), | 341 | SH1_MD_DQLP_MMR_DIR_PRIVEC0), |
343 | -1UL); | 342 | -1UL); |
344 | HUB_S((u64 *) | 343 | HUB_S((u64 *) |
345 | GLOBAL_MMR_ADDR(nasid, | 344 | GLOBAL_MMR_ADDR(nasid, |
346 | SH1_MD_DQRP_MMR_DIR_PRIVEC0), | 345 | SH1_MD_DQRP_MMR_DIR_PRIVEC0), |
347 | -1UL); | 346 | -1UL); |
348 | } | 347 | } |
349 | } | 348 | } |
@@ -360,7 +359,7 @@ xpc_restrict_IPI_ops(void) | |||
360 | int node; | 359 | int node; |
361 | int nasid; | 360 | int nasid; |
362 | 361 | ||
363 | // >>> Change SH_IPI_ACCESS code to use SAL call once it is available. | 362 | /* >>> Change SH_IPI_ACCESS code to use SAL call once it is available */ |
364 | 363 | ||
365 | if (is_shub2()) { | 364 | if (is_shub2()) { |
366 | 365 | ||
@@ -385,10 +384,10 @@ xpc_restrict_IPI_ops(void) | |||
385 | 384 | ||
386 | if (enable_shub_wars_1_1()) { | 385 | if (enable_shub_wars_1_1()) { |
387 | HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, | 386 | HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, |
388 | SH1_MD_DQLP_MMR_DIR_PRIVEC0), | 387 | SH1_MD_DQLP_MMR_DIR_PRIVEC0), |
389 | xpc_prot_vec[node]); | 388 | xpc_prot_vec[node]); |
390 | HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, | 389 | HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, |
391 | SH1_MD_DQRP_MMR_DIR_PRIVEC0), | 390 | SH1_MD_DQRP_MMR_DIR_PRIVEC0), |
392 | xpc_prot_vec[node]); | 391 | xpc_prot_vec[node]); |
393 | } | 392 | } |
394 | } | 393 | } |
@@ -411,13 +410,11 @@ xpc_check_remote_hb(void) | |||
411 | 410 | ||
412 | for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { | 411 | for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { |
413 | 412 | ||
414 | if (xpc_exiting) { | 413 | if (xpc_exiting) |
415 | break; | 414 | break; |
416 | } | ||
417 | 415 | ||
418 | if (partid == sn_partition_id) { | 416 | if (partid == sn_partition_id) |
419 | continue; | 417 | continue; |
420 | } | ||
421 | 418 | ||
422 | part = &xpc_partitions[partid]; | 419 | part = &xpc_partitions[partid]; |
423 | 420 | ||
@@ -471,24 +468,21 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids, | |||
471 | /* get the reserved page's physical address */ | 468 | /* get the reserved page's physical address */ |
472 | 469 | ||
473 | *remote_rp_pa = xpc_get_rsvd_page_pa(nasid); | 470 | *remote_rp_pa = xpc_get_rsvd_page_pa(nasid); |
474 | if (*remote_rp_pa == 0) { | 471 | if (*remote_rp_pa == 0) |
475 | return xpcNoRsvdPageAddr; | 472 | return xpcNoRsvdPageAddr; |
476 | } | ||
477 | 473 | ||
478 | /* pull over the reserved page header and part_nasids mask */ | 474 | /* pull over the reserved page header and part_nasids mask */ |
479 | bres = xp_bte_copy(*remote_rp_pa, (u64)remote_rp, | 475 | bres = xp_bte_copy(*remote_rp_pa, (u64)remote_rp, |
480 | XPC_RP_HEADER_SIZE + xp_nasid_mask_bytes, | 476 | XPC_RP_HEADER_SIZE + xp_nasid_mask_bytes, |
481 | (BTE_NOTIFY | BTE_WACQUIRE), NULL); | 477 | (BTE_NOTIFY | BTE_WACQUIRE), NULL); |
482 | if (bres != BTE_SUCCESS) { | 478 | if (bres != BTE_SUCCESS) |
483 | return xpc_map_bte_errors(bres); | 479 | return xpc_map_bte_errors(bres); |
484 | } | ||
485 | 480 | ||
486 | if (discovered_nasids != NULL) { | 481 | if (discovered_nasids != NULL) { |
487 | u64 *remote_part_nasids = XPC_RP_PART_NASIDS(remote_rp); | 482 | u64 *remote_part_nasids = XPC_RP_PART_NASIDS(remote_rp); |
488 | 483 | ||
489 | for (i = 0; i < xp_nasid_mask_words; i++) { | 484 | for (i = 0; i < xp_nasid_mask_words; i++) |
490 | discovered_nasids[i] |= remote_part_nasids[i]; | 485 | discovered_nasids[i] |= remote_part_nasids[i]; |
491 | } | ||
492 | } | 486 | } |
493 | 487 | ||
494 | /* check that the partid is for another partition */ | 488 | /* check that the partid is for another partition */ |
@@ -498,9 +492,8 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids, | |||
498 | return xpcInvalidPartid; | 492 | return xpcInvalidPartid; |
499 | } | 493 | } |
500 | 494 | ||
501 | if (remote_rp->partid == sn_partition_id) { | 495 | if (remote_rp->partid == sn_partition_id) |
502 | return xpcLocalPartid; | 496 | return xpcLocalPartid; |
503 | } | ||
504 | 497 | ||
505 | if (XPC_VERSION_MAJOR(remote_rp->version) != | 498 | if (XPC_VERSION_MAJOR(remote_rp->version) != |
506 | XPC_VERSION_MAJOR(XPC_RP_VERSION)) { | 499 | XPC_VERSION_MAJOR(XPC_RP_VERSION)) { |
@@ -521,16 +514,14 @@ xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars) | |||
521 | { | 514 | { |
522 | int bres; | 515 | int bres; |
523 | 516 | ||
524 | if (remote_vars_pa == 0) { | 517 | if (remote_vars_pa == 0) |
525 | return xpcVarsNotSet; | 518 | return xpcVarsNotSet; |
526 | } | ||
527 | 519 | ||
528 | /* pull over the cross partition variables */ | 520 | /* pull over the cross partition variables */ |
529 | bres = xp_bte_copy(remote_vars_pa, (u64)remote_vars, XPC_RP_VARS_SIZE, | 521 | bres = xp_bte_copy(remote_vars_pa, (u64)remote_vars, XPC_RP_VARS_SIZE, |
530 | (BTE_NOTIFY | BTE_WACQUIRE), NULL); | 522 | (BTE_NOTIFY | BTE_WACQUIRE), NULL); |
531 | if (bres != BTE_SUCCESS) { | 523 | if (bres != BTE_SUCCESS) |
532 | return xpc_map_bte_errors(bres); | 524 | return xpc_map_bte_errors(bres); |
533 | } | ||
534 | 525 | ||
535 | if (XPC_VERSION_MAJOR(remote_vars->version) != | 526 | if (XPC_VERSION_MAJOR(remote_vars->version) != |
536 | XPC_VERSION_MAJOR(XPC_V_VERSION)) { | 527 | XPC_VERSION_MAJOR(XPC_V_VERSION)) { |
@@ -630,9 +621,9 @@ xpc_identify_act_IRQ_req(int nasid) | |||
630 | 621 | ||
631 | remote_vars_pa = remote_rp->vars_pa; | 622 | remote_vars_pa = remote_rp->vars_pa; |
632 | remote_rp_version = remote_rp->version; | 623 | remote_rp_version = remote_rp->version; |
633 | if (XPC_SUPPORTS_RP_STAMP(remote_rp_version)) { | 624 | if (XPC_SUPPORTS_RP_STAMP(remote_rp_version)) |
634 | remote_rp_stamp = remote_rp->stamp; | 625 | remote_rp_stamp = remote_rp->stamp; |
635 | } | 626 | |
636 | partid = remote_rp->partid; | 627 | partid = remote_rp->partid; |
637 | part = &xpc_partitions[partid]; | 628 | part = &xpc_partitions[partid]; |
638 | 629 | ||
@@ -656,7 +647,8 @@ xpc_identify_act_IRQ_req(int nasid) | |||
656 | "%ld:0x%lx\n", (int)nasid, (int)partid, part->act_IRQ_rcvd, | 647 | "%ld:0x%lx\n", (int)nasid, (int)partid, part->act_IRQ_rcvd, |
657 | remote_vars->heartbeat, remote_vars->heartbeating_to_mask); | 648 | remote_vars->heartbeat, remote_vars->heartbeating_to_mask); |
658 | 649 | ||
659 | if (xpc_partition_disengaged(part) && part->act_state == XPC_P_INACTIVE) { | 650 | if (xpc_partition_disengaged(part) && |
651 | part->act_state == XPC_P_INACTIVE) { | ||
660 | 652 | ||
661 | xpc_update_partition_info(part, remote_rp_version, | 653 | xpc_update_partition_info(part, remote_rp_version, |
662 | &remote_rp_stamp, remote_rp_pa, | 654 | &remote_rp_stamp, remote_rp_pa, |
@@ -791,9 +783,8 @@ xpc_identify_act_IRQ_sender(void) | |||
791 | /* scan through act AMO variable looking for non-zero entries */ | 783 | /* scan through act AMO variable looking for non-zero entries */ |
792 | for (word = 0; word < xp_nasid_mask_words; word++) { | 784 | for (word = 0; word < xp_nasid_mask_words; word++) { |
793 | 785 | ||
794 | if (xpc_exiting) { | 786 | if (xpc_exiting) |
795 | break; | 787 | break; |
796 | } | ||
797 | 788 | ||
798 | nasid_mask = xpc_IPI_receive(&act_amos[word]); | 789 | nasid_mask = xpc_IPI_receive(&act_amos[word]); |
799 | if (nasid_mask == 0) { | 790 | if (nasid_mask == 0) { |
@@ -840,7 +831,8 @@ xpc_partition_disengaged(struct xpc_partition *part) | |||
840 | disengaged = (xpc_partition_engaged(1UL << partid) == 0); | 831 | disengaged = (xpc_partition_engaged(1UL << partid) == 0); |
841 | if (part->disengage_request_timeout) { | 832 | if (part->disengage_request_timeout) { |
842 | if (!disengaged) { | 833 | if (!disengaged) { |
843 | if (time_before(jiffies, part->disengage_request_timeout)) { | 834 | if (time_before(jiffies, |
835 | part->disengage_request_timeout)) { | ||
844 | /* timelimit hasn't been reached yet */ | 836 | /* timelimit hasn't been reached yet */ |
845 | return 0; | 837 | return 0; |
846 | } | 838 | } |
@@ -866,13 +858,11 @@ xpc_partition_disengaged(struct xpc_partition *part) | |||
866 | 858 | ||
867 | DBUG_ON(part->act_state != XPC_P_DEACTIVATING && | 859 | DBUG_ON(part->act_state != XPC_P_DEACTIVATING && |
868 | part->act_state != XPC_P_INACTIVE); | 860 | part->act_state != XPC_P_INACTIVE); |
869 | if (part->act_state != XPC_P_INACTIVE) { | 861 | if (part->act_state != XPC_P_INACTIVE) |
870 | xpc_wakeup_channel_mgr(part); | 862 | xpc_wakeup_channel_mgr(part); |
871 | } | ||
872 | 863 | ||
873 | if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) { | 864 | if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) |
874 | xpc_cancel_partition_disengage_request(part); | 865 | xpc_cancel_partition_disengage_request(part); |
875 | } | ||
876 | } | 866 | } |
877 | return disengaged; | 867 | return disengaged; |
878 | } | 868 | } |
@@ -1000,9 +990,9 @@ xpc_discovery(void) | |||
1000 | remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE + | 990 | remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE + |
1001 | xp_nasid_mask_bytes, | 991 | xp_nasid_mask_bytes, |
1002 | GFP_KERNEL, &remote_rp_base); | 992 | GFP_KERNEL, &remote_rp_base); |
1003 | if (remote_rp == NULL) { | 993 | if (remote_rp == NULL) |
1004 | return; | 994 | return; |
1005 | } | 995 | |
1006 | remote_vars = (struct xpc_vars *)remote_rp; | 996 | remote_vars = (struct xpc_vars *)remote_rp; |
1007 | 997 | ||
1008 | discovered_nasids = kzalloc(sizeof(u64) * xp_nasid_mask_words, | 998 | discovered_nasids = kzalloc(sizeof(u64) * xp_nasid_mask_words, |
@@ -1035,18 +1025,16 @@ xpc_discovery(void) | |||
1035 | 1025 | ||
1036 | for (region = 0; region < max_regions; region++) { | 1026 | for (region = 0; region < max_regions; region++) { |
1037 | 1027 | ||
1038 | if ((volatile int)xpc_exiting) { | 1028 | if (xpc_exiting) |
1039 | break; | 1029 | break; |
1040 | } | ||
1041 | 1030 | ||
1042 | dev_dbg(xpc_part, "searching region %d\n", region); | 1031 | dev_dbg(xpc_part, "searching region %d\n", region); |
1043 | 1032 | ||
1044 | for (nasid = (region * region_size * 2); | 1033 | for (nasid = (region * region_size * 2); |
1045 | nasid < ((region + 1) * region_size * 2); nasid += 2) { | 1034 | nasid < ((region + 1) * region_size * 2); nasid += 2) { |
1046 | 1035 | ||
1047 | if ((volatile int)xpc_exiting) { | 1036 | if (xpc_exiting) |
1048 | break; | 1037 | break; |
1049 | } | ||
1050 | 1038 | ||
1051 | dev_dbg(xpc_part, "checking nasid %d\n", nasid); | 1039 | dev_dbg(xpc_part, "checking nasid %d\n", nasid); |
1052 | 1040 | ||
@@ -1080,9 +1068,9 @@ xpc_discovery(void) | |||
1080 | "from nasid %d, reason=%d\n", nasid, | 1068 | "from nasid %d, reason=%d\n", nasid, |
1081 | ret); | 1069 | ret); |
1082 | 1070 | ||
1083 | if (ret == xpcLocalPartid) { | 1071 | if (ret == xpcLocalPartid) |
1084 | break; | 1072 | break; |
1085 | } | 1073 | |
1086 | continue; | 1074 | continue; |
1087 | } | 1075 | } |
1088 | 1076 | ||
@@ -1171,9 +1159,8 @@ xpc_initiate_partid_to_nasids(partid_t partid, void *nasid_mask) | |||
1171 | int bte_res; | 1159 | int bte_res; |
1172 | 1160 | ||
1173 | part = &xpc_partitions[partid]; | 1161 | part = &xpc_partitions[partid]; |
1174 | if (part->remote_rp_pa == 0) { | 1162 | if (part->remote_rp_pa == 0) |
1175 | return xpcPartitionDown; | 1163 | return xpcPartitionDown; |
1176 | } | ||
1177 | 1164 | ||
1178 | memset(nasid_mask, 0, XP_NASID_MASK_BYTES); | 1165 | memset(nasid_mask, 0, XP_NASID_MASK_BYTES); |
1179 | 1166 | ||