Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dbd51be0 authored by Jaswinder Singh Rajput's avatar Jaswinder Singh Rajput Committed by Ingo Molnar
Browse files

x86: Clean up mtrr/main.c



Fix following trivial style problems:

  ERROR: trailing whitespace X 25
  WARNING: Use #include <linux/uaccess.h> instead of <asm/uaccess.h>
  WARNING: Use #include <linux/kvm_para.h> instead of <asm/kvm_para.h>
  ERROR: do not initialise externals to 0 or NULL X 2
  ERROR: "foo * bar" should be "foo *bar" X 5
  ERROR: do not use assignment in if condition X 2
  WARNING: line over 80 characters X 8
  ERROR: return is not a function, parentheses are not required
  WARNING: braces {} are not necessary for any arm of this statement
  ERROR: space required before the open parenthesis '(' X 2
  ERROR: open brace '{' following function declarations go on the next line
  ERROR: space required after that ',' (ctx:VxV) X 8
  ERROR: space required before the open parenthesis '(' X 3
  ERROR: else should follow close brace '}'
  WARNING: space prohibited between function name and open parenthesis '('
  WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable X 2

Also use pr_debug and pr_warning where possible.

total: 50 errors, 14 warnings

arch/x86/kernel/cpu/mtrr/main.o:

   text	   data	    bss	    dec	    hex	filename
   3668	    116	   4156	   7940	   1f04	main.o.before
   3668	    116	   4156	   7940	   1f04	main.o.after

md5:
   e01af2fd28deef77c8d01e71acfbd365  main.o.before.asm
   e01af2fd28deef77c8d01e71acfbd365  main.o.after.asm

Suggested-by: default avatarAlan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: default avatarJaswinder Singh Rajput <jaswinderrajput@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Yinghai Lu <yinghai@kernel.org>
LKML-Reference: <20090703164225.GA21447@elte.hu>
Cc: Avi Kivity <avi@redhat.com> # Avi, please have a look at the kvm_para.h bit
[ More cleanups ]
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 09b22c85
Loading
Loading
Loading
Loading
+242 −213
Original line number Original line Diff line number Diff line
@@ -31,32 +31,37 @@
    System Programming Guide; Section 9.11. (1997 edition - PPro).
    System Programming Guide; Section 9.11. (1997 edition - PPro).
*/
*/


#define DEBUG

#include <linux/types.h> /* FIXME: kvm_para.h needs this */

#include <linux/kvm_para.h>
#include <linux/uaccess.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/sort.h>
#include <linux/cpu.h>
#include <linux/pci.h>
#include <linux/pci.h>
#include <linux/smp.h>
#include <linux/smp.h>
#include <linux/cpu.h>
#include <linux/mutex.h>
#include <linux/sort.h>


#include <asm/processor.h>
#include <asm/e820.h>
#include <asm/e820.h>
#include <asm/mtrr.h>
#include <asm/mtrr.h>
#include <asm/uaccess.h>
#include <asm/processor.h>
#include <asm/msr.h>
#include <asm/msr.h>
#include <asm/kvm_para.h>

#include "mtrr.h"
#include "mtrr.h"


u32 num_var_ranges = 0;
u32 num_var_ranges;


unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES];
unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES];
static DEFINE_MUTEX(mtrr_mutex);
static DEFINE_MUTEX(mtrr_mutex);


u64 size_or_mask, size_and_mask;
u64 size_or_mask, size_and_mask;


static struct mtrr_ops * mtrr_ops[X86_VENDOR_NUM] = {};
static struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM];


struct mtrr_ops * mtrr_if = NULL;
struct mtrr_ops *mtrr_if;


static void set_mtrr(unsigned int reg, unsigned long base,
static void set_mtrr(unsigned int reg, unsigned long base,
		     unsigned long size, mtrr_type type);
		     unsigned long size, mtrr_type type);
@@ -73,29 +78,35 @@ static int have_wrcomb(void)
	struct pci_dev *dev;
	struct pci_dev *dev;
	u8 rev;
	u8 rev;


	if ((dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) != NULL) {
	dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, NULL);
		/* ServerWorks LE chipsets < rev 6 have problems with write-combining
	if (dev != NULL) {
		   Don't allow it and leave room for other chipsets to be tagged */
		/*
		 * ServerWorks LE chipsets < rev 6 have problems with
		 * write-combining. Don't allow it and leave room for other
		 * chipsets to be tagged
		 */
		if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS &&
		if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS &&
		    dev->device == PCI_DEVICE_ID_SERVERWORKS_LE) {
		    dev->device == PCI_DEVICE_ID_SERVERWORKS_LE) {
			pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev);
			pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev);
			if (rev <= 5) {
			if (rev <= 5) {
				printk(KERN_INFO "mtrr: Serverworks LE rev < 6 detected. Write-combining disabled.\n");
				pr_info("mtrr: Serverworks LE rev < 6 detected. Write-combining disabled.\n");
				pci_dev_put(dev);
				pci_dev_put(dev);
				return 0;
				return 0;
			}
			}
		}
		}
		/* Intel 450NX errata # 23. Non ascending cacheline evictions to
		/*
		   write combining memory may resulting in data corruption */
		 * Intel 450NX errata # 23. Non ascending cacheline evictions to
		 * write combining memory may resulting in data corruption
		 */
		if (dev->vendor == PCI_VENDOR_ID_INTEL &&
		if (dev->vendor == PCI_VENDOR_ID_INTEL &&
		    dev->device == PCI_DEVICE_ID_INTEL_82451NX) {
		    dev->device == PCI_DEVICE_ID_INTEL_82451NX) {
			printk(KERN_INFO "mtrr: Intel 450NX MMC detected. Write-combining disabled.\n");
			pr_info("mtrr: Intel 450NX MMC detected. Write-combining disabled.\n");
			pci_dev_put(dev);
			pci_dev_put(dev);
			return 0;
			return 0;
		}
		}
		pci_dev_put(dev);
		pci_dev_put(dev);
	}
	}
	return (mtrr_if->have_wrcomb ? mtrr_if->have_wrcomb() : 0);
	return mtrr_if->have_wrcomb ? mtrr_if->have_wrcomb() : 0;
}
}


/*  This function returns the number of variable MTRRs  */
/*  This function returns the number of variable MTRRs  */
@@ -103,12 +114,13 @@ static void __init set_num_var_ranges(void)
{
{
	unsigned long config = 0, dummy;
	unsigned long config = 0, dummy;


	if (use_intel()) {
	if (use_intel())
		rdmsr(MSR_MTRRcap, config, dummy);
		rdmsr(MSR_MTRRcap, config, dummy);
	} else if (is_cpu(AMD))
	else if (is_cpu(AMD))
		config = 2;
		config = 2;
	else if (is_cpu(CYRIX) || is_cpu(CENTAUR))
	else if (is_cpu(CYRIX) || is_cpu(CENTAUR))
		config = 8;
		config = 8;

	num_var_ranges = config & 0xff;
	num_var_ranges = config & 0xff;
}
}


@@ -130,10 +142,12 @@ struct set_mtrr_data {
	mtrr_type	smp_type;
	mtrr_type	smp_type;
};
};


static void ipi_handler(void *info)
/**
/*  [SUMMARY] Synchronisation handler. Executed by "other" CPUs.
 * ipi_handler - Synchronisation handler. Executed by "other" CPUs.
    [RETURNS] Nothing.
 *
 * Returns nothing.
 */
 */
static void ipi_handler(void *info)
{
{
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
	struct set_mtrr_data *data = info;
	struct set_mtrr_data *data = info;
@@ -146,11 +160,12 @@ static void ipi_handler(void *info)
		cpu_relax();
		cpu_relax();


	/*  The master has cleared me to execute  */
	/*  The master has cleared me to execute  */
	if (data->smp_reg != ~0U) 
	if (data->smp_reg != ~0U) {
		mtrr_if->set(data->smp_reg, data->smp_base,
		mtrr_if->set(data->smp_reg, data->smp_base,
			     data->smp_size, data->smp_type);
			     data->smp_size, data->smp_type);
	else
	} else {
		mtrr_if->set_all();
		mtrr_if->set_all();
	}


	atomic_dec(&data->count);
	atomic_dec(&data->count);
	while (atomic_read(&data->gate))
	while (atomic_read(&data->gate))
@@ -161,7 +176,8 @@ static void ipi_handler(void *info)
#endif
#endif
}
}


static inline int types_compatible(mtrr_type type1, mtrr_type type2) {
static inline int types_compatible(mtrr_type type1, mtrr_type type2)
{
	return type1 == MTRR_TYPE_UNCACHABLE ||
	return type1 == MTRR_TYPE_UNCACHABLE ||
	       type2 == MTRR_TYPE_UNCACHABLE ||
	       type2 == MTRR_TYPE_UNCACHABLE ||
	       (type1 == MTRR_TYPE_WRTHROUGH && type2 == MTRR_TYPE_WRBACK) ||
	       (type1 == MTRR_TYPE_WRTHROUGH && type2 == MTRR_TYPE_WRBACK) ||
@@ -197,18 +213,19 @@ static inline int types_compatible(mtrr_type type1, mtrr_type type2) {
 * of CPUs. As each CPU disables interrupts, it'll decrement it once. We wait
 * of CPUs. As each CPU disables interrupts, it'll decrement it once. We wait
 * until it hits 0 and proceed. We set the data.gate flag and reset data.count.
 * until it hits 0 and proceed. We set the data.gate flag and reset data.count.
 * Meanwhile, they are waiting for that flag to be set. Once it's set, each
 * Meanwhile, they are waiting for that flag to be set. Once it's set, each
 * CPU goes through the transition of updating MTRRs. The CPU vendors may each do it 
 * CPU goes through the transition of updating MTRRs.
 * differently, so we call mtrr_if->set() callback and let them take care of it.
 * The CPU vendors may each do it differently,
 * When they're done, they again decrement data->count and wait for data.gate to 
 * so we call mtrr_if->set() callback and let them take care of it.
 * be reset. 
 * When they're done, they again decrement data->count and wait for data.gate
 * When we finish, we wait for data.count to hit 0 and toggle the data.gate flag.
 * to be reset.
 * When we finish, we wait for data.count to hit 0 and toggle the data.gate flag
 * Everyone then enables interrupts and we all continue on.
 * Everyone then enables interrupts and we all continue on.
 *
 *
 * Note that the mechanism is the same for UP systems, too; all the SMP stuff
 * Note that the mechanism is the same for UP systems, too; all the SMP stuff
 * becomes nops.
 * becomes nops.
 */
 */
static void set_mtrr(unsigned int reg, unsigned long base,
static void
		     unsigned long size, mtrr_type type)
set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type type)
{
{
	struct set_mtrr_data data;
	struct set_mtrr_data data;
	unsigned long flags;
	unsigned long flags;
@@ -218,7 +235,8 @@ static void set_mtrr(unsigned int reg, unsigned long base,
	data.smp_size = size;
	data.smp_size = size;
	data.smp_type = type;
	data.smp_type = type;
	atomic_set(&data.count, num_booting_cpus() - 1);
	atomic_set(&data.count, num_booting_cpus() - 1);
	/* make sure data.count is visible before unleashing other CPUs */

	/* Make sure data.count is visible before unleashing other CPUs */
	smp_wmb();
	smp_wmb();
	atomic_set(&data.gate, 0);
	atomic_set(&data.gate, 0);


@@ -231,14 +249,15 @@ static void set_mtrr(unsigned int reg, unsigned long base,
	while (atomic_read(&data.count))
	while (atomic_read(&data.count))
		cpu_relax();
		cpu_relax();


	/* ok, reset count and toggle gate */
	/* Ok, reset count and toggle gate */
	atomic_set(&data.count, num_booting_cpus() - 1);
	atomic_set(&data.count, num_booting_cpus() - 1);
	smp_wmb();
	smp_wmb();
	atomic_set(&data.gate, 1);
	atomic_set(&data.gate, 1);


	/* do our MTRR business */
	/* Do our MTRR business */


	/* HACK!
	/*
	 * HACK!
	 * We use this same function to initialize the mtrrs on boot.
	 * We use this same function to initialize the mtrrs on boot.
	 * The state of the boot cpu's mtrrs has been saved, and we want
	 * The state of the boot cpu's mtrrs has been saved, and we want
	 * to replicate across all the APs.
	 * to replicate across all the APs.
@@ -247,7 +266,7 @@ static void set_mtrr(unsigned int reg, unsigned long base,
	if (reg != ~0U)
	if (reg != ~0U)
		mtrr_if->set(reg, base, size, type);
		mtrr_if->set(reg, base, size, type);


	/* wait for the others */
	/* Wait for the others */
	while (atomic_read(&data.count))
	while (atomic_read(&data.count))
		cpu_relax();
		cpu_relax();


@@ -300,39 +319,38 @@ static void set_mtrr(unsigned int reg, unsigned long base,
 * BUGS: Needs a quiet flag for the cases where drivers do not mind
 * BUGS: Needs a quiet flag for the cases where drivers do not mind
 * failures and do not wish system log messages to be sent.
 * failures and do not wish system log messages to be sent.
 */
 */

int mtrr_add_page(unsigned long base, unsigned long size,
int mtrr_add_page(unsigned long base, unsigned long size,
		  unsigned int type, bool increment)
		  unsigned int type, bool increment)
{
{
	unsigned long lbase, lsize;
	int i, replace, error;
	int i, replace, error;
	mtrr_type ltype;
	mtrr_type ltype;
	unsigned long lbase, lsize;


	if (!mtrr_if)
	if (!mtrr_if)
		return -ENXIO;
		return -ENXIO;


	if ((error = mtrr_if->validate_add_page(base,size,type)))
	error = mtrr_if->validate_add_page(base, size, type);
	if (error)
		return error;
		return error;


	if (type >= MTRR_NUM_TYPES) {
	if (type >= MTRR_NUM_TYPES) {
		printk(KERN_WARNING "mtrr: type: %u invalid\n", type);
		pr_warning("mtrr: type: %u invalid\n", type);
		return -EINVAL;
		return -EINVAL;
	}
	}


	/* If the type is WC, check that this processor supports it */
	/* If the type is WC, check that this processor supports it */
	if ((type == MTRR_TYPE_WRCOMB) && !have_wrcomb()) {
	if ((type == MTRR_TYPE_WRCOMB) && !have_wrcomb()) {
		printk(KERN_WARNING
		pr_warning("mtrr: your processor doesn't support write-combining\n");
		       "mtrr: your processor doesn't support write-combining\n");
		return -ENOSYS;
		return -ENOSYS;
	}
	}


	if (!size) {
	if (!size) {
		printk(KERN_WARNING "mtrr: zero sized request\n");
		pr_warning("mtrr: zero sized request\n");
		return -EINVAL;
		return -EINVAL;
	}
	}


	if (base & size_or_mask || size & size_or_mask) {
	if (base & size_or_mask || size & size_or_mask) {
		printk(KERN_WARNING "mtrr: base or size exceeds the MTRR width\n");
		pr_warning("mtrr: base or size exceeds the MTRR width\n");
		return -EINVAL;
		return -EINVAL;
	}
	}


@@ -341,25 +359,29 @@ int mtrr_add_page(unsigned long base, unsigned long size,


	/* No CPU hotplug when we change MTRR entries */
	/* No CPU hotplug when we change MTRR entries */
	get_online_cpus();
	get_online_cpus();

	/* Search for existing MTRR  */
	/* Search for existing MTRR  */
	mutex_lock(&mtrr_mutex);
	mutex_lock(&mtrr_mutex);
	for (i = 0; i < num_var_ranges; ++i) {
	for (i = 0; i < num_var_ranges; ++i) {
		mtrr_if->get(i, &lbase, &lsize, &ltype);
		mtrr_if->get(i, &lbase, &lsize, &ltype);
		if (!lsize || base > lbase + lsize - 1 || base + size - 1 < lbase)
		if (!lsize || base > lbase + lsize - 1 ||
		    base + size - 1 < lbase)
			continue;
			continue;
		/*  At this point we know there is some kind of overlap/enclosure  */
		/*
		 * At this point we know there is some kind of
		 * overlap/enclosure
		 */
		if (base < lbase || base + size - 1 > lbase + lsize - 1) {
		if (base < lbase || base + size - 1 > lbase + lsize - 1) {
			if (base <= lbase && base + size - 1 >= lbase + lsize - 1) {
			if (base <= lbase &&
			    base + size - 1 >= lbase + lsize - 1) {
				/*  New region encloses an existing region  */
				/*  New region encloses an existing region  */
				if (type == ltype) {
				if (type == ltype) {
					replace = replace == -1 ? i : -2;
					replace = replace == -1 ? i : -2;
					continue;
					continue;
				}
				} else if (types_compatible(type, ltype))
				else if (types_compatible(type, ltype))
					continue;
					continue;
			}
			}
			printk(KERN_WARNING
			pr_warning("mtrr: 0x%lx000,0x%lx000 overlaps existing"
			       "mtrr: 0x%lx000,0x%lx000 overlaps existing"
				" 0x%lx000,0x%lx000\n", base, size, lbase,
				" 0x%lx000,0x%lx000\n", base, size, lbase,
				lsize);
				lsize);
			goto out;
			goto out;
@@ -368,7 +390,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
		if (ltype != type) {
		if (ltype != type) {
			if (types_compatible(type, ltype))
			if (types_compatible(type, ltype))
				continue;
				continue;
			printk (KERN_WARNING "mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
			pr_warning("mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
				base, size, mtrr_attrib_to_str(ltype),
				base, size, mtrr_attrib_to_str(ltype),
				mtrr_attrib_to_str(type));
				mtrr_attrib_to_str(type));
			goto out;
			goto out;
@@ -393,8 +415,9 @@ int mtrr_add_page(unsigned long base, unsigned long size,
				mtrr_usage_table[replace] = 0;
				mtrr_usage_table[replace] = 0;
			}
			}
		}
		}
	} else
	} else {
		printk(KERN_INFO "mtrr: no more MTRRs available\n");
		pr_info("mtrr: no more MTRRs available\n");
	}
	error = i;
	error = i;
 out:
 out:
	mutex_unlock(&mtrr_mutex);
	mutex_unlock(&mtrr_mutex);
@@ -405,10 +428,8 @@ int mtrr_add_page(unsigned long base, unsigned long size,
static int mtrr_check(unsigned long base, unsigned long size)
static int mtrr_check(unsigned long base, unsigned long size)
{
{
	if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
	if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
		printk(KERN_WARNING
		pr_warning("mtrr: size and base must be multiples of 4 kiB\n");
			"mtrr: size and base must be multiples of 4 kiB\n");
		pr_debug("mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
		printk(KERN_DEBUG
			"mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
		dump_stack();
		dump_stack();
		return -1;
		return -1;
	}
	}
@@ -450,9 +471,7 @@ static int mtrr_check(unsigned long base, unsigned long size)
 * BUGS: Needs a quiet flag for the cases where drivers do not mind
 * BUGS: Needs a quiet flag for the cases where drivers do not mind
 * failures and do not wish system log messages to be sent.
 * failures and do not wish system log messages to be sent.
 */
 */

int mtrr_add(unsigned long base, unsigned long size, unsigned int type,
int
mtrr_add(unsigned long base, unsigned long size, unsigned int type,
	     bool increment)
	     bool increment)
{
{
	if (mtrr_check(base, size))
	if (mtrr_check(base, size))
@@ -460,6 +479,7 @@ mtrr_add(unsigned long base, unsigned long size, unsigned int type,
	return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
	return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
			     increment);
			     increment);
}
}
EXPORT_SYMBOL(mtrr_add);


/**
/**
 * mtrr_del_page - delete a memory type region
 * mtrr_del_page - delete a memory type region
@@ -475,7 +495,6 @@ mtrr_add(unsigned long base, unsigned long size, unsigned int type,
 * On success the register is returned, on failure a negative error
 * On success the register is returned, on failure a negative error
 * code.
 * code.
 */
 */

int mtrr_del_page(int reg, unsigned long base, unsigned long size)
int mtrr_del_page(int reg, unsigned long base, unsigned long size)
{
{
	int i, max;
	int i, max;
@@ -500,22 +519,22 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
			}
			}
		}
		}
		if (reg < 0) {
		if (reg < 0) {
			printk(KERN_DEBUG "mtrr: no MTRR for %lx000,%lx000 found\n", base,
			pr_debug("mtrr: no MTRR for %lx000,%lx000 found\n",
			       size);
				 base, size);
			goto out;
			goto out;
		}
		}
	}
	}
	if (reg >= max) {
	if (reg >= max) {
		printk(KERN_WARNING "mtrr: register: %d too big\n", reg);
		pr_warning("mtrr: register: %d too big\n", reg);
		goto out;
		goto out;
	}
	}
	mtrr_if->get(reg, &lbase, &lsize, &ltype);
	mtrr_if->get(reg, &lbase, &lsize, &ltype);
	if (lsize < 1) {
	if (lsize < 1) {
		printk(KERN_WARNING "mtrr: MTRR %d not used\n", reg);
		pr_warning("mtrr: MTRR %d not used\n", reg);
		goto out;
		goto out;
	}
	}
	if (mtrr_usage_table[reg] < 1) {
	if (mtrr_usage_table[reg] < 1) {
		printk(KERN_WARNING "mtrr: reg: %d has count=0\n", reg);
		pr_warning("mtrr: reg: %d has count=0\n", reg);
		goto out;
		goto out;
	}
	}
	if (--mtrr_usage_table[reg] < 1)
	if (--mtrr_usage_table[reg] < 1)
@@ -526,6 +545,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
	put_online_cpus();
	put_online_cpus();
	return error;
	return error;
}
}

/**
/**
 * mtrr_del - delete a memory type region
 * mtrr_del - delete a memory type region
 * @reg: Register returned by mtrr_add
 * @reg: Register returned by mtrr_add
@@ -540,19 +560,16 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
 * On success the register is returned, on failure a negative error
 * On success the register is returned, on failure a negative error
 * code.
 * code.
 */
 */

int mtrr_del(int reg, unsigned long base, unsigned long size)
int
mtrr_del(int reg, unsigned long base, unsigned long size)
{
{
	if (mtrr_check(base, size))
	if (mtrr_check(base, size))
		return -EINVAL;
		return -EINVAL;
	return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
	return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
}
}

EXPORT_SYMBOL(mtrr_add);
EXPORT_SYMBOL(mtrr_del);
EXPORT_SYMBOL(mtrr_del);


/* HACK ALERT!
/*
 * HACK ALERT!
 * These should be called implicitly, but we can't yet until all the initcall
 * These should be called implicitly, but we can't yet until all the initcall
 * stuff is done...
 * stuff is done...
 */
 */
@@ -581,8 +598,7 @@ static int mtrr_save(struct sys_device * sysdev, pm_message_t state)
	int i;
	int i;


	for (i = 0; i < num_var_ranges; i++) {
	for (i = 0; i < num_var_ranges; i++) {
		mtrr_if->get(i,
		mtrr_if->get(i, &mtrr_value[i].lbase,
			     &mtrr_value[i].lbase,
				&mtrr_value[i].lsize,
				&mtrr_value[i].lsize,
				&mtrr_value[i].ltype);
				&mtrr_value[i].ltype);
	}
	}
@@ -594,12 +610,12 @@ static int mtrr_restore(struct sys_device * sysdev)
	int i;
	int i;


	for (i = 0; i < num_var_ranges; i++) {
	for (i = 0; i < num_var_ranges; i++) {
		if (mtrr_value[i].lsize)
		if (mtrr_value[i].lsize) {
			set_mtrr(i,
			set_mtrr(i, mtrr_value[i].lbase,
				 mtrr_value[i].lbase,
				    mtrr_value[i].lsize,
				    mtrr_value[i].lsize,
				    mtrr_value[i].ltype);
				    mtrr_value[i].ltype);
		}
		}
	}
	return 0;
	return 0;
}
}


@@ -622,6 +638,7 @@ int __initdata changed_by_mtrr_cleanup;
void __init mtrr_bp_init(void)
void __init mtrr_bp_init(void)
{
{
	u32 phys_addr;
	u32 phys_addr;

	init_ifs();
	init_ifs();


	phys_addr = 32;
	phys_addr = 32;
@@ -632,9 +649,11 @@ void __init mtrr_bp_init(void)
		size_and_mask = 0x00f00000;
		size_and_mask = 0x00f00000;
		phys_addr = 36;
		phys_addr = 36;


		/* This is an AMD specific MSR, but we assume(hope?) that
		/*
		   Intel will implement it to when they extend the address
		 * This is an AMD specific MSR, but we assume(hope?) that
		   bus of the Xeon. */
		 * Intel will implement it to when they extend the address
		 * bus of the Xeon.
		 */
		if (cpuid_eax(0x80000000) >= 0x80000008) {
		if (cpuid_eax(0x80000000) >= 0x80000008) {
			phys_addr = cpuid_eax(0x80000008) & 0xff;
			phys_addr = cpuid_eax(0x80000008) & 0xff;
			/* CPUID workaround for Intel 0F33/0F34 CPU */
			/* CPUID workaround for Intel 0F33/0F34 CPU */
@@ -649,8 +668,10 @@ void __init mtrr_bp_init(void)
			size_and_mask = ~size_or_mask & 0xfffff00000ULL;
			size_and_mask = ~size_or_mask & 0xfffff00000ULL;
		} else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR &&
		} else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR &&
			   boot_cpu_data.x86 == 6) {
			   boot_cpu_data.x86 == 6) {
			/* VIA C* family have Intel style MTRRs, but
			/*
			   don't support PAE */
			 * VIA C* family have Intel style MTRRs,
			 * but don't support PAE
			 */
			size_or_mask = 0xfff00000;		/* 32 bits */
			size_or_mask = 0xfff00000;		/* 32 bits */
			size_and_mask = 0;
			size_and_mask = 0;
			phys_addr = 32;
			phys_addr = 32;
@@ -694,7 +715,6 @@ void __init mtrr_bp_init(void)
				changed_by_mtrr_cleanup = 1;
				changed_by_mtrr_cleanup = 1;
				mtrr_if->set_all();
				mtrr_if->set_all();
			}
			}

		}
		}
	}
	}
}
}
@@ -706,12 +726,17 @@ void mtrr_ap_init(void)
	if (!mtrr_if || !use_intel())
	if (!mtrr_if || !use_intel())
		return;
		return;
	/*
	/*
	 * Ideally we should hold mtrr_mutex here to avoid mtrr entries changed,
	 * Ideally we should hold mtrr_mutex here to avoid mtrr entries
	 * but this routine will be called in cpu boot time, holding the lock
	 * changed, but this routine will be called in cpu boot time,
	 * breaks it. This routine is called in two cases: 1.very earily time
	 * holding the lock breaks it.
	 * of software resume, when there absolutely isn't mtrr entry changes;
	 *
	 * 2.cpu hotadd time. We let mtrr_add/del_page hold cpuhotplug lock to
	 * This routine is called in two cases:
	 * prevent mtrr entry changes
	 *
	 *   1. very earily time of software resume, when there absolutely
	 *      isn't mtrr entry changes;
	 *
	 *   2. cpu hotadd time. We let mtrr_add/del_page hold cpuhotplug
	 *      lock to prevent mtrr entry changes
	 */
	 */
	local_irq_save(flags);
	local_irq_save(flags);


@@ -732,19 +757,23 @@ static int __init mtrr_init_finialize(void)
{
{
	if (!mtrr_if)
	if (!mtrr_if)
		return 0;
		return 0;

	if (use_intel()) {
	if (use_intel()) {
		if (!changed_by_mtrr_cleanup)
		if (!changed_by_mtrr_cleanup)
			mtrr_state_warn();
			mtrr_state_warn();
	} else {
		return 0;
		/* The CPUs haven't MTRR and seem to not support SMP. They have
	}

	/*
	 * The CPU has no MTRR and seems to not support SMP. They have
	 * specific drivers, we use a tricky method to support
	 * specific drivers, we use a tricky method to support
	 * suspend/resume for them.
	 * suspend/resume for them.
	 *
	 * TBD: is there any system with such CPU which supports
	 * TBD: is there any system with such CPU which supports
		 * suspend/resume?  if no, we should remove the code.
	 * suspend/resume? If no, we should remove the code.
	 */
	 */
		sysdev_driver_register(&cpu_sysdev_class,
	sysdev_driver_register(&cpu_sysdev_class, &mtrr_sysdev_driver);
			&mtrr_sysdev_driver);

	}
	return 0;
	return 0;
}
}
subsys_initcall(mtrr_init_finialize);
subsys_initcall(mtrr_init_finialize);