summaryrefslogtreecommitdiff
path: root/arch/um/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/kernel')
-rw-r--r--arch/um/kernel/Makefile13
-rw-r--r--arch/um/kernel/um_arch.c48
2 files changed, 55 insertions, 6 deletions
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 2fdd00de5a72..1d18e4e46989 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -17,7 +17,7 @@ extra-y := vmlinux.lds
obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \
physmem.o process.o ptrace.o reboot.o sigio.o \
signal.o syscall.o sysrq.o time.o tlb.o trap.o \
- um_arch.o umid.o maccess.o kmsg_dump.o skas/
+ um_arch.o umid.o maccess.o kmsg_dump.o capflags.o skas/
obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
obj-$(CONFIG_GPROF) += gprof_syms.o
@@ -29,7 +29,7 @@ USER_OBJS := config.o
include arch/um/scripts/Makefile.rules
-targets := config.c config.tmp
+targets := config.c config.tmp capflags.c
# Be careful with the below Sed code - sed is pitfall-rich!
# We use sed to lower build requirements, for "embedded" builders for instance.
@@ -44,6 +44,15 @@ quiet_cmd_quote1 = QUOTE $@
$(obj)/config.c: $(src)/config.c.in $(obj)/config.tmp FORCE
$(call if_changed,quote2)
+quiet_cmd_mkcapflags = MKCAP $@
+ cmd_mkcapflags = $(CONFIG_SHELL) $(srctree)/$(src)/../../x86/kernel/cpu/mkcapflags.sh $@ $^
+
+cpufeature = $(src)/../../x86/include/asm/cpufeatures.h
+vmxfeature = $(src)/../../x86/include/asm/vmxfeatures.h
+
+$(obj)/capflags.c: $(cpufeature) $(vmxfeature) $(src)/../../x86/kernel/cpu/mkcapflags.sh FORCE
+ $(call if_changed,mkcapflags)
+
quiet_cmd_quote2 = QUOTE $@
cmd_quote2 = sed -e '/CONFIG/{' \
-e 's/"CONFIG"//' \
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 74e07e748a9b..20cce10bde51 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -6,6 +6,7 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/mm.h>
+#include <linux/ctype.h>
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/string.h>
@@ -16,6 +17,7 @@
#include <linux/suspend.h>
#include <asm/processor.h>
+#include <asm/cpufeature.h>
#include <asm/sections.h>
#include <asm/setup.h>
#include <as-layout.h>
@@ -50,9 +52,13 @@ static void __init add_arg(char *arg)
*/
struct cpuinfo_um boot_cpu_data = {
.loops_per_jiffy = 0,
- .ipi_pipe = { -1, -1 }
+ .ipi_pipe = { -1, -1 },
+ .cache_alignment = L1_CACHE_BYTES,
+ .x86_capability = { 0 }
};
+EXPORT_SYMBOL(boot_cpu_data);
+
union thread_union cpu0_irqstack
__section(".data..init_irqstack") =
{ .thread_info = INIT_THREAD_INFO(init_task) };
@@ -62,17 +68,25 @@ static char host_info[(__NEW_UTS_LEN + 1) * 5];
static int show_cpuinfo(struct seq_file *m, void *v)
{
- int index = 0;
+ int i = 0;
- seq_printf(m, "processor\t: %d\n", index);
+ seq_printf(m, "processor\t: %d\n", i);
seq_printf(m, "vendor_id\t: User Mode Linux\n");
seq_printf(m, "model name\t: UML\n");
seq_printf(m, "mode\t\t: skas\n");
seq_printf(m, "host\t\t: %s\n", host_info);
- seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
+ seq_printf(m, "fpu\t\t: %s\n", cpu_has(&boot_cpu_data, X86_FEATURE_FPU) ? "yes" : "no");
+ seq_printf(m, "flags\t\t:");
+ for (i = 0; i < 32*NCAPINTS; i++)
+ if (cpu_has(&boot_cpu_data, i) && (x86_cap_flags[i] != NULL))
+ seq_printf(m, " %s", x86_cap_flags[i]);
+ seq_printf(m, "\n");
+ seq_printf(m, "cache_alignment\t: %d\n", boot_cpu_data.cache_alignment);
+ seq_printf(m, "bogomips\t: %lu.%02lu\n",
loops_per_jiffy/(500000/HZ),
(loops_per_jiffy/(5000/HZ)) % 100);
+
return 0;
}
@@ -261,6 +275,30 @@ EXPORT_SYMBOL(end_iomem);
#define MIN_VMALLOC (32 * 1024 * 1024)
+static void parse_host_cpu_flags(char *line)
+{
+ int i;
+ for (i = 0; i < 32*NCAPINTS; i++) {
+ if ((x86_cap_flags[i] != NULL) && strstr(line, x86_cap_flags[i]))
+ set_cpu_cap(&boot_cpu_data, i);;
+ }
+}
+static void parse_cache_line(char *line)
+{
+ long res;
+ char *to_parse = strstr(line, ":");
+ if (to_parse) {
+ to_parse++;
+ while (*to_parse != 0 && isspace(*to_parse)) {
+ to_parse++;
+ }
+ if (kstrtoul(to_parse, 10, &res) == 0 && is_power_of_2(res))
+ boot_cpu_data.cache_alignment = res;
+ else
+ boot_cpu_data.cache_alignment = L1_CACHE_BYTES;
+ }
+}
+
int __init linux_main(int argc, char **argv)
{
unsigned long avail, diff;
@@ -297,6 +335,8 @@ int __init linux_main(int argc, char **argv)
/* OS sanity checks that need to happen before the kernel runs */
os_early_checks();
+ get_host_cpu_features(parse_host_cpu_flags, parse_cache_line);
+
brk_start = (unsigned long) sbrk(0);
/*