bitkeeper revision 1.1159.199.1 (41ab4412dnDymGEqZNhEzt67Yzgmxw)

MTRR support for privileged kernels. Should help our X-server support.
This commit is contained in:
kaf24@scramble.cl.cam.ac.uk committed 2004-11-29 15:45:22 +00:00
1 parent b582b9903a
commit 3ef3ee4b43
9 files changed
+282 -2

No files matched your search

+2
View File
@@ -138,6 +138,8 @@
40f56238eczveJ86k_4hNxCLRQIF-g linux-2.6.9-xen-sparse/arch/xen/i386/kernel/Makefile
40f56238rXVTJQKbBuXXLH52qEArcg linux-2.6.9-xen-sparse/arch/xen/i386/kernel/cpu/Makefile
40f562385s4lr6Zg92gExe7UQ4A76Q linux-2.6.9-xen-sparse/arch/xen/i386/kernel/cpu/common.c
41ab440bnpxZdWShZrGgM9pPaz5rmA linux-2.6.9-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/Makefile
41ab440bBKWz-aEOEojU4PAMXe3Ppg linux-2.6.9-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/main.c
40f56238XDtHSijkAFlbv1PT8Bhw_Q linux-2.6.9-xen-sparse/arch/xen/i386/kernel/entry.S
40f56238bnvciAuyzAiMkdzGErYt1A linux-2.6.9-xen-sparse/arch/xen/i386/kernel/head.S
40f58a0d31M2EkuPbG94ns_nOi0PVA linux-2.6.9-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c
@@ -110,6 +110,7 @@ CONFIG_X86_CPUID=y
# CONFIG_EDD is not set
CONFIG_NOHIGHMEM=y
# CONFIG_HIGHMEM4G is not set
CONFIG_MTRR=y
CONFIG_HAVE_DEC_LOCK=y
# CONFIG_REGPARM is not set
@@ -564,6 +564,11 @@ config HAVE_ARCH_BOOTMEM_NODE
# low memory. Setting this option will put user-space page table
# entries in high memory.
config MTRR
bool
depends on XEN_PRIVILEGED_GUEST
default y
#config MTRR
# bool "MTRR (Memory Type Range Register) support"
# ---help---
@@ -18,7 +18,7 @@ c-obj-y += umc.o
#obj-$(CONFIG_X86_MCE) += ../../../../i386/kernel/cpu/mcheck/
#obj-$(CONFIG_MTRR) += ../../../../i386/kernel/cpu/mtrr/
obj-$(CONFIG_MTRR) += mtrr/
#obj-$(CONFIG_CPU_FREQ) += ../../../../i386/kernel/cpu/cpufreq/
c-link :=
@@ -0,0 +1,16 @@
obj-y := main.o
c-obj-y := if.o
c-link :=
$(patsubst %.o,$(obj)/%.c,$(c-obj-y) $(c-link)): $(obj)/mtrr.h
@ln -fsn $(srctree)/arch/i386/kernel/cpu/mtrr/$(notdir $@) $@
$(patsubst %.o,$(obj)/%.c,$(obj-y)): $(obj)/mtrr.h
$(obj)/mtrr.h:
@ln -fsn $(srctree)/arch/i386/kernel/cpu/mtrr/mtrr.h $@
obj-y += $(c-obj-y)
clean-files += $(patsubst %.o,%.c,$(c-obj-y) $(c-obj-) $(c-link))
@@ -0,0 +1,165 @@
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/ctype.h>
#include <linux/module.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h>
#include <asm/mtrr.h>
#include "mtrr.h"
void generic_get_mtrr(unsigned int reg, unsigned long *base,
unsigned int *size, mtrr_type * type)
{
dom0_op_t op;
op.cmd = DOM0_READ_MEMTYPE;
op.u.read_memtype.reg = reg;
(void)HYPERVISOR_dom0_op(&op);
*size = op.u.read_memtype.nr_pfns;
*base = op.u.read_memtype.pfn;
*type = op.u.read_memtype.type;
}
struct mtrr_ops generic_mtrr_ops = {
.use_intel_if = 1,
.get = generic_get_mtrr,
};
struct mtrr_ops *mtrr_if = &generic_mtrr_ops;
unsigned int num_var_ranges;
unsigned int *usage_table;
void __init set_num_var_ranges(void)
{
dom0_op_t op;
for (num_var_ranges = 0; ; num_var_ranges++) {
op.cmd = DOM0_READ_MEMTYPE;
op.u.read_memtype.reg = num_var_ranges;
if (HYPERVISOR_dom0_op(&op) != 0)
break;
}
}
static void __init init_table(void)
{
int i, max;
max = num_var_ranges;
if ((usage_table = kmalloc(max * sizeof *usage_table, GFP_KERNEL))
== NULL) {
printk(KERN_ERR "mtrr: could not allocate\n");
return;
}
for (i = 0; i < max; i++)
usage_table[i] = 0;
}
int mtrr_add_page(unsigned long base, unsigned long size,
unsigned int type, char increment)
{
int error;
dom0_op_t op;
op.cmd = DOM0_ADD_MEMTYPE;
op.u.add_memtype.pfn = base;
op.u.add_memtype.nr_pfns = size;
op.u.add_memtype.type = type;
if ((error = HYPERVISOR_dom0_op(&op)))
return error;
if (increment)
++usage_table[op.u.add_memtype.reg];
return op.u.add_memtype.reg;
}
int
mtrr_add(unsigned long base, unsigned long size, unsigned int type,
char increment)
{
if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
printk(KERN_WARNING "mtrr: size and base must be multiples of 4 kiB\n");
printk(KERN_DEBUG "mtrr: size: 0x%lx base: 0x%lx\n", size, base);
return -EINVAL;
}
return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
increment);
}
int mtrr_del_page(int reg, unsigned long base, unsigned long size)
{
int i, max;
mtrr_type ltype;
unsigned long lbase;
unsigned int lsize;
int error = -EINVAL;
dom0_op_t op;
max = num_var_ranges;
if (reg < 0) {
/* Search for existing MTRR */
for (i = 0; i < max; ++i) {
mtrr_if->get(i, &lbase, &lsize, &ltype);
if (lbase == base && lsize == size) {
reg = i;
break;
}
}
if (reg < 0) {
printk(KERN_DEBUG "mtrr: no MTRR for %lx000,%lx000 found\n", base,
size);
goto out;
}
}
if (usage_table[reg] < 1) {
printk(KERN_WARNING "mtrr: reg: %d has count=0\n", reg);
goto out;
}
if (--usage_table[reg] < 1) {
op.cmd = DOM0_DEL_MEMTYPE;
op.u.del_memtype.handle = 0;
op.u.add_memtype.reg = reg;
(void)HYPERVISOR_dom0_op(&op);
}
error = reg;
out:
return error;
}
int
mtrr_del(int reg, unsigned long base, unsigned long size)
{
if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
printk(KERN_INFO "mtrr: size and base must be multiples of 4 kiB\n");
printk(KERN_DEBUG "mtrr: size: 0x%lx base: 0x%lx\n", size, base);
return -EINVAL;
}
return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
}
EXPORT_SYMBOL(mtrr_add);
EXPORT_SYMBOL(mtrr_del);
static int __init mtrr_init(void)
{
struct cpuinfo_x86 *c = &boot_cpu_data;
if (!(xen_start_info.flags & SIF_PRIVILEGED))
return -ENODEV;
if ((!cpu_has(c, X86_FEATURE_MTRR)) &&
(!cpu_has(c, X86_FEATURE_K6_MTRR)) &&
(!cpu_has(c, X86_FEATURE_CYRIX_ARR)) &&
(!cpu_has(c, X86_FEATURE_CENTAUR_MCR)))
return -ENODEV;
set_num_var_ranges();
init_table();
return 0;
}
subsys_initcall(mtrr_init);
@@ -28,8 +28,9 @@ void __init machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c)
clear_bit(X86_FEATURE_DE, c->x86_capability);
clear_bit(X86_FEATURE_PSE, c->x86_capability);
clear_bit(X86_FEATURE_PGE, c->x86_capability);
clear_bit(X86_FEATURE_MTRR, c->x86_capability);
clear_bit(X86_FEATURE_FXSR, c->x86_capability);
if (!(xen_start_info.flags & SIF_PRIVILEGED))
clear_bit(X86_FEATURE_MTRR, c->x86_capability);
}
extern void hypervisor_callback(void);
+37
View File
@@ -21,6 +21,9 @@
#include <asm/shadow.h>
#include <public/sched_ctl.h>
#include <asm/mtrr.h>
#include "mtrr/mtrr.h"
#define TRC_DOM0OP_ENTER_BASE 0x00020000
#define TRC_DOM0OP_LEAVE_BASE 0x00030000
@@ -93,6 +96,40 @@ long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op)
}
break;
case DOM0_ADD_MEMTYPE:
{
ret = mtrr_add_page(
op->u.add_memtype.pfn,
op->u.add_memtype.nr_pfns,
op->u.add_memtype.type,
1);
}
break;
case DOM0_DEL_MEMTYPE:
{
ret = mtrr_del_page(op->u.del_memtype.reg, 0, 0);
}
break;
case DOM0_READ_MEMTYPE:
{
unsigned long pfn;
unsigned int nr_pfns;
mtrr_type type;
ret = -EINVAL;
if ( op->u.read_memtype.reg < num_var_ranges )
{
mtrr_if->get(op->u.read_memtype.reg, &pfn, &nr_pfns, &type);
(void)__put_user(pfn, &u_dom0_op->u.read_memtype.pfn);
(void)__put_user(nr_pfns, &u_dom0_op->u.read_memtype.nr_pfns);
(void)__put_user(type, &u_dom0_op->u.read_memtype.type);
ret = 0;
}
}
break;
default:
ret = -ENOSYS;
+53
View File
@@ -336,6 +336,56 @@ typedef struct {
u32 type; /* 8: vm_assist cmd */
} PACKED dom0_setdomainvmassist_t; /* 12 bytes */
/*
* Request memory range (@pfn, @pfn+@nr_pfns-1) to have type @type.
* On x86, @type is an architecture-defined MTRR memory type.
* On success, returns the MTRR that was used (@reg) and a handle that can
* be passed to DOM0_DEL_MEMTYPE to accurately tear down the new setting.
* (x86-specific).
*/
#define DOM0_ADD_MEMTYPE 31
typedef struct {
/* IN variables. */
memory_t pfn; /* 0 */
MEMORY_PADDING;
memory_t nr_pfns; /* 8 */
MEMORY_PADDING;
u32 type; /* 16 */
u32 __pad0;
/* OUT variables. */
u32 handle; /* 24 */
u32 reg; /* 28 */
} PACKED dom0_add_memtype_t; /* 32 bytes */
/*
* Tear down an existing memory-range type. If @handle is remembered then it
* should be passed in to accurately tear down the correct setting (in case
* of overlapping memory regions with differing types). If it is not known
* then @handle should be set to zero. In all cases @reg must be set.
* (x86-specific).
*/
#define DOM0_DEL_MEMTYPE 32
typedef struct {
/* IN variables. */
u32 handle; /* 0 */
u32 reg; /* 4 */
} PACKED dom0_del_memtype_t; /* 8 bytes */
/* Read current type of an MTRR (x86-specific). */
#define DOM0_READ_MEMTYPE 33
typedef struct {
/* IN variables. */
u32 reg; /* 0 */
u32 __pad0;
/* OUT variables. */
memory_t pfn; /* 8 */
MEMORY_PADDING;
memory_t nr_pfns; /* 16 */
MEMORY_PADDING;
u32 type; /* 24 */
u32 __pad1;
} PACKED dom0_read_memtype_t; /* 32 bytes */
typedef struct {
u32 cmd; /* 0 */
u32 interface_version; /* 4 */ /* DOM0_INTERFACE_VERSION */
@@ -366,6 +416,9 @@ typedef struct {
dom0_setdomainmaxmem_t setdomainmaxmem;
dom0_getpageframeinfo2_t getpageframeinfo2;
dom0_setdomainvmassist_t setdomainvmassist;
dom0_add_memtype_t add_memtype;
dom0_del_memtype_t del_memtype;
dom0_read_memtype_t read_memtype;
} PACKED u;
} PACKED dom0_op_t; /* 80 bytes */
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.