diff options
-rw-r--r-- | arch/x86/include/asm/mtrr.h | 28 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mtrr/if.c | 10 |
2 files changed, 24 insertions, 14 deletions
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h index 4365ffdb461f..7e3f17f92c66 100644 --- a/arch/x86/include/asm/mtrr.h +++ b/arch/x86/include/asm/mtrr.h | |||
@@ -29,18 +29,18 @@ | |||
29 | 29 | ||
30 | #define MTRR_IOCTL_BASE 'M' | 30 | #define MTRR_IOCTL_BASE 'M' |
31 | 31 | ||
32 | struct mtrr_sentry { | ||
33 | unsigned long base; /* Base address */ | ||
34 | unsigned int size; /* Size of region */ | ||
35 | unsigned int type; /* Type of region */ | ||
36 | }; | ||
37 | |||
38 | /* Warning: this structure has a different order from i386 | 32 | /* Warning: this structure has a different order from i386 |
39 | on x86-64. The 32bit emulation code takes care of that. | 33 | on x86-64. The 32bit emulation code takes care of that. |
40 | But you need to use this for 64bit, otherwise your X server | 34 | But you need to use this for 64bit, otherwise your X server |
41 | will break. */ | 35 | will break. */ |
42 | 36 | ||
43 | #ifdef __i386__ | 37 | #ifdef __i386__ |
38 | struct mtrr_sentry { | ||
39 | unsigned long base; /* Base address */ | ||
40 | unsigned int size; /* Size of region */ | ||
41 | unsigned int type; /* Type of region */ | ||
42 | }; | ||
43 | |||
44 | struct mtrr_gentry { | 44 | struct mtrr_gentry { |
45 | unsigned int regnum; /* Register number */ | 45 | unsigned int regnum; /* Register number */ |
46 | unsigned long base; /* Base address */ | 46 | unsigned long base; /* Base address */ |
@@ -50,12 +50,20 @@ struct mtrr_gentry { | |||
50 | 50 | ||
51 | #else /* __i386__ */ | 51 | #else /* __i386__ */ |
52 | 52 | ||
53 | struct mtrr_sentry { | ||
54 | __u64 base; /* Base address */ | ||
55 | __u32 size; /* Size of region */ | ||
56 | __u32 type; /* Type of region */ | ||
57 | }; | ||
58 | |||
53 | struct mtrr_gentry { | 59 | struct mtrr_gentry { |
54 | unsigned long base; /* Base address */ | 60 | __u64 base; /* Base address */ |
55 | unsigned int size; /* Size of region */ | 61 | __u32 size; /* Size of region */ |
56 | unsigned int regnum; /* Register number */ | 62 | __u32 regnum; /* Register number */ |
57 | unsigned int type; /* Type of region */ | 63 | __u32 type; /* Type of region */ |
64 | __u32 _pad; /* Unused */ | ||
58 | }; | 65 | }; |
66 | |||
59 | #endif /* !__i386__ */ | 67 | #endif /* !__i386__ */ |
60 | 68 | ||
61 | struct mtrr_var_range { | 69 | struct mtrr_var_range { |
diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c index 79289632cb27..a041e094b8b9 100644 --- a/arch/x86/kernel/cpu/mtrr/if.c +++ b/arch/x86/kernel/cpu/mtrr/if.c | |||
@@ -167,6 +167,7 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) | |||
167 | { | 167 | { |
168 | int err = 0; | 168 | int err = 0; |
169 | mtrr_type type; | 169 | mtrr_type type; |
170 | unsigned long base; | ||
170 | unsigned long size; | 171 | unsigned long size; |
171 | struct mtrr_sentry sentry; | 172 | struct mtrr_sentry sentry; |
172 | struct mtrr_gentry gentry; | 173 | struct mtrr_gentry gentry; |
@@ -267,14 +268,14 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) | |||
267 | #endif | 268 | #endif |
268 | if (gentry.regnum >= num_var_ranges) | 269 | if (gentry.regnum >= num_var_ranges) |
269 | return -EINVAL; | 270 | return -EINVAL; |
270 | mtrr_if->get(gentry.regnum, &gentry.base, &size, &type); | 271 | mtrr_if->get(gentry.regnum, &base, &size, &type); |
271 | 272 | ||
272 | /* Hide entries that go above 4GB */ | 273 | /* Hide entries that go above 4GB */ |
273 | if (gentry.base + size - 1 >= (1UL << (8 * sizeof(gentry.size) - PAGE_SHIFT)) | 274 | if (base + size - 1 >= (1UL << (8 * sizeof(gentry.size) - PAGE_SHIFT)) |
274 | || size >= (1UL << (8 * sizeof(gentry.size) - PAGE_SHIFT))) | 275 | || size >= (1UL << (8 * sizeof(gentry.size) - PAGE_SHIFT))) |
275 | gentry.base = gentry.size = gentry.type = 0; | 276 | gentry.base = gentry.size = gentry.type = 0; |
276 | else { | 277 | else { |
277 | gentry.base <<= PAGE_SHIFT; | 278 | gentry.base = base << PAGE_SHIFT; |
278 | gentry.size = size << PAGE_SHIFT; | 279 | gentry.size = size << PAGE_SHIFT; |
279 | gentry.type = type; | 280 | gentry.type = type; |
280 | } | 281 | } |
@@ -321,11 +322,12 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) | |||
321 | #endif | 322 | #endif |
322 | if (gentry.regnum >= num_var_ranges) | 323 | if (gentry.regnum >= num_var_ranges) |
323 | return -EINVAL; | 324 | return -EINVAL; |
324 | mtrr_if->get(gentry.regnum, &gentry.base, &size, &type); | 325 | mtrr_if->get(gentry.regnum, &base, &size, &type); |
325 | /* Hide entries that would overflow */ | 326 | /* Hide entries that would overflow */ |
326 | if (size != (__typeof__(gentry.size))size) | 327 | if (size != (__typeof__(gentry.size))size) |
327 | gentry.base = gentry.size = gentry.type = 0; | 328 | gentry.base = gentry.size = gentry.type = 0; |
328 | else { | 329 | else { |
330 | gentry.base = base; | ||
329 | gentry.size = size; | 331 | gentry.size = size; |
330 | gentry.type = type; | 332 | gentry.type = type; |
331 | } | 333 | } |