[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