Cleanups & fixes for the MTRR driver
PATCH 1/1 Cleanups & fixes for the MTRR driver
To fix some bugs and cut down code duplication between i386 and x86-64 I decided to reuse (using symlinks) the i386 MTRR driver for x86-64. To do that I did some cleanups and a few bug fixes in the i386 mtrr driver.
- Convert it to seq_file. This makes it a lot cleaner and gets rid of some cruft.
- Some long -> int required on 64bit (nop on 32bit)
- Add some RED-PENs for unfixed bugs (e.g. it doesn't support physical addresses > 4GB on 32bit hosts and the SMP locking is not very strong)
- Remove bogus // in mtrr_write that made the function a nop (= only ioctl was working for changing)
- Unify duplicated mtrr_strings define.
- Some other minor fixes and cleanups
Patch for 2.5.49.
Please consider applying,
-Andi
arch/i386/kernel/cpu/mtrr/generic.c +9 -8
@@ -1,3 +1,5 @@ +/* This only handles 32bit MTRR on 32bit hosts. This is strictly wrong +because MTRRs can span upto 40 bits (36bits on most modern x86) */ #include <linux/init.h> #include <linux/slab.h> #include <linux/mm.h>
@@ -30,7 +32,7 @@ get_mtrr_var_range(unsigned int index, sstatic void __init get_fixed_ranges (mtrr_type * frs) { -unsigned long *p = (unsigned long *) frs; +unsigned int *p = (unsigned int *) frs;int i;rdmsr (MTRRfix64K_00000_MSR, p[0 ], p[1 ]);
@@ -46,7 +48,7 @@ void get_mtrr_state(void) {unsigned int i;struct mtrr_var_range *vrs; -unsigned long lo, dummy; +unsigned lo, dummy;if (!mtrr_state.var_ranges) { mtrr_state.var_ranges = kmalloc(num_var_ranges * sizeof (struct mtrr_var_range),
@@ -113,11 +115,10 @@ int generic_get_free_region(unsigned lonreturn -ENOSPC ; } -void generic_get_mtrr (unsigned int reg,unsigned long *base,unsigned long *size,mtrr_type * type) { -unsigned long mask_lo, mask_hi, base_lo, base_hi; +unsigned int mask_lo, mask_hi, base_lo, base_hi;rdmsr (MTRRphysMask_MSR (reg), mask_lo, mask_hi);if ((mask_lo &0x800 ) ==0 ) {
@@ -143,10 +144,10 @@ void generic_get_mtrr(unsigned int reg,static int __init set_fixed_ranges (mtrr_type * frs) { -unsigned long *p = (unsigned long *) frs; +unsigned int *p = (unsigned int *) frs;int changed = FALSE;int i; -unsigned long lo, hi; +unsigned int lo, hi;rdmsr (MTRRfix64K_00000_MSR, lo, hi);if (p[0 ] != lo || p[1 ] != hi) {
@@ -228,13 +229,13 @@ static unsigned long set_mtrr_state(u32 } -static u32 cr4 =0 ; +static unsigned long cr4 =0 ;static u32 deftype_lo, deftype_hi;static spinlock_t set_atomicity_lock =SPIN_LOCK_UNLOCKED ;static void prepare_set (void ) { -u32 cr0; +unsigned long cr0;/* Note that this is not ideal, since the cache is only flushed/disabled for this CPU while the MTRRs are changed, but changing this requires
arch/i386/kernel/cpu/mtrr/if.c +37 -48
172 lines not on this page · raw message
arch/i386/kernel/cpu/mtrr/main.c +16 -16
@@ -36,7 +36,6 @@#include <linux/pci.h> #include <linux/smp.h> -#define MTRR_NEED_STRINGS #include <asm/mtrr.h> #include <asm/uaccess.h>
@@ -54,6 +53,7 @@ static DECLARE_MUTEX(main_lock);u32 size_or_mask, size_and_mask;static struct mtrr_ops * mtrr_ops[X86_VENDOR_NUM ] = {}; +struct mtrr_ops * mtrr_if =NULL ;__initdata char *mtrr_if_name[] = {
@@ -125,14 +125,6 @@ static void init_table(void) }for (i =0 ; i < max; i++) usage_table[i] =1 ; -#ifdef USERSPACE_INTERFACE -if ((ascii_buffer =kmalloc (max *LINE_SIZE ,GFP_KERNEL )) ==NULL ) { -printk ("mtrr: could not allocate\n" ); -return ; - } - ascii_buf_bytes =0 ; -compute_ascii (); -#endif }struct set_mtrr_data {
@@ -163,7 +155,7 @@ static void ipi_handler(void *info) }/* The master has cleared me to execute */ -if (data->smp_reg != ~0UL ) +if (data->smp_reg != ~0U ) mtrr_if->set (data->smp_reg, data->smp_base, data->smp_size, data->smp_type);else
@@ -253,7 +245,7 @@ static void set_mtrr(unsigned int reg, u* to replicate across all the APs. * If we're doing that @reg is set to something special... */ -if (reg != ~0UL ) +if (reg != ~0U ) mtrr_if->set (reg,base,size,type);/* wait for the others */
@@ -361,7 +353,6 @@ int mtrr_add_page(unsigned long base, un }if (increment) ++usage_table[i]; -compute_ascii (); error = i; goto out; }
@@ -370,7 +361,6 @@ int mtrr_add_page(unsigned long base, unif (i >=0 ) {set_mtrr (i, base, size, type); usage_table[i] =1 ; -compute_ascii (); }else printk ("mtrr: no more MTRRs available\n" ); error = i;
@@ -491,7 +481,6 @@ int mtrr_del_page(int reg, unsigned long }if (--usage_table[reg] <1 )set_mtrr (reg,0 ,0 ,0 ); -compute_ascii (); error = reg; out:up (&main_lock);
@@ -547,7 +536,7 @@ static void init_other_cpus(void)get_mtrr_state ();/* bring up the other processors */ -set_mtrr (~0UL ,0 ,0 ,0 ); +set_mtrr (~0U ,0 ,0 ,0 );if (use_intel ()) {finalize_mtrr_state ();
@@ -583,7 +572,7 @@ static int __init mtrr_init(void)query the width (in bits) of the physical addressable memory on the Hammer family. */ -if (boot_cpu_data.x86 ==7 +if (boot_cpu_data.x86 >=7 && (cpuid_eax (0x80000000 ) >=0x80000008 )) {u32 phys_addr; phys_addr =cpuid_eax (0x80000008 ) &0xff ;
@@ -643,5 +632,16 @@ static int __init mtrr_init(void)return mtrr_if ? -ENXIO :0 ; } +char *mtrr_strings[MTRR_NUM_TYPES ] = +{ +"uncachable" ,/* 0 */ +"write-combining" ,/* 1 */ +"?" ,/* 2 */ +"?" ,/* 3 */ +"write-through" ,/* 4 */ +"write-protect" ,/* 5 */ +"write-back" ,/* 6 */ +}; +core_initcall (mtrr_init);
arch/i386/kernel/cpu/mtrr/mtrr.h +0 -3
@@ -85,9 +85,6 @@ void get_mtrr_state(void);extern void set_mtrr_ops (struct mtrr_ops * ops); -/* Don't even ask... */ -extern void compute_ascii (void ); -extern u32 size_or_mask, size_and_mask;extern struct mtrr_ops * mtrr_if;
include/asm-i386/mtrr.h +2 -13
@@ -65,21 +65,10 @@ struct mtrr_gentry#define MTRR_TYPE_WRBACK 6#define MTRR_NUM_TYPES 7 -#ifdef MTRR_NEED_STRINGS -static char *mtrr_strings[MTRR_NUM_TYPES ] = -{ -"uncachable" ,/* 0 */ -"write-combining" ,/* 1 */ -"?" ,/* 2 */ -"?" ,/* 3 */ -"write-through" ,/* 4 */ -"write-protect" ,/* 5 */ -"write-back" ,/* 6 */ -}; -#endif -#ifdef __KERNEL__ +extern char *mtrr_strings[]; +/* The following functions are for use by other drivers */ # ifdef CONFIG_MTRR extern int mtrr_add (unsigned long base, unsigned long size,