Skip to content

Commit

Permalink
x86_64 SGI UV: Fix writes to led registers on remote uv hubs.
Browse files Browse the repository at this point in the history
The wrong address was being used to write the SCIR led regs on remote
hubs.  Also, there was an inconsistency between how BIOS and the kernel
indexed these regs.  Standardize on using the lower 6 bits of the APIC
ID as the index.

This patch fixes the problem of writing to an errant address to a
cpu # >= 64.

Signed-off-by: Mike Travis <travis@sgi.com>
Reviewed-by: Jack Steiner <steiner@sgi.com>
Cc: stable@kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Mike Travis authored and Linus Torvalds committed Dec 30, 2009
1 parent 66f0dc4 commit 9a7262a
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 7 deletions.
20 changes: 19 additions & 1 deletion arch/x86/include/asm/uv/uv_hub.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,18 @@ static inline unsigned long uv_global_gru_mmr_address(int pnode, unsigned long o
return UV_GLOBAL_GRU_MMR_BASE | offset | (pnode << uv_hub_info->m_val);
}

static inline void uv_write_global_mmr8(int pnode, unsigned long offset,
unsigned char val)
{
writeb(val, uv_global_mmr64_address(pnode, offset));
}

static inline unsigned char uv_read_global_mmr8(int pnode,
unsigned long offset)
{
return readb(uv_global_mmr64_address(pnode, offset));
}

/*
* Access hub local MMRs. Faster than using global space but only local MMRs
* are accessible.
Expand Down Expand Up @@ -457,11 +469,17 @@ static inline void uv_set_scir_bits(unsigned char value)
}
}

static inline unsigned long uv_scir_offset(int apicid)
{
return SCIR_LOCAL_MMR_BASE | (apicid & 0x3f);
}

static inline void uv_set_cpu_scir_bits(int cpu, unsigned char value)
{
if (uv_cpu_hub_info(cpu)->scir.state != value) {
uv_write_global_mmr8(uv_cpu_to_pnode(cpu),
uv_cpu_hub_info(cpu)->scir.offset, value);
uv_cpu_hub_info(cpu)->scir.state = value;
uv_write_local_mmr8(uv_cpu_hub_info(cpu)->scir.offset, value);
}
}

Expand Down
12 changes: 6 additions & 6 deletions arch/x86/kernel/apic/x2apic_uv_x.c
Original file line number Diff line number Diff line change
Expand Up @@ -629,8 +629,10 @@ void __init uv_system_init(void)
uv_rtc_init();

for_each_present_cpu(cpu) {
int apicid = per_cpu(x86_cpu_to_apicid, cpu);

nid = cpu_to_node(cpu);
pnode = uv_apicid_to_pnode(per_cpu(x86_cpu_to_apicid, cpu));
pnode = uv_apicid_to_pnode(apicid);
blade = boot_pnode_to_blade(pnode);
lcpu = uv_blade_info[blade].nr_possible_cpus;
uv_blade_info[blade].nr_possible_cpus++;
Expand All @@ -651,15 +653,13 @@ void __init uv_system_init(void)
uv_cpu_hub_info(cpu)->gnode_extra = gnode_extra;
uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base;
uv_cpu_hub_info(cpu)->coherency_domain_number = sn_coherency_id;
uv_cpu_hub_info(cpu)->scir.offset = SCIR_LOCAL_MMR_BASE + lcpu;
uv_cpu_hub_info(cpu)->scir.offset = uv_scir_offset(apicid);
uv_node_to_blade[nid] = blade;
uv_cpu_to_blade[cpu] = blade;
max_pnode = max(pnode, max_pnode);

printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, "
"lcpu %d, blade %d\n",
cpu, per_cpu(x86_cpu_to_apicid, cpu), pnode, nid,
lcpu, blade);
printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, lcpu %d, blade %d\n",
cpu, apicid, pnode, nid, lcpu, blade);
}

/* Add blade/pnode info for nodes without cpus */
Expand Down

0 comments on commit 9a7262a

Please sign in to comment.