Skip to content

Commit

Permalink
x86, mtrr: Use explicit sizing and padding for the 64-bit ioctls
Browse files Browse the repository at this point in the history
Specify the data structures for the 64-bit ioctls with explicit sizing
and padding so that the x32 kernel will correctly use the 64-bit forms
of these ioctls.  Note that these ioctls are bogus in both forms on
both 32 and 64 bits; even on 64 bits the maximum MTRR size is only 44
bits long.

Note that nothing really is supposed to use these ioctls and that the
preferred interface is text strings on /proc/mtrr, or better yet,
nothing at all (use /sys/bus/pci/devices/*/resource*_wc for write
combining; that uses PAT not MTRRs.)

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Cc: H. J. Lu <hjl.tools@gmail.com>
Tested-by: Nitin A. Kamble <nitin.a.kamble@intel.com>
Link: http://lkml.kernel.org/n/tip-vwvnlu3hjmtkwvij4qxtm90l@git.kernel.org
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
  • Loading branch information
H. Peter Anvin authored and H. Peter Anvin committed Mar 1, 2012
1 parent 8bd69c2 commit b263b31
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 14 deletions.
28 changes: 18 additions & 10 deletions arch/x86/include/asm/mtrr.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,18 @@

#define MTRR_IOCTL_BASE 'M'

struct mtrr_sentry {
unsigned long base; /* Base address */
unsigned int size; /* Size of region */
unsigned int type; /* Type of region */
};

/* Warning: this structure has a different order from i386
on x86-64. The 32bit emulation code takes care of that.
But you need to use this for 64bit, otherwise your X server
will break. */

#ifdef __i386__
struct mtrr_sentry {
unsigned long base; /* Base address */
unsigned int size; /* Size of region */
unsigned int type; /* Type of region */
};

struct mtrr_gentry {
unsigned int regnum; /* Register number */
unsigned long base; /* Base address */
Expand All @@ -50,12 +50,20 @@ struct mtrr_gentry {

#else /* __i386__ */

struct mtrr_sentry {
__u64 base; /* Base address */
__u32 size; /* Size of region */
__u32 type; /* Type of region */
};

struct mtrr_gentry {
unsigned long base; /* Base address */
unsigned int size; /* Size of region */
unsigned int regnum; /* Register number */
unsigned int type; /* Type of region */
__u64 base; /* Base address */
__u32 size; /* Size of region */
__u32 regnum; /* Register number */
__u32 type; /* Type of region */
__u32 _pad; /* Unused */
};

#endif /* !__i386__ */

struct mtrr_var_range {
Expand Down
10 changes: 6 additions & 4 deletions arch/x86/kernel/cpu/mtrr/if.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
{
int err = 0;
mtrr_type type;
unsigned long base;
unsigned long size;
struct mtrr_sentry sentry;
struct mtrr_gentry gentry;
Expand Down Expand Up @@ -267,14 +268,14 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
#endif
if (gentry.regnum >= num_var_ranges)
return -EINVAL;
mtrr_if->get(gentry.regnum, &gentry.base, &size, &type);
mtrr_if->get(gentry.regnum, &base, &size, &type);

/* Hide entries that go above 4GB */
if (gentry.base + size - 1 >= (1UL << (8 * sizeof(gentry.size) - PAGE_SHIFT))
if (base + size - 1 >= (1UL << (8 * sizeof(gentry.size) - PAGE_SHIFT))
|| size >= (1UL << (8 * sizeof(gentry.size) - PAGE_SHIFT)))
gentry.base = gentry.size = gentry.type = 0;
else {
gentry.base <<= PAGE_SHIFT;
gentry.base = base << PAGE_SHIFT;
gentry.size = size << PAGE_SHIFT;
gentry.type = type;
}
Expand Down Expand Up @@ -321,11 +322,12 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
#endif
if (gentry.regnum >= num_var_ranges)
return -EINVAL;
mtrr_if->get(gentry.regnum, &gentry.base, &size, &type);
mtrr_if->get(gentry.regnum, &base, &size, &type);
/* Hide entries that would overflow */
if (size != (__typeof__(gentry.size))size)
gentry.base = gentry.size = gentry.type = 0;
else {
gentry.base = base;
gentry.size = size;
gentry.type = type;
}
Expand Down

0 comments on commit b263b31

Please sign in to comment.