Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9def39be authored by Josh Triplett's avatar Josh Triplett
Browse files

x86: Support compiling out human-friendly processor feature names



The table mapping CPUID bits to human-readable strings takes up a
non-trivial amount of space, and only exists to support /proc/cpuinfo
and a couple of kernel messages.  Since programs depend on the format of
/proc/cpuinfo, force inclusion of the table when building with /proc
support; otherwise, support omitting that table to save space, in which
case the kernel messages will print features numerically instead.

In addition to saving 1408 bytes out of vmlinux, this also saves 1373
bytes out of the uncompressed setup code, which contributes directly to
the size of bzImage.

Signed-off-by: default avatarJosh Triplett <josh@joshtriplett.org>
parent 39f838e0
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -136,6 +136,7 @@ config X86
	select HAVE_ACPI_APEI if ACPI
	select HAVE_ACPI_APEI_NMI if ACPI
	select ACPI_LEGACY_TABLES_LOOKUP if ACPI
	select X86_FEATURE_NAMES if PROC_FS

config INSTRUCTION_DECODER
	def_bool y
@@ -313,6 +314,17 @@ config SMP

	  If you don't know what to do here, say N.

config X86_FEATURE_NAMES
	bool "Processor feature human-readable names" if EMBEDDED
	default y
	---help---
	  This option compiles in a table of x86 feature bits and corresponding
	  names.  This is required to support /proc/cpuinfo and a few kernel
	  messages.  You can disable this to save space, at the expense of
	  making those few kernel messages show numeric feature bits instead.

	  If in doubt, say Y.

config X86_X2APIC
	bool "Support x2apic"
	depends on X86_LOCAL_APIC && X86_64 && IRQ_REMAP
+5 −2
Original line number Diff line number Diff line
@@ -35,12 +35,14 @@ setup-y += video-vesa.o
setup-y		+= video-bios.o

targets		+= $(setup-y)
hostprogs-y	:= mkcpustr tools/build
hostprogs-y	:= tools/build
hostprogs-$(CONFIG_X86_FEATURE_NAMES) += mkcpustr

HOST_EXTRACFLAGS += -I$(srctree)/tools/include \
		    -include include/generated/autoconf.h \
	            -D__EXPORTED_HEADERS__

ifdef CONFIG_X86_FEATURE_NAMES
$(obj)/cpu.o: $(obj)/cpustr.h

quiet_cmd_cpustr = CPUSTR  $@
@@ -48,6 +50,7 @@ quiet_cmd_cpustr = CPUSTR $@
targets += cpustr.h
$(obj)/cpustr.h: $(obj)/mkcpustr FORCE
	$(call if_changed,cpustr)
endif

# ---------------------------------------------------------------------------

+41 −27
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@
 */

#include "boot.h"
#ifdef CONFIG_X86_FEATURE_NAMES
#include "cpustr.h"
#endif

static char *cpu_name(int level)
{
@@ -32,32 +34,13 @@ static char *cpu_name(int level)
	}
}

int validate_cpu(void)
static void show_cap_strs(u32 *err_flags)
{
	u32 *err_flags;
	int cpu_level, req_level;
	const unsigned char *msg_strs;

	check_cpu(&cpu_level, &req_level, &err_flags);

	if (cpu_level < req_level) {
		printf("This kernel requires an %s CPU, ",
		       cpu_name(req_level));
		printf("but only detected an %s CPU.\n",
		       cpu_name(cpu_level));
		return -1;
	}

	if (err_flags) {
	int i, j;
		puts("This kernel requires the following features "
		     "not present on the CPU:\n");

		msg_strs = (const unsigned char *)x86_cap_strs;

#ifdef CONFIG_X86_FEATURE_NAMES
	const unsigned char *msg_strs = (const unsigned char *)x86_cap_strs;
	for (i = 0; i < NCAPINTS; i++) {
		u32 e = err_flags[i];

		for (j = 0; j < 32; j++) {
			if (msg_strs[0] < i ||
			    (msg_strs[0] == i && msg_strs[1] < j)) {
@@ -77,6 +60,37 @@ int validate_cpu(void)
			e >>= 1;
		}
	}
#else
	for (i = 0; i < NCAPINTS; i++) {
		u32 e = err_flags[i];
		for (j = 0; j < 32; j++) {
			if (e & 1)
				printf("%d:%d ", i, j);
			e >>= 1;
		}
	}
#endif
}

int validate_cpu(void)
{
	u32 *err_flags;
	int cpu_level, req_level;

	check_cpu(&cpu_level, &req_level, &err_flags);

	if (cpu_level < req_level) {
		printf("This kernel requires an %s CPU, ",
		       cpu_name(req_level));
		printf("but only detected an %s CPU.\n",
		       cpu_name(cpu_level));
		return -1;
	}

	if (err_flags) {
		puts("This kernel requires the following features "
		     "not present on the CPU:\n");
		show_cap_strs(err_flags);
		putchar('\n');
		return -1;
	} else {
+7 −0
Original line number Diff line number Diff line
@@ -250,8 +250,15 @@
#include <asm/asm.h>
#include <linux/bitops.h>

#ifdef CONFIG_X86_FEATURE_NAMES
extern const char * const x86_cap_flags[NCAPINTS*32];
extern const char * const x86_power_flags[32];
#define X86_CAP_FMT "%s"
#define x86_cap_flag(flag) x86_cap_flags[flag]
#else
#define X86_CAP_FMT "%d:%d"
#define x86_cap_flag(flag) ((flag) >> 5), ((flag) & 31)
#endif

/*
 * In order to save room, we index into this array by doing
+4 −1
Original line number Diff line number Diff line
@@ -13,11 +13,12 @@ nostackp := $(call cc-option, -fno-stack-protector)
CFLAGS_common.o		:= $(nostackp)

obj-y			:= intel_cacheinfo.o scattered.o topology.o
obj-y			+= capflags.o powerflags.o common.o
obj-y			+= common.o
obj-y			+= rdrand.o
obj-y			+= match.o

obj-$(CONFIG_PROC_FS)	+= proc.o
obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o

obj-$(CONFIG_X86_32)	+= bugs.o
obj-$(CONFIG_X86_64)	+= bugs_64.o
@@ -50,6 +51,7 @@ obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o perf_event_amd_ibs.o

obj-$(CONFIG_HYPERVISOR_GUEST)		+= vmware.o hypervisor.o mshyperv.o

ifdef CONFIG_X86_FEATURE_NAMES
quiet_cmd_mkcapflags = MKCAP   $@
      cmd_mkcapflags = $(CONFIG_SHELL) $(srctree)/$(src)/mkcapflags.sh $< $@

@@ -58,3 +60,4 @@ cpufeature = $(src)/../../include/asm/cpufeature.h
targets += capflags.c
$(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.sh FORCE
	$(call if_changed,mkcapflags)
endif
Loading