]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86_64/kernel/setup.c
[PATCH] x86_64: Support alternative() in vsyscalls
[linux-2.6-omap-h63xx.git] / arch / x86_64 / kernel / setup.c
index 750e01dcbdf49f364940c87f5ab6b4bc158d460a..8090a0a4688271649cb562491655b2b7983e85fe 100644 (file)
@@ -35,6 +35,7 @@
 #include <asm/processor.h>
 #include <linux/console.h>
 #include <linux/seq_file.h>
+#include <linux/crash_dump.h>
 #include <linux/root_dev.h>
 #include <linux/pci.h>
 #include <linux/acpi.h>
@@ -42,6 +43,9 @@
 #include <linux/edd.h>
 #include <linux/mmzone.h>
 #include <linux/kexec.h>
+#include <linux/cpufreq.h>
+#include <linux/dmi.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/mtrr.h>
 #include <asm/uaccess.h>
@@ -60,7 +64,9 @@
 #include <asm/setup.h>
 #include <asm/mach_apic.h>
 #include <asm/numa.h>
+#include <asm/swiotlb.h>
 #include <asm/sections.h>
+#include <asm/gart-mapping.h>
 
 /*
  * Machine setup..
@@ -85,11 +91,6 @@ int bootloader_type;
 
 unsigned long saved_video_mode;
 
-#ifdef CONFIG_SWIOTLB
-int swiotlb;
-EXPORT_SYMBOL(swiotlb);
-#endif
-
 /*
  * Setup options
  */
@@ -274,6 +275,7 @@ static __init void parse_cmdline_early (char ** cmdline_p)
 {
        char c = ' ', *to = command_line, *from = COMMAND_LINE;
        int len = 0;
+       int userdef = 0;
 
        /* Save unparsed command line copy for /proc/cmdline */
        memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
@@ -348,7 +350,9 @@ static __init void parse_cmdline_early (char ** cmdline_p)
                if (!memcmp(from, "noapic", 6)) 
                        skip_ioapic_setup = 1;
 
-               if (!memcmp(from, "apic", 4)) { 
+               /* Make sure to not confuse with apic= */
+               if (!memcmp(from, "apic", 4) &&
+                       (from[4] == ' ' || from[4] == 0)) {
                        skip_ioapic_setup = 0;
                        ioapic_force = 1;
                }
@@ -356,16 +360,36 @@ static __init void parse_cmdline_early (char ** cmdline_p)
                if (!memcmp(from, "mem=", 4))
                        parse_memopt(from+4, &from); 
 
+               if (!memcmp(from, "memmap=", 7)) {
+                       /* exactmap option is for used defined memory */
+                       if (!memcmp(from+7, "exactmap", 8)) {
+#ifdef CONFIG_CRASH_DUMP
+                               /* If we are doing a crash dump, we
+                                * still need to know the real mem
+                                * size before original memory map is
+                                * reset.
+                                */
+                               saved_max_pfn = e820_end_of_ram();
+#endif
+                               from += 8+7;
+                               end_pfn_map = 0;
+                               e820.nr_map = 0;
+                               userdef = 1;
+                       }
+                       else {
+                               parse_memmapopt(from+7, &from);
+                               userdef = 1;
+                       }
+               }
+
 #ifdef CONFIG_NUMA
                if (!memcmp(from, "numa=", 5))
                        numa_setup(from+5); 
 #endif
 
-#ifdef CONFIG_GART_IOMMU 
                if (!memcmp(from,"iommu=",6)) { 
                        iommu_setup(from+6); 
                }
-#endif
 
                if (!memcmp(from,"oops=panic", 10))
                        panic_on_oops = 1;
@@ -394,6 +418,14 @@ static __init void parse_cmdline_early (char ** cmdline_p)
                }
 #endif
 
+#ifdef CONFIG_PROC_VMCORE
+               /* elfcorehdr= specifies the location of elf core header
+                * stored by the crashed kernel. This option will be passed
+                * by kexec loader to the capture kernel.
+                */
+               else if(!memcmp(from, "elfcorehdr=", 11))
+                       elfcorehdr_addr = memparse(from+11, &from);
+#endif
        next_char:
                c = *(from++);
                if (!c)
@@ -402,6 +434,10 @@ static __init void parse_cmdline_early (char ** cmdline_p)
                        break;
                *(to++) = c;
        }
+       if (userdef) {
+               printk(KERN_INFO "user-defined physical RAM map:\n");
+               e820_print_map("user");
+       }
        *to = '\0';
        *cmdline_p = command_line;
 }
@@ -442,6 +478,8 @@ static unsigned char *k8_nops[ASM_NOP_MAX+1] = {
      k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
 }; 
 
+extern char __vsyscall_0;
+
 /* Replace instructions with better alternatives for this CPU type.
 
    This runs before SMP is initialized to avoid SMP problems with
@@ -453,11 +491,17 @@ void apply_alternatives(void *start, void *end)
        struct alt_instr *a; 
        int diff, i, k;
        for (a = start; (void *)a < end; a++) { 
+               u8 *instr;
+
                if (!boot_cpu_has(a->cpuid))
                        continue;
 
                BUG_ON(a->replacementlen > a->instrlen); 
-               __inline_memcpy(a->instr, a->replacement, a->replacementlen); 
+               instr = a->instr;
+               /* vsyscall code is not mapped yet. resolve it manually. */
+               if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END)
+                       instr = __va(instr - (u8*)VSYSCALL_START + (u8*)__pa_symbol(&__vsyscall_0));
+               __inline_memcpy(instr, a->replacement, a->replacementlen);
                diff = a->instrlen - a->replacementlen; 
 
                /* Pad the rest with nops */
@@ -465,7 +509,7 @@ void apply_alternatives(void *start, void *end)
                        k = diff;
                        if (k > ASM_NOP_MAX)
                                k = ASM_NOP_MAX;
-                       __inline_memcpy(a->instr + i, k8_nops[k], k); 
+                       __inline_memcpy(instr + i, k8_nops[k], k);
                } 
        }
 } 
@@ -873,6 +917,10 @@ static int __init init_amd(struct cpuinfo_x86 *c)
        } 
        display_cacheinfo(c);
 
+       /* c->x86_power is 8000_0007 edx. Bit 8 is constant TSC */
+       if (c->x86_power & (1<<8))
+               set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
+
        if (c->extended_cpuid_level >= 0x80000008) {
                c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
                if (c->x86_max_cores & (c->x86_max_cores - 1))
@@ -991,7 +1039,8 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
 
        if (c->x86 == 15)
                c->x86_cache_alignment = c->x86_clflush_size * 2;
-       if (c->x86 >= 15)
+       if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
+           (c->x86 == 0x6 && c->x86_model >= 0x0e))
                set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
        c->x86_max_cores = intel_num_cpu_cores(c);
 
@@ -1191,7 +1240,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, "nx", NULL, "mmxext", NULL,
-               NULL, "fxsr_opt", NULL, NULL, NULL, "lm", "3dnowext", "3dnow",
+               NULL, "fxsr_opt", "rdtscp", NULL, NULL, "lm", "3dnowext", "3dnow",
 
                /* Transmeta-defined */
                "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
@@ -1219,7 +1268,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
                /* AMD-defined (#2) */
-               "lahf_lm", "cmp_legacy", NULL, NULL, NULL, NULL, NULL, NULL,
+               "lahf_lm", "cmp_legacy", "svm", NULL, "cr8_legacy", NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -1230,7 +1279,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                "vid",  /* voltage id control */
                "ttp",  /* thermal trip */
                "tm",
-               "stc"
+               "stc",
+               NULL,
+               /* nothing */   /* constant_tsc - moved to flags */
        };
 
 
@@ -1256,8 +1307,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                seq_printf(m, "stepping\t: unknown\n");
        
        if (cpu_has(c,X86_FEATURE_TSC)) {
+               unsigned int freq = cpufreq_quick_get((unsigned)(c-cpu_data));
+               if (!freq)
+                       freq = cpu_khz;
                seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
-                            cpu_khz / 1000, (cpu_khz % 1000));
+                            freq / 1000, (freq % 1000));
        }
 
        /* Cache size */
@@ -1307,8 +1361,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                unsigned i;
                for (i = 0; i < 32; i++) 
                        if (c->x86_power & (1 << i)) {
-                               if (i < ARRAY_SIZE(x86_power_flags))
-                                       seq_printf(m, " %s", x86_power_flags[i]);
+                               if (i < ARRAY_SIZE(x86_power_flags) &&
+                                       x86_power_flags[i])
+                                       seq_printf(m, "%s%s",
+                                               x86_power_flags[i][0]?" ":"",
+                                               x86_power_flags[i]);
                                else
                                        seq_printf(m, " [%d]", i);
                        }
@@ -1340,3 +1397,11 @@ struct seq_operations cpuinfo_op = {
        .stop = c_stop,
        .show = show_cpuinfo,
 };
+
+static int __init run_dmi_scan(void)
+{
+       dmi_scan_machine();
+       return 0;
+}
+core_initcall(run_dmi_scan);
+