]> Pileus Git - ~andy/linux/blobdiff - drivers/char/hw_random/via-rng.c
bnx2x: Duplication in promisc mode
[~andy/linux] / drivers / char / hw_random / via-rng.c
index 4e9573c1d39eabbd025c07a9b7a549e85080aaa8..d0387a84eec1363ff40a05854ecaf48f51f63701 100644 (file)
@@ -24,6 +24,7 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <crypto/padlock.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/hw_random.h>
@@ -34,7 +35,6 @@
 #include <asm/i387.h>
 
 
-#define PFX    KBUILD_MODNAME ": "
 
 
 enum {
@@ -81,8 +81,7 @@ static inline u32 xstore(u32 *addr, u32 edx_in)
        ts_state = irq_ts_save();
 
        asm(".byte 0x0F,0xA7,0xC0 /* xstore %%edi (addr=%0) */"
-               :"=m"(*addr), "=a"(eax_out)
-               :"D"(addr), "d"(edx_in));
+               : "=m" (*addr), "=a" (eax_out), "+d" (edx_in), "+D" (addr));
 
        irq_ts_restore(ts_state);
        return eax_out;
@@ -90,8 +89,10 @@ static inline u32 xstore(u32 *addr, u32 edx_in)
 
 static int via_rng_data_present(struct hwrng *rng, int wait)
 {
+       char buf[16 + PADLOCK_ALIGNMENT - STACK_ALIGN] __attribute__
+               ((aligned(STACK_ALIGN)));
+       u32 *via_rng_datum = (u32 *)PTR_ALIGN(&buf[0], PADLOCK_ALIGNMENT);
        u32 bytes_out;
-       u32 *via_rng_datum = (u32 *)(&rng->priv);
        int i;
 
        /* We choose the recommended 1-byte-per-instruction RNG rate,
@@ -115,6 +116,7 @@ static int via_rng_data_present(struct hwrng *rng, int wait)
                        break;
                udelay(10);
        }
+       rng->priv = *via_rng_datum;
        return bytes_out ? 1 : 0;
 }
 
@@ -132,6 +134,19 @@ static int via_rng_init(struct hwrng *rng)
        struct cpuinfo_x86 *c = &cpu_data(0);
        u32 lo, hi, old_lo;
 
+       /* VIA Nano CPUs don't have the MSR_VIA_RNG anymore.  The RNG
+        * is always enabled if CPUID rng_en is set.  There is no
+        * RNG configuration like it used to be the case in this
+        * register */
+       if ((c->x86 == 6) && (c->x86_model >= 0x0f)) {
+               if (!cpu_has_xstore_enabled) {
+                       printk(KERN_ERR PFX "can't enable hardware RNG "
+                               "if XSTORE is not enabled\n");
+                       return -ENODEV;
+               }
+               return 0;
+       }
+
        /* Control the RNG via MSR.  Tread lightly and pay very close
         * close attention to values written, as the reserved fields
         * are documented to be "undefined and unpredictable"; but it
@@ -205,5 +220,5 @@ static void __exit mod_exit(void)
 module_init(mod_init);
 module_exit(mod_exit);
 
-MODULE_DESCRIPTION("H/W RNG driver for VIA chipsets");
+MODULE_DESCRIPTION("H/W RNG driver for VIA CPU with PadLock");
 MODULE_LICENSE("GPL");