[PATCH 1/6] Add new mtrr_add_unaligned function

From: Thomas Schlichter
Date: Wed Oct 14 2009 - 13:25:33 EST


This function creates multiple MTRR entries for unaligned memory regions.

Signed-off-by: Thomas Schlichter <thomas.schlichter@xxxxxx>
---
arch/x86/include/asm/mtrr.h | 8 ++++++++
arch/x86/kernel/cpu/mtrr/main.c | 30 ++++++++++++++++++++++++++++++
2 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
index 4365ffd..2e0d99d 100644
--- a/arch/x86/include/asm/mtrr.h
+++ b/arch/x86/include/asm/mtrr.h
@@ -116,6 +116,9 @@ extern int mtrr_add(unsigned long base, unsigned long size,
unsigned int type, bool increment);
extern int mtrr_add_page(unsigned long base, unsigned long size,
unsigned int type, bool increment);
+extern void mtrr_add_unaligned(unsigned long base, unsigned long size,
+ unsigned int type, bool increment,
+ int *mtrr_usage);
extern int mtrr_del(int reg, unsigned long base, unsigned long size);
extern int mtrr_del_page(int reg, unsigned long base, unsigned long size);
extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi);
@@ -146,6 +149,11 @@ static inline int mtrr_add_page(unsigned long base, unsigned long size,
{
return -ENODEV;
}
+static inline void mtrr_add_unaligned(unsigned long base, unsigned long size,
+ unsigned int type, bool increment,
+ int *mtrr_usage)
+{
+}
static inline int mtrr_del(int reg, unsigned long base, unsigned long size)
{
return -ENODEV;
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index 84e83de..5bf769b 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -487,6 +487,36 @@ int mtrr_add(unsigned long base, unsigned long size, unsigned int type,
}
EXPORT_SYMBOL(mtrr_add);

+void mtrr_add_unaligned(unsigned long base, unsigned long size,
+ unsigned int type, bool increment, int *mtrr_usage)
+{
+ int i;
+ unsigned long ptr1, ptr2, end = base + size;
+
+ // round down size to next power ot two
+ size = __rounddown_pow_of_two(size);
+
+ // accordingly align pointers
+ ptr1 = ptr2 = (base + size - 1) & ~(size - 1);
+
+ while (size >= PAGE_SIZE) {
+ if (ptr1 + size <= end) {
+ i = mtrr_add(ptr1, size, type, increment);
+ if (i >= 0 && increment && mtrr_usage)
+ ++mtrr_usage[i];
+ ptr1 += size;
+ }
+ if (base + size <= ptr2) {
+ ptr2 -= size;
+ i = mtrr_add(ptr2, size, type, increment);
+ if (i >= 0 && increment && mtrr_usage)
+ ++mtrr_usage[i];
+ }
+ size >>= 1;
+ }
+}
+EXPORT_SYMBOL(mtrr_add_unaligned);
+
/**
* mtrr_del_page - delete a memory type region
* @reg: Register returned by mtrr_add
--
1.6.5


--Boundary-00=_U+h2K2gddSw6RDO
Content-Type: text/x-patch;
charset="iso-8859-1";
name="0002-Make-num_var_ranges-accessible-outside-MTRR-code.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="0002-Make-num_var_ranges-accessible-outside-MTRR-code.patch"