mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 08:44:21 +08:00
x86, mtrr: Use explicit sizing and padding for the 64-bit ioctls
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>
This commit is contained in:
parent
8bd69c2d5f
commit
b263b31e8a
@ -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 */
|
||||
@ -50,12 +50,20 @@ struct mtrr_gentry {
|
||||
|
||||
#else /* __i386__ */
|
||||
|
||||
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 */
|
||||
struct mtrr_sentry {
|
||||
__u64 base; /* Base address */
|
||||
__u32 size; /* Size of region */
|
||||
__u32 type; /* Type of region */
|
||||
};
|
||||
|
||||
struct mtrr_gentry {
|
||||
__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 {
|
||||
|
@ -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;
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user