aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2019-02-06 19:36:43 -0500
committerDave Airlie <airlied@redhat.com>2019-02-06 19:36:47 -0500
commit78eb1ca47589f0cd9db2ceb28b60434e8d512131 (patch)
treed3bd7737415f9748937ea869b4aca249cbb29727
parent8628752d0c97c0b4d0406c39e313a30db950eba6 (diff)
parent9ddac734aa310c5fbc0ec93602335d2a39092451 (diff)
Merge branch 'vmwgfx-fixes-5.0-2' of git://people.freedesktop.org/~thomash/linux into drm-fixes
A patch set from Christoph for vmwgfx dma mode detection breakage with the new dma code restructuring in 5.0 A couple of fixes also CC'd stable Finally an improved IOMMU detection that automatically enables dma mapping also with other vIOMMUS than the intel one if present and enabled. Currently trying to start a VM in that case would fail catastrophically. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Thomas Hellstrom <thellstrom@vmware.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190206194735.4663-1-thellstrom@vmware.com
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c81
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c6
3 files changed, 36 insertions, 53 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 25afb1d594e3..7ef5dcb06104 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -26,6 +26,7 @@
26 **************************************************************************/ 26 **************************************************************************/
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/console.h> 28#include <linux/console.h>
29#include <linux/dma-mapping.h>
29 30
30#include <drm/drmP.h> 31#include <drm/drmP.h>
31#include "vmwgfx_drv.h" 32#include "vmwgfx_drv.h"
@@ -34,7 +35,6 @@
34#include <drm/ttm/ttm_placement.h> 35#include <drm/ttm/ttm_placement.h>
35#include <drm/ttm/ttm_bo_driver.h> 36#include <drm/ttm/ttm_bo_driver.h>
36#include <drm/ttm/ttm_module.h> 37#include <drm/ttm/ttm_module.h>
37#include <linux/intel-iommu.h>
38 38
39#define VMWGFX_DRIVER_DESC "Linux drm driver for VMware graphics devices" 39#define VMWGFX_DRIVER_DESC "Linux drm driver for VMware graphics devices"
40#define VMWGFX_CHIP_SVGAII 0 40#define VMWGFX_CHIP_SVGAII 0
@@ -546,6 +546,21 @@ static void vmw_get_initial_size(struct vmw_private *dev_priv)
546} 546}
547 547
548/** 548/**
549 * vmw_assume_iommu - Figure out whether coherent dma-remapping might be
550 * taking place.
551 * @dev: Pointer to the struct drm_device.
552 *
553 * Return: true if iommu present, false otherwise.
554 */
555static bool vmw_assume_iommu(struct drm_device *dev)
556{
557 const struct dma_map_ops *ops = get_dma_ops(dev->dev);
558
559 return !dma_is_direct(ops) && ops &&
560 ops->map_page != dma_direct_map_page;
561}
562
563/**
549 * vmw_dma_select_mode - Determine how DMA mappings should be set up for this 564 * vmw_dma_select_mode - Determine how DMA mappings should be set up for this
550 * system. 565 * system.
551 * 566 *
@@ -565,55 +580,27 @@ static int vmw_dma_select_mode(struct vmw_private *dev_priv)
565 [vmw_dma_alloc_coherent] = "Using coherent TTM pages.", 580 [vmw_dma_alloc_coherent] = "Using coherent TTM pages.",
566 [vmw_dma_map_populate] = "Keeping DMA mappings.", 581 [vmw_dma_map_populate] = "Keeping DMA mappings.",
567 [vmw_dma_map_bind] = "Giving up DMA mappings early."}; 582 [vmw_dma_map_bind] = "Giving up DMA mappings early."};
568#ifdef CONFIG_X86
569 const struct dma_map_ops *dma_ops = get_dma_ops(dev_priv->dev->dev);
570 583
571#ifdef CONFIG_INTEL_IOMMU 584 if (vmw_force_coherent)
572 if (intel_iommu_enabled) { 585 dev_priv->map_mode = vmw_dma_alloc_coherent;
586 else if (vmw_assume_iommu(dev_priv->dev))
573 dev_priv->map_mode = vmw_dma_map_populate; 587 dev_priv->map_mode = vmw_dma_map_populate;
574 goto out_fixup; 588 else if (!vmw_force_iommu)
575 }
576#endif
577
578 if (!(vmw_force_iommu || vmw_force_coherent)) {
579 dev_priv->map_mode = vmw_dma_phys; 589 dev_priv->map_mode = vmw_dma_phys;
580 DRM_INFO("DMA map mode: %s\n", names[dev_priv->map_mode]); 590 else if (IS_ENABLED(CONFIG_SWIOTLB) && swiotlb_nr_tbl())
581 return 0;
582 }
583
584 dev_priv->map_mode = vmw_dma_map_populate;
585
586 if (dma_ops && dma_ops->sync_single_for_cpu)
587 dev_priv->map_mode = vmw_dma_alloc_coherent; 591 dev_priv->map_mode = vmw_dma_alloc_coherent;
588#ifdef CONFIG_SWIOTLB 592 else
589 if (swiotlb_nr_tbl() == 0)
590 dev_priv->map_mode = vmw_dma_map_populate; 593 dev_priv->map_mode = vmw_dma_map_populate;
591#endif
592 594
593#ifdef CONFIG_INTEL_IOMMU 595 if (dev_priv->map_mode == vmw_dma_map_populate && vmw_restrict_iommu)
594out_fixup:
595#endif
596 if (dev_priv->map_mode == vmw_dma_map_populate &&
597 vmw_restrict_iommu)
598 dev_priv->map_mode = vmw_dma_map_bind; 596 dev_priv->map_mode = vmw_dma_map_bind;
599 597
600 if (vmw_force_coherent) 598 /* No TTM coherent page pool? FIXME: Ask TTM instead! */
601 dev_priv->map_mode = vmw_dma_alloc_coherent; 599 if (!(IS_ENABLED(CONFIG_SWIOTLB) || IS_ENABLED(CONFIG_INTEL_IOMMU)) &&
602 600 (dev_priv->map_mode == vmw_dma_alloc_coherent))
603#if !defined(CONFIG_SWIOTLB) && !defined(CONFIG_INTEL_IOMMU)
604 /*
605 * No coherent page pool
606 */
607 if (dev_priv->map_mode == vmw_dma_alloc_coherent)
608 return -EINVAL; 601 return -EINVAL;
609#endif
610
611#else /* CONFIG_X86 */
612 dev_priv->map_mode = vmw_dma_map_populate;
613#endif /* CONFIG_X86 */
614 602
615 DRM_INFO("DMA map mode: %s\n", names[dev_priv->map_mode]); 603 DRM_INFO("DMA map mode: %s\n", names[dev_priv->map_mode]);
616
617 return 0; 604 return 0;
618} 605}
619 606
@@ -625,24 +612,20 @@ out_fixup:
625 * With 32-bit we can only handle 32 bit PFNs. Optionally set that 612 * With 32-bit we can only handle 32 bit PFNs. Optionally set that
626 * restriction also for 64-bit systems. 613 * restriction also for 64-bit systems.
627 */ 614 */
628#ifdef CONFIG_INTEL_IOMMU
629static int vmw_dma_masks(struct vmw_private *dev_priv) 615static int vmw_dma_masks(struct vmw_private *dev_priv)
630{ 616{
631 struct drm_device *dev = dev_priv->dev; 617 struct drm_device *dev = dev_priv->dev;
618 int ret = 0;
632 619
633 if (intel_iommu_enabled && 620 ret = dma_set_mask_and_coherent(dev->dev, DMA_BIT_MASK(64));
621 if (dev_priv->map_mode != vmw_dma_phys &&
634 (sizeof(unsigned long) == 4 || vmw_restrict_dma_mask)) { 622 (sizeof(unsigned long) == 4 || vmw_restrict_dma_mask)) {
635 DRM_INFO("Restricting DMA addresses to 44 bits.\n"); 623 DRM_INFO("Restricting DMA addresses to 44 bits.\n");
636 return dma_set_mask(dev->dev, DMA_BIT_MASK(44)); 624 return dma_set_mask_and_coherent(dev->dev, DMA_BIT_MASK(44));
637 } 625 }
638 return 0; 626
639} 627 return ret;
640#else
641static int vmw_dma_masks(struct vmw_private *dev_priv)
642{
643 return 0;
644} 628}
645#endif
646 629
647static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) 630static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
648{ 631{
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index f2d13a72c05d..88b8178d4687 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -3570,7 +3570,7 @@ int vmw_execbuf_fence_commands(struct drm_file *file_priv,
3570 *p_fence = NULL; 3570 *p_fence = NULL;
3571 } 3571 }
3572 3572
3573 return 0; 3573 return ret;
3574} 3574}
3575 3575
3576/** 3576/**
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index b351fb5214d3..ed2f67822f45 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1646,7 +1646,7 @@ static int vmw_kms_check_topology(struct drm_device *dev,
1646 struct drm_connector_state *conn_state; 1646 struct drm_connector_state *conn_state;
1647 struct vmw_connector_state *vmw_conn_state; 1647 struct vmw_connector_state *vmw_conn_state;
1648 1648
1649 if (!du->pref_active) { 1649 if (!du->pref_active && new_crtc_state->enable) {
1650 ret = -EINVAL; 1650 ret = -EINVAL;
1651 goto clean; 1651 goto clean;
1652 } 1652 }
@@ -2554,8 +2554,8 @@ void vmw_kms_helper_validation_finish(struct vmw_private *dev_priv,
2554 user_fence_rep) 2554 user_fence_rep)
2555{ 2555{
2556 struct vmw_fence_obj *fence = NULL; 2556 struct vmw_fence_obj *fence = NULL;
2557 uint32_t handle; 2557 uint32_t handle = 0;
2558 int ret; 2558 int ret = 0;
2559 2559
2560 if (file_priv || user_fence_rep || vmw_validation_has_bos(ctx) || 2560 if (file_priv || user_fence_rep || vmw_validation_has_bos(ctx) ||
2561 out_fence) 2561 out_fence)