diff options
| -rw-r--r-- | arch/x86/include/asm/uv/uv_bau.h | 1 | ||||
| -rw-r--r-- | arch/x86/include/asm/uv/uv_hub.h | 37 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/x2apic_uv_x.c | 7 | ||||
| -rw-r--r-- | arch/x86/platform/uv/tlb_uv.c | 17 |
4 files changed, 46 insertions, 16 deletions
diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index c568ccca6e0e..8e862aaf0d90 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h | |||
| @@ -55,6 +55,7 @@ | |||
| 55 | #define UV_BAU_TUNABLES_DIR "sgi_uv" | 55 | #define UV_BAU_TUNABLES_DIR "sgi_uv" |
| 56 | #define UV_BAU_TUNABLES_FILE "bau_tunables" | 56 | #define UV_BAU_TUNABLES_FILE "bau_tunables" |
| 57 | #define WHITESPACE " \t\n" | 57 | #define WHITESPACE " \t\n" |
| 58 | #define uv_mmask ((1UL << uv_hub_info->m_val) - 1) | ||
| 58 | #define uv_physnodeaddr(x) ((__pa((unsigned long)(x)) & uv_mmask)) | 59 | #define uv_physnodeaddr(x) ((__pa((unsigned long)(x)) & uv_mmask)) |
| 59 | #define cpubit_isset(cpu, bau_local_cpumask) \ | 60 | #define cpubit_isset(cpu, bau_local_cpumask) \ |
| 60 | test_bit((cpu), (bau_local_cpumask).bits) | 61 | test_bit((cpu), (bau_local_cpumask).bits) |
diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h index f26544a15214..54a13aaebc40 100644 --- a/arch/x86/include/asm/uv/uv_hub.h +++ b/arch/x86/include/asm/uv/uv_hub.h | |||
| @@ -46,6 +46,13 @@ | |||
| 46 | * PNODE - the low N bits of the GNODE. The PNODE is the most useful variant | 46 | * PNODE - the low N bits of the GNODE. The PNODE is the most useful variant |
| 47 | * of the nasid for socket usage. | 47 | * of the nasid for socket usage. |
| 48 | * | 48 | * |
| 49 | * GPA - (global physical address) a socket physical address converted | ||
| 50 | * so that it can be used by the GRU as a global address. Socket | ||
| 51 | * physical addresses 1) need additional NASID (node) bits added | ||
| 52 | * to the high end of the address, and 2) unaliased if the | ||
| 53 | * partition does not have a physical address 0. In addition, on | ||
| 54 | * UV2 rev 1, GPAs need the gnode left shifted to bits 39 or 40. | ||
| 55 | * | ||
| 49 | * | 56 | * |
| 50 | * NumaLink Global Physical Address Format: | 57 | * NumaLink Global Physical Address Format: |
| 51 | * +--------------------------------+---------------------+ | 58 | * +--------------------------------+---------------------+ |
| @@ -141,6 +148,8 @@ struct uv_hub_info_s { | |||
| 141 | unsigned int gnode_extra; | 148 | unsigned int gnode_extra; |
| 142 | unsigned char hub_revision; | 149 | unsigned char hub_revision; |
| 143 | unsigned char apic_pnode_shift; | 150 | unsigned char apic_pnode_shift; |
| 151 | unsigned char m_shift; | ||
| 152 | unsigned char n_lshift; | ||
| 144 | unsigned long gnode_upper; | 153 | unsigned long gnode_upper; |
| 145 | unsigned long lowmem_remap_top; | 154 | unsigned long lowmem_remap_top; |
| 146 | unsigned long lowmem_remap_base; | 155 | unsigned long lowmem_remap_base; |
| @@ -177,6 +186,16 @@ static inline int is_uv2_hub(void) | |||
| 177 | return uv_hub_info->hub_revision >= UV2_HUB_REVISION_BASE; | 186 | return uv_hub_info->hub_revision >= UV2_HUB_REVISION_BASE; |
| 178 | } | 187 | } |
| 179 | 188 | ||
| 189 | static inline int is_uv2_1_hub(void) | ||
| 190 | { | ||
| 191 | return uv_hub_info->hub_revision == UV2_HUB_REVISION_BASE; | ||
| 192 | } | ||
| 193 | |||
| 194 | static inline int is_uv2_2_hub(void) | ||
| 195 | { | ||
| 196 | return uv_hub_info->hub_revision == UV2_HUB_REVISION_BASE + 1; | ||
| 197 | } | ||
| 198 | |||
| 180 | union uvh_apicid { | 199 | union uvh_apicid { |
| 181 | unsigned long v; | 200 | unsigned long v; |
| 182 | struct uvh_apicid_s { | 201 | struct uvh_apicid_s { |
| @@ -276,7 +295,10 @@ static inline unsigned long uv_soc_phys_ram_to_gpa(unsigned long paddr) | |||
| 276 | { | 295 | { |
| 277 | if (paddr < uv_hub_info->lowmem_remap_top) | 296 | if (paddr < uv_hub_info->lowmem_remap_top) |
| 278 | paddr |= uv_hub_info->lowmem_remap_base; | 297 | paddr |= uv_hub_info->lowmem_remap_base; |
| 279 | return paddr | uv_hub_info->gnode_upper; | 298 | paddr |= uv_hub_info->gnode_upper; |
| 299 | paddr = ((paddr << uv_hub_info->m_shift) >> uv_hub_info->m_shift) | | ||
| 300 | ((paddr >> uv_hub_info->m_val) << uv_hub_info->n_lshift); | ||
| 301 | return paddr; | ||
| 280 | } | 302 | } |
| 281 | 303 | ||
| 282 | 304 | ||
| @@ -300,16 +322,19 @@ static inline unsigned long uv_gpa_to_soc_phys_ram(unsigned long gpa) | |||
| 300 | unsigned long remap_base = uv_hub_info->lowmem_remap_base; | 322 | unsigned long remap_base = uv_hub_info->lowmem_remap_base; |
| 301 | unsigned long remap_top = uv_hub_info->lowmem_remap_top; | 323 | unsigned long remap_top = uv_hub_info->lowmem_remap_top; |
| 302 | 324 | ||
| 325 | gpa = ((gpa << uv_hub_info->m_shift) >> uv_hub_info->m_shift) | | ||
| 326 | ((gpa >> uv_hub_info->n_lshift) << uv_hub_info->m_val); | ||
| 327 | gpa = gpa & uv_hub_info->gpa_mask; | ||
| 303 | if (paddr >= remap_base && paddr < remap_base + remap_top) | 328 | if (paddr >= remap_base && paddr < remap_base + remap_top) |
| 304 | paddr -= remap_base; | 329 | paddr -= remap_base; |
| 305 | return paddr; | 330 | return paddr; |
| 306 | } | 331 | } |
| 307 | 332 | ||
| 308 | 333 | ||
| 309 | /* gnode -> pnode */ | 334 | /* gpa -> pnode */ |
| 310 | static inline unsigned long uv_gpa_to_gnode(unsigned long gpa) | 335 | static inline unsigned long uv_gpa_to_gnode(unsigned long gpa) |
| 311 | { | 336 | { |
| 312 | return gpa >> uv_hub_info->m_val; | 337 | return gpa >> uv_hub_info->n_lshift; |
| 313 | } | 338 | } |
| 314 | 339 | ||
| 315 | /* gpa -> pnode */ | 340 | /* gpa -> pnode */ |
| @@ -320,6 +345,12 @@ static inline int uv_gpa_to_pnode(unsigned long gpa) | |||
| 320 | return uv_gpa_to_gnode(gpa) & n_mask; | 345 | return uv_gpa_to_gnode(gpa) & n_mask; |
| 321 | } | 346 | } |
| 322 | 347 | ||
| 348 | /* gpa -> node offset*/ | ||
| 349 | static inline unsigned long uv_gpa_to_offset(unsigned long gpa) | ||
| 350 | { | ||
| 351 | return (gpa << uv_hub_info->m_shift) >> uv_hub_info->m_shift; | ||
| 352 | } | ||
| 353 | |||
| 323 | /* pnode, offset --> socket virtual */ | 354 | /* pnode, offset --> socket virtual */ |
| 324 | static inline void *uv_pnode_offset_to_vaddr(int pnode, unsigned long offset) | 355 | static inline void *uv_pnode_offset_to_vaddr(int pnode, unsigned long offset) |
| 325 | { | 356 | { |
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 75be00ecfff2..62ae3001ae02 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
| @@ -820,6 +820,10 @@ void __init uv_system_init(void) | |||
| 820 | uv_cpu_hub_info(cpu)->apic_pnode_shift = uvh_apicid.s.pnode_shift; | 820 | uv_cpu_hub_info(cpu)->apic_pnode_shift = uvh_apicid.s.pnode_shift; |
| 821 | uv_cpu_hub_info(cpu)->hub_revision = uv_hub_info->hub_revision; | 821 | uv_cpu_hub_info(cpu)->hub_revision = uv_hub_info->hub_revision; |
| 822 | 822 | ||
| 823 | uv_cpu_hub_info(cpu)->m_shift = 64 - m_val; | ||
| 824 | uv_cpu_hub_info(cpu)->n_lshift = is_uv2_1_hub() ? | ||
| 825 | (m_val == 40 ? 40 : 39) : m_val; | ||
| 826 | |||
| 823 | pnode = uv_apicid_to_pnode(apicid); | 827 | pnode = uv_apicid_to_pnode(apicid); |
| 824 | blade = boot_pnode_to_blade(pnode); | 828 | blade = boot_pnode_to_blade(pnode); |
| 825 | lcpu = uv_blade_info[blade].nr_possible_cpus; | 829 | lcpu = uv_blade_info[blade].nr_possible_cpus; |
| @@ -850,8 +854,7 @@ void __init uv_system_init(void) | |||
| 850 | if (uv_node_to_blade[nid] >= 0) | 854 | if (uv_node_to_blade[nid] >= 0) |
| 851 | continue; | 855 | continue; |
| 852 | paddr = node_start_pfn(nid) << PAGE_SHIFT; | 856 | paddr = node_start_pfn(nid) << PAGE_SHIFT; |
| 853 | paddr = uv_soc_phys_ram_to_gpa(paddr); | 857 | pnode = uv_gpa_to_pnode(uv_soc_phys_ram_to_gpa(paddr)); |
| 854 | pnode = (paddr >> m_val) & pnode_mask; | ||
| 855 | blade = boot_pnode_to_blade(pnode); | 858 | blade = boot_pnode_to_blade(pnode); |
| 856 | uv_node_to_blade[nid] = blade; | 859 | uv_node_to_blade[nid] = blade; |
| 857 | } | 860 | } |
diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index db8b915f54bc..5b552198f774 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c | |||
| @@ -115,9 +115,6 @@ early_param("nobau", setup_nobau); | |||
| 115 | 115 | ||
| 116 | /* base pnode in this partition */ | 116 | /* base pnode in this partition */ |
| 117 | static int uv_base_pnode __read_mostly; | 117 | static int uv_base_pnode __read_mostly; |
| 118 | /* position of pnode (which is nasid>>1): */ | ||
| 119 | static int uv_nshift __read_mostly; | ||
| 120 | static unsigned long uv_mmask __read_mostly; | ||
| 121 | 118 | ||
| 122 | static DEFINE_PER_CPU(struct ptc_stats, ptcstats); | 119 | static DEFINE_PER_CPU(struct ptc_stats, ptcstats); |
| 123 | static DEFINE_PER_CPU(struct bau_control, bau_control); | 120 | static DEFINE_PER_CPU(struct bau_control, bau_control); |
| @@ -1435,7 +1432,7 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode) | |||
| 1435 | { | 1432 | { |
| 1436 | int i; | 1433 | int i; |
| 1437 | int cpu; | 1434 | int cpu; |
| 1438 | unsigned long pa; | 1435 | unsigned long gpa; |
| 1439 | unsigned long m; | 1436 | unsigned long m; |
| 1440 | unsigned long n; | 1437 | unsigned long n; |
| 1441 | size_t dsize; | 1438 | size_t dsize; |
| @@ -1451,9 +1448,9 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode) | |||
| 1451 | bau_desc = kmalloc_node(dsize, GFP_KERNEL, node); | 1448 | bau_desc = kmalloc_node(dsize, GFP_KERNEL, node); |
| 1452 | BUG_ON(!bau_desc); | 1449 | BUG_ON(!bau_desc); |
| 1453 | 1450 | ||
| 1454 | pa = uv_gpa(bau_desc); /* need the real nasid*/ | 1451 | gpa = uv_gpa(bau_desc); |
| 1455 | n = pa >> uv_nshift; | 1452 | n = uv_gpa_to_gnode(gpa); |
| 1456 | m = pa & uv_mmask; | 1453 | m = uv_gpa_to_offset(gpa); |
| 1457 | 1454 | ||
| 1458 | /* the 14-bit pnode */ | 1455 | /* the 14-bit pnode */ |
| 1459 | write_mmr_descriptor_base(pnode, (n << UV_DESC_PSHIFT | m)); | 1456 | write_mmr_descriptor_base(pnode, (n << UV_DESC_PSHIFT | m)); |
| @@ -1525,9 +1522,9 @@ static void pq_init(int node, int pnode) | |||
| 1525 | bcp->queue_last = pqp + (DEST_Q_SIZE - 1); | 1522 | bcp->queue_last = pqp + (DEST_Q_SIZE - 1); |
| 1526 | } | 1523 | } |
| 1527 | /* | 1524 | /* |
| 1528 | * need the pnode of where the memory was really allocated | 1525 | * need the gnode of where the memory was really allocated |
| 1529 | */ | 1526 | */ |
| 1530 | pn = uv_gpa(pqp) >> uv_nshift; | 1527 | pn = uv_gpa_to_gnode(uv_gpa(pqp)); |
| 1531 | first = uv_physnodeaddr(pqp); | 1528 | first = uv_physnodeaddr(pqp); |
| 1532 | pn_first = ((unsigned long)pn << UV_PAYLOADQ_PNODE_SHIFT) | first; | 1529 | pn_first = ((unsigned long)pn << UV_PAYLOADQ_PNODE_SHIFT) | first; |
| 1533 | last = uv_physnodeaddr(pqp + (DEST_Q_SIZE - 1)); | 1530 | last = uv_physnodeaddr(pqp + (DEST_Q_SIZE - 1)); |
| @@ -1837,8 +1834,6 @@ static int __init uv_bau_init(void) | |||
| 1837 | zalloc_cpumask_var_node(mask, GFP_KERNEL, cpu_to_node(cur_cpu)); | 1834 | zalloc_cpumask_var_node(mask, GFP_KERNEL, cpu_to_node(cur_cpu)); |
| 1838 | } | 1835 | } |
| 1839 | 1836 | ||
| 1840 | uv_nshift = uv_hub_info->m_val; | ||
| 1841 | uv_mmask = (1UL << uv_hub_info->m_val) - 1; | ||
| 1842 | nuvhubs = uv_num_possible_blades(); | 1837 | nuvhubs = uv_num_possible_blades(); |
| 1843 | spin_lock_init(&disable_lock); | 1838 | spin_lock_init(&disable_lock); |
| 1844 | congested_cycles = usec_2_cycles(congested_respns_us); | 1839 | congested_cycles = usec_2_cycles(congested_respns_us); |
