Skip to contentSkip to conversation

add Via Nehemiah ("xstore") rng support

PATCH In review Jeff Garzik 4 participants 6 messages Mar 12, 2003 Char and misc drivers

lore
Share & tools
lore
#0 lore raw

PATCH 3/3 add Via Nehemiah ("xstore") rng support

Via came up with a nifty feature on their "Nehemiah" generation of the C3 CPU: the xstore instruction. If the 'rep' prefix is not present, the instruction stores 0/1/2/4/8 bytes of random data to a memory location.

This xstore instruction forms the basis of this third patch, which adds support for the Via RNG to the newly-modular hw_random driver.

Note that since xstore is a new instruction, GNU binutils does not support it. We must use gcc inline asm to hand-code the machine language instruction in hexidecimal. Eventually I will get around to patching GNU binutils to support xstore natively, but even then we won't want to force users to update their binutils to bleeding-edge-latest, I don't think...

Review from x86 experts is especially appreciated here, as I am from an x86 expert myself.

# --------------------------------------------
# 03/03/11 [email protected] 1.1103
# [hw_random] add support for Via Nehemiah RNG ("xstore" insn) # --------------------------------------------
#

arch/i386/kernel/cpu/centaur.c +31 -15
diff -Nru a/arch/i386/kernel/cpu/centaur.c b/arch/i386/kernel/cpu/centaur.c
@@ -248,6 +248,36 @@
 }
 #endif
 
+static void __init init_c3(struct cpuinfo_x86 *c)
+{
+	u32  lo, hi;
+
+	/* Test for Centaur Extended Feature Flags presence */
+	if (cpuid_eax(0xC0000000) >= 0xC0000001) {
+		set_bit(X86_FEATURE_CENTAUR_EFF, c->x86_capability);
+
+		/* test for on-chip RNG */
+		if (cpuid_edx(0xC0000001) & (1 << 2))
+			set_bit(X86_FEATURE_XSTORE, c->x86_capability);
+	}
+
+	switch (c->x86_model) {
+		case 6 ... 8:		/* Cyrix III family */
+			rdmsr (MSR_VIA_FCR, lo, hi);
+			lo |= (1<<1 | 1<<7);	/* Report CX8 & enable PGE */
+			wrmsr (MSR_VIA_FCR, lo, hi);
+
+			set_bit(X86_FEATURE_CX8, c->x86_capability);
+			set_bit(X86_FEATURE_3DNOW, c->x86_capability);
+
+		case 9:	/* Nehemiah */
+		default:
+			get_model_name(c);
+			display_cacheinfo(c);
+			break;
+	}
+}
+
 static void __init init_centaur(struct cpuinfo_x86 *c)
 {
 	enum {
@@ -386,21 +416,7 @@
 			break;
 
 		case 6:
-			switch (c->x86_model) {
-				case 6 ... 8:		/* Cyrix III family */
-					rdmsr (MSR_VIA_FCR, lo, hi);
-					lo |= (1<<1 | 1<<7);	/* Report CX8 & enable PGE */
-					wrmsr (MSR_VIA_FCR, lo, hi);
-
-					set_bit(X86_FEATURE_CX8, c->x86_capability);
-					set_bit(X86_FEATURE_3DNOW, c->x86_capability);
-
-				case 9:	/* Nehemiah */
-				default:
-					get_model_name(c);
-					display_cacheinfo(c);
-					break;
-			}
+			init_c3(c);
 			break;
 	}
 }
arch/i386/kernel/cpu/proc.c +2 -1
diff -Nru a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
@@ -37,7 +37,8 @@
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
 		/* Other (Linux-defined) */
-		"cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr", NULL, NULL, NULL, NULL,
+		"cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
+		"centaur_eff", "xstore", NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
drivers/char/Kconfig +1 -1
diff -Nru a/drivers/char/Kconfig b/drivers/char/Kconfig
@@ -710,7 +710,7 @@
 	  If you're not sure, say N.
 
 config HW_RANDOM
-	tristate "Intel/AMD H/W Random Number Generator support"
+	tristate "Intel/AMD/Via H/W Random Number Generator support"
 	depends on (X86 || IA64) && PCI
 	---help---
 	  This driver provides kernel-side support for the Random Number
drivers/char/hw_random.c +145 -1

186 lines not on this page · raw message

include/asm-i386/cpufeature.h +3 -0
diff -Nru a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h
@@ -63,6 +63,8 @@
 #define X86_FEATURE_K6_MTRR	(3*32+ 1) /* AMD K6 nonstandard MTRRs */
 #define X86_FEATURE_CYRIX_ARR	(3*32+ 2) /* Cyrix ARRs (= MTRRs) */
 #define X86_FEATURE_CENTAUR_MCR	(3*32+ 3) /* Centaur MCRs (= MTRRs) */
+#define X86_FEATURE_CENTAUR_EFF	(3*32+ 4) /* Centaur Extended Feature Flags */
+#define X86_FEATURE_XSTORE	(3*32+ 5) /* on-CPU RNG present (xstore insn) */
 
 
 #define cpu_has(c, bit)		test_bit(bit, (c)->x86_capability)
@@ -87,6 +89,7 @@
 #define cpu_has_k6_mtrr		boot_cpu_has(X86_FEATURE_K6_MTRR)
 #define cpu_has_cyrix_arr	boot_cpu_has(X86_FEATURE_CYRIX_ARR)
 #define cpu_has_centaur_mcr	boot_cpu_has(X86_FEATURE_CENTAUR_MCR)
+#define cpu_has_xstore		boot_cpu_has(X86_FEATURE_XSTORE)
 
 #endif /* __ASM_I386_CPUFEATURE_H */
 
include/asm-i386/msr.h +1 -0
diff -Nru a/include/asm-i386/msr.h b/include/asm-i386/msr.h
@@ -218,6 +218,7 @@
 /* VIA Cyrix defined MSRs*/
 #define MSR_VIA_FCR			0x1107
 #define MSR_VIA_LONGHAUL		0x110a
+#define MSR_VIA_RNG			0x110b
 #define MSR_VIA_BCR2			0x1147
 
 /* Transmeta defined MSRs */
#1 lore raw
Quoted 1 line

Review from x86 experts is especially appreciated here, as I am from an x86 expert myself.

er, "I am far from an x86 expert"...

#2 lore raw
In reply to Jeff Garzik
Quoted 2 lines · Jeff Garzik

Review from x86 experts is especially appreciated here, as I am from an x86 expert myself.

only minor niggles.

drivers/char/Kconfig line 713

Quoted 9 lines

diff -Nru a/drivers/char/Kconfig b/drivers/char/Kconfig

drivers/char/Kconfig +1 -1
@@ -710,7 +710,7 @@
 	  If you're not sure, say N.
 
 config HW_RANDOM
-	tristate "Intel/AMD H/W Random Number Generator support"
+	tristate "Intel/AMD/Via H/W Random Number Generator support"

s/Via/VIA/

drivers/char/hw_random.c line 2

Quoted 7 lines

diff -Nru a/drivers/char/hw_random.c b/drivers/char/hw_random.c

drivers/char/hw_random.c +1 -1
@@ -1,5 +1,5 @@
 /*
- 	Hardware driver for the Intel/AMD Random Number Generators (RNG)
+ 	Hardware driver for the Intel/AMD/Via Random Number Generators (RNG)

Ditto

drivers/char/hw_random.c line 451

Quoted 3 lines
drivers/char/hw_random.c +3 -0
+	rdmsr(MSR_VIA_RNG, lo, hi);
+	if ((lo & VIA_RNG_ENABLE) == 0) {
+		printk(KERN_ERR PFX "cannot enable Via C3 RNG, aborting\n");

Ditto.

Quoted 1 line

+#define cpu_has_xstore boot_cpu_has(X86_FEATURE_XSTORE)

Do we want to do this check only on VIA CPUs I wonder. As a vendor specific extension, I'd be inclined to do that.

Niggles aside, looks good! Can't test it though, as my current Nehemiah is pre-production, and seems to have a broken RNG.

Dave

#3 lore raw
Quoted 5 lines · Dave Jones
Quoted 2 lines

+#define cpu_has_xstore boot_cpu_has(X86_FEATURE_XSTORE)

Do we want to do this check only on VIA CPUs I wonder. As a vendor specific extension, I'd be inclined to do that.

No, the whole point of all the crud in arch/i386/kernel/cpu is to make those tests _once_ at bootup, and then the internal kernel "extended CPU feature set" has a unique feature-set that is independent of manufacturers and totally disjunct, so that we never need to care about manufacturers ever again.

Linus

#4 lore raw
Followup to:  <[email protected]>
By author:    Linus Torvalds <[email protected]>
In newsgroup: linux.dev.kernel
Quoted 15 lines · Dave Jones
Quoted 5 lines
Quoted 2 lines

+#define cpu_has_xstore boot_cpu_has(X86_FEATURE_XSTORE)

Do we want to do this check only on VIA CPUs I wonder. As a vendor specific extension, I'd be inclined to do that.

No, the whole point of all the crud in arch/i386/kernel/cpu is to make those tests _once_ at bootup, and then the internal kernel "extended CPU feature set" has a unique feature-set that is independent of manufacturers and totally disjunct, so that we never need to care about manufacturers ever again.

Right. I have also pointed out to Jeff already that the test is done wrong... it's pretty clear from the code that VIA has set up a feature flag space of their own like Intel, AMD and Transmeta already have (which is a good thing), so we should add that as an additional word in the feature test vector instead of special-casing such a bit.

In fact, we need to add two words since Intel ran out of theirs and started using additional flags in %ecx just recently.

-hpa

Signature · 3 lines
<[email protected]> at work, <[email protected]> in private!
"Unix gives you enough rope to shoot yourself in the foot."
Architectures needed: ia64 m68k mips64 ppc ppc64 s390 s390x sh v850 x86-64
#5 lore raw
In reply to Linus Torvalds
Quoted 9 lines · Linus Torvalds
Quoted 3 lines
Quoted 1 line

+#define cpu_has_xstore boot_cpu_has(X86_FEATURE_XSTORE)

Do we want to do this check only on VIA CPUs I wonder. As a vendor specific extension, I'd be inclined to do that.

No, the whole point of all the crud in arch/i386/kernel/cpu is to make those tests _once_ at bootup, and then the internal kernel "extended CPU feature set" has a unique feature-set that is independent of manufacturers and totally disjunct, so that we never need to care about manufacturers ever again.

Of course. Obviously a pre-caffeine email.

Dave