[patch-2.3.47] /dev/cpu/microcode

From: Tigran Aivazian (tigran@sco.COM)
Date: Tue Feb 22 2000 - 08:00:23 EST


Hi Linus,

This patch does two things:

  a) implements device trimming, i.e. ability to clear/free saved copy of
     applied microcode (users requested it and it makes sense so why not?)
     on open() with O_WRONLY, e.g. ">microcode" from shell.

  b) moves /proc/driver/microcode to a devfs-based /dev/cpu/microcode.
    Many people, including H. Peter Anvin and Richard Gooch argued that it
    should be done, and they are, imho, right.

The devfs side was reviewed and OK'd by Richard.

  http://www.ocston.org/~tigran/patches/microcode/mc-2.3.47.patch

Regards,
------
Tigran A. Aivazian | http://www.sco.com
Escalations Research Group | tel: +44-(0)1923-813796
Santa Cruz Operation Ltd | http://www.ocston.org/~tigran

diff -urN -X dontdiff linux/Documentation/Configure.help linux-mc/Documentation/Configure.help
--- linux/Documentation/Configure.help Mon Feb 21 07:06:32 2000
+++ linux-mc/Documentation/Configure.help Tue Feb 22 08:04:19 2000
@@ -10846,12 +10846,17 @@
   Pentium III, Xeon etc. You will obviously need the actual microcode
   binary data itself which is not shipped with the Linux kernel.
   Contact Intel to obtain the latest revision of microcode for
- your CPU(s). With this support compiled you can use dd(1) to write
- microcode, for example:
+ your CPU(s), start at http://program.intel.com/communication.htm.
+ As an interim solution, you can go to ftp://ftp.sco.com/SLS and download
+ the latest ptf7045 and extract the file /etc/p6updata if you know the SVR4
+ pkg format. With microcode update support compiled you can use dd(1) to
+ upgrade microcode on your processors, for example:
 
- # dd if=/etc/microcode of=/proc/driver/microcode bs=98304 count=1
+ # dd if=/etc/microcode of=/dev/cpu/microcode bs=98304 count=1
 
- You need to be superuser to do that.
+ You need to be superuser to do that. Also, to use microcode driver
+ you need to have devfs support enabled in the kernel (which you
+ should anyway).
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
diff -urN -X dontdiff linux/arch/i386/config.in linux-mc/arch/i386/config.in
--- linux/arch/i386/config.in Mon Feb 21 07:06:33 2000
+++ linux-mc/arch/i386/config.in Tue Feb 22 07:26:51 2000
@@ -49,8 +49,8 @@
    define_bool CONFIG_X86_USE_3DNOW y
 fi
 
-if [ "$CONFIG_PROC_FS" = "y" ]; then
- tristate '/proc/driver/microcode - Intel P6 CPU microcode support' CONFIG_MICROCODE
+if [ "$CONFIG_DEVFS_FS" = "y" ]; then
+ tristate '/dev/cpu/microcode - Intel P6 CPU microcode support' CONFIG_MICROCODE
 fi
 
 choice 'High Memory Support' \
diff -urN -X dontdiff linux/arch/i386/kernel/Makefile linux-mc/arch/i386/kernel/Makefile
--- linux/arch/i386/kernel/Makefile Wed Feb 16 22:36:52 2000
+++ linux-mc/arch/i386/kernel/Makefile Tue Feb 22 06:19:36 2000
@@ -40,14 +40,12 @@
   endif
 endif
 
-ifeq ($(CONFIG_PROC_FS),y)
 ifeq ($(CONFIG_MICROCODE),y)
 OX_OBJS += microcode.o
 else
   ifeq ($(CONFIG_MICROCODE),m)
   MX_OBJS += microcode.o
   endif
-endif
 endif
 
 ifeq ($(CONFIG_ACPI),y)
diff -urN -X dontdiff linux/arch/i386/kernel/microcode.c linux-mc/arch/i386/kernel/microcode.c
--- linux/arch/i386/kernel/microcode.c Mon Feb 21 07:06:33 2000
+++ linux-mc/arch/i386/kernel/microcode.c Tue Feb 22 08:50:41 2000
@@ -20,20 +20,27 @@
  * Initial release.
  * 1.01 18 February 2000, Tigran Aivazian <tigran@sco.com>
  * Added read() support + cleanups.
+ * 1.02 22 February 2000, Tigran Aivazian <tigran@sco.com>
+ * Added 'device trimming' support, O_WRONLY clears and
+ * frees the saved copy of applied microcode. Thanks to
+ * George Greer <greerga@nidhogg.ham.muohio.edu> for the idea.
+ * Also, moved /proc/driver/microcode -> /dev/cpu/microcode
+ * and made it use devfs.
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/smp_lock.h>
-#include <linux/proc_fs.h>
+#include <linux/devfs_fs_kernel.h>
 
 #include <asm/msr.h>
 #include <asm/uaccess.h>
 #include <asm/processor.h>
 
-#define MICROCODE_VERSION "1.01"
+#define MICROCODE_VERSION "1.02"
 
 MODULE_DESCRIPTION("CPU (P6) microcode update driver");
 MODULE_AUTHOR("Tigran Aivazian <tigran@ocston.org>");
@@ -53,7 +60,7 @@
 /*
  * Bits in microcode_status. (31 bits of room for future expansion)
  */
-#define MICROCODE_IS_OPEN 0 /* set if /dev/microcode is in use */
+#define MICROCODE_IS_OPEN 0 /* set if device is in use */
 static unsigned long microcode_status = 0;
 
 /* the actual array of microcode blocks, each 2048 bytes */
@@ -68,39 +75,26 @@
         release: microcode_release,
 };
 
-static struct inode_operations microcode_inops = {
- default_file_ops: &microcode_fops,
-};
-
-static struct proc_dir_entry *proc_microcode;
+static devfs_handle_t devfs_handle = NULL;
 
 static int __init microcode_init(void)
 {
- int size;
 
- proc_microcode = create_proc_entry("microcode", S_IWUSR|S_IRUSR, proc_root_driver);
- if (!proc_microcode) {
- printk(KERN_ERR "microcode: can't create /proc/driver/microcode\n");
+ devfs_handle = devfs_register(NULL, "cpu/microcode", 0, DEVFS_FL_DEFAULT, 0, 0,
+ S_IFREG | S_IRUSR | S_IWUSR, 0, 0, &microcode_fops, NULL);
+ if (!devfs_handle) {
+ printk(KERN_ERR "microcode: can't create /dev/cpu/microcode\n");
                 return -ENOMEM;
         }
- proc_microcode->ops = &microcode_inops;
- size = smp_num_cpus * sizeof(struct microcode);
- mc_applied = kmalloc(size, GFP_KERNEL);
- if (!mc_applied) {
- remove_proc_entry("microcode", proc_root_driver);
- printk(KERN_ERR "microcode: can't allocate memory for saved microcode\n");
- return -ENOMEM;
- }
- memset(mc_applied, 0, size); /* so that reading from offsets corresponding to failed
- update makes this obvious */
         printk(KERN_INFO "P6 Microcode Update Driver v%s registered\n", MICROCODE_VERSION);
         return 0;
 }
 
 static void __exit microcode_exit(void)
 {
- remove_proc_entry("microcode", proc_root_driver);
- kfree(mc_applied);
+ devfs_unregister(devfs_handle);
+ if (mc_applied)
+ kfree(mc_applied);
         printk(KERN_INFO "P6 Microcode Update Driver v%s unregistered\n", MICROCODE_VERSION);
 }
 
@@ -119,6 +113,15 @@
         if (test_and_set_bit(MICROCODE_IS_OPEN, &microcode_status))
                 return -EBUSY;
 
+ if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
+ devfs_set_file_size(devfs_handle, 0);
+ if (mc_applied) {
+ memset(mc_applied, 0, smp_num_cpus * sizeof(struct microcode));
+ kfree(mc_applied);
+ mc_applied = NULL;
+ }
+ }
+
         MOD_INC_USE_COUNT;
 
         return 0;
@@ -224,8 +227,8 @@
 {
         size_t fsize = smp_num_cpus * sizeof(struct microcode);
 
- if (!proc_microcode->size || *ppos >= fsize)
- return 0; /* EOF */
+ if (*ppos >= fsize)
+ return 0;
         if (*ppos + len > fsize)
                 len = fsize - *ppos;
         if (copy_to_user(buf, mc_applied + *ppos, len))
@@ -243,6 +246,15 @@
                         sizeof(struct microcode));
                 return -EINVAL;
         }
+ if (!mc_applied) {
+ int size = smp_num_cpus * sizeof(struct microcode);
+ mc_applied = kmalloc(size, GFP_KERNEL);
+ if (!mc_applied) {
+ printk(KERN_ERR "microcode: can't allocate memory for saved microcode\n");
+ return -ENOMEM;
+ }
+ memset(mc_applied, 0, size);
+ }
         lock_kernel();
         microcode_num = len/sizeof(struct microcode);
         microcode = vmalloc(len);
@@ -257,7 +269,7 @@
         }
         ret = do_microcode_update();
         if (!ret) {
- proc_microcode->size = smp_num_cpus * sizeof(struct microcode);
+ devfs_set_file_size(devfs_handle, smp_num_cpus * sizeof(struct microcode));
                 ret = (ssize_t)len;
         }
         vfree(microcode);

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Feb 23 2000 - 21:00:30 EST