linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] wire up CPU features to udev based module loading
@ 2013-11-11 10:19 Ard Biesheuvel
  2013-11-11 10:19 ` [PATCH 1/4] x86: move arch_cpu_uevent() to generic code Ard Biesheuvel
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Ard Biesheuvel @ 2013-11-11 10:19 UTC (permalink / raw)
  To: x86, linux-arm-kernel, linux-kernel
  Cc: gregkh, catalin.marinas, hpa, steve.capper, ak, dave.martin,
	Ard Biesheuvel

This series implements automatic module loading based on optional CPU features,
and tries to do so in a generic way.

Typical usage would look like this:

static struct cpu_feature mod_cpu_feature[] = {
	{ HWCAP_CRC32 },
	{}
};
MODULE_DEVICE_TABLE(cpu, mod_cpu_feature);

where (on the arm64 arch) the module in question would be loaded automatically
if the CPU has support for the optional CRC instructions. [Note that the example
is based on a pending patch by Steve Capper: 'arm64: Add hwcaps for crypto and
CRC32 extensions']

Changes wrt RFC version of this series:
- this time, instead of doing something entirely separate for non-x86 archs, the
  new generic modalias version allocates enough bits to cover all x86 features
  (320+), and the x86 version was tweaked to resemble the generic one more
  closely (i.e., both use 'cpu:type:...:feature:...' now)
- removed the weak and alias GCC attribute foo

Ard Biesheuvel (4):
  x86: move arch_cpu_uevent() to generic code
  cpu: advertise CPU features over udev in a generic way
  x86: align with generic cpu modalias
  arm64: advertise CPU features for modalias matching

 arch/arm64/Kconfig                |  3 +++
 arch/arm64/kernel/setup.c         | 20 ++++++++++++++++++++
 arch/x86/kernel/cpu/match.c       | 14 +-------------
 drivers/base/cpu.c                | 15 ++++++++++++++-
 include/linux/cpu.h               |  1 -
 include/linux/mod_devicetable.h   | 11 +++++++++++
 scripts/mod/devicetable-offsets.c |  3 +++
 scripts/mod/file2alias.c          | 20 +++++++++++++++-----
 8 files changed, 67 insertions(+), 20 deletions(-)

-- 
1.8.3.2


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/4] x86: move arch_cpu_uevent() to generic code
  2013-11-11 10:19 [PATCH 0/4] wire up CPU features to udev based module loading Ard Biesheuvel
@ 2013-11-11 10:19 ` Ard Biesheuvel
  2013-11-11 10:19 ` [PATCH 2/4] cpu: advertise CPU features over udev in a generic way Ard Biesheuvel
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: Ard Biesheuvel @ 2013-11-11 10:19 UTC (permalink / raw)
  To: x86, linux-arm-kernel, linux-kernel
  Cc: gregkh, catalin.marinas, hpa, steve.capper, ak, dave.martin,
	Ard Biesheuvel

Only x86 implements arch_cpu_uevent(), and there is nothing arch
specific about it, so move it to drivers/base/cpu.c.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/x86/kernel/cpu/match.c | 11 -----------
 drivers/base/cpu.c          | 15 ++++++++++++++-
 include/linux/cpu.h         |  1 -
 3 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c
index 3656537..ab6082a 100644
--- a/arch/x86/kernel/cpu/match.c
+++ b/arch/x86/kernel/cpu/match.c
@@ -78,14 +78,3 @@ ssize_t arch_print_cpu_modalias(struct device *dev,
 	*buf++ = '\n';
 	return buf - bufptr;
 }
-
-int arch_cpu_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
-	char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
-	if (buf) {
-		arch_print_cpu_modalias(NULL, NULL, buf);
-		add_uevent_var(env, "MODALIAS=%s", buf);
-		kfree(buf);
-	}
-	return 0;
-}
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 848ebbd..49c6f4b 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -275,6 +275,19 @@ static void cpu_device_release(struct device *dev)
 	 */
 }
 
+#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
+static int cpu_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+	char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	if (buf) {
+		arch_print_cpu_modalias(NULL, NULL, buf);
+		add_uevent_var(env, "MODALIAS=%s", buf);
+		kfree(buf);
+	}
+	return 0;
+}
+#endif
+
 /*
  * register_cpu - Setup a sysfs device for a CPU.
  * @cpu - cpu->hotpluggable field set to 1 will generate a control file in
@@ -296,7 +309,7 @@ int register_cpu(struct cpu *cpu, int num)
 	cpu->dev.offline = !cpu_online(num);
 	cpu->dev.of_node = of_get_cpu_node(num, NULL);
 #ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
-	cpu->dev.bus->uevent = arch_cpu_uevent;
+	cpu->dev.bus->uevent = cpu_uevent;
 #endif
 	cpu->dev.groups = common_cpu_attr_groups;
 	if (cpu->hotpluggable)
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 801ff9e..c12ddd1 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -44,7 +44,6 @@ extern ssize_t arch_cpu_release(const char *, size_t);
 struct notifier_block;
 
 #ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
-extern int arch_cpu_uevent(struct device *dev, struct kobj_uevent_env *env);
 extern ssize_t arch_print_cpu_modalias(struct device *dev,
 				       struct device_attribute *attr,
 				       char *bufptr);
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/4] cpu: advertise CPU features over udev in a generic way
  2013-11-11 10:19 [PATCH 0/4] wire up CPU features to udev based module loading Ard Biesheuvel
  2013-11-11 10:19 ` [PATCH 1/4] x86: move arch_cpu_uevent() to generic code Ard Biesheuvel
@ 2013-11-11 10:19 ` Ard Biesheuvel
  2013-11-11 10:19 ` [PATCH 3/4] x86: align with generic cpu modalias Ard Biesheuvel
  2013-11-11 10:19 ` [PATCH 4/4] arm64: advertise CPU features for modalias matching Ard Biesheuvel
  3 siblings, 0 replies; 8+ messages in thread
From: Ard Biesheuvel @ 2013-11-11 10:19 UTC (permalink / raw)
  To: x86, linux-arm-kernel, linux-kernel
  Cc: gregkh, catalin.marinas, hpa, steve.capper, ak, dave.martin,
	Ard Biesheuvel

This patch implements a generic modalias 'cpu:type:...:feature:...'
which enables CPU feature flag based module loading in a generic way.
All the arch needs to do is enable CONFIG_ARCH_HAS_CPU_AUTOPROBE and
implement arch_print_cpu_modalias(). The modules need to declare the
CPU feature they depend on with MODULE_DEVICE_TABLE(cpu, ...)

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 include/linux/mod_devicetable.h   | 11 +++++++++++
 scripts/mod/devicetable-offsets.c |  3 +++
 scripts/mod/file2alias.c          | 10 ++++++++++
 3 files changed, 24 insertions(+)

diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 45e9214..da20e57 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -564,6 +564,17 @@ struct x86_cpu_id {
 #define X86_MODEL_ANY  0
 #define X86_FEATURE_ANY 0	/* Same as FPU, you can't test for that */
 
+/*
+ * Generic table type for tracking CPU features.
+ * @feature:	the bit number of the feature (0000 - ffff)
+ *
+ * How the bit numbers map to actual CPU features is entirely up to the arch
+ */
+
+struct generic_cpu_id {
+	__u16	feature;
+};
+
 #define IPACK_ANY_FORMAT 0xff
 #define IPACK_ANY_ID (~0)
 struct ipack_device_id {
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
index bb5d115..1aa2126 100644
--- a/scripts/mod/devicetable-offsets.c
+++ b/scripts/mod/devicetable-offsets.c
@@ -174,6 +174,9 @@ int main(void)
 	DEVID_FIELD(x86_cpu_id, model);
 	DEVID_FIELD(x86_cpu_id, vendor);
 
+	DEVID(generic_cpu_id);
+	DEVID_FIELD(generic_cpu_id, feature);
+
 	DEVID(mei_cl_device_id);
 	DEVID_FIELD(mei_cl_device_id, name);
 
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 2370863..efc7abe 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -1135,6 +1135,16 @@ static int do_x86cpu_entry(const char *filename, void *symval,
 }
 ADD_TO_DEVTABLE("x86cpu", x86_cpu_id, do_x86cpu_entry);
 
+/* LOOKS like cpu:type:*:feature:*FEAT* */
+static int do_cpu_entry(const char *filename, void *symval, char *alias)
+{
+	DEF_FIELD(symval, generic_cpu_id, feature);
+
+	sprintf(alias, "cpu:type:*:feature:*%04X*", feature);
+	return 1;
+}
+ADD_TO_DEVTABLE("cpu", generic_cpu_id, do_cpu_entry);
+
 /* Looks like: mei:S */
 static int do_mei_entry(const char *filename, void *symval,
 			char *alias)
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/4] x86: align with generic cpu modalias
  2013-11-11 10:19 [PATCH 0/4] wire up CPU features to udev based module loading Ard Biesheuvel
  2013-11-11 10:19 ` [PATCH 1/4] x86: move arch_cpu_uevent() to generic code Ard Biesheuvel
  2013-11-11 10:19 ` [PATCH 2/4] cpu: advertise CPU features over udev in a generic way Ard Biesheuvel
@ 2013-11-11 10:19 ` Ard Biesheuvel
  2013-11-11 10:19 ` [PATCH 4/4] arm64: advertise CPU features for modalias matching Ard Biesheuvel
  3 siblings, 0 replies; 8+ messages in thread
From: Ard Biesheuvel @ 2013-11-11 10:19 UTC (permalink / raw)
  To: x86, linux-arm-kernel, linux-kernel
  Cc: gregkh, catalin.marinas, hpa, steve.capper, ak, dave.martin,
	Ard Biesheuvel

Align with the new generic 'cpu:type:...:features:...' modalias
by moving the 'x86' prefix and the vendor/family/model IDs into
the 'type' field.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/x86/kernel/cpu/match.c |  3 +--
 scripts/mod/file2alias.c    | 10 +++++-----
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c
index ab6082a..82e92b2 100644
--- a/arch/x86/kernel/cpu/match.c
+++ b/arch/x86/kernel/cpu/match.c
@@ -56,8 +56,7 @@ ssize_t arch_print_cpu_modalias(struct device *dev,
 	int i, n;
 	char *buf = bufptr;
 
-	n = snprintf(buf, size, "x86cpu:vendor:%04X:family:%04X:"
-		     "model:%04X:feature:",
+	n = snprintf(buf, size, "cpu:type:x86,ven%04Xfam%04Xmod%04X:feature:",
 		boot_cpu_data.x86_vendor,
 		boot_cpu_data.x86,
 		boot_cpu_data.x86_model);
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index efc7abe..856c343 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -1110,7 +1110,7 @@ static int do_amba_entry(const char *filename,
 }
 ADD_TO_DEVTABLE("amba", amba_id, do_amba_entry);
 
-/* LOOKS like x86cpu:vendor:VVVV:family:FFFF:model:MMMM:feature:*,FEAT,*
+/* LOOKS like cpu:type:x86,venVVVVfamFFFFmodMMMM:feature:*,FEAT,*
  * All fields are numbers. It would be nicer to use strings for vendor
  * and feature, but getting those out of the build system here is too
  * complicated.
@@ -1124,10 +1124,10 @@ static int do_x86cpu_entry(const char *filename, void *symval,
 	DEF_FIELD(symval, x86_cpu_id, model);
 	DEF_FIELD(symval, x86_cpu_id, vendor);
 
-	strcpy(alias, "x86cpu:");
-	ADD(alias, "vendor:",  vendor != X86_VENDOR_ANY, vendor);
-	ADD(alias, ":family:", family != X86_FAMILY_ANY, family);
-	ADD(alias, ":model:",  model  != X86_MODEL_ANY,  model);
+	strcpy(alias, "cpu:type:x86,");
+	ADD(alias, "ven", vendor != X86_VENDOR_ANY, vendor);
+	ADD(alias, "fam", family != X86_FAMILY_ANY, family);
+	ADD(alias, "mod", model  != X86_MODEL_ANY,  model);
 	strcat(alias, ":feature:*");
 	if (feature != X86_FEATURE_ANY)
 		sprintf(alias + strlen(alias), "%04X*", feature);
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/4] arm64: advertise CPU features for modalias matching
  2013-11-11 10:19 [PATCH 0/4] wire up CPU features to udev based module loading Ard Biesheuvel
                   ` (2 preceding siblings ...)
  2013-11-11 10:19 ` [PATCH 3/4] x86: align with generic cpu modalias Ard Biesheuvel
@ 2013-11-11 10:19 ` Ard Biesheuvel
  2013-11-14 15:29   ` Catalin Marinas
  3 siblings, 1 reply; 8+ messages in thread
From: Ard Biesheuvel @ 2013-11-11 10:19 UTC (permalink / raw)
  To: x86, linux-arm-kernel, linux-kernel
  Cc: gregkh, catalin.marinas, hpa, steve.capper, ak, dave.martin,
	Ard Biesheuvel

This enables the generic implementation in drivers/base/cpu.c
that allows modules to be loaded automatically based on the
optional features supported (and advertised over udev) by the
CPU.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/Kconfig        |  3 +++
 arch/arm64/kernel/setup.c | 20 ++++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c044548..50cd97f 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -202,6 +202,9 @@ config ARCH_WANT_HUGE_PMD_SHARE
 config HAVE_ARCH_TRANSPARENT_HUGEPAGE
 	def_bool y
 
+config ARCH_HAS_CPU_AUTOPROBE
+	def_bool y
+
 source "mm/Kconfig"
 
 config XEN_DOM0
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 780a7aa..4774304 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -403,3 +403,23 @@ const struct seq_operations cpuinfo_op = {
 	.stop	= c_stop,
 	.show	= c_show
 };
+
+ssize_t arch_print_cpu_modalias(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	unsigned int caps;
+	ssize_t n;
+	int i;
+
+	/*
+	 * With 32 features maximum (taking 5 bytes each to print), we don't
+	 * need to worry about overrunning the PAGE_SIZE sized buffer.
+	 */
+	n = sprintf(buf, "cpu:type:arm64:feature:");
+	for (caps = elf_hwcap, i = 0; caps; caps >>= 1, i++)
+		if (caps & 1)
+			n += sprintf(&buf[n], ",%04X", i);
+	buf[n++] = '\n';
+	return n;
+}
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/4] arm64: advertise CPU features for modalias matching
  2013-11-11 10:19 ` [PATCH 4/4] arm64: advertise CPU features for modalias matching Ard Biesheuvel
@ 2013-11-14 15:29   ` Catalin Marinas
  2013-11-14 16:14     ` Ard Biesheuvel
  0 siblings, 1 reply; 8+ messages in thread
From: Catalin Marinas @ 2013-11-14 15:29 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: x86, linux-arm-kernel, linux-kernel, gregkh, hpa, steve.capper,
	ak, Dave P Martin

On Mon, Nov 11, 2013 at 10:19:35AM +0000, Ard Biesheuvel wrote:
> +ssize_t arch_print_cpu_modalias(struct device *dev,
> +				struct device_attribute *attr,
> +				char *buf)
> +{
> +	unsigned int caps;
> +	ssize_t n;
> +	int i;
> +
> +	/*
> +	 * With 32 features maximum (taking 5 bytes each to print), we don't
> +	 * need to worry about overrunning the PAGE_SIZE sized buffer.
> +	 */
> +	n = sprintf(buf, "cpu:type:arm64:feature:");

I would use "aarch64" here instead of arm64 for consistency with the
architecture mode, compiler triplet and ELF_PLATFORM definition in the
kernel.

-- 
Catalin

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/4] arm64: advertise CPU features for modalias matching
  2013-11-14 15:29   ` Catalin Marinas
@ 2013-11-14 16:14     ` Ard Biesheuvel
  2013-11-14 19:05       ` H. Peter Anvin
  0 siblings, 1 reply; 8+ messages in thread
From: Ard Biesheuvel @ 2013-11-14 16:14 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: x86, linux-arm-kernel, linux-kernel, gregkh, hpa, steve.capper,
	ak, Dave P Martin

On 14 November 2013 16:29, Catalin Marinas <catalin.marinas@arm.com> wrote:
> On Mon, Nov 11, 2013 at 10:19:35AM +0000, Ard Biesheuvel wrote:
>> +ssize_t arch_print_cpu_modalias(struct device *dev,
>> +                             struct device_attribute *attr,
>> +                             char *buf)
>> +{
>> +     unsigned int caps;
>> +     ssize_t n;
>> +     int i;
>> +
>> +     /*
>> +      * With 32 features maximum (taking 5 bytes each to print), we don't
>> +      * need to worry about overrunning the PAGE_SIZE sized buffer.
>> +      */
>> +     n = sprintf(buf, "cpu:type:arm64:feature:");
>
> I would use "aarch64" here instead of arm64 for consistency with the
> architecture mode, compiler triplet and ELF_PLATFORM definition in the
> kernel.

OK, I will change that.

Regards,
Ard,

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/4] arm64: advertise CPU features for modalias matching
  2013-11-14 16:14     ` Ard Biesheuvel
@ 2013-11-14 19:05       ` H. Peter Anvin
  0 siblings, 0 replies; 8+ messages in thread
From: H. Peter Anvin @ 2013-11-14 19:05 UTC (permalink / raw)
  To: Ard Biesheuvel, Catalin Marinas
  Cc: x86, linux-arm-kernel, linux-kernel, gregkh, steve.capper, ak,
	Dave P Martin

arch/what again?

Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>On 14 November 2013 16:29, Catalin Marinas <catalin.marinas@arm.com>
>wrote:
>> On Mon, Nov 11, 2013 at 10:19:35AM +0000, Ard Biesheuvel wrote:
>>> +ssize_t arch_print_cpu_modalias(struct device *dev,
>>> +                             struct device_attribute *attr,
>>> +                             char *buf)
>>> +{
>>> +     unsigned int caps;
>>> +     ssize_t n;
>>> +     int i;
>>> +
>>> +     /*
>>> +      * With 32 features maximum (taking 5 bytes each to print), we
>don't
>>> +      * need to worry about overrunning the PAGE_SIZE sized buffer.
>>> +      */
>>> +     n = sprintf(buf, "cpu:type:arm64:feature:");
>>
>> I would use "aarch64" here instead of arm64 for consistency with the
>> architecture mode, compiler triplet and ELF_PLATFORM definition in
>the
>> kernel.
>
>OK, I will change that.
>
>Regards,
>Ard,

-- 
Sent from my mobile phone.  Please pardon brevity and lack of formatting.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2013-11-14 19:06 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-11 10:19 [PATCH 0/4] wire up CPU features to udev based module loading Ard Biesheuvel
2013-11-11 10:19 ` [PATCH 1/4] x86: move arch_cpu_uevent() to generic code Ard Biesheuvel
2013-11-11 10:19 ` [PATCH 2/4] cpu: advertise CPU features over udev in a generic way Ard Biesheuvel
2013-11-11 10:19 ` [PATCH 3/4] x86: align with generic cpu modalias Ard Biesheuvel
2013-11-11 10:19 ` [PATCH 4/4] arm64: advertise CPU features for modalias matching Ard Biesheuvel
2013-11-14 15:29   ` Catalin Marinas
2013-11-14 16:14     ` Ard Biesheuvel
2013-11-14 19:05       ` H. Peter Anvin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).