Skip to content

Commit

Permalink
agp/intel: Restrict GTT mapping to valid range on i915 and i945
Browse files Browse the repository at this point in the history
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: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Eric Anholt <eric@anholt.net>
  • Loading branch information
Chris Wilson authored and Eric Anholt committed May 26, 2010
1 parent 9a7e849 commit f1befe7
Showing 1 changed file with 39 additions and 7 deletions.
46 changes: 39 additions & 7 deletions drivers/char/agp/intel-gtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
*/
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit f1befe7

Please sign in to comment.