aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/apic/x2apic_uv_x.c49
1 files changed, 46 insertions, 3 deletions
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
index efaf2d4f9c3c..2270a777d647 100644
--- a/arch/x86/kernel/apic/x2apic_uv_x.c
+++ b/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -26,6 +26,7 @@
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/crash_dump.h> 27#include <linux/crash_dump.h>
28#include <linux/reboot.h> 28#include <linux/reboot.h>
29#include <linux/memory.h>
29 30
30#include <asm/uv/uv_mmrs.h> 31#include <asm/uv/uv_mmrs.h>
31#include <asm/uv/uv_hub.h> 32#include <asm/uv/uv_hub.h>
@@ -392,6 +393,40 @@ extern int uv_hub_info_version(void)
392} 393}
393EXPORT_SYMBOL(uv_hub_info_version); 394EXPORT_SYMBOL(uv_hub_info_version);
394 395
396/* Default UV memory block size is 2GB */
397static unsigned long mem_block_size = (2UL << 30);
398
399static __init int adj_blksize(u32 lgre)
400{
401 unsigned long base = (unsigned long)lgre << UV_GAM_RANGE_SHFT;
402 unsigned long size;
403
404 for (size = mem_block_size; size > MIN_MEMORY_BLOCK_SIZE; size >>= 1)
405 if (IS_ALIGNED(base, size))
406 break;
407
408 if (size >= mem_block_size)
409 return 0;
410
411 mem_block_size = size;
412 return 1;
413}
414
415static __init void set_block_size(void)
416{
417 unsigned int order = ffs(mem_block_size);
418
419 if (order) {
420 /* adjust for ffs return of 1..64 */
421 set_memory_block_size_order(order - 1);
422 pr_info("UV: mem_block_size set to 0x%lx\n", mem_block_size);
423 } else {
424 /* bad or zero value, default to 1UL << 31 (2GB) */
425 pr_err("UV: mem_block_size error with 0x%lx\n", mem_block_size);
426 set_memory_block_size_order(31);
427 }
428}
429
395/* Build GAM range lookup table: */ 430/* Build GAM range lookup table: */
396static __init void build_uv_gr_table(void) 431static __init void build_uv_gr_table(void)
397{ 432{
@@ -1180,23 +1215,30 @@ static void __init decode_gam_rng_tbl(unsigned long ptr)
1180 << UV_GAM_RANGE_SHFT); 1215 << UV_GAM_RANGE_SHFT);
1181 int order = 0; 1216 int order = 0;
1182 char suffix[] = " KMGTPE"; 1217 char suffix[] = " KMGTPE";
1218 int flag = ' ';
1183 1219
1184 while (size > 9999 && order < sizeof(suffix)) { 1220 while (size > 9999 && order < sizeof(suffix)) {
1185 size /= 1024; 1221 size /= 1024;
1186 order++; 1222 order++;
1187 } 1223 }
1188 1224
1225 /* adjust max block size to current range start */
1226 if (gre->type == 1 || gre->type == 2)
1227 if (adj_blksize(lgre))
1228 flag = '*';
1229
1189 if (!index) { 1230 if (!index) {
1190 pr_info("UV: GAM Range Table...\n"); 1231 pr_info("UV: GAM Range Table...\n");
1191 pr_info("UV: # %20s %14s %5s %4s %5s %3s %2s\n", "Range", "", "Size", "Type", "NASID", "SID", "PN"); 1232 pr_info("UV: # %20s %14s %6s %4s %5s %3s %2s\n", "Range", "", "Size", "Type", "NASID", "SID", "PN");
1192 } 1233 }
1193 pr_info("UV: %2d: 0x%014lx-0x%014lx %5lu%c %3d %04x %02x %02x\n", 1234 pr_info("UV: %2d: 0x%014lx-0x%014lx%c %5lu%c %3d %04x %02x %02x\n",
1194 index++, 1235 index++,
1195 (unsigned long)lgre << UV_GAM_RANGE_SHFT, 1236 (unsigned long)lgre << UV_GAM_RANGE_SHFT,
1196 (unsigned long)gre->limit << UV_GAM_RANGE_SHFT, 1237 (unsigned long)gre->limit << UV_GAM_RANGE_SHFT,
1197 size, suffix[order], 1238 flag, size, suffix[order],
1198 gre->type, gre->nasid, gre->sockid, gre->pnode); 1239 gre->type, gre->nasid, gre->sockid, gre->pnode);
1199 1240
1241 /* update to next range start */
1200 lgre = gre->limit; 1242 lgre = gre->limit;
1201 if (sock_min > gre->sockid) 1243 if (sock_min > gre->sockid)
1202 sock_min = gre->sockid; 1244 sock_min = gre->sockid;
@@ -1427,6 +1469,7 @@ static void __init uv_system_init_hub(void)
1427 1469
1428 build_socket_tables(); 1470 build_socket_tables();
1429 build_uv_gr_table(); 1471 build_uv_gr_table();
1472 set_block_size();
1430 uv_init_hub_info(&hub_info); 1473 uv_init_hub_info(&hub_info);
1431 uv_possible_blades = num_possible_nodes(); 1474 uv_possible_blades = num_possible_nodes();
1432 if (!_node_to_pnode) 1475 if (!_node_to_pnode)