Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 80b2c386 authored by Michel Dänzer's avatar Michel Dänzer Committed by Dave Airlie
Browse files

drm/radeon: Fix u32 overflows when determining AGP base address in card space.

The overflows could lead to the AGP aperture overlapping the framebuffer are    in the card's address space when the latter is located at the very end of th    32 bit address space, which would result in a freeze on X server startup,
probably because the card read commands from the framebuffer instead of from    AGP.

See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=392915

 .

Signed-off-by: default avatarDave Airlie <airlied@linux.ie>
parent cd839d00
Loading
Loading
Loading
Loading
+4 −4
Original line number Original line Diff line number Diff line
@@ -1560,8 +1560,8 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
		if (dev_priv->flags & RADEON_IS_AGP) {
		if (dev_priv->flags & RADEON_IS_AGP) {
			base = dev->agp->base;
			base = dev->agp->base;
			/* Check if valid */
			/* Check if valid */
			if ((base + dev_priv->gart_size) > dev_priv->fb_location &&
			if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location &&
			    base < (dev_priv->fb_location + dev_priv->fb_size)) {
			    base < (dev_priv->fb_location + dev_priv->fb_size - 1)) {
				DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n",
				DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n",
					 dev->agp->base);
					 dev->agp->base);
				base = 0;
				base = 0;
@@ -1571,8 +1571,8 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
		/* If not or if AGP is at 0 (Macs), try to put it elsewhere */
		/* If not or if AGP is at 0 (Macs), try to put it elsewhere */
		if (base == 0) {
		if (base == 0) {
			base = dev_priv->fb_location + dev_priv->fb_size;
			base = dev_priv->fb_location + dev_priv->fb_size;
			if (((base + dev_priv->gart_size) & 0xfffffffful)
			if (base < dev_priv->fb_location ||
			    < base)
			    ((base + dev_priv->gart_size) & 0xfffffffful) < base)
				base = dev_priv->fb_location
				base = dev_priv->fb_location
					- dev_priv->gart_size;
					- dev_priv->gart_size;
		}		
		}