From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dave Airlie Subject: [PATCH 1/2] drm: move pci bus master enable into driver. Date: Mon, 19 Dec 2011 14:16:29 +0000 Message-ID: <1324304190-8368-2-git-send-email-airlied@gmail.com> References: <1324304190-8368-1-git-send-email-airlied@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by gabe.freedesktop.org (Postfix) with ESMTP id 66F1B9E75D for ; Mon, 19 Dec 2011 06:18:04 -0800 (PST) Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id pBJEI4xd010727 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 19 Dec 2011 09:18:04 -0500 Received: from optimus.redhat.com (vpn1-6-94.ams2.redhat.com [10.36.6.94]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id pBJEI1XI002679 for ; Mon, 19 Dec 2011 09:18:03 -0500 In-Reply-To: <1324304190-8368-1-git-send-email-airlied@gmail.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dri-devel-bounces+sf-dri-devel=m.gmane.org@lists.freedesktop.org Errors-To: dri-devel-bounces+sf-dri-devel=m.gmane.org@lists.freedesktop.org To: dri-devel@lists.freedesktop.org List-Id: dri-devel@lists.freedesktop.org From: Dave Airlie The current enabling of bus mastering in the drm midlayer allows a large race condition under kexec. When a kexec'ed kernel re-enables bus mastering for the GPU, previously setup dma blocks may cause writes to random pieces of memory. On radeon the writeback mechanism can cause these sorts of issues. This patch doesn't fix the problem, but it moves the bus master enable under the individual drivers control so they can move enabling it until later in their load cycle and close the race. Fix for radeon kms driver will be in a follow-up patch. Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_pci.c | 2 -- drivers/gpu/drm/gma500/psb_drv.c | 2 ++ drivers/gpu/drm/i810/i810_dma.c | 2 ++ drivers/gpu/drm/i915/i915_dma.c | 2 ++ drivers/gpu/drm/mga/mga_dma.c | 2 ++ drivers/gpu/drm/nouveau/nouveau_state.c | 2 ++ drivers/gpu/drm/r128/r128_drv.c | 1 + drivers/gpu/drm/radeon/radeon_cp.c | 2 ++ drivers/gpu/drm/radeon/radeon_kms.c | 2 ++ drivers/gpu/drm/sis/sis_drv.c | 2 ++ drivers/gpu/drm/via/via_map.c | 2 ++ drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 ++ 12 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index d4d10b7..13f3d93 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c @@ -324,8 +324,6 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, if (ret) goto err_g1; - pci_set_master(pdev); - dev->pdev = pdev; dev->dev = &pdev->dev; diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index add3156..ff30b71 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -286,6 +286,8 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) dev_priv->dev = dev; dev->dev_private = (void *) dev_priv; + pci_set_master(dev->pdev); + if (!IS_PSB(dev)) { if (pci_enable_msi(dev->pdev)) dev_warn(dev->dev, "Enabling MSI failed!\n"); diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 8f371e8..56989a3 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c @@ -1210,6 +1210,8 @@ int i810_driver_load(struct drm_device *dev, unsigned long flags) dev->types[8] = _DRM_STAT_SECONDARY; dev->types[9] = _DRM_STAT_DMA; + pci_set_master(dev->pdev); + return 0; } diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a9533c5..da07a8c 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1917,6 +1917,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto free_priv; } + pci_set_master(dev->pdev); + /* overlay on gen2 is broken and can't address above 1G */ if (IS_GEN2(dev)) dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c index 5ccb65de..507aa3d 100644 --- a/drivers/gpu/drm/mga/mga_dma.c +++ b/drivers/gpu/drm/mga/mga_dma.c @@ -403,6 +403,8 @@ int mga_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT; dev_priv->chipset = flags; + pci_set_master(dev->pdev); + dev_priv->mmio_base = pci_resource_start(dev->pdev, 1); dev_priv->mmio_size = pci_resource_len(dev->pdev, 1); diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 82478e0..37f7bba 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -1000,6 +1000,8 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) dev->dev_private = dev_priv; dev_priv->dev = dev; + pci_set_master(dev->pdev); + dev_priv->flags = flags & NOUVEAU_FLAGS; NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n", diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c index 6a5f439..88718fa 100644 --- a/drivers/gpu/drm/r128/r128_drv.c +++ b/drivers/gpu/drm/r128/r128_drv.c @@ -85,6 +85,7 @@ static struct drm_driver driver = { int r128_driver_load(struct drm_device *dev, unsigned long flags) { + pci_set_master(dev->pdev); return drm_vblank_init(dev, 1); } diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index 72ae826..0ebb7d4 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c @@ -2115,6 +2115,8 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) break; } + pci_set_master(dev->pdev); + if (drm_pci_device_is_agp(dev)) dev_priv->flags |= RADEON_IS_AGP; else if (pci_is_pcie(dev->pdev)) diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index be2c122..601b6bd 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -57,6 +57,8 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) } dev->dev_private = (void *)rdev; + pci_set_master(dev->pdev); + /* update BUS flag */ if (drm_pci_device_is_agp(dev)) { flags |= RADEON_IS_AGP; diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index bda96a8..c483363 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c @@ -42,6 +42,8 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset) drm_sis_private_t *dev_priv; int ret; + pci_set_master(dev->pdev); + dev_priv = kzalloc(sizeof(drm_sis_private_t), GFP_KERNEL); if (dev_priv == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/via/via_map.c b/drivers/gpu/drm/via/via_map.c index 6cca9a7..1d88595 100644 --- a/drivers/gpu/drm/via/via_map.c +++ b/drivers/gpu/drm/via/via_map.c @@ -104,6 +104,8 @@ int via_driver_load(struct drm_device *dev, unsigned long chipset) dev_priv->chipset = chipset; + pci_set_master(dev->pdev); + ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); if (ret) { kfree(dev_priv); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index f390f5f..9364b7b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -400,6 +400,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) } memset(dev_priv, 0, sizeof(*dev_priv)); + pci_set_master(dev->pdev); + dev_priv->dev = dev; dev_priv->vmw_chipset = chipset; dev_priv->last_read_seqno = (uint32_t) -100; -- 1.7.7.3