1 #include <linux/capability.h>
5 #include <linux/module.h>
6 #include <linux/ctype.h>
7 #include <linux/string.h>
8 #include <linux/slab.h>
17 #define FILE_FCOUNT(f) (((struct seq_file *)((f)->private_data))->private)
32 return (x <= 6) ? mtrr_strings[
x] :
"?";
38 mtrr_file_add(
unsigned long base,
unsigned long size,
46 fcount = kzalloc(max *
sizeof *fcount,
GFP_KERNEL);
64 mtrr_file_del(
unsigned long base,
unsigned long size,
65 struct file *file,
int page)
94 mtrr_write(
struct file *file,
const char __user *
buf,
size_t len, loff_t * ppos)
98 unsigned long long base,
size;
122 ptr = line + linelen - 1;
123 if (linelen && *ptr ==
'\n')
126 if (!
strncmp(line,
"disable=", 8)) {
144 if ((base & 0xfff) || (size & 0xfff))
153 if (
strcmp(ptr, mtrr_strings[i]))
157 err =
mtrr_add_page((
unsigned long)base, (
unsigned long)size, i,
true);
166 mtrr_ioctl(
struct file *file,
unsigned int cmd,
unsigned long __arg)
194 case MTRRIOC32_ADD_ENTRY:
195 case MTRRIOC32_SET_ENTRY:
196 case MTRRIOC32_DEL_ENTRY:
197 case MTRRIOC32_KILL_ENTRY:
198 case MTRRIOC32_ADD_PAGE_ENTRY:
199 case MTRRIOC32_SET_PAGE_ENTRY:
200 case MTRRIOC32_DEL_PAGE_ENTRY:
201 case MTRRIOC32_KILL_PAGE_ENTRY: {
204 s32 = (
struct mtrr_sentry32
__user *)__arg;
205 err =
get_user(sentry.base, &s32->base);
206 err |=
get_user(sentry.size, &s32->size);
207 err |=
get_user(sentry.type, &s32->type);
212 case MTRRIOC32_GET_ENTRY:
213 case MTRRIOC32_GET_PAGE_ENTRY: {
214 struct mtrr_gentry32
__user *g32;
216 g32 = (
struct mtrr_gentry32
__user *)__arg;
217 err =
get_user(gentry.regnum, &g32->regnum);
218 err |=
get_user(gentry.base, &g32->base);
219 err |=
get_user(gentry.size, &g32->size);
220 err |=
get_user(gentry.type, &g32->type);
233 case MTRRIOC32_ADD_ENTRY:
238 mtrr_file_add(sentry.base, sentry.size, sentry.type,
true,
243 case MTRRIOC32_SET_ENTRY:
247 err =
mtrr_add(sentry.base, sentry.size, sentry.type,
false);
251 case MTRRIOC32_DEL_ENTRY:
255 err = mtrr_file_del(sentry.base, sentry.size, file, 0);
259 case MTRRIOC32_KILL_ENTRY:
263 err =
mtrr_del(-1, sentry.base, sentry.size);
267 case MTRRIOC32_GET_ENTRY:
271 mtrr_if->get(gentry.regnum, &base, &size, &type);
274 if (base + size - 1 >= (1
UL << (8 *
sizeof(gentry.size) -
PAGE_SHIFT))
275 || size >= (1
UL << (8 *
sizeof(gentry.size) -
PAGE_SHIFT)))
276 gentry.base = gentry.size = gentry.type = 0;
286 case MTRRIOC32_ADD_PAGE_ENTRY:
291 mtrr_file_add(sentry.base, sentry.size, sentry.type,
true,
296 case MTRRIOC32_SET_PAGE_ENTRY:
305 case MTRRIOC32_DEL_PAGE_ENTRY:
309 err = mtrr_file_del(sentry.base, sentry.size, file, 1);
313 case MTRRIOC32_KILL_PAGE_ENTRY:
321 case MTRRIOC32_GET_PAGE_ENTRY:
325 mtrr_if->get(gentry.regnum, &base, &size, &type);
327 if (size != (__typeof__(gentry.size))size)
328 gentry.base = gentry.size = gentry.type = 0;
347 case MTRRIOC32_GET_ENTRY:
348 case MTRRIOC32_GET_PAGE_ENTRY: {
349 struct mtrr_gentry32
__user *g32;
351 g32 = (
struct mtrr_gentry32
__user *)__arg;
352 err =
put_user(gentry.base, &g32->base);
353 err |=
put_user(gentry.size, &g32->size);
354 err |=
put_user(gentry.regnum, &g32->regnum);
355 err |=
put_user(gentry.type, &g32->type);
363 static int mtrr_close(
struct inode *
ino,
struct file *file)
368 if (fcount !=
NULL) {
370 for (i = 0; i <
max; ++
i) {
371 while (fcount[i] > 0) {
384 static int mtrr_open(
struct inode *
inode,
struct file *file)
399 .unlocked_ioctl = mtrr_ioctl,
400 .compat_ioctl = mtrr_ioctl,
401 .release = mtrr_close,
409 unsigned long base,
size;
413 for (i = 0; i <
max; i++) {
414 mtrr_if->get(i, &base, &size, &type);
428 len +=
seq_printf(seq,
"reg%02i: base=0x%06lx000 "
429 "(%5luMB), size=%5lu%cB, count=%d: %s\n",
437 static int __init mtrr_if_init(
void)