Merge branches 'x86-fixes-for-linus' and 'x86-uv-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86, alternative: Call stop_machine_text_poke() on all cpus x86-32: Restore irq stacks NUMA-aware allocations x86, memblock: Fix early_node_mem with big reserved region. * 'x86-uv-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86, uv: More Westmere support on SGI UV x86, uv: Enable Westmere support on SGI UV
This commit is contained in:
Коммит
2d10d8737c
|
@ -5,7 +5,7 @@
|
||||||
*
|
*
|
||||||
* SGI UV architectural definitions
|
* SGI UV architectural definitions
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved.
|
* Copyright (C) 2007-2010 Silicon Graphics, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _ASM_X86_UV_UV_HUB_H
|
#ifndef _ASM_X86_UV_UV_HUB_H
|
||||||
|
@ -77,7 +77,8 @@
|
||||||
*
|
*
|
||||||
* 1111110000000000
|
* 1111110000000000
|
||||||
* 5432109876543210
|
* 5432109876543210
|
||||||
* pppppppppplc0cch
|
* pppppppppplc0cch Nehalem-EX
|
||||||
|
* ppppppppplcc0cch Westmere-EX
|
||||||
* sssssssssss
|
* sssssssssss
|
||||||
*
|
*
|
||||||
* p = pnode bits
|
* p = pnode bits
|
||||||
|
@ -148,12 +149,25 @@ struct uv_hub_info_s {
|
||||||
unsigned char m_val;
|
unsigned char m_val;
|
||||||
unsigned char n_val;
|
unsigned char n_val;
|
||||||
struct uv_scir_s scir;
|
struct uv_scir_s scir;
|
||||||
|
unsigned char apic_pnode_shift;
|
||||||
};
|
};
|
||||||
|
|
||||||
DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
|
DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
|
||||||
#define uv_hub_info (&__get_cpu_var(__uv_hub_info))
|
#define uv_hub_info (&__get_cpu_var(__uv_hub_info))
|
||||||
#define uv_cpu_hub_info(cpu) (&per_cpu(__uv_hub_info, cpu))
|
#define uv_cpu_hub_info(cpu) (&per_cpu(__uv_hub_info, cpu))
|
||||||
|
|
||||||
|
union uvh_apicid {
|
||||||
|
unsigned long v;
|
||||||
|
struct uvh_apicid_s {
|
||||||
|
unsigned long local_apic_mask : 24;
|
||||||
|
unsigned long local_apic_shift : 5;
|
||||||
|
unsigned long unused1 : 3;
|
||||||
|
unsigned long pnode_mask : 24;
|
||||||
|
unsigned long pnode_shift : 5;
|
||||||
|
unsigned long unused2 : 3;
|
||||||
|
} s;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Local & Global MMR space macros.
|
* Local & Global MMR space macros.
|
||||||
* Note: macros are intended to be used ONLY by inline functions
|
* Note: macros are intended to be used ONLY by inline functions
|
||||||
|
@ -182,6 +196,7 @@ DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
|
||||||
#define UV_GLOBAL_MMR64_PNODE_BITS(p) \
|
#define UV_GLOBAL_MMR64_PNODE_BITS(p) \
|
||||||
(((unsigned long)(p)) << UV_GLOBAL_MMR64_PNODE_SHIFT)
|
(((unsigned long)(p)) << UV_GLOBAL_MMR64_PNODE_SHIFT)
|
||||||
|
|
||||||
|
#define UVH_APICID 0x002D0E00L
|
||||||
#define UV_APIC_PNODE_SHIFT 6
|
#define UV_APIC_PNODE_SHIFT 6
|
||||||
|
|
||||||
/* Local Bus from cpu's perspective */
|
/* Local Bus from cpu's perspective */
|
||||||
|
@ -280,7 +295,7 @@ static inline void *uv_pnode_offset_to_vaddr(int pnode, unsigned long offset)
|
||||||
*/
|
*/
|
||||||
static inline int uv_apicid_to_pnode(int apicid)
|
static inline int uv_apicid_to_pnode(int apicid)
|
||||||
{
|
{
|
||||||
return (apicid >> UV_APIC_PNODE_SHIFT);
|
return (apicid >> uv_hub_info->apic_pnode_shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -638,7 +638,7 @@ void *__kprobes text_poke_smp(void *addr, const void *opcode, size_t len)
|
||||||
atomic_set(&stop_machine_first, 1);
|
atomic_set(&stop_machine_first, 1);
|
||||||
wrote_text = 0;
|
wrote_text = 0;
|
||||||
/* Use __stop_machine() because the caller already got online_cpus. */
|
/* Use __stop_machine() because the caller already got online_cpus. */
|
||||||
__stop_machine(stop_machine_text_poke, (void *)&tpp, NULL);
|
__stop_machine(stop_machine_text_poke, (void *)&tpp, cpu_online_mask);
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*
|
*
|
||||||
* SGI UV APIC functions (note: not an Intel compatible APIC)
|
* SGI UV APIC functions (note: not an Intel compatible APIC)
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009 Silicon Graphics, Inc. All rights reserved.
|
* Copyright (C) 2007-2010 Silicon Graphics, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
#include <linux/cpumask.h>
|
#include <linux/cpumask.h>
|
||||||
#include <linux/hardirq.h>
|
#include <linux/hardirq.h>
|
||||||
|
@ -41,6 +41,7 @@ DEFINE_PER_CPU(int, x2apic_extra_bits);
|
||||||
|
|
||||||
static enum uv_system_type uv_system_type;
|
static enum uv_system_type uv_system_type;
|
||||||
static u64 gru_start_paddr, gru_end_paddr;
|
static u64 gru_start_paddr, gru_end_paddr;
|
||||||
|
static union uvh_apicid uvh_apicid;
|
||||||
int uv_min_hub_revision_id;
|
int uv_min_hub_revision_id;
|
||||||
EXPORT_SYMBOL_GPL(uv_min_hub_revision_id);
|
EXPORT_SYMBOL_GPL(uv_min_hub_revision_id);
|
||||||
static DEFINE_SPINLOCK(uv_nmi_lock);
|
static DEFINE_SPINLOCK(uv_nmi_lock);
|
||||||
|
@ -70,12 +71,27 @@ static int early_get_nodeid(void)
|
||||||
return node_id.s.node_id;
|
return node_id.s.node_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __init early_get_apic_pnode_shift(void)
|
||||||
|
{
|
||||||
|
unsigned long *mmr;
|
||||||
|
|
||||||
|
mmr = early_ioremap(UV_LOCAL_MMR_BASE | UVH_APICID, sizeof(*mmr));
|
||||||
|
uvh_apicid.v = *mmr;
|
||||||
|
early_iounmap(mmr, sizeof(*mmr));
|
||||||
|
if (!uvh_apicid.v)
|
||||||
|
/*
|
||||||
|
* Old bios, use default value
|
||||||
|
*/
|
||||||
|
uvh_apicid.s.pnode_shift = UV_APIC_PNODE_SHIFT;
|
||||||
|
}
|
||||||
|
|
||||||
static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
|
static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
|
||||||
{
|
{
|
||||||
int nodeid;
|
int nodeid;
|
||||||
|
|
||||||
if (!strcmp(oem_id, "SGI")) {
|
if (!strcmp(oem_id, "SGI")) {
|
||||||
nodeid = early_get_nodeid();
|
nodeid = early_get_nodeid();
|
||||||
|
early_get_apic_pnode_shift();
|
||||||
x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range;
|
x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range;
|
||||||
x86_platform.nmi_init = uv_nmi_init;
|
x86_platform.nmi_init = uv_nmi_init;
|
||||||
if (!strcmp(oem_table_id, "UVL"))
|
if (!strcmp(oem_table_id, "UVL"))
|
||||||
|
@ -84,7 +100,7 @@ static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
|
||||||
uv_system_type = UV_X2APIC;
|
uv_system_type = UV_X2APIC;
|
||||||
else if (!strcmp(oem_table_id, "UVH")) {
|
else if (!strcmp(oem_table_id, "UVH")) {
|
||||||
__get_cpu_var(x2apic_extra_bits) =
|
__get_cpu_var(x2apic_extra_bits) =
|
||||||
nodeid << (UV_APIC_PNODE_SHIFT - 1);
|
nodeid << (uvh_apicid.s.pnode_shift - 1);
|
||||||
uv_system_type = UV_NON_UNIQUE_APIC;
|
uv_system_type = UV_NON_UNIQUE_APIC;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -716,6 +732,10 @@ void __init uv_system_init(void)
|
||||||
int apicid = per_cpu(x86_cpu_to_apicid, cpu);
|
int apicid = per_cpu(x86_cpu_to_apicid, cpu);
|
||||||
|
|
||||||
nid = cpu_to_node(cpu);
|
nid = cpu_to_node(cpu);
|
||||||
|
/*
|
||||||
|
* apic_pnode_shift must be set before calling uv_apicid_to_pnode();
|
||||||
|
*/
|
||||||
|
uv_cpu_hub_info(cpu)->apic_pnode_shift = uvh_apicid.s.pnode_shift;
|
||||||
pnode = uv_apicid_to_pnode(apicid);
|
pnode = uv_apicid_to_pnode(apicid);
|
||||||
blade = boot_pnode_to_blade(pnode);
|
blade = boot_pnode_to_blade(pnode);
|
||||||
lcpu = uv_blade_info[blade].nr_possible_cpus;
|
lcpu = uv_blade_info[blade].nr_possible_cpus;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/percpu.h>
|
#include <linux/percpu.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
|
||||||
#include <asm/apic.h>
|
#include <asm/apic.h>
|
||||||
|
|
||||||
|
@ -125,7 +126,9 @@ void __cpuinit irq_ctx_init(int cpu)
|
||||||
if (per_cpu(hardirq_ctx, cpu))
|
if (per_cpu(hardirq_ctx, cpu))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
irqctx = (union irq_ctx *)__get_free_pages(THREAD_FLAGS, THREAD_ORDER);
|
irqctx = page_address(alloc_pages_node(cpu_to_node(cpu),
|
||||||
|
THREAD_FLAGS,
|
||||||
|
THREAD_ORDER));
|
||||||
irqctx->tinfo.task = NULL;
|
irqctx->tinfo.task = NULL;
|
||||||
irqctx->tinfo.exec_domain = NULL;
|
irqctx->tinfo.exec_domain = NULL;
|
||||||
irqctx->tinfo.cpu = cpu;
|
irqctx->tinfo.cpu = cpu;
|
||||||
|
@ -134,7 +137,9 @@ void __cpuinit irq_ctx_init(int cpu)
|
||||||
|
|
||||||
per_cpu(hardirq_ctx, cpu) = irqctx;
|
per_cpu(hardirq_ctx, cpu) = irqctx;
|
||||||
|
|
||||||
irqctx = (union irq_ctx *)__get_free_pages(THREAD_FLAGS, THREAD_ORDER);
|
irqctx = page_address(alloc_pages_node(cpu_to_node(cpu),
|
||||||
|
THREAD_FLAGS,
|
||||||
|
THREAD_ORDER));
|
||||||
irqctx->tinfo.task = NULL;
|
irqctx->tinfo.task = NULL;
|
||||||
irqctx->tinfo.exec_domain = NULL;
|
irqctx->tinfo.exec_domain = NULL;
|
||||||
irqctx->tinfo.cpu = cpu;
|
irqctx->tinfo.cpu = cpu;
|
||||||
|
|
|
@ -178,11 +178,8 @@ static void * __init early_node_mem(int nodeid, unsigned long start,
|
||||||
|
|
||||||
/* extend the search scope */
|
/* extend the search scope */
|
||||||
end = max_pfn_mapped << PAGE_SHIFT;
|
end = max_pfn_mapped << PAGE_SHIFT;
|
||||||
if (end > (MAX_DMA32_PFN<<PAGE_SHIFT))
|
|
||||||
start = MAX_DMA32_PFN<<PAGE_SHIFT;
|
|
||||||
else
|
|
||||||
start = MAX_DMA_PFN << PAGE_SHIFT;
|
start = MAX_DMA_PFN << PAGE_SHIFT;
|
||||||
mem = memblock_x86_find_in_range_node(nodeid, start, end, size, align);
|
mem = memblock_find_in_range(start, end, size, align);
|
||||||
if (mem != MEMBLOCK_ERROR)
|
if (mem != MEMBLOCK_ERROR)
|
||||||
return __va(mem);
|
return __va(mem);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче