diff --git a/[refs] b/[refs] index 2f355e258017..f18e1370aa67 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c4dc59ae7af8c1c116d2cb4dffba337f032a6bee +refs/heads/master: 78cbac65fd77242f3e5d77f4d7a71e8bc869fe4d diff --git a/trunk/arch/x86/ia32/ia32_signal.c b/trunk/arch/x86/ia32/ia32_signal.c index 20af4c79579a..cb3856a18c85 100644 --- a/trunk/arch/x86/ia32/ia32_signal.c +++ b/trunk/arch/x86/ia32/ia32_signal.c @@ -36,11 +36,6 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -#define FIX_EFLAGS (X86_EFLAGS_AC | X86_EFLAGS_OF | \ - X86_EFLAGS_DF | X86_EFLAGS_TF | X86_EFLAGS_SF | \ - X86_EFLAGS_ZF | X86_EFLAGS_AF | X86_EFLAGS_PF | \ - X86_EFLAGS_CF) - asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); void signal_fault(struct pt_regs *regs, void __user *frame, char *where); @@ -253,7 +248,7 @@ static int ia32_restore_sigcontext(struct pt_regs *regs, regs->ss |= 3; err |= __get_user(tmpflags, &sc->flags); - regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS); + regs->flags = (regs->flags & ~0x40DD5) | (tmpflags & 0x40DD5); /* disable syscall checks */ regs->orig_ax = -1; @@ -520,6 +515,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, compat_sigset_t *set, struct pt_regs *regs) { struct rt_sigframe __user *frame; + struct exec_domain *ed = current_thread_info()->exec_domain; void __user *restorer; int err = 0; @@ -542,7 +538,8 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) goto give_sigsegv; - err |= __put_user(sig, &frame->sig); + err |= __put_user((ed && ed->signal_invmap && sig < 32 + ? ed->signal_invmap[sig] : sig), &frame->sig); err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo); err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc); err |= copy_siginfo_to_user32(&frame->info, info); diff --git a/trunk/arch/x86/kernel/cpu/amd.c b/trunk/arch/x86/kernel/cpu/amd.c index cae9cabc3031..81a07ca65d44 100644 --- a/trunk/arch/x86/kernel/cpu/amd.c +++ b/trunk/arch/x86/kernel/cpu/amd.c @@ -24,6 +24,8 @@ extern void vide(void); __asm__(".align 4\nvide: ret"); +int force_mwait __cpuinitdata; + static void __cpuinit early_init_amd(struct cpuinfo_x86 *c) { if (cpuid_eax(0x80000000) >= 0x80000007) { diff --git a/trunk/arch/x86/kernel/cpu/common_64.c b/trunk/arch/x86/kernel/cpu/common_64.c index 2a4475beea4a..7b8cc72feb40 100644 --- a/trunk/arch/x86/kernel/cpu/common_64.c +++ b/trunk/arch/x86/kernel/cpu/common_64.c @@ -7,9 +7,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/trunk/arch/x86/kernel/e820.c b/trunk/arch/x86/kernel/e820.c index 9af89078f7bb..28c29180b380 100644 --- a/trunk/arch/x86/kernel/e820.c +++ b/trunk/arch/x86/kernel/e820.c @@ -877,8 +877,7 @@ void __init early_res_to_bootmem(u64 start, u64 end) for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) count++; - printk(KERN_INFO "(%d early reservations) ==> bootmem [%010llx - %010llx]\n", - count, start, end); + printk(KERN_INFO "(%d early reservations) ==> bootmem\n", count); for (i = 0; i < count; i++) { struct early_res *r = &early_res[i]; printk(KERN_INFO " #%d [%010llx - %010llx] %16s", i, @@ -1299,6 +1298,11 @@ void __init e820_reserve_resources(void) } } +/* + * Non-standard memory setup can be specified via this quirk: + */ +char * (*arch_memory_setup_quirk)(void); + char *__init default_machine_specific_memory_setup(void) { char *who = "BIOS-e820"; @@ -1339,8 +1343,8 @@ char *__init default_machine_specific_memory_setup(void) char *__init __attribute__((weak)) machine_specific_memory_setup(void) { - if (x86_quirks->arch_memory_setup) { - char *who = x86_quirks->arch_memory_setup(); + if (arch_memory_setup_quirk) { + char *who = arch_memory_setup_quirk(); if (who) return who; @@ -1363,3 +1367,24 @@ void __init setup_memory_map(void) printk(KERN_INFO "BIOS-provided physical RAM map:\n"); e820_print_map(who); } + +#ifdef CONFIG_X86_64 +int __init arch_get_ram_range(int slot, u64 *addr, u64 *size) +{ + int i; + + if (slot < 0 || slot >= e820.nr_map) + return -1; + for (i = slot; i < e820.nr_map; i++) { + if (e820.map[i].type != E820_RAM) + continue; + break; + } + if (i == e820.nr_map || e820.map[i].addr > (max_pfn << PAGE_SHIFT)) + return -1; + *addr = e820.map[i].addr; + *size = min_t(u64, e820.map[i].size + e820.map[i].addr, + max_pfn << PAGE_SHIFT) - *addr; + return i + 1; +} +#endif diff --git a/trunk/arch/x86/kernel/io_delay.c b/trunk/arch/x86/kernel/io_delay.c index 1c3a66a67f83..5921e5f0a640 100644 --- a/trunk/arch/x86/kernel/io_delay.c +++ b/trunk/arch/x86/kernel/io_delay.c @@ -103,9 +103,6 @@ void __init io_delay_init(void) static int __init io_delay_param(char *s) { - if (!s) - return -EINVAL; - if (!strcmp(s, "0x80")) io_delay_type = CONFIG_IO_DELAY_TYPE_0X80; else if (!strcmp(s, "0xed")) diff --git a/trunk/arch/x86/kernel/mpparse.c b/trunk/arch/x86/kernel/mpparse.c index 6ae005ccaed8..3b25e49380c6 100644 --- a/trunk/arch/x86/kernel/mpparse.c +++ b/trunk/arch/x86/kernel/mpparse.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #ifdef CONFIG_X86_32 @@ -49,6 +48,76 @@ static int __init mpf_checksum(unsigned char *mp, int len) return sum & 0xFF; } +#ifdef CONFIG_X86_NUMAQ +int found_numaq; +/* + * Have to match translation table entries to main table entries by counter + * hence the mpc_record variable .... can't see a less disgusting way of + * doing this .... + */ +struct mpc_config_translation { + unsigned char mpc_type; + unsigned char trans_len; + unsigned char trans_type; + unsigned char trans_quad; + unsigned char trans_global; + unsigned char trans_local; + unsigned short trans_reserved; +}; + + +static int mpc_record; +static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] + __cpuinitdata; + +static inline int generate_logical_apicid(int quad, int phys_apicid) +{ + return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1); +} + + +static inline int mpc_apic_id(struct mpc_config_processor *m, + struct mpc_config_translation *translation_record) +{ + int quad = translation_record->trans_quad; + int logical_apicid = generate_logical_apicid(quad, m->mpc_apicid); + + printk(KERN_DEBUG "Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n", + m->mpc_apicid, + (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, + (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, + m->mpc_apicver, quad, logical_apicid); + return logical_apicid; +} + +int mp_bus_id_to_node[MAX_MP_BUSSES]; + +int mp_bus_id_to_local[MAX_MP_BUSSES]; + +static void mpc_oem_bus_info(struct mpc_config_bus *m, char *name, + struct mpc_config_translation *translation) +{ + int quad = translation->trans_quad; + int local = translation->trans_local; + + mp_bus_id_to_node[m->mpc_busid] = quad; + mp_bus_id_to_local[m->mpc_busid] = local; + printk(KERN_INFO "Bus #%d is %s (node %d)\n", + m->mpc_busid, name, quad); +} + +int quad_local_to_mp_bus_id [NR_CPUS/4][4]; +static void mpc_oem_pci_bus(struct mpc_config_bus *m, + struct mpc_config_translation *translation) +{ + int quad = translation->trans_quad; + int local = translation->trans_local; + + quad_local_to_mp_bus_id[quad][local] = m->mpc_busid; +} + +#endif + static void __cpuinit MP_processor_info(struct mpc_config_processor *m) { int apicid; @@ -58,12 +127,14 @@ static void __cpuinit MP_processor_info(struct mpc_config_processor *m) disabled_cpus++; return; } - - if (x86_quirks->mpc_apic_id) - apicid = x86_quirks->mpc_apic_id(m); +#ifdef CONFIG_X86_NUMAQ + if (found_numaq) + apicid = mpc_apic_id(m, translation_table[mpc_record]); else apicid = m->mpc_apicid; - +#else + apicid = m->mpc_apicid; +#endif if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { bootup_cpu = " (Bootup-CPU)"; boot_cpu_physical_apicid = m->mpc_apicid; @@ -80,10 +151,12 @@ static void __init MP_bus_info(struct mpc_config_bus *m) memcpy(str, m->mpc_bustype, 6); str[6] = 0; - if (x86_quirks->mpc_oem_bus_info) - x86_quirks->mpc_oem_bus_info(m, str); - else - printk(KERN_INFO "Bus #%d is %s\n", m->mpc_busid, str); +#ifdef CONFIG_X86_NUMAQ + if (found_numaq) + mpc_oem_bus_info(m, str, translation_table[mpc_record]); +#else + printk(KERN_INFO "Bus #%d is %s\n", m->mpc_busid, str); +#endif #if MAX_MP_BUSSES < 256 if (m->mpc_busid >= MAX_MP_BUSSES) { @@ -100,9 +173,10 @@ static void __init MP_bus_info(struct mpc_config_bus *m) mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; #endif } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI) - 1) == 0) { - if (x86_quirks->mpc_oem_pci_bus) - x86_quirks->mpc_oem_pci_bus(m); - +#ifdef CONFIG_X86_NUMAQ + if (found_numaq) + mpc_oem_pci_bus(m, translation_table[mpc_record]); +#endif clear_bit(m->mpc_busid, mp_bus_not_pci); #if defined(CONFIG_EISA) || defined (CONFIG_MCA) mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI; @@ -242,6 +316,83 @@ static void __init MP_lintsrc_info(struct mpc_config_lintsrc *m) m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint); } +#ifdef CONFIG_X86_NUMAQ +static void __init MP_translation_info(struct mpc_config_translation *m) +{ + printk(KERN_INFO + "Translation: record %d, type %d, quad %d, global %d, local %d\n", + mpc_record, m->trans_type, m->trans_quad, m->trans_global, + m->trans_local); + + if (mpc_record >= MAX_MPC_ENTRY) + printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n"); + else + translation_table[mpc_record] = m; /* stash this for later */ + if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad)) + node_set_online(m->trans_quad); +} + +/* + * Read/parse the MPC oem tables + */ + +static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable, + unsigned short oemsize) +{ + int count = sizeof(*oemtable); /* the header size */ + unsigned char *oemptr = ((unsigned char *)oemtable) + count; + + mpc_record = 0; + printk(KERN_INFO "Found an OEM MPC table at %8p - parsing it ... \n", + oemtable); + if (memcmp(oemtable->oem_signature, MPC_OEM_SIGNATURE, 4)) { + printk(KERN_WARNING + "SMP mpc oemtable: bad signature [%c%c%c%c]!\n", + oemtable->oem_signature[0], oemtable->oem_signature[1], + oemtable->oem_signature[2], oemtable->oem_signature[3]); + return; + } + if (mpf_checksum((unsigned char *)oemtable, oemtable->oem_length)) { + printk(KERN_WARNING "SMP oem mptable: checksum error!\n"); + return; + } + while (count < oemtable->oem_length) { + switch (*oemptr) { + case MP_TRANSLATION: + { + struct mpc_config_translation *m = + (struct mpc_config_translation *)oemptr; + MP_translation_info(m); + oemptr += sizeof(*m); + count += sizeof(*m); + ++mpc_record; + break; + } + default: + { + printk(KERN_WARNING + "Unrecognised OEM table entry type! - %d\n", + (int)*oemptr); + return; + } + } + } +} + +void numaq_mps_oem_check(struct mp_config_table *mpc, char *oem, + char *productid) +{ + if (strncmp(oem, "IBM NUMA", 8)) + printk("Warning! Not a NUMA-Q system!\n"); + else + found_numaq = 1; + + if (mpc->mpc_oemptr) + smp_read_mpc_oem((struct mp_config_oemtable *)mpc->mpc_oemptr, + mpc->mpc_oemsize); +} +#endif /* CONFIG_X86_NUMAQ */ + /* * Read/parse the MPC */ @@ -306,6 +457,7 @@ static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early) } else mps_oem_check(mpc, oem, str); #endif + /* save the local APIC address, it might be non-default */ if (!acpi_lapic) mp_lapic_addr = mpc->mpc_lapic; @@ -313,17 +465,12 @@ static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early) if (early) return 1; - if (mpc->mpc_oemptr && x86_quirks->smp_read_mpc_oem) { - struct mp_config_oemtable *oem_table = (struct mp_config_oemtable *)(unsigned long)mpc->mpc_oemptr; - x86_quirks->smp_read_mpc_oem(oem_table, mpc->mpc_oemsize); - } - /* * Now process the configuration blocks. */ - if (x86_quirks->mpc_record) - *x86_quirks->mpc_record = 0; - +#ifdef CONFIG_X86_NUMAQ + mpc_record = 0; +#endif while (count < mpc->mpc_length) { switch (*mpt) { case MP_PROCESSOR: @@ -389,8 +536,9 @@ static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early) count = mpc->mpc_length; break; } - if (x86_quirks->mpc_record) - (*x86_quirks->mpc_record)++; +#ifdef CONFIG_X86_NUMAQ + ++mpc_record; +#endif } #ifdef CONFIG_X86_GENERICARCH @@ -577,6 +725,12 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type) static struct intel_mp_floating *mpf_found; +/* + * Machine specific quirk for finding the SMP config before other setup + * activities destroy the table: + */ +int (*mach_get_smp_config_quirk)(unsigned int early); + /* * Scan the memory blocks for an SMP configuration block. */ @@ -584,8 +738,8 @@ static void __init __get_smp_config(unsigned int early) { struct intel_mp_floating *mpf = mpf_found; - if (x86_quirks->mach_get_smp_config) { - if (x86_quirks->mach_get_smp_config(early)) + if (mach_get_smp_config_quirk) { + if (mach_get_smp_config_quirk(early)) return; } if (acpi_lapic && early) @@ -745,12 +899,14 @@ static int __init smp_scan_config(unsigned long base, unsigned long length, return 0; } +int (*mach_find_smp_config_quirk)(unsigned int reserve); + static void __init __find_smp_config(unsigned int reserve) { unsigned int address; - if (x86_quirks->mach_find_smp_config) { - if (x86_quirks->mach_find_smp_config(reserve)) + if (mach_find_smp_config_quirk) { + if (mach_find_smp_config_quirk(reserve)) return; } /* diff --git a/trunk/arch/x86/kernel/numaq_32.c b/trunk/arch/x86/kernel/numaq_32.c index b8c45610b20a..a23e8233b9ac 100644 --- a/trunk/arch/x86/kernel/numaq_32.c +++ b/trunk/arch/x86/kernel/numaq_32.c @@ -33,7 +33,6 @@ #include #include #include -#include #define MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT)) @@ -72,188 +71,6 @@ static void __init smp_dump_qct(void) } } - -void __init numaq_tsc_disable(void) -{ - if (!found_numaq) - return; - - if (num_online_nodes() > 1) { - printk(KERN_DEBUG "NUMAQ: disabling TSC\n"); - setup_clear_cpu_cap(X86_FEATURE_TSC); - } -} - -static int __init numaq_pre_time_init(void) -{ - numaq_tsc_disable(); - return 0; -} - -int found_numaq; -/* - * Have to match translation table entries to main table entries by counter - * hence the mpc_record variable .... can't see a less disgusting way of - * doing this .... - */ -struct mpc_config_translation { - unsigned char mpc_type; - unsigned char trans_len; - unsigned char trans_type; - unsigned char trans_quad; - unsigned char trans_global; - unsigned char trans_local; - unsigned short trans_reserved; -}; - -/* x86_quirks member */ -static int mpc_record; -static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] - __cpuinitdata; - -static inline int generate_logical_apicid(int quad, int phys_apicid) -{ - return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1); -} - -/* x86_quirks member */ -static int mpc_apic_id(struct mpc_config_processor *m) -{ - int quad = translation_table[mpc_record]->trans_quad; - int logical_apicid = generate_logical_apicid(quad, m->mpc_apicid); - - printk(KERN_DEBUG "Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n", - m->mpc_apicid, - (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, - (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, - m->mpc_apicver, quad, logical_apicid); - return logical_apicid; -} - -int mp_bus_id_to_node[MAX_MP_BUSSES]; - -int mp_bus_id_to_local[MAX_MP_BUSSES]; - -/* x86_quirks member */ -static void mpc_oem_bus_info(struct mpc_config_bus *m, char *name) -{ - int quad = translation_table[mpc_record]->trans_quad; - int local = translation_table[mpc_record]->trans_local; - - mp_bus_id_to_node[m->mpc_busid] = quad; - mp_bus_id_to_local[m->mpc_busid] = local; - printk(KERN_INFO "Bus #%d is %s (node %d)\n", - m->mpc_busid, name, quad); -} - -int quad_local_to_mp_bus_id [NR_CPUS/4][4]; - -/* x86_quirks member */ -static void mpc_oem_pci_bus(struct mpc_config_bus *m) -{ - int quad = translation_table[mpc_record]->trans_quad; - int local = translation_table[mpc_record]->trans_local; - - quad_local_to_mp_bus_id[quad][local] = m->mpc_busid; -} - -static void __init MP_translation_info(struct mpc_config_translation *m) -{ - printk(KERN_INFO - "Translation: record %d, type %d, quad %d, global %d, local %d\n", - mpc_record, m->trans_type, m->trans_quad, m->trans_global, - m->trans_local); - - if (mpc_record >= MAX_MPC_ENTRY) - printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n"); - else - translation_table[mpc_record] = m; /* stash this for later */ - if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad)) - node_set_online(m->trans_quad); -} - -static int __init mpf_checksum(unsigned char *mp, int len) -{ - int sum = 0; - - while (len--) - sum += *mp++; - - return sum & 0xFF; -} - -/* - * Read/parse the MPC oem tables - */ - -static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable, - unsigned short oemsize) -{ - int count = sizeof(*oemtable); /* the header size */ - unsigned char *oemptr = ((unsigned char *)oemtable) + count; - - mpc_record = 0; - printk(KERN_INFO "Found an OEM MPC table at %8p - parsing it ... \n", - oemtable); - if (memcmp(oemtable->oem_signature, MPC_OEM_SIGNATURE, 4)) { - printk(KERN_WARNING - "SMP mpc oemtable: bad signature [%c%c%c%c]!\n", - oemtable->oem_signature[0], oemtable->oem_signature[1], - oemtable->oem_signature[2], oemtable->oem_signature[3]); - return; - } - if (mpf_checksum((unsigned char *)oemtable, oemtable->oem_length)) { - printk(KERN_WARNING "SMP oem mptable: checksum error!\n"); - return; - } - while (count < oemtable->oem_length) { - switch (*oemptr) { - case MP_TRANSLATION: - { - struct mpc_config_translation *m = - (struct mpc_config_translation *)oemptr; - MP_translation_info(m); - oemptr += sizeof(*m); - count += sizeof(*m); - ++mpc_record; - break; - } - default: - { - printk(KERN_WARNING - "Unrecognised OEM table entry type! - %d\n", - (int)*oemptr); - return; - } - } - } -} - -static struct x86_quirks numaq_x86_quirks __initdata = { - .arch_pre_time_init = numaq_pre_time_init, - .arch_time_init = NULL, - .arch_pre_intr_init = NULL, - .arch_memory_setup = NULL, - .arch_intr_init = NULL, - .arch_trap_init = NULL, - .mach_get_smp_config = NULL, - .mach_find_smp_config = NULL, - .mpc_record = &mpc_record, - .mpc_apic_id = mpc_apic_id, - .mpc_oem_bus_info = mpc_oem_bus_info, - .mpc_oem_pci_bus = mpc_oem_pci_bus, - .smp_read_mpc_oem = smp_read_mpc_oem, -}; - -void numaq_mps_oem_check(struct mp_config_table *mpc, char *oem, - char *productid) -{ - if (strncmp(oem, "IBM NUMA", 8)) - printk("Warning! Not a NUMA-Q system!\n"); - else - found_numaq = 1; -} - static __init void early_check_numaq(void) { /* @@ -265,9 +82,6 @@ static __init void early_check_numaq(void) */ if (smp_found_config) early_get_smp_config(); - - if (found_numaq) - x86_quirks = &numaq_x86_quirks; } int __init get_memcfg_numaq(void) @@ -278,3 +92,14 @@ int __init get_memcfg_numaq(void) smp_dump_qct(); return 1; } + +void __init numaq_tsc_disable(void) +{ + if (!found_numaq) + return; + + if (num_online_nodes() > 1) { + printk(KERN_DEBUG "NUMAQ: disabling TSC\n"); + setup_clear_cpu_cap(X86_FEATURE_TSC); + } +} diff --git a/trunk/arch/x86/kernel/pci-dma.c b/trunk/arch/x86/kernel/pci-dma.c index 702714bd1511..8467ec2320f1 100644 --- a/trunk/arch/x86/kernel/pci-dma.c +++ b/trunk/arch/x86/kernel/pci-dma.c @@ -9,7 +9,8 @@ #include #include -static int forbid_dac __read_mostly; +int forbid_dac __read_mostly; +EXPORT_SYMBOL(forbid_dac); const struct dma_mapping_ops *dma_ops; EXPORT_SYMBOL(dma_ops); diff --git a/trunk/arch/x86/kernel/process.c b/trunk/arch/x86/kernel/process.c index 9f94bb1c8117..4d629c62f4f8 100644 --- a/trunk/arch/x86/kernel/process.c +++ b/trunk/arch/x86/kernel/process.c @@ -199,7 +199,6 @@ static void poll_idle(void) * * idle=mwait overrides this decision and forces the usage of mwait. */ -static int __cpuinitdata force_mwait; #define MWAIT_INFO 0x05 #define MWAIT_ECX_EXTENDED_INFO 0x01 @@ -327,9 +326,6 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) static int __init idle_setup(char *str) { - if (!str) - return -EINVAL; - if (!strcmp(str, "poll")) { printk("using polling idle threads.\n"); pm_idle = poll_idle; diff --git a/trunk/arch/x86/kernel/setup.c b/trunk/arch/x86/kernel/setup.c index 4064616cfa85..531b55b8e81a 100644 --- a/trunk/arch/x86/kernel/setup.c +++ b/trunk/arch/x86/kernel/setup.c @@ -57,8 +57,12 @@ #include #include #include +#include #include +#include +#include +#include #include #include #include @@ -100,6 +104,7 @@ #include #include +#include #include #include #ifdef CONFIG_X86_64 @@ -574,10 +579,6 @@ static int __init setup_elfcorehdr(char *arg) early_param("elfcorehdr", setup_elfcorehdr); #endif -static struct x86_quirks default_x86_quirks __initdata; - -struct x86_quirks *x86_quirks __initdata = &default_x86_quirks; - /* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures @@ -853,6 +854,14 @@ void __init setup_arch(char **cmdline_p) init_cpu_to_node(); #endif +#ifdef CONFIG_X86_NUMAQ + /* + * need to check online nodes num, call it + * here before time_init/tsc_init + */ + numaq_tsc_disable(); +#endif + init_apic_mappings(); ioapic_init_mappings(); diff --git a/trunk/arch/x86/kernel/signal_32.c b/trunk/arch/x86/kernel/signal_32.c index d633d801f858..d92373630963 100644 --- a/trunk/arch/x86/kernel/signal_32.c +++ b/trunk/arch/x86/kernel/signal_32.c @@ -212,7 +212,7 @@ asmlinkage unsigned long sys_sigreturn(unsigned long __unused) badframe: if (show_unhandled_signals && printk_ratelimit()) { - printk("%s%s[%d] bad frame in sigreturn frame:" + printk(KERN_INFO "%s%s[%d] bad frame in sigreturn frame:" "%p ip:%lx sp:%lx oeax:%lx", task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG, current->comm, task_pid_nr(current), frame, regs->ip, diff --git a/trunk/arch/x86/kernel/smpboot.c b/trunk/arch/x86/kernel/smpboot.c index a9ca7dadc852..687376ab07e8 100644 --- a/trunk/arch/x86/kernel/smpboot.c +++ b/trunk/arch/x86/kernel/smpboot.c @@ -1390,8 +1390,7 @@ static int __init parse_maxcpus(char *arg) { extern unsigned int maxcpus; - if (arg) - maxcpus = simple_strtoul(arg, NULL, 0); + maxcpus = simple_strtoul(arg, NULL, 0); return 0; } early_param("maxcpus", parse_maxcpus); diff --git a/trunk/arch/x86/kernel/time_32.c b/trunk/arch/x86/kernel/time_32.c index ffe3c664afc0..059ca6ee59b4 100644 --- a/trunk/arch/x86/kernel/time_32.c +++ b/trunk/arch/x86/kernel/time_32.c @@ -129,7 +129,6 @@ void __init hpet_time_init(void) */ void __init time_init(void) { - pre_time_init_hook(); tsc_init(); late_time_init = choose_time_init(); } diff --git a/trunk/arch/x86/kernel/traps_32.c b/trunk/arch/x86/kernel/traps_32.c index 8a768973c4f0..51cccde376a5 100644 --- a/trunk/arch/x86/kernel/traps_32.c +++ b/trunk/arch/x86/kernel/traps_32.c @@ -383,6 +383,54 @@ int is_valid_bugaddr(unsigned long ip) return ud2 == 0x0b0f; } +static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED; +static int die_owner = -1; +static unsigned int die_nest_count; + +unsigned __kprobes long oops_begin(void) +{ + unsigned long flags; + + oops_enter(); + + if (die_owner != raw_smp_processor_id()) { + console_verbose(); + raw_local_irq_save(flags); + __raw_spin_lock(&die_lock); + die_owner = smp_processor_id(); + die_nest_count = 0; + bust_spinlocks(1); + } else { + raw_local_irq_save(flags); + } + die_nest_count++; + return flags; +} + +void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) +{ + bust_spinlocks(0); + die_owner = -1; + add_taint(TAINT_DIE); + __raw_spin_unlock(&die_lock); + raw_local_irq_restore(flags); + + if (!regs) + return; + + if (kexec_should_crash(current)) + crash_kexec(regs); + + if (in_interrupt()) + panic("Fatal exception in interrupt"); + + if (panic_on_oops) + panic("Fatal exception"); + + oops_exit(); + do_exit(signr); +} + int __kprobes __die(const char *str, struct pt_regs *regs, long err) { unsigned short ss; @@ -423,31 +471,9 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err) */ void die(const char *str, struct pt_regs *regs, long err) { - static struct { - raw_spinlock_t lock; - u32 lock_owner; - int lock_owner_depth; - } die = { - .lock = __RAW_SPIN_LOCK_UNLOCKED, - .lock_owner = -1, - .lock_owner_depth = 0 - }; - unsigned long flags; - - oops_enter(); - - if (die.lock_owner != raw_smp_processor_id()) { - console_verbose(); - raw_local_irq_save(flags); - __raw_spin_lock(&die.lock); - die.lock_owner = smp_processor_id(); - die.lock_owner_depth = 0; - bust_spinlocks(1); - } else { - raw_local_irq_save(flags); - } + unsigned long flags = oops_begin(); - if (++die.lock_owner_depth < 3) { + if (die_nest_count < 3) { report_bug(regs->ip, regs); if (__die(str, regs, err)) @@ -456,26 +482,7 @@ void die(const char *str, struct pt_regs *regs, long err) printk(KERN_EMERG "Recursive die() failure, output suppressed\n"); } - bust_spinlocks(0); - die.lock_owner = -1; - add_taint(TAINT_DIE); - __raw_spin_unlock(&die.lock); - raw_local_irq_restore(flags); - - if (!regs) - return; - - if (kexec_should_crash(current)) - crash_kexec(regs); - - if (in_interrupt()) - panic("Fatal exception in interrupt"); - - if (panic_on_oops) - panic("Fatal exception"); - - oops_exit(); - do_exit(SIGSEGV); + oops_end(flags, regs, SIGSEGV); } static inline void diff --git a/trunk/arch/x86/kernel/traps_64.c b/trunk/arch/x86/kernel/traps_64.c index 2696a6837782..babdbe673b7f 100644 --- a/trunk/arch/x86/kernel/traps_64.c +++ b/trunk/arch/x86/kernel/traps_64.c @@ -518,7 +518,7 @@ unsigned __kprobes long oops_begin(void) } void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) -{ +{ die_owner = -1; bust_spinlocks(0); die_nest_count--; diff --git a/trunk/arch/x86/kernel/visws_quirks.c b/trunk/arch/x86/kernel/visws_quirks.c index 41e01b145c48..e94bdb6add1d 100644 --- a/trunk/arch/x86/kernel/visws_quirks.c +++ b/trunk/arch/x86/kernel/visws_quirks.c @@ -73,7 +73,7 @@ int is_visws_box(void) return visws_board_type >= 0; } -static int __init visws_time_init(void) +static int __init visws_time_init_quirk(void) { printk(KERN_INFO "Starting Cobalt Timer system clock\n"); @@ -93,7 +93,7 @@ static int __init visws_time_init(void) return 0; } -static int __init visws_pre_intr_init(void) +static int __init visws_pre_intr_init_quirk(void) { init_VISWS_APIC_irqs(); @@ -114,7 +114,7 @@ EXPORT_SYMBOL(sgivwfb_mem_size); long long mem_size __initdata = 0; -static char * __init visws_memory_setup(void) +static char * __init visws_memory_setup_quirk(void) { long long gfx_mem_size = 8 * MB; @@ -176,7 +176,7 @@ static void visws_machine_power_off(void) outl(PIIX_SPECIAL_STOP, 0xCFC); } -static int __init visws_get_smp_config(unsigned int early) +static int __init visws_get_smp_config_quirk(unsigned int early) { /* * Prevent MP-table parsing by the generic code: @@ -192,7 +192,7 @@ extern unsigned int __cpuinitdata maxcpus; * No problem for Linux. */ -static void __init MP_processor_info(struct mpc_config_processor *m) +static void __init MP_processor_info (struct mpc_config_processor *m) { int ver, logical_apicid; physid_mask_t apic_cpus; @@ -232,7 +232,7 @@ static void __init MP_processor_info(struct mpc_config_processor *m) apic_version[m->mpc_apicid] = ver; } -static int __init visws_find_smp_config(unsigned int reserve) +int __init visws_find_smp_config_quirk(unsigned int reserve) { struct mpc_config_processor *mp = phys_to_virt(CO_CPU_TAB_PHYS); unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS)); @@ -258,17 +258,7 @@ static int __init visws_find_smp_config(unsigned int reserve) return 1; } -static int visws_trap_init(void); - -static struct x86_quirks visws_x86_quirks __initdata = { - .arch_time_init = visws_time_init, - .arch_pre_intr_init = visws_pre_intr_init, - .arch_memory_setup = visws_memory_setup, - .arch_intr_init = NULL, - .arch_trap_init = visws_trap_init, - .mach_get_smp_config = visws_get_smp_config, - .mach_find_smp_config = visws_find_smp_config, -}; +extern int visws_trap_init_quirk(void); void __init visws_early_detect(void) { @@ -282,10 +272,16 @@ void __init visws_early_detect(void) /* * Install special quirks for timer, interrupt and memory setup: + */ + arch_time_init_quirk = visws_time_init_quirk; + arch_pre_intr_init_quirk = visws_pre_intr_init_quirk; + arch_memory_setup_quirk = visws_memory_setup_quirk; + + /* * Fall back to generic behavior for traps: - * Override generic MP-table parsing: */ - x86_quirks = &visws_x86_quirks; + arch_intr_init_quirk = NULL; + arch_trap_init_quirk = visws_trap_init_quirk; /* * Install reboot quirks: @@ -298,6 +294,12 @@ void __init visws_early_detect(void) */ no_broadcast = 0; + /* + * Override generic MP-table parsing: + */ + mach_get_smp_config_quirk = visws_get_smp_config_quirk; + mach_find_smp_config_quirk = visws_find_smp_config_quirk; + #ifdef CONFIG_X86_IO_APIC /* * Turn off IO-APIC detection and initialization: @@ -424,7 +426,7 @@ static __init void cobalt_init(void) co_apic_read(CO_APIC_ID)); } -static int __init visws_trap_init(void) +int __init visws_trap_init_quirk(void) { lithium_init(); cobalt_init(); diff --git a/trunk/arch/x86/mach-default/setup.c b/trunk/arch/x86/mach-default/setup.c index 3d317836be9e..48278fa7d3de 100644 --- a/trunk/arch/x86/mach-default/setup.c +++ b/trunk/arch/x86/mach-default/setup.c @@ -10,6 +10,14 @@ #include #include +/* + * Any quirks to be performed to initialize timers/irqs/etc? + */ +int (*arch_time_init_quirk)(void); +int (*arch_pre_intr_init_quirk)(void); +int (*arch_intr_init_quirk)(void); +int (*arch_trap_init_quirk)(void); + #ifdef CONFIG_HOTPLUG_CPU #define DEFAULT_SEND_IPI (1) #else @@ -29,8 +37,8 @@ int no_broadcast=DEFAULT_SEND_IPI; **/ void __init pre_intr_init_hook(void) { - if (x86_quirks->arch_pre_intr_init) { - if (x86_quirks->arch_pre_intr_init()) + if (arch_pre_intr_init_quirk) { + if (arch_pre_intr_init_quirk()) return; } init_ISA_irqs(); @@ -56,8 +64,8 @@ static struct irqaction irq2 = { **/ void __init intr_init_hook(void) { - if (x86_quirks->arch_intr_init) { - if (x86_quirks->arch_intr_init()) + if (arch_intr_init_quirk) { + if (arch_intr_init_quirk()) return; } #ifdef CONFIG_X86_LOCAL_APIC @@ -89,8 +97,8 @@ void __init pre_setup_arch_hook(void) **/ void __init trap_init_hook(void) { - if (x86_quirks->arch_trap_init) { - if (x86_quirks->arch_trap_init()) + if (arch_trap_init_quirk) { + if (arch_trap_init_quirk()) return; } } @@ -102,16 +110,6 @@ static struct irqaction irq0 = { .name = "timer" }; -/** - * pre_time_init_hook - do any specific initialisations before. - * - **/ -void __init pre_time_init_hook(void) -{ - if (x86_quirks->arch_pre_time_init) - x86_quirks->arch_pre_time_init(); -} - /** * time_init_hook - do any specific initialisations for the system timer. * @@ -121,13 +119,13 @@ void __init pre_time_init_hook(void) **/ void __init time_init_hook(void) { - if (x86_quirks->arch_time_init) { + if (arch_time_init_quirk) { /* * A nonzero return code does not mean failure, it means * that the architecture quirk does not want any * generic (timer) setup to be performed after this: */ - if (x86_quirks->arch_time_init()) + if (arch_time_init_quirk()) return; } diff --git a/trunk/arch/x86/vdso/vma.c b/trunk/arch/x86/vdso/vma.c index 257ba4a10abf..19a6cfaf5db9 100644 --- a/trunk/arch/x86/vdso/vma.c +++ b/trunk/arch/x86/vdso/vma.c @@ -21,8 +21,7 @@ unsigned int __read_mostly vdso_enabled = 1; extern char vdso_start[], vdso_end[]; extern unsigned short vdso_sync_cpuid; -static struct page **vdso_pages; -static unsigned vdso_size; +struct page **vdso_pages; static inline void *var_ref(void *p, char *name) { @@ -39,7 +38,6 @@ static int __init init_vdso_vars(void) int i; char *vbase; - vdso_size = npages << PAGE_SHIFT; vdso_pages = kmalloc(sizeof(struct page *) * npages, GFP_KERNEL); if (!vdso_pages) goto oom; @@ -103,19 +101,20 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) struct mm_struct *mm = current->mm; unsigned long addr; int ret; + unsigned len = round_up(vdso_end - vdso_start, PAGE_SIZE); if (!vdso_enabled) return 0; down_write(&mm->mmap_sem); - addr = vdso_addr(mm->start_stack, vdso_size); - addr = get_unmapped_area(NULL, addr, vdso_size, 0, 0); + addr = vdso_addr(mm->start_stack, len); + addr = get_unmapped_area(NULL, addr, len, 0, 0); if (IS_ERR_VALUE(addr)) { ret = addr; goto up_fail; } - ret = install_special_mapping(mm, addr, vdso_size, + ret = install_special_mapping(mm, addr, len, VM_READ|VM_EXEC| VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC| VM_ALWAYSDUMP, diff --git a/trunk/include/asm-x86/arch_hooks.h b/trunk/include/asm-x86/arch_hooks.h index 8411750ceb63..768aee8a04ef 100644 --- a/trunk/include/asm-x86/arch_hooks.h +++ b/trunk/include/asm-x86/arch_hooks.h @@ -21,7 +21,6 @@ extern void intr_init_hook(void); extern void pre_intr_init_hook(void); extern void pre_setup_arch_hook(void); extern void trap_init_hook(void); -extern void pre_time_init_hook(void); extern void time_init_hook(void); extern void mca_nmi_hook(void); diff --git a/trunk/include/asm-x86/bitops.h b/trunk/include/asm-x86/bitops.h index cfb2b64f76e7..96b1829cea15 100644 --- a/trunk/include/asm-x86/bitops.h +++ b/trunk/include/asm-x86/bitops.h @@ -356,7 +356,7 @@ static inline unsigned long ffz(unsigned long word) * __fls: find last set bit in word * @word: The word to search * - * Undefined if no set bit exists, so code should check against 0 first. + * Undefined if no zero exists, so code should check against ~0UL first. */ static inline unsigned long __fls(unsigned long word) { diff --git a/trunk/include/asm-x86/dma-mapping.h b/trunk/include/asm-x86/dma-mapping.h index c2ddd3d1b883..a1a4dc7fe6ec 100644 --- a/trunk/include/asm-x86/dma-mapping.h +++ b/trunk/include/asm-x86/dma-mapping.h @@ -14,6 +14,7 @@ extern dma_addr_t bad_dma_address; extern int iommu_merge; extern struct device fallback_dev; extern int panic_on_overflow; +extern int forbid_dac; extern int force_iommu; struct dma_mapping_ops { diff --git a/trunk/include/asm-x86/mach-generic/mach_mpspec.h b/trunk/include/asm-x86/mach-generic/mach_mpspec.h index c83c120be538..9ef0b941bb22 100644 --- a/trunk/include/asm-x86/mach-generic/mach_mpspec.h +++ b/trunk/include/asm-x86/mach-generic/mach_mpspec.h @@ -7,6 +7,4 @@ /* Maximum 256 PCI busses, plus 1 ISA bus in each of 4 cabinets. */ #define MAX_MP_BUSSES 260 -extern void numaq_mps_oem_check(struct mp_config_table *mpc, char *oem, - char *productid); #endif /* __ASM_MACH_MPSPEC_H */ diff --git a/trunk/include/asm-x86/mach-visws/entry_arch.h b/trunk/include/asm-x86/mach-visws/entry_arch.h new file mode 100644 index 000000000000..86be554342d4 --- /dev/null +++ b/trunk/include/asm-x86/mach-visws/entry_arch.h @@ -0,0 +1,5 @@ +/* + * VISWS uses the standard Linux entry points: + */ + +#include "../mach-default/entry_arch.h" diff --git a/trunk/include/asm-x86/mach-visws/mach_apic.h b/trunk/include/asm-x86/mach-visws/mach_apic.h new file mode 100644 index 000000000000..6943e7a1d0e6 --- /dev/null +++ b/trunk/include/asm-x86/mach-visws/mach_apic.h @@ -0,0 +1 @@ +#include "../mach-default/mach_apic.h" diff --git a/trunk/include/asm-x86/mach-visws/mach_apicdef.h b/trunk/include/asm-x86/mach-visws/mach_apicdef.h new file mode 100644 index 000000000000..42711d152a93 --- /dev/null +++ b/trunk/include/asm-x86/mach-visws/mach_apicdef.h @@ -0,0 +1 @@ +#include "../mach-default/mach_apicdef.h" diff --git a/trunk/include/asm-x86/mach-visws/setup_arch.h b/trunk/include/asm-x86/mach-visws/setup_arch.h new file mode 100644 index 000000000000..fa4766ca2d10 --- /dev/null +++ b/trunk/include/asm-x86/mach-visws/setup_arch.h @@ -0,0 +1 @@ +#include "../mach-default/setup_arch.h" diff --git a/trunk/include/asm-x86/mach-visws/smpboot_hooks.h b/trunk/include/asm-x86/mach-visws/smpboot_hooks.h new file mode 100644 index 000000000000..e4433ca88715 --- /dev/null +++ b/trunk/include/asm-x86/mach-visws/smpboot_hooks.h @@ -0,0 +1 @@ +#include "../mach-default/smpboot_hooks.h" diff --git a/trunk/include/asm-x86/processor.h b/trunk/include/asm-x86/processor.h index 15cb82a44e89..55402d2ab938 100644 --- a/trunk/include/asm-x86/processor.h +++ b/trunk/include/asm-x86/processor.h @@ -722,6 +722,8 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx) extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx); +extern int force_mwait; + extern void select_idle_routine(const struct cpuinfo_x86 *c); extern unsigned long boot_option_idle_override; diff --git a/trunk/include/asm-x86/setup.h b/trunk/include/asm-x86/setup.h index f003ceaad6af..90ab2225e71b 100644 --- a/trunk/include/asm-x86/setup.h +++ b/trunk/include/asm-x86/setup.h @@ -19,28 +19,13 @@ static inline int is_visws_box(void) { return 0; } /* * Any setup quirks to be performed? */ -struct mpc_config_processor; -struct mpc_config_bus; -struct mp_config_oemtable; -struct x86_quirks { - int (*arch_pre_time_init)(void); - int (*arch_time_init)(void); - int (*arch_pre_intr_init)(void); - int (*arch_intr_init)(void); - int (*arch_trap_init)(void); - char * (*arch_memory_setup)(void); - int (*mach_get_smp_config)(unsigned int early); - int (*mach_find_smp_config)(unsigned int reserve); - - int *mpc_record; - int (*mpc_apic_id)(struct mpc_config_processor *m); - void (*mpc_oem_bus_info)(struct mpc_config_bus *m, char *name); - void (*mpc_oem_pci_bus)(struct mpc_config_bus *m); - void (*smp_read_mpc_oem)(struct mp_config_oemtable *oemtable, - unsigned short oemsize); -}; - -extern struct x86_quirks *x86_quirks; +extern int (*arch_time_init_quirk)(void); +extern int (*arch_pre_intr_init_quirk)(void); +extern int (*arch_intr_init_quirk)(void); +extern int (*arch_trap_init_quirk)(void); +extern char * (*arch_memory_setup_quirk)(void); +extern int (*mach_get_smp_config_quirk)(unsigned int early); +extern int (*mach_find_smp_config_quirk)(unsigned int reserve); #ifndef CONFIG_PARAVIRT #define paravirt_post_allocator_init() do {} while (0)