Commit f1befe71 authored by Chris Wilson's avatar Chris Wilson Committed by Eric Anholt

agp/intel: Restrict GTT mapping to valid range on i915 and i945

References:

  Bug 15733 - Crash when accessing nonexistent GTT entries in i915
  https://bugzilla.kernel.org/show_bug.cgi?id=15733

On G33 and above, the size of the GTT space is determined by the GMCH
control register. Prior to this revision, the size is determined by the
size of the aperture. So we must careful to map and fill the appropriate
range depending on chipset.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent 9a7e8492
......@@ -1059,7 +1059,7 @@ static void intel_i9xx_setup_flush(void)
}
}
static int intel_i915_configure(void)
static int intel_i9xx_configure(void)
{
struct aper_size_info_fixed *current_size;
u32 temp;
......@@ -1207,6 +1207,38 @@ static int intel_i9xx_fetch_size(void)
return 0;
}
static int intel_i915_get_gtt_size(void)
{
int size;
if (IS_G33) {
u16 gmch_ctrl;
/* G33's GTT size defined in gmch_ctrl */
pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl);
switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {
case G33_PGETBL_SIZE_1M:
size = 1024;
break;
case G33_PGETBL_SIZE_2M:
size = 2048;
break;
default:
dev_info(&agp_bridge->dev->dev,
"unknown page table size 0x%x, assuming 512KB\n",
(gmch_ctrl & G33_PGETBL_SIZE_MASK));
size = 512;
}
} else {
/* On previous hardware, the GTT size was just what was
* required to map the aperture.
*/
size = agp_bridge->driver->fetch_size();
}
return KB(size);
}
/* The intel i915 automatically initializes the agp aperture during POST.
* Use the memory already set aside for in the GTT.
*/
......@@ -1216,7 +1248,7 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
struct aper_size_info_fixed *size;
int num_entries;
u32 temp, temp2;
int gtt_map_size = 256 * 1024;
int gtt_map_size;
size = agp_bridge->current_size;
page_order = size->page_order;
......@@ -1226,8 +1258,8 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp);
pci_read_config_dword(intel_private.pcidev, I915_PTEADDR, &temp2);
if (IS_G33)
gtt_map_size = 1024 * 1024; /* 1M on G33 */
gtt_map_size = intel_i915_get_gtt_size();
intel_private.gtt = ioremap(temp2, gtt_map_size);
if (!intel_private.gtt)
return -ENOMEM;
......@@ -1422,7 +1454,7 @@ static const struct agp_bridge_driver intel_915_driver = {
.size_type = FIXED_APER_SIZE,
.num_aperture_sizes = 4,
.needs_scratch_page = true,
.configure = intel_i915_configure,
.configure = intel_i9xx_configure,
.fetch_size = intel_i9xx_fetch_size,
.cleanup = intel_i915_cleanup,
.mask_memory = intel_i810_mask_memory,
......@@ -1455,7 +1487,7 @@ static const struct agp_bridge_driver intel_i965_driver = {
.size_type = FIXED_APER_SIZE,
.num_aperture_sizes = 4,
.needs_scratch_page = true,
.configure = intel_i915_configure,
.configure = intel_i9xx_configure,
.fetch_size = intel_i9xx_fetch_size,
.cleanup = intel_i915_cleanup,
.mask_memory = intel_i965_mask_memory,
......@@ -1488,7 +1520,7 @@ static const struct agp_bridge_driver intel_g33_driver = {
.size_type = FIXED_APER_SIZE,
.num_aperture_sizes = 4,
.needs_scratch_page = true,
.configure = intel_i915_configure,
.configure = intel_i9xx_configure,
.fetch_size = intel_i9xx_fetch_size,
.cleanup = intel_i915_cleanup,
.mask_memory = intel_i965_mask_memory,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment