[PATCH v3] um: enable the use of optimized xor routines in UML
Anton Ivanov
anton.ivanov at cambridgegreys.com
Thu Nov 12 06:33:00 EST 2020
On 12/11/2020 11:12, anton.ivanov at cambridgegreys.com wrote:
> From: Anton Ivanov <anton.ivanov at cambridgegreys.com>
>
> This patch enable the use of optimized xor routines from the x86
> tree as well as supply the necessary macros for them to be used in
> UML.
>
> The macros supply several "fake" flags and definitions to allow
> using the x86 files "as is".
>
> This patchset implements only the flags needed for the optimized
> strings.h, xor.h and checksum.h implementations instead of
> trying to copy the entire x86 flags environment.
>
> Signed-off-by: Anton Ivanov <anton.ivanov at cambridgegreys.com>
> ---
> arch/um/include/asm/cpufeature.h | 17 +++++++++++++
> arch/um/include/asm/cpufeatures.h | 14 +++++++++++
> arch/um/include/asm/processor-generic.h | 3 +++
> arch/um/include/asm/xor-x86.h | 1 +
> arch/um/include/asm/xor.h | 17 ++++++++++++-
> arch/um/include/asm/xor_32.h | 1 +
> arch/um/include/asm/xor_64.h | 1 +
> arch/um/include/asm/xor_avx.h | 1 +
> arch/um/include/shared/os.h | 1 +
> arch/um/kernel/um_arch.c | 17 +++++++++++--
> arch/um/os-Linux/start_up.c | 32 +++++++++++++++++++++++++
This still misses a file - I forgot to add the fake "fpu" definitions which NOOP the fpu_enter/fpu_exit use from x86.
I just sent an amended version.
A.
> 11 files changed, 102 insertions(+), 3 deletions(-)
> create mode 100644 arch/um/include/asm/cpufeature.h
> create mode 100644 arch/um/include/asm/cpufeatures.h
> create mode 120000 arch/um/include/asm/xor-x86.h
> create mode 120000 arch/um/include/asm/xor_32.h
> create mode 120000 arch/um/include/asm/xor_64.h
> create mode 120000 arch/um/include/asm/xor_avx.h
>
> diff --git a/arch/um/include/asm/cpufeature.h b/arch/um/include/asm/cpufeature.h
> new file mode 100644
> index 000000000000..abd2975fd825
> --- /dev/null
> +++ b/arch/um/include/asm/cpufeature.h
> @@ -0,0 +1,17 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _ASM_UM_CPUFEATURE_H
> +#define _ASM_UM_CPUFEATURE_H
> +
> +#include <asm/asm.h>
> +#include <linux/bitops.h>
> +#include <asm/processor-generic.h>
> +#include <asm/cpufeatures.h>
> +
> +
> +const char *host_cpu_feature_names[] = {"mmx", "xmm", "avx", "osxsave", "rep_good", "erms"};
> +#define MAX_UM_CPU_FEATURES ARRAY_SIZE(host_cpu_feature_names)
> +
> +
> +#define boot_cpu_has(bit) (boot_cpu_data.host_features & bit)
> +
> +#endif /* _ASM_UM_CPUFEATURE_H */
> diff --git a/arch/um/include/asm/cpufeatures.h b/arch/um/include/asm/cpufeatures.h
> new file mode 100644
> index 000000000000..ee08a65cd49b
> --- /dev/null
> +++ b/arch/um/include/asm/cpufeatures.h
> @@ -0,0 +1,14 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _ASM_UM_CPUFEATURES_H
> +#define _ASM_UM_CPUFEATURES_H
> +
> +/* Fake x86 Features of actual interest to UML */
> +
> +#define X86_FEATURE_MMX (1 << 0)
> +#define X86_FEATURE_XMM (1 << 1)
> +#define X86_FEATURE_AVX (1 << 2)
> +#define X86_FEATURE_OSXSAVE (1 << 3)
> +#define X86_FEATURE_REP_GOOD (1 << 4)
> +#define X86_FEATURE_ERMS (1 << 5)
> +
> +#endif /* _ASM_UM_CPUFEATURES_H */
> diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h
> index afd9b267cf81..b8bcddbb1898 100644
> --- a/arch/um/include/asm/processor-generic.h
> +++ b/arch/um/include/asm/processor-generic.h
> @@ -90,6 +90,9 @@ extern void start_thread(struct pt_regs *regs, unsigned long entry,
> struct cpuinfo_um {
> unsigned long loops_per_jiffy;
> int ipi_pipe[2];
> + /* There is only a small set of x86 features we are interested
> + * in for now */
> + unsigned long host_features;
> };
>
> extern struct cpuinfo_um boot_cpu_data;
> diff --git a/arch/um/include/asm/xor-x86.h b/arch/um/include/asm/xor-x86.h
> new file mode 120000
> index 000000000000..beff7de6890d
> --- /dev/null
> +++ b/arch/um/include/asm/xor-x86.h
> @@ -0,0 +1 @@
> +../../../x86/include/asm/xor.h
> \ No newline at end of file
> diff --git a/arch/um/include/asm/xor.h b/arch/um/include/asm/xor.h
> index 36b33d62a35d..18bcb5b6189d 100644
> --- a/arch/um/include/asm/xor.h
> +++ b/arch/um/include/asm/xor.h
> @@ -1,7 +1,22 @@
> /* SPDX-License-Identifier: GPL-2.0 */
> -#include <asm-generic/xor.h>
> +#ifndef _ASM_UM_XOR_H
> +#define _ASM_UM_XOR_H
> +
> +#ifdef CONFIG_64BIT
> +#undef CONFIG_X86_32
> +#else
> +#define CONFIG_X86_32 1
> +#endif
> +
> +#include <asm/cpufeature.h>
> +#include <asm/xor-x86.h>
> #include <linux/time-internal.h>
>
> +#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT
> +#undef XOR_SELECT_TEMPLATE
> /* pick an arbitrary one - measuring isn't possible with inf-cpu */
> #define XOR_SELECT_TEMPLATE(x) \
> (time_travel_mode == TT_MODE_INFCPU ? &xor_block_8regs : NULL)
> +#endif
> +
> +#endif
> diff --git a/arch/um/include/asm/xor_32.h b/arch/um/include/asm/xor_32.h
> new file mode 120000
> index 000000000000..8a0894e996d7
> --- /dev/null
> +++ b/arch/um/include/asm/xor_32.h
> @@ -0,0 +1 @@
> +../../../x86/include/asm/xor_32.h
> \ No newline at end of file
> diff --git a/arch/um/include/asm/xor_64.h b/arch/um/include/asm/xor_64.h
> new file mode 120000
> index 000000000000..b8d346c516bf
> --- /dev/null
> +++ b/arch/um/include/asm/xor_64.h
> @@ -0,0 +1 @@
> +../../../x86/include/asm/xor_64.h
> \ No newline at end of file
> diff --git a/arch/um/include/asm/xor_avx.h b/arch/um/include/asm/xor_avx.h
> new file mode 120000
> index 000000000000..370ded122095
> --- /dev/null
> +++ b/arch/um/include/asm/xor_avx.h
> @@ -0,0 +1 @@
> +../../../x86/include/asm/xor_avx.h
> \ No newline at end of file
> diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
> index f467d28fc0b4..c2ff855af603 100644
> --- a/arch/um/include/shared/os.h
> +++ b/arch/um/include/shared/os.h
> @@ -187,6 +187,7 @@ int os_poll(unsigned int n, const int *fds);
> extern void os_early_checks(void);
> extern void os_check_bugs(void);
> extern void check_host_supports_tls(int *supports_tls, int *tls_min);
> +extern unsigned long check_host_cpu_features(const char **feature_names, int n);
>
> /* mem.c */
> extern int create_mem_file(unsigned long long len);
> diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
> index 76b37297b7d4..b7dfc4fcc130 100644
> --- a/arch/um/kernel/um_arch.c
> +++ b/arch/um/kernel/um_arch.c
> @@ -15,6 +15,7 @@
> #include <linux/kmsg_dump.h>
>
> #include <asm/processor.h>
> +#include <asm/cpufeature.h>
> #include <asm/sections.h>
> #include <asm/setup.h>
> #include <as-layout.h>
> @@ -48,9 +49,12 @@ 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 },
> + .host_features = 0
> };
>
> +EXPORT_SYMBOL(boot_cpu_data);
> +
> union thread_union cpu0_irqstack
> __section(".data..init_irqstack") =
> { .thread_info = INIT_THREAD_INFO(init_task) };
> @@ -67,9 +71,15 @@ static int show_cpuinfo(struct seq_file *m, void *v)
> 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, "bogomips\t: %lu.%02lu\n",
> loops_per_jiffy/(500000/HZ),
> (loops_per_jiffy/(5000/HZ)) % 100);
> + seq_printf(m, "flags\t\t:");
> + for (index = 0; index < MAX_UM_CPU_FEATURES; index++) {
> + if (boot_cpu_data.host_features & (1 << index))
> + seq_printf(m, " %s", host_cpu_feature_names[index]);
> + }
> + seq_printf(m, "\n\n");
>
> return 0;
> }
> @@ -275,6 +285,9 @@ int __init linux_main(int argc, char **argv)
> /* OS sanity checks that need to happen before the kernel runs */
> os_early_checks();
>
> + boot_cpu_data.host_features =
> + check_host_cpu_features(host_cpu_feature_names, MAX_UM_CPU_FEATURES);
> +
> brk_start = (unsigned long) sbrk(0);
>
> /*
> diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
> index f79dc338279e..be884ed86b30 100644
> --- a/arch/um/os-Linux/start_up.c
> +++ b/arch/um/os-Linux/start_up.c
> @@ -321,6 +321,38 @@ static void __init check_coredump_limit(void)
> os_info("%llu\n", (unsigned long long)lim.rlim_max);
> }
>
> +unsigned long __init check_host_cpu_features(const char **feature_names, int n)
> +{
> + FILE *cpuinfo;
> + char *line = NULL;
> + size_t len = 0;
> + int i;
> + bool done_parsing = false;
> + unsigned long result = 0;
> +
> + cpuinfo = fopen("/proc/cpuinfo", "r");
> + if (cpuinfo == NULL) {
> + os_info("Failed to get host CPU features\n");
> + } else {
> + while ((getline(&line, &len, cpuinfo)) != -1) {
> + if (strstr(line, "flags")) {
> + for (i = 0; i < n; i++) {
> + if (strstr(line, feature_names[i])) {
> + result |= (1 << i);
> + }
> + }
> + done_parsing = true;
> + }
> + free(line);
> + line = NULL;
> + if (done_parsing)
> + break;
> + }
> + fclose(cpuinfo);
> + }
> + return result;
> +}
> +
> void __init os_early_checks(void)
> {
> int pid;
--
Anton R. Ivanov
Cambridgegreys Limited. Registered in England. Company Number 10273661
https://www.cambridgegreys.com/
More information about the linux-um
mailing list