mirror of
https://github.com/adulau/aha.git
synced 2024-12-27 11:16:11 +00:00
Merge branch 'x86-fixes-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, irq: Allow 0xff for /proc/irq/[n]/smp_affinity on an 8-cpu system Makefile: Unexport LC_ALL instead of clearing it x86: Fix objdump version check in arch/x86/tools/chkobjdump.awk x86: Reenable TSC sync check at boot, even with NONSTOP_TSC x86: Don't use POSIX character classes in gen-insn-attr-x86.awk Makefile: set LC_CTYPE, LC_COLLATE, LC_NUMERIC to C x86: Increase MAX_EARLY_RES; insufficient on 32-bit NUMA x86: Fix checking of SRAT when node 0 ram is not from 0 x86, cpuid: Add "volatile" to asm in native_cpuid() x86, msr: msrs_alloc/free for CONFIG_SMP=n x86, amd: Get multi-node CPU info from NodeId MSR instead of PCI config space x86: Add IA32_TSC_AUX MSR and use it x86, msr/cpuid: Register enough minors for the MSR and CPUID drivers initramfs: add missing decompressor error check bzip2: Add missing checks for malloc returning NULL bzip2/lzma/gzip: pre-boot malloc doesn't return NULL on failure
This commit is contained in:
commit
3981e15286
31 changed files with 307 additions and 320 deletions
7
Makefile
7
Makefile
|
@ -16,6 +16,13 @@ NAME = Man-Eating Seals of Antiquity
|
||||||
# o print "Entering directory ...";
|
# o print "Entering directory ...";
|
||||||
MAKEFLAGS += -rR --no-print-directory
|
MAKEFLAGS += -rR --no-print-directory
|
||||||
|
|
||||||
|
# Avoid funny character set dependencies
|
||||||
|
unexport LC_ALL
|
||||||
|
LC_CTYPE=C
|
||||||
|
LC_COLLATE=C
|
||||||
|
LC_NUMERIC=C
|
||||||
|
export LC_CTYPE LC_COLLATE LC_NUMERIC
|
||||||
|
|
||||||
# We are using a recursive build, so we need to do a little thinking
|
# We are using a recursive build, so we need to do a little thinking
|
||||||
# to get the ordering right.
|
# to get the ordering right.
|
||||||
#
|
#
|
||||||
|
|
|
@ -153,6 +153,7 @@
|
||||||
#define X86_FEATURE_SSE5 (6*32+11) /* SSE-5 */
|
#define X86_FEATURE_SSE5 (6*32+11) /* SSE-5 */
|
||||||
#define X86_FEATURE_SKINIT (6*32+12) /* SKINIT/STGI instructions */
|
#define X86_FEATURE_SKINIT (6*32+12) /* SKINIT/STGI instructions */
|
||||||
#define X86_FEATURE_WDT (6*32+13) /* Watchdog timer */
|
#define X86_FEATURE_WDT (6*32+13) /* Watchdog timer */
|
||||||
|
#define X86_FEATURE_NODEID_MSR (6*32+19) /* NodeId MSR */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Auxiliary flags: Linux defined - For features scattered in various
|
* Auxiliary flags: Linux defined - For features scattered in various
|
||||||
|
|
|
@ -103,7 +103,8 @@ extern int assign_irq_vector(int, struct irq_cfg *, const struct cpumask *);
|
||||||
extern void send_cleanup_vector(struct irq_cfg *);
|
extern void send_cleanup_vector(struct irq_cfg *);
|
||||||
|
|
||||||
struct irq_desc;
|
struct irq_desc;
|
||||||
extern unsigned int set_desc_affinity(struct irq_desc *, const struct cpumask *);
|
extern unsigned int set_desc_affinity(struct irq_desc *, const struct cpumask *,
|
||||||
|
unsigned int *dest_id);
|
||||||
extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin, struct io_apic_irq_attr *irq_attr);
|
extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin, struct io_apic_irq_attr *irq_attr);
|
||||||
extern void setup_ioapic_dest(void);
|
extern void setup_ioapic_dest(void);
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#define MSR_FS_BASE 0xc0000100 /* 64bit FS base */
|
#define MSR_FS_BASE 0xc0000100 /* 64bit FS base */
|
||||||
#define MSR_GS_BASE 0xc0000101 /* 64bit GS base */
|
#define MSR_GS_BASE 0xc0000101 /* 64bit GS base */
|
||||||
#define MSR_KERNEL_GS_BASE 0xc0000102 /* SwapGS GS shadow */
|
#define MSR_KERNEL_GS_BASE 0xc0000102 /* SwapGS GS shadow */
|
||||||
|
#define MSR_TSC_AUX 0xc0000103 /* Auxiliary TSC */
|
||||||
|
|
||||||
/* EFER bits: */
|
/* EFER bits: */
|
||||||
#define _EFER_SCE 0 /* SYSCALL/SYSRET */
|
#define _EFER_SCE 0 /* SYSCALL/SYSRET */
|
||||||
|
@ -123,6 +124,7 @@
|
||||||
#define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2
|
#define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2
|
||||||
#define FAM10H_MMIO_CONF_BASE_MASK 0xfffffff
|
#define FAM10H_MMIO_CONF_BASE_MASK 0xfffffff
|
||||||
#define FAM10H_MMIO_CONF_BASE_SHIFT 20
|
#define FAM10H_MMIO_CONF_BASE_SHIFT 20
|
||||||
|
#define MSR_FAM10H_NODE_ID 0xc001100c
|
||||||
|
|
||||||
/* K8 MSRs */
|
/* K8 MSRs */
|
||||||
#define MSR_K8_TOP_MEM1 0xc001001a
|
#define MSR_K8_TOP_MEM1 0xc001001a
|
||||||
|
|
|
@ -27,6 +27,18 @@ struct msr {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct msr_info {
|
||||||
|
u32 msr_no;
|
||||||
|
struct msr reg;
|
||||||
|
struct msr *msrs;
|
||||||
|
int err;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct msr_regs_info {
|
||||||
|
u32 *regs;
|
||||||
|
int err;
|
||||||
|
};
|
||||||
|
|
||||||
static inline unsigned long long native_read_tscp(unsigned int *aux)
|
static inline unsigned long long native_read_tscp(unsigned int *aux)
|
||||||
{
|
{
|
||||||
unsigned long low, high;
|
unsigned long low, high;
|
||||||
|
@ -240,9 +252,9 @@ do { \
|
||||||
#define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val), \
|
#define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val), \
|
||||||
(u32)((val) >> 32))
|
(u32)((val) >> 32))
|
||||||
|
|
||||||
#define write_tsc(val1, val2) wrmsr(0x10, (val1), (val2))
|
#define write_tsc(val1, val2) wrmsr(MSR_IA32_TSC, (val1), (val2))
|
||||||
|
|
||||||
#define write_rdtscp_aux(val) wrmsr(0xc0000103, (val), 0)
|
#define write_rdtscp_aux(val) wrmsr(MSR_TSC_AUX, (val), 0)
|
||||||
|
|
||||||
struct msr *msrs_alloc(void);
|
struct msr *msrs_alloc(void);
|
||||||
void msrs_free(struct msr *msrs);
|
void msrs_free(struct msr *msrs);
|
||||||
|
|
|
@ -181,7 +181,7 @@ static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
|
||||||
unsigned int *ecx, unsigned int *edx)
|
unsigned int *ecx, unsigned int *edx)
|
||||||
{
|
{
|
||||||
/* ecx is often an input as well as an output. */
|
/* ecx is often an input as well as an output. */
|
||||||
asm("cpuid"
|
asm volatile("cpuid"
|
||||||
: "=a" (*eax),
|
: "=a" (*eax),
|
||||||
"=b" (*ebx),
|
"=b" (*ebx),
|
||||||
"=c" (*ecx),
|
"=c" (*ecx),
|
||||||
|
|
|
@ -306,10 +306,7 @@ physflat_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
|
||||||
if (cpumask_test_cpu(cpu, cpu_online_mask))
|
if (cpumask_test_cpu(cpu, cpu_online_mask))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (cpu < nr_cpu_ids)
|
return per_cpu(x86_cpu_to_apicid, cpu);
|
||||||
return per_cpu(x86_cpu_to_apicid, cpu);
|
|
||||||
|
|
||||||
return BAD_APICID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct apic apic_physflat = {
|
struct apic apic_physflat = {
|
||||||
|
|
|
@ -131,10 +131,7 @@ static unsigned int bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
|
||||||
if (cpumask_test_cpu(cpu, cpu_online_mask))
|
if (cpumask_test_cpu(cpu, cpu_online_mask))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (cpu < nr_cpu_ids)
|
return bigsmp_cpu_to_logical_apicid(cpu);
|
||||||
return bigsmp_cpu_to_logical_apicid(cpu);
|
|
||||||
|
|
||||||
return BAD_APICID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb)
|
static int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb)
|
||||||
|
|
|
@ -2276,26 +2276,28 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Either sets desc->affinity to a valid value, and returns
|
* Either sets desc->affinity to a valid value, and returns
|
||||||
* ->cpu_mask_to_apicid of that, or returns BAD_APICID and
|
* ->cpu_mask_to_apicid of that in dest_id, or returns -1 and
|
||||||
* leaves desc->affinity untouched.
|
* leaves desc->affinity untouched.
|
||||||
*/
|
*/
|
||||||
unsigned int
|
unsigned int
|
||||||
set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask)
|
set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask,
|
||||||
|
unsigned int *dest_id)
|
||||||
{
|
{
|
||||||
struct irq_cfg *cfg;
|
struct irq_cfg *cfg;
|
||||||
unsigned int irq;
|
unsigned int irq;
|
||||||
|
|
||||||
if (!cpumask_intersects(mask, cpu_online_mask))
|
if (!cpumask_intersects(mask, cpu_online_mask))
|
||||||
return BAD_APICID;
|
return -1;
|
||||||
|
|
||||||
irq = desc->irq;
|
irq = desc->irq;
|
||||||
cfg = desc->chip_data;
|
cfg = desc->chip_data;
|
||||||
if (assign_irq_vector(irq, cfg, mask))
|
if (assign_irq_vector(irq, cfg, mask))
|
||||||
return BAD_APICID;
|
return -1;
|
||||||
|
|
||||||
cpumask_copy(desc->affinity, mask);
|
cpumask_copy(desc->affinity, mask);
|
||||||
|
|
||||||
return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain);
|
*dest_id = apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -2311,12 +2313,11 @@ set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
|
||||||
cfg = desc->chip_data;
|
cfg = desc->chip_data;
|
||||||
|
|
||||||
spin_lock_irqsave(&ioapic_lock, flags);
|
spin_lock_irqsave(&ioapic_lock, flags);
|
||||||
dest = set_desc_affinity(desc, mask);
|
ret = set_desc_affinity(desc, mask, &dest);
|
||||||
if (dest != BAD_APICID) {
|
if (!ret) {
|
||||||
/* Only the high 8 bits are valid. */
|
/* Only the high 8 bits are valid. */
|
||||||
dest = SET_APIC_LOGICAL_ID(dest);
|
dest = SET_APIC_LOGICAL_ID(dest);
|
||||||
__target_IO_APIC_irq(irq, dest, cfg);
|
__target_IO_APIC_irq(irq, dest, cfg);
|
||||||
ret = 0;
|
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&ioapic_lock, flags);
|
spin_unlock_irqrestore(&ioapic_lock, flags);
|
||||||
|
|
||||||
|
@ -3351,8 +3352,7 @@ static int set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
|
||||||
struct msi_msg msg;
|
struct msi_msg msg;
|
||||||
unsigned int dest;
|
unsigned int dest;
|
||||||
|
|
||||||
dest = set_desc_affinity(desc, mask);
|
if (set_desc_affinity(desc, mask, &dest))
|
||||||
if (dest == BAD_APICID)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
cfg = desc->chip_data;
|
cfg = desc->chip_data;
|
||||||
|
@ -3384,8 +3384,7 @@ ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
|
||||||
if (get_irte(irq, &irte))
|
if (get_irte(irq, &irte))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
dest = set_desc_affinity(desc, mask);
|
if (set_desc_affinity(desc, mask, &dest))
|
||||||
if (dest == BAD_APICID)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
irte.vector = cfg->vector;
|
irte.vector = cfg->vector;
|
||||||
|
@ -3567,8 +3566,7 @@ static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
|
||||||
struct msi_msg msg;
|
struct msi_msg msg;
|
||||||
unsigned int dest;
|
unsigned int dest;
|
||||||
|
|
||||||
dest = set_desc_affinity(desc, mask);
|
if (set_desc_affinity(desc, mask, &dest))
|
||||||
if (dest == BAD_APICID)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
cfg = desc->chip_data;
|
cfg = desc->chip_data;
|
||||||
|
@ -3623,8 +3621,7 @@ static int hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
|
||||||
struct msi_msg msg;
|
struct msi_msg msg;
|
||||||
unsigned int dest;
|
unsigned int dest;
|
||||||
|
|
||||||
dest = set_desc_affinity(desc, mask);
|
if (set_desc_affinity(desc, mask, &dest))
|
||||||
if (dest == BAD_APICID)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
cfg = desc->chip_data;
|
cfg = desc->chip_data;
|
||||||
|
@ -3730,8 +3727,7 @@ static int set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask)
|
||||||
struct irq_cfg *cfg;
|
struct irq_cfg *cfg;
|
||||||
unsigned int dest;
|
unsigned int dest;
|
||||||
|
|
||||||
dest = set_desc_affinity(desc, mask);
|
if (set_desc_affinity(desc, mask, &dest))
|
||||||
if (dest == BAD_APICID)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
cfg = desc->chip_data;
|
cfg = desc->chip_data;
|
||||||
|
|
|
@ -148,10 +148,7 @@ x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cpu < nr_cpu_ids)
|
return per_cpu(x86_cpu_to_logical_apicid, cpu);
|
||||||
return per_cpu(x86_cpu_to_logical_apicid, cpu);
|
|
||||||
|
|
||||||
return BAD_APICID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int x2apic_cluster_phys_get_apic_id(unsigned long x)
|
static unsigned int x2apic_cluster_phys_get_apic_id(unsigned long x)
|
||||||
|
|
|
@ -146,10 +146,7 @@ x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cpu < nr_cpu_ids)
|
return per_cpu(x86_cpu_to_apicid, cpu);
|
||||||
return per_cpu(x86_cpu_to_apicid, cpu);
|
|
||||||
|
|
||||||
return BAD_APICID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int x2apic_phys_get_apic_id(unsigned long x)
|
static unsigned int x2apic_phys_get_apic_id(unsigned long x)
|
||||||
|
|
|
@ -225,10 +225,7 @@ uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
|
||||||
if (cpumask_test_cpu(cpu, cpu_online_mask))
|
if (cpumask_test_cpu(cpu, cpu_online_mask))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (cpu < nr_cpu_ids)
|
return per_cpu(x86_cpu_to_apicid, cpu);
|
||||||
return per_cpu(x86_cpu_to_apicid, cpu);
|
|
||||||
|
|
||||||
return BAD_APICID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int x2apic_get_apic_id(unsigned long x)
|
static unsigned int x2apic_get_apic_id(unsigned long x)
|
||||||
|
|
|
@ -254,59 +254,36 @@ static int __cpuinit nearby_node(int apicid)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fixup core topology information for AMD multi-node processors.
|
* Fixup core topology information for AMD multi-node processors.
|
||||||
* Assumption 1: Number of cores in each internal node is the same.
|
* Assumption: Number of cores in each internal node is the same.
|
||||||
* Assumption 2: Mixed systems with both single-node and dual-node
|
|
||||||
* processors are not supported.
|
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_X86_HT
|
#ifdef CONFIG_X86_HT
|
||||||
static void __cpuinit amd_fixup_dcm(struct cpuinfo_x86 *c)
|
static void __cpuinit amd_fixup_dcm(struct cpuinfo_x86 *c)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_PCI
|
unsigned long long value;
|
||||||
u32 t, cpn;
|
u32 nodes, cores_per_node;
|
||||||
u8 n, n_id;
|
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
|
|
||||||
|
if (!cpu_has(c, X86_FEATURE_NODEID_MSR))
|
||||||
|
return;
|
||||||
|
|
||||||
/* fixup topology information only once for a core */
|
/* fixup topology information only once for a core */
|
||||||
if (cpu_has(c, X86_FEATURE_AMD_DCM))
|
if (cpu_has(c, X86_FEATURE_AMD_DCM))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* check for multi-node processor on boot cpu */
|
rdmsrl(MSR_FAM10H_NODE_ID, value);
|
||||||
t = read_pci_config(0, 24, 3, 0xe8);
|
|
||||||
if (!(t & (1 << 29)))
|
nodes = ((value >> 3) & 7) + 1;
|
||||||
|
if (nodes == 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
set_cpu_cap(c, X86_FEATURE_AMD_DCM);
|
set_cpu_cap(c, X86_FEATURE_AMD_DCM);
|
||||||
|
cores_per_node = c->x86_max_cores / nodes;
|
||||||
|
|
||||||
/* cores per node: each internal node has half the number of cores */
|
/* store NodeID, use llc_shared_map to store sibling info */
|
||||||
cpn = c->x86_max_cores >> 1;
|
per_cpu(cpu_llc_id, cpu) = value & 7;
|
||||||
|
|
||||||
/* even-numbered NB_id of this dual-node processor */
|
/* fixup core id to be in range from 0 to (cores_per_node - 1) */
|
||||||
n = c->phys_proc_id << 1;
|
c->cpu_core_id = c->cpu_core_id % cores_per_node;
|
||||||
|
|
||||||
/*
|
|
||||||
* determine internal node id and assign cores fifty-fifty to
|
|
||||||
* each node of the dual-node processor
|
|
||||||
*/
|
|
||||||
t = read_pci_config(0, 24 + n, 3, 0xe8);
|
|
||||||
n = (t>>30) & 0x3;
|
|
||||||
if (n == 0) {
|
|
||||||
if (c->cpu_core_id < cpn)
|
|
||||||
n_id = 0;
|
|
||||||
else
|
|
||||||
n_id = 1;
|
|
||||||
} else {
|
|
||||||
if (c->cpu_core_id < cpn)
|
|
||||||
n_id = 1;
|
|
||||||
else
|
|
||||||
n_id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* compute entire NodeID, use llc_shared_map to store sibling info */
|
|
||||||
per_cpu(cpu_llc_id, cpu) = (c->phys_proc_id << 1) + n_id;
|
|
||||||
|
|
||||||
/* fixup core id to be in range from 0 to cpn */
|
|
||||||
c->cpu_core_id = c->cpu_core_id % cpn;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,6 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
|
||||||
if (c->x86_power & (1 << 8)) {
|
if (c->x86_power & (1 << 8)) {
|
||||||
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
|
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
|
||||||
set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
|
set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
|
||||||
set_cpu_cap(c, X86_FEATURE_TSC_RELIABLE);
|
|
||||||
sched_clock_stable = 1;
|
sched_clock_stable = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,7 +187,8 @@ static int __init cpuid_init(void)
|
||||||
int i, err = 0;
|
int i, err = 0;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
if (register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops)) {
|
if (__register_chrdev(CPUID_MAJOR, 0, NR_CPUS,
|
||||||
|
"cpu/cpuid", &cpuid_fops)) {
|
||||||
printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n",
|
printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n",
|
||||||
CPUID_MAJOR);
|
CPUID_MAJOR);
|
||||||
err = -EBUSY;
|
err = -EBUSY;
|
||||||
|
@ -216,7 +217,7 @@ out_class:
|
||||||
}
|
}
|
||||||
class_destroy(cpuid_class);
|
class_destroy(cpuid_class);
|
||||||
out_chrdev:
|
out_chrdev:
|
||||||
unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
|
__unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid");
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -724,7 +724,7 @@ core_initcall(e820_mark_nvs_memory);
|
||||||
/*
|
/*
|
||||||
* Early reserved memory areas.
|
* Early reserved memory areas.
|
||||||
*/
|
*/
|
||||||
#define MAX_EARLY_RES 20
|
#define MAX_EARLY_RES 32
|
||||||
|
|
||||||
struct early_res {
|
struct early_res {
|
||||||
u64 start, end;
|
u64 start, end;
|
||||||
|
|
|
@ -246,7 +246,7 @@ static int __init msr_init(void)
|
||||||
int i, err = 0;
|
int i, err = 0;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
if (register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops)) {
|
if (__register_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr", &msr_fops)) {
|
||||||
printk(KERN_ERR "msr: unable to get major %d for msr\n",
|
printk(KERN_ERR "msr: unable to get major %d for msr\n",
|
||||||
MSR_MAJOR);
|
MSR_MAJOR);
|
||||||
err = -EBUSY;
|
err = -EBUSY;
|
||||||
|
@ -274,7 +274,7 @@ out_class:
|
||||||
msr_device_destroy(i);
|
msr_device_destroy(i);
|
||||||
class_destroy(msr_class);
|
class_destroy(msr_class);
|
||||||
out_chrdev:
|
out_chrdev:
|
||||||
unregister_chrdev(MSR_MAJOR, "cpu/msr");
|
__unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -763,6 +763,7 @@ void mark_tsc_unstable(char *reason)
|
||||||
{
|
{
|
||||||
if (!tsc_unstable) {
|
if (!tsc_unstable) {
|
||||||
tsc_unstable = 1;
|
tsc_unstable = 1;
|
||||||
|
sched_clock_stable = 0;
|
||||||
printk(KERN_INFO "Marking TSC unstable due to %s\n", reason);
|
printk(KERN_INFO "Marking TSC unstable due to %s\n", reason);
|
||||||
/* Change only the rating, when not registered */
|
/* Change only the rating, when not registered */
|
||||||
if (clocksource_tsc.mult)
|
if (clocksource_tsc.mult)
|
||||||
|
|
|
@ -215,8 +215,7 @@ static int uv_set_irq_affinity(unsigned int irq, const struct cpumask *mask)
|
||||||
unsigned long mmr_offset;
|
unsigned long mmr_offset;
|
||||||
unsigned mmr_pnode;
|
unsigned mmr_pnode;
|
||||||
|
|
||||||
dest = set_desc_affinity(desc, mask);
|
if (set_desc_affinity(desc, mask, &dest))
|
||||||
if (dest == BAD_APICID)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
mmr_value = 0;
|
mmr_value = 0;
|
||||||
|
|
|
@ -14,7 +14,7 @@ $(obj)/inat.o: $(obj)/inat-tables.c
|
||||||
|
|
||||||
clean-files := inat-tables.c
|
clean-files := inat-tables.c
|
||||||
|
|
||||||
obj-$(CONFIG_SMP) := msr.o
|
obj-$(CONFIG_SMP) += msr-smp.o
|
||||||
|
|
||||||
lib-y := delay.o
|
lib-y := delay.o
|
||||||
lib-y += thunk_$(BITS).o
|
lib-y += thunk_$(BITS).o
|
||||||
|
@ -22,7 +22,7 @@ lib-y += usercopy_$(BITS).o getuser.o putuser.o
|
||||||
lib-y += memcpy_$(BITS).o
|
lib-y += memcpy_$(BITS).o
|
||||||
lib-$(CONFIG_KPROBES) += insn.o inat.o
|
lib-$(CONFIG_KPROBES) += insn.o inat.o
|
||||||
|
|
||||||
obj-y += msr-reg.o msr-reg-export.o
|
obj-y += msr.o msr-reg.o msr-reg-export.o
|
||||||
|
|
||||||
ifeq ($(CONFIG_X86_32),y)
|
ifeq ($(CONFIG_X86_32),y)
|
||||||
obj-y += atomic64_32.o
|
obj-y += atomic64_32.o
|
||||||
|
|
204
arch/x86/lib/msr-smp.c
Normal file
204
arch/x86/lib/msr-smp.c
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/preempt.h>
|
||||||
|
#include <linux/smp.h>
|
||||||
|
#include <asm/msr.h>
|
||||||
|
|
||||||
|
static void __rdmsr_on_cpu(void *info)
|
||||||
|
{
|
||||||
|
struct msr_info *rv = info;
|
||||||
|
struct msr *reg;
|
||||||
|
int this_cpu = raw_smp_processor_id();
|
||||||
|
|
||||||
|
if (rv->msrs)
|
||||||
|
reg = per_cpu_ptr(rv->msrs, this_cpu);
|
||||||
|
else
|
||||||
|
reg = &rv->reg;
|
||||||
|
|
||||||
|
rdmsr(rv->msr_no, reg->l, reg->h);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __wrmsr_on_cpu(void *info)
|
||||||
|
{
|
||||||
|
struct msr_info *rv = info;
|
||||||
|
struct msr *reg;
|
||||||
|
int this_cpu = raw_smp_processor_id();
|
||||||
|
|
||||||
|
if (rv->msrs)
|
||||||
|
reg = per_cpu_ptr(rv->msrs, this_cpu);
|
||||||
|
else
|
||||||
|
reg = &rv->reg;
|
||||||
|
|
||||||
|
wrmsr(rv->msr_no, reg->l, reg->h);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct msr_info rv;
|
||||||
|
|
||||||
|
memset(&rv, 0, sizeof(rv));
|
||||||
|
|
||||||
|
rv.msr_no = msr_no;
|
||||||
|
err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
|
||||||
|
*l = rv.reg.l;
|
||||||
|
*h = rv.reg.h;
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rdmsr_on_cpu);
|
||||||
|
|
||||||
|
int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct msr_info rv;
|
||||||
|
|
||||||
|
memset(&rv, 0, sizeof(rv));
|
||||||
|
|
||||||
|
rv.msr_no = msr_no;
|
||||||
|
rv.reg.l = l;
|
||||||
|
rv.reg.h = h;
|
||||||
|
err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(wrmsr_on_cpu);
|
||||||
|
|
||||||
|
static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no,
|
||||||
|
struct msr *msrs,
|
||||||
|
void (*msr_func) (void *info))
|
||||||
|
{
|
||||||
|
struct msr_info rv;
|
||||||
|
int this_cpu;
|
||||||
|
|
||||||
|
memset(&rv, 0, sizeof(rv));
|
||||||
|
|
||||||
|
rv.msrs = msrs;
|
||||||
|
rv.msr_no = msr_no;
|
||||||
|
|
||||||
|
this_cpu = get_cpu();
|
||||||
|
|
||||||
|
if (cpumask_test_cpu(this_cpu, mask))
|
||||||
|
msr_func(&rv);
|
||||||
|
|
||||||
|
smp_call_function_many(mask, msr_func, &rv, 1);
|
||||||
|
put_cpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rdmsr on a bunch of CPUs
|
||||||
|
*
|
||||||
|
* @mask: which CPUs
|
||||||
|
* @msr_no: which MSR
|
||||||
|
* @msrs: array of MSR values
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
|
||||||
|
{
|
||||||
|
__rwmsr_on_cpus(mask, msr_no, msrs, __rdmsr_on_cpu);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rdmsr_on_cpus);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wrmsr on a bunch of CPUs
|
||||||
|
*
|
||||||
|
* @mask: which CPUs
|
||||||
|
* @msr_no: which MSR
|
||||||
|
* @msrs: array of MSR values
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
|
||||||
|
{
|
||||||
|
__rwmsr_on_cpus(mask, msr_no, msrs, __wrmsr_on_cpu);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(wrmsr_on_cpus);
|
||||||
|
|
||||||
|
/* These "safe" variants are slower and should be used when the target MSR
|
||||||
|
may not actually exist. */
|
||||||
|
static void __rdmsr_safe_on_cpu(void *info)
|
||||||
|
{
|
||||||
|
struct msr_info *rv = info;
|
||||||
|
|
||||||
|
rv->err = rdmsr_safe(rv->msr_no, &rv->reg.l, &rv->reg.h);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __wrmsr_safe_on_cpu(void *info)
|
||||||
|
{
|
||||||
|
struct msr_info *rv = info;
|
||||||
|
|
||||||
|
rv->err = wrmsr_safe(rv->msr_no, rv->reg.l, rv->reg.h);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct msr_info rv;
|
||||||
|
|
||||||
|
memset(&rv, 0, sizeof(rv));
|
||||||
|
|
||||||
|
rv.msr_no = msr_no;
|
||||||
|
err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1);
|
||||||
|
*l = rv.reg.l;
|
||||||
|
*h = rv.reg.h;
|
||||||
|
|
||||||
|
return err ? err : rv.err;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rdmsr_safe_on_cpu);
|
||||||
|
|
||||||
|
int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct msr_info rv;
|
||||||
|
|
||||||
|
memset(&rv, 0, sizeof(rv));
|
||||||
|
|
||||||
|
rv.msr_no = msr_no;
|
||||||
|
rv.reg.l = l;
|
||||||
|
rv.reg.h = h;
|
||||||
|
err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1);
|
||||||
|
|
||||||
|
return err ? err : rv.err;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(wrmsr_safe_on_cpu);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These variants are significantly slower, but allows control over
|
||||||
|
* the entire 32-bit GPR set.
|
||||||
|
*/
|
||||||
|
static void __rdmsr_safe_regs_on_cpu(void *info)
|
||||||
|
{
|
||||||
|
struct msr_regs_info *rv = info;
|
||||||
|
|
||||||
|
rv->err = rdmsr_safe_regs(rv->regs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __wrmsr_safe_regs_on_cpu(void *info)
|
||||||
|
{
|
||||||
|
struct msr_regs_info *rv = info;
|
||||||
|
|
||||||
|
rv->err = wrmsr_safe_regs(rv->regs);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct msr_regs_info rv;
|
||||||
|
|
||||||
|
rv.regs = regs;
|
||||||
|
rv.err = -EIO;
|
||||||
|
err = smp_call_function_single(cpu, __rdmsr_safe_regs_on_cpu, &rv, 1);
|
||||||
|
|
||||||
|
return err ? err : rv.err;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rdmsr_safe_regs_on_cpu);
|
||||||
|
|
||||||
|
int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct msr_regs_info rv;
|
||||||
|
|
||||||
|
rv.regs = regs;
|
||||||
|
rv.err = -EIO;
|
||||||
|
err = smp_call_function_single(cpu, __wrmsr_safe_regs_on_cpu, &rv, 1);
|
||||||
|
|
||||||
|
return err ? err : rv.err;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(wrmsr_safe_regs_on_cpu);
|
|
@ -1,123 +1,7 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/preempt.h>
|
#include <linux/preempt.h>
|
||||||
#include <linux/smp.h>
|
|
||||||
#include <asm/msr.h>
|
#include <asm/msr.h>
|
||||||
|
|
||||||
struct msr_info {
|
|
||||||
u32 msr_no;
|
|
||||||
struct msr reg;
|
|
||||||
struct msr *msrs;
|
|
||||||
int err;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void __rdmsr_on_cpu(void *info)
|
|
||||||
{
|
|
||||||
struct msr_info *rv = info;
|
|
||||||
struct msr *reg;
|
|
||||||
int this_cpu = raw_smp_processor_id();
|
|
||||||
|
|
||||||
if (rv->msrs)
|
|
||||||
reg = per_cpu_ptr(rv->msrs, this_cpu);
|
|
||||||
else
|
|
||||||
reg = &rv->reg;
|
|
||||||
|
|
||||||
rdmsr(rv->msr_no, reg->l, reg->h);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __wrmsr_on_cpu(void *info)
|
|
||||||
{
|
|
||||||
struct msr_info *rv = info;
|
|
||||||
struct msr *reg;
|
|
||||||
int this_cpu = raw_smp_processor_id();
|
|
||||||
|
|
||||||
if (rv->msrs)
|
|
||||||
reg = per_cpu_ptr(rv->msrs, this_cpu);
|
|
||||||
else
|
|
||||||
reg = &rv->reg;
|
|
||||||
|
|
||||||
wrmsr(rv->msr_no, reg->l, reg->h);
|
|
||||||
}
|
|
||||||
|
|
||||||
int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
struct msr_info rv;
|
|
||||||
|
|
||||||
memset(&rv, 0, sizeof(rv));
|
|
||||||
|
|
||||||
rv.msr_no = msr_no;
|
|
||||||
err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
|
|
||||||
*l = rv.reg.l;
|
|
||||||
*h = rv.reg.h;
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(rdmsr_on_cpu);
|
|
||||||
|
|
||||||
int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
struct msr_info rv;
|
|
||||||
|
|
||||||
memset(&rv, 0, sizeof(rv));
|
|
||||||
|
|
||||||
rv.msr_no = msr_no;
|
|
||||||
rv.reg.l = l;
|
|
||||||
rv.reg.h = h;
|
|
||||||
err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(wrmsr_on_cpu);
|
|
||||||
|
|
||||||
static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no,
|
|
||||||
struct msr *msrs,
|
|
||||||
void (*msr_func) (void *info))
|
|
||||||
{
|
|
||||||
struct msr_info rv;
|
|
||||||
int this_cpu;
|
|
||||||
|
|
||||||
memset(&rv, 0, sizeof(rv));
|
|
||||||
|
|
||||||
rv.msrs = msrs;
|
|
||||||
rv.msr_no = msr_no;
|
|
||||||
|
|
||||||
this_cpu = get_cpu();
|
|
||||||
|
|
||||||
if (cpumask_test_cpu(this_cpu, mask))
|
|
||||||
msr_func(&rv);
|
|
||||||
|
|
||||||
smp_call_function_many(mask, msr_func, &rv, 1);
|
|
||||||
put_cpu();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* rdmsr on a bunch of CPUs
|
|
||||||
*
|
|
||||||
* @mask: which CPUs
|
|
||||||
* @msr_no: which MSR
|
|
||||||
* @msrs: array of MSR values
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
|
|
||||||
{
|
|
||||||
__rwmsr_on_cpus(mask, msr_no, msrs, __rdmsr_on_cpu);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(rdmsr_on_cpus);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* wrmsr on a bunch of CPUs
|
|
||||||
*
|
|
||||||
* @mask: which CPUs
|
|
||||||
* @msr_no: which MSR
|
|
||||||
* @msrs: array of MSR values
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
|
|
||||||
{
|
|
||||||
__rwmsr_on_cpus(mask, msr_no, msrs, __wrmsr_on_cpu);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(wrmsr_on_cpus);
|
|
||||||
|
|
||||||
struct msr *msrs_alloc(void)
|
struct msr *msrs_alloc(void)
|
||||||
{
|
{
|
||||||
struct msr *msrs = NULL;
|
struct msr *msrs = NULL;
|
||||||
|
@ -137,100 +21,3 @@ void msrs_free(struct msr *msrs)
|
||||||
free_percpu(msrs);
|
free_percpu(msrs);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(msrs_free);
|
EXPORT_SYMBOL(msrs_free);
|
||||||
|
|
||||||
/* These "safe" variants are slower and should be used when the target MSR
|
|
||||||
may not actually exist. */
|
|
||||||
static void __rdmsr_safe_on_cpu(void *info)
|
|
||||||
{
|
|
||||||
struct msr_info *rv = info;
|
|
||||||
|
|
||||||
rv->err = rdmsr_safe(rv->msr_no, &rv->reg.l, &rv->reg.h);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __wrmsr_safe_on_cpu(void *info)
|
|
||||||
{
|
|
||||||
struct msr_info *rv = info;
|
|
||||||
|
|
||||||
rv->err = wrmsr_safe(rv->msr_no, rv->reg.l, rv->reg.h);
|
|
||||||
}
|
|
||||||
|
|
||||||
int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
struct msr_info rv;
|
|
||||||
|
|
||||||
memset(&rv, 0, sizeof(rv));
|
|
||||||
|
|
||||||
rv.msr_no = msr_no;
|
|
||||||
err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1);
|
|
||||||
*l = rv.reg.l;
|
|
||||||
*h = rv.reg.h;
|
|
||||||
|
|
||||||
return err ? err : rv.err;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(rdmsr_safe_on_cpu);
|
|
||||||
|
|
||||||
int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
struct msr_info rv;
|
|
||||||
|
|
||||||
memset(&rv, 0, sizeof(rv));
|
|
||||||
|
|
||||||
rv.msr_no = msr_no;
|
|
||||||
rv.reg.l = l;
|
|
||||||
rv.reg.h = h;
|
|
||||||
err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1);
|
|
||||||
|
|
||||||
return err ? err : rv.err;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(wrmsr_safe_on_cpu);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These variants are significantly slower, but allows control over
|
|
||||||
* the entire 32-bit GPR set.
|
|
||||||
*/
|
|
||||||
struct msr_regs_info {
|
|
||||||
u32 *regs;
|
|
||||||
int err;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void __rdmsr_safe_regs_on_cpu(void *info)
|
|
||||||
{
|
|
||||||
struct msr_regs_info *rv = info;
|
|
||||||
|
|
||||||
rv->err = rdmsr_safe_regs(rv->regs);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __wrmsr_safe_regs_on_cpu(void *info)
|
|
||||||
{
|
|
||||||
struct msr_regs_info *rv = info;
|
|
||||||
|
|
||||||
rv->err = wrmsr_safe_regs(rv->regs);
|
|
||||||
}
|
|
||||||
|
|
||||||
int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
struct msr_regs_info rv;
|
|
||||||
|
|
||||||
rv.regs = regs;
|
|
||||||
rv.err = -EIO;
|
|
||||||
err = smp_call_function_single(cpu, __rdmsr_safe_regs_on_cpu, &rv, 1);
|
|
||||||
|
|
||||||
return err ? err : rv.err;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(rdmsr_safe_regs_on_cpu);
|
|
||||||
|
|
||||||
int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
struct msr_regs_info rv;
|
|
||||||
|
|
||||||
rv.regs = regs;
|
|
||||||
rv.err = -EIO;
|
|
||||||
err = smp_call_function_single(cpu, __wrmsr_safe_regs_on_cpu, &rv, 1);
|
|
||||||
|
|
||||||
return err ? err : rv.err;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(wrmsr_safe_regs_on_cpu);
|
|
||||||
|
|
|
@ -267,6 +267,8 @@ int __init get_memcfg_from_srat(void)
|
||||||
e820_register_active_regions(chunk->nid, chunk->start_pfn,
|
e820_register_active_regions(chunk->nid, chunk->start_pfn,
|
||||||
min(chunk->end_pfn, max_pfn));
|
min(chunk->end_pfn, max_pfn));
|
||||||
}
|
}
|
||||||
|
/* for out of order entries in SRAT */
|
||||||
|
sort_node_map();
|
||||||
|
|
||||||
for_each_online_node(nid) {
|
for_each_online_node(nid) {
|
||||||
unsigned long start = node_start_pfn[nid];
|
unsigned long start = node_start_pfn[nid];
|
||||||
|
|
|
@ -317,7 +317,7 @@ static int __init nodes_cover_memory(const struct bootnode *nodes)
|
||||||
unsigned long s = nodes[i].start >> PAGE_SHIFT;
|
unsigned long s = nodes[i].start >> PAGE_SHIFT;
|
||||||
unsigned long e = nodes[i].end >> PAGE_SHIFT;
|
unsigned long e = nodes[i].end >> PAGE_SHIFT;
|
||||||
pxmram += e - s;
|
pxmram += e - s;
|
||||||
pxmram -= absent_pages_in_range(s, e);
|
pxmram -= __absent_pages_in_range(i, s, e);
|
||||||
if ((long)pxmram < 0)
|
if ((long)pxmram < 0)
|
||||||
pxmram = 0;
|
pxmram = 0;
|
||||||
}
|
}
|
||||||
|
@ -373,6 +373,8 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
|
||||||
for_each_node_mask(i, nodes_parsed)
|
for_each_node_mask(i, nodes_parsed)
|
||||||
e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT,
|
e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT,
|
||||||
nodes[i].end >> PAGE_SHIFT);
|
nodes[i].end >> PAGE_SHIFT);
|
||||||
|
/* for out of order entries in SRAT */
|
||||||
|
sort_node_map();
|
||||||
if (!nodes_cover_memory(nodes)) {
|
if (!nodes_cover_memory(nodes)) {
|
||||||
bad_srat();
|
bad_srat();
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -9,7 +9,7 @@ BEGIN {
|
||||||
}
|
}
|
||||||
|
|
||||||
/^GNU/ {
|
/^GNU/ {
|
||||||
split($4, ver, ".");
|
split($3, ver, ".");
|
||||||
if (ver[1] > od_ver ||
|
if (ver[1] > od_ver ||
|
||||||
(ver[1] == od_ver && ver[2] >= od_sver)) {
|
(ver[1] == od_ver && ver[2] >= od_sver)) {
|
||||||
exit 1;
|
exit 1;
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
|
|
||||||
# Awk implementation sanity check
|
# Awk implementation sanity check
|
||||||
function check_awk_implement() {
|
function check_awk_implement() {
|
||||||
if (!match("abc", "[[:lower:]]+"))
|
|
||||||
return "Your awk doesn't support charactor-class."
|
|
||||||
if (sprintf("%x", 0) != "0")
|
if (sprintf("%x", 0) != "0")
|
||||||
return "Your awk has a printf-format problem."
|
return "Your awk has a printf-format problem."
|
||||||
return ""
|
return ""
|
||||||
|
@ -44,12 +42,12 @@ BEGIN {
|
||||||
delete gtable
|
delete gtable
|
||||||
delete atable
|
delete atable
|
||||||
|
|
||||||
opnd_expr = "^[[:alpha:]/]"
|
opnd_expr = "^[A-Za-z/]"
|
||||||
ext_expr = "^\\("
|
ext_expr = "^\\("
|
||||||
sep_expr = "^\\|$"
|
sep_expr = "^\\|$"
|
||||||
group_expr = "^Grp[[:alnum:]]+"
|
group_expr = "^Grp[0-9A-Za-z]+"
|
||||||
|
|
||||||
imm_expr = "^[IJAO][[:lower:]]"
|
imm_expr = "^[IJAO][a-z]"
|
||||||
imm_flag["Ib"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
|
imm_flag["Ib"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
|
||||||
imm_flag["Jb"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
|
imm_flag["Jb"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
|
||||||
imm_flag["Iw"] = "INAT_MAKE_IMM(INAT_IMM_WORD)"
|
imm_flag["Iw"] = "INAT_MAKE_IMM(INAT_IMM_WORD)"
|
||||||
|
@ -62,7 +60,7 @@ BEGIN {
|
||||||
imm_flag["Ob"] = "INAT_MOFFSET"
|
imm_flag["Ob"] = "INAT_MOFFSET"
|
||||||
imm_flag["Ov"] = "INAT_MOFFSET"
|
imm_flag["Ov"] = "INAT_MOFFSET"
|
||||||
|
|
||||||
modrm_expr = "^([CDEGMNPQRSUVW/][[:lower:]]+|NTA|T[012])"
|
modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])"
|
||||||
force64_expr = "\\([df]64\\)"
|
force64_expr = "\\([df]64\\)"
|
||||||
rex_expr = "^REX(\\.[XRWB]+)*"
|
rex_expr = "^REX(\\.[XRWB]+)*"
|
||||||
fpu_expr = "^ESC" # TODO
|
fpu_expr = "^ESC" # TODO
|
||||||
|
|
|
@ -25,7 +25,7 @@ static void *malloc(int size)
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
error("Malloc error");
|
return NULL;
|
||||||
if (!malloc_ptr)
|
if (!malloc_ptr)
|
||||||
malloc_ptr = free_mem_ptr;
|
malloc_ptr = free_mem_ptr;
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ static void *malloc(int size)
|
||||||
malloc_ptr += size;
|
malloc_ptr += size;
|
||||||
|
|
||||||
if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr)
|
if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr)
|
||||||
error("Out of memory");
|
return NULL;
|
||||||
|
|
||||||
malloc_count++;
|
malloc_count++;
|
||||||
return p;
|
return p;
|
||||||
|
|
|
@ -1037,6 +1037,9 @@ extern void add_active_range(unsigned int nid, unsigned long start_pfn,
|
||||||
extern void remove_active_range(unsigned int nid, unsigned long start_pfn,
|
extern void remove_active_range(unsigned int nid, unsigned long start_pfn,
|
||||||
unsigned long end_pfn);
|
unsigned long end_pfn);
|
||||||
extern void remove_all_active_ranges(void);
|
extern void remove_all_active_ranges(void);
|
||||||
|
void sort_node_map(void);
|
||||||
|
unsigned long __absent_pages_in_range(int nid, unsigned long start_pfn,
|
||||||
|
unsigned long end_pfn);
|
||||||
extern unsigned long absent_pages_in_range(unsigned long start_pfn,
|
extern unsigned long absent_pages_in_range(unsigned long start_pfn,
|
||||||
unsigned long end_pfn);
|
unsigned long end_pfn);
|
||||||
extern void get_pfn_range_for_nid(unsigned int nid,
|
extern void get_pfn_range_for_nid(unsigned int nid,
|
||||||
|
|
|
@ -413,7 +413,7 @@ static unsigned my_inptr; /* index of next byte to be processed in inbuf */
|
||||||
|
|
||||||
static char * __init unpack_to_rootfs(char *buf, unsigned len)
|
static char * __init unpack_to_rootfs(char *buf, unsigned len)
|
||||||
{
|
{
|
||||||
int written;
|
int written, res;
|
||||||
decompress_fn decompress;
|
decompress_fn decompress;
|
||||||
const char *compress_name;
|
const char *compress_name;
|
||||||
static __initdata char msg_buf[64];
|
static __initdata char msg_buf[64];
|
||||||
|
@ -445,10 +445,12 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len)
|
||||||
}
|
}
|
||||||
this_header = 0;
|
this_header = 0;
|
||||||
decompress = decompress_method(buf, len, &compress_name);
|
decompress = decompress_method(buf, len, &compress_name);
|
||||||
if (decompress)
|
if (decompress) {
|
||||||
decompress(buf, len, NULL, flush_buffer, NULL,
|
res = decompress(buf, len, NULL, flush_buffer, NULL,
|
||||||
&my_inptr, error);
|
&my_inptr, error);
|
||||||
else if (compress_name) {
|
if (res)
|
||||||
|
error("decompressor failed");
|
||||||
|
} else if (compress_name) {
|
||||||
if (!message) {
|
if (!message) {
|
||||||
snprintf(msg_buf, sizeof msg_buf,
|
snprintf(msg_buf, sizeof msg_buf,
|
||||||
"compression method %s not configured",
|
"compression method %s not configured",
|
||||||
|
|
|
@ -637,6 +637,8 @@ static int INIT start_bunzip(struct bunzip_data **bdp, void *inbuf, int len,
|
||||||
|
|
||||||
/* Allocate bunzip_data. Most fields initialize to zero. */
|
/* Allocate bunzip_data. Most fields initialize to zero. */
|
||||||
bd = *bdp = malloc(i);
|
bd = *bdp = malloc(i);
|
||||||
|
if (!bd)
|
||||||
|
return RETVAL_OUT_OF_MEMORY;
|
||||||
memset(bd, 0, sizeof(struct bunzip_data));
|
memset(bd, 0, sizeof(struct bunzip_data));
|
||||||
/* Setup input buffer */
|
/* Setup input buffer */
|
||||||
bd->inbuf = inbuf;
|
bd->inbuf = inbuf;
|
||||||
|
@ -664,6 +666,8 @@ static int INIT start_bunzip(struct bunzip_data **bdp, void *inbuf, int len,
|
||||||
bd->dbufSize = 100000*(i-BZh0);
|
bd->dbufSize = 100000*(i-BZh0);
|
||||||
|
|
||||||
bd->dbuf = large_malloc(bd->dbufSize * sizeof(int));
|
bd->dbuf = large_malloc(bd->dbufSize * sizeof(int));
|
||||||
|
if (!bd->dbuf)
|
||||||
|
return RETVAL_OUT_OF_MEMORY;
|
||||||
return RETVAL_OK;
|
return RETVAL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -686,7 +690,7 @@ STATIC int INIT bunzip2(unsigned char *buf, int len,
|
||||||
|
|
||||||
if (!outbuf) {
|
if (!outbuf) {
|
||||||
error("Could not allocate output bufer");
|
error("Could not allocate output bufer");
|
||||||
return -1;
|
return RETVAL_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
if (buf)
|
if (buf)
|
||||||
inbuf = buf;
|
inbuf = buf;
|
||||||
|
@ -694,6 +698,7 @@ STATIC int INIT bunzip2(unsigned char *buf, int len,
|
||||||
inbuf = malloc(BZIP2_IOBUF_SIZE);
|
inbuf = malloc(BZIP2_IOBUF_SIZE);
|
||||||
if (!inbuf) {
|
if (!inbuf) {
|
||||||
error("Could not allocate input bufer");
|
error("Could not allocate input bufer");
|
||||||
|
i = RETVAL_OUT_OF_MEMORY;
|
||||||
goto exit_0;
|
goto exit_0;
|
||||||
}
|
}
|
||||||
i = start_bunzip(&bd, inbuf, len, fill);
|
i = start_bunzip(&bd, inbuf, len, fill);
|
||||||
|
@ -720,11 +725,14 @@ STATIC int INIT bunzip2(unsigned char *buf, int len,
|
||||||
} else if (i == RETVAL_UNEXPECTED_OUTPUT_EOF) {
|
} else if (i == RETVAL_UNEXPECTED_OUTPUT_EOF) {
|
||||||
error("Compressed file ends unexpectedly");
|
error("Compressed file ends unexpectedly");
|
||||||
}
|
}
|
||||||
|
if (!bd)
|
||||||
|
goto exit_1;
|
||||||
if (bd->dbuf)
|
if (bd->dbuf)
|
||||||
large_free(bd->dbuf);
|
large_free(bd->dbuf);
|
||||||
if (pos)
|
if (pos)
|
||||||
*pos = bd->inbufPos;
|
*pos = bd->inbufPos;
|
||||||
free(bd);
|
free(bd);
|
||||||
|
exit_1:
|
||||||
if (!buf)
|
if (!buf)
|
||||||
free(inbuf);
|
free(inbuf);
|
||||||
exit_0:
|
exit_0:
|
||||||
|
|
|
@ -3579,7 +3579,7 @@ static unsigned long __meminit zone_spanned_pages_in_node(int nid,
|
||||||
* Return the number of holes in a range on a node. If nid is MAX_NUMNODES,
|
* Return the number of holes in a range on a node. If nid is MAX_NUMNODES,
|
||||||
* then all holes in the requested range will be accounted for.
|
* then all holes in the requested range will be accounted for.
|
||||||
*/
|
*/
|
||||||
static unsigned long __meminit __absent_pages_in_range(int nid,
|
unsigned long __meminit __absent_pages_in_range(int nid,
|
||||||
unsigned long range_start_pfn,
|
unsigned long range_start_pfn,
|
||||||
unsigned long range_end_pfn)
|
unsigned long range_end_pfn)
|
||||||
{
|
{
|
||||||
|
@ -4108,7 +4108,7 @@ static int __init cmp_node_active_region(const void *a, const void *b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sort the node_map by start_pfn */
|
/* sort the node_map by start_pfn */
|
||||||
static void __init sort_node_map(void)
|
void __init sort_node_map(void)
|
||||||
{
|
{
|
||||||
sort(early_node_map, (size_t)nr_nodemap_entries,
|
sort(early_node_map, (size_t)nr_nodemap_entries,
|
||||||
sizeof(struct node_active_region),
|
sizeof(struct node_active_region),
|
||||||
|
|
Loading…
Reference in a new issue