Skip to content

Commit 78eb1ca

Browse files
committed
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
2 parents 8628752 + 9ddac73 commit 78eb1ca

File tree

3 files changed

+36
-53
lines changed

3 files changed

+36
-53
lines changed

drivers/gpu/drm/vmwgfx/vmwgfx_drv.c

Lines changed: 32 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
**************************************************************************/
2727
#include <linux/module.h>
2828
#include <linux/console.h>
29+
#include <linux/dma-mapping.h>
2930

3031
#include <drm/drmP.h>
3132
#include "vmwgfx_drv.h"
@@ -34,7 +35,6 @@
3435
#include <drm/ttm/ttm_placement.h>
3536
#include <drm/ttm/ttm_bo_driver.h>
3637
#include <drm/ttm/ttm_module.h>
37-
#include <linux/intel-iommu.h>
3838

3939
#define VMWGFX_DRIVER_DESC "Linux drm driver for VMware graphics devices"
4040
#define VMWGFX_CHIP_SVGAII 0
@@ -545,6 +545,21 @@ static void vmw_get_initial_size(struct vmw_private *dev_priv)
545545
dev_priv->initial_height = height;
546546
}
547547

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+
*/
555+
static 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+
548563
/**
549564
* vmw_dma_select_mode - Determine how DMA mappings should be set up for this
550565
* system.
@@ -565,55 +580,27 @@ static int vmw_dma_select_mode(struct vmw_private *dev_priv)
565580
[vmw_dma_alloc_coherent] = "Using coherent TTM pages.",
566581
[vmw_dma_map_populate] = "Keeping DMA mappings.",
567582
[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);
570583

571-
#ifdef CONFIG_INTEL_IOMMU
572-
if (intel_iommu_enabled) {
584+
if (vmw_force_coherent)
585+
dev_priv->map_mode = vmw_dma_alloc_coherent;
586+
else if (vmw_assume_iommu(dev_priv->dev))
573587
dev_priv->map_mode = vmw_dma_map_populate;
574-
goto out_fixup;
575-
}
576-
#endif
577-
578-
if (!(vmw_force_iommu || vmw_force_coherent)) {
588+
else if (!vmw_force_iommu)
579589
dev_priv->map_mode = vmw_dma_phys;
580-
DRM_INFO("DMA map mode: %s\n", names[dev_priv->map_mode]);
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)
590+
else if (IS_ENABLED(CONFIG_SWIOTLB) && swiotlb_nr_tbl())
587591
dev_priv->map_mode = vmw_dma_alloc_coherent;
588-
#ifdef CONFIG_SWIOTLB
589-
if (swiotlb_nr_tbl() == 0)
592+
else
590593
dev_priv->map_mode = vmw_dma_map_populate;
591-
#endif
592594

593-
#ifdef CONFIG_INTEL_IOMMU
594-
out_fixup:
595-
#endif
596-
if (dev_priv->map_mode == vmw_dma_map_populate &&
597-
vmw_restrict_iommu)
595+
if (dev_priv->map_mode == vmw_dma_map_populate && vmw_restrict_iommu)
598596
dev_priv->map_mode = vmw_dma_map_bind;
599597

600-
if (vmw_force_coherent)
601-
dev_priv->map_mode = vmw_dma_alloc_coherent;
602-
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)
598+
/* No TTM coherent page pool? FIXME: Ask TTM instead! */
599+
if (!(IS_ENABLED(CONFIG_SWIOTLB) || IS_ENABLED(CONFIG_INTEL_IOMMU)) &&
600+
(dev_priv->map_mode == vmw_dma_alloc_coherent))
608601
return -EINVAL;
609-
#endif
610-
611-
#else /* CONFIG_X86 */
612-
dev_priv->map_mode = vmw_dma_map_populate;
613-
#endif /* CONFIG_X86 */
614602

615603
DRM_INFO("DMA map mode: %s\n", names[dev_priv->map_mode]);
616-
617604
return 0;
618605
}
619606

@@ -625,24 +612,20 @@ static int vmw_dma_select_mode(struct vmw_private *dev_priv)
625612
* With 32-bit we can only handle 32 bit PFNs. Optionally set that
626613
* restriction also for 64-bit systems.
627614
*/
628-
#ifdef CONFIG_INTEL_IOMMU
629615
static int vmw_dma_masks(struct vmw_private *dev_priv)
630616
{
631617
struct drm_device *dev = dev_priv->dev;
618+
int ret = 0;
632619

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 &&
634622
(sizeof(unsigned long) == 4 || vmw_restrict_dma_mask)) {
635623
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));
637625
}
638-
return 0;
639-
}
640-
#else
641-
static int vmw_dma_masks(struct vmw_private *dev_priv)
642-
{
643-
return 0;
626+
627+
return ret;
644628
}
645-
#endif
646629

647630
static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
648631
{

drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3570,7 +3570,7 @@ int vmw_execbuf_fence_commands(struct drm_file *file_priv,
35703570
*p_fence = NULL;
35713571
}
35723572

3573-
return 0;
3573+
return ret;
35743574
}
35753575

35763576
/**

drivers/gpu/drm/vmwgfx/vmwgfx_kms.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1646,7 +1646,7 @@ static int vmw_kms_check_topology(struct drm_device *dev,
16461646
struct drm_connector_state *conn_state;
16471647
struct vmw_connector_state *vmw_conn_state;
16481648

1649-
if (!du->pref_active) {
1649+
if (!du->pref_active && new_crtc_state->enable) {
16501650
ret = -EINVAL;
16511651
goto clean;
16521652
}
@@ -2554,8 +2554,8 @@ void vmw_kms_helper_validation_finish(struct vmw_private *dev_priv,
25542554
user_fence_rep)
25552555
{
25562556
struct vmw_fence_obj *fence = NULL;
2557-
uint32_t handle;
2558-
int ret;
2557+
uint32_t handle = 0;
2558+
int ret = 0;
25592559

25602560
if (file_priv || user_fence_rep || vmw_validation_has_bos(ctx) ||
25612561
out_fence)

0 commit comments

Comments
 (0)