]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/qxl: use separate offset spaces for the two slots / ttm memory types.
authorGerd Hoffmann <kraxel@redhat.com>
Fri, 18 Jan 2019 12:20:03 +0000 (13:20 +0100)
committerGerd Hoffmann <kraxel@redhat.com>
Mon, 28 Jan 2019 13:24:52 +0000 (14:24 +0100)
Without that ttm offsets are not unique, they can refer to objects
in both VRAM and PRIV memory (aka main and surfaces slot).

One of those "why things didn't blow up without this" moments.
Probably offset conflicts are rare enough by pure luck.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Noralf Trønnes <noralf@tronnes.org>
Link: http://patchwork.freedesktop.org/patch/msgid/20190118122020.27596-7-kraxel@redhat.com
drivers/gpu/drm/qxl/qxl_drv.h
drivers/gpu/drm/qxl/qxl_kms.c
drivers/gpu/drm/qxl/qxl_ttm.c

index 3ebe66abf259b4a138b76c2c1c7bbaab71bc445d..27e0a3fc08e61255dc6b30674851aa88c67bff40 100644 (file)
@@ -136,6 +136,7 @@ struct qxl_memslot {
        uint64_t        start_phys_addr;
        uint64_t        size;
        uint64_t        high_bits;
+       uint64_t        gpu_offset;
 };
 
 enum {
@@ -312,8 +313,10 @@ qxl_bo_physical_address(struct qxl_device *qdev, struct qxl_bo *bo,
                (bo->tbo.mem.mem_type == TTM_PL_VRAM)
                ? &qdev->main_slot : &qdev->surfaces_slot;
 
+       WARN_ON_ONCE((bo->tbo.offset & slot->gpu_offset) != slot->gpu_offset);
+
        /* TODO - need to hold one of the locks to read tbo.offset */
-       return slot->high_bits | (bo->tbo.offset + offset);
+       return slot->high_bits | (bo->tbo.offset - slot->gpu_offset + offset);
 }
 
 /* qxl_fb.c */
index 9936b3111bb22113a46fb95dce30601483eb78df..bee61fa2c9bcb33f2d6166d1f5bf6aea22b38830 100644 (file)
@@ -83,10 +83,11 @@ static void setup_slot(struct qxl_device *qdev,
        high_bits <<= (64 - (qdev->rom->slot_gen_bits + qdev->rom->slot_id_bits));
        slot->high_bits = high_bits;
 
-       DRM_INFO("slot %d (%s): base 0x%08lx, size 0x%08lx\n",
+       DRM_INFO("slot %d (%s): base 0x%08lx, size 0x%08lx, gpu_offset 0x%lx\n",
                 slot->index, slot->name,
                 (unsigned long)slot->start_phys_addr,
-                (unsigned long)slot->size);
+                (unsigned long)slot->size,
+                (unsigned long)slot->gpu_offset);
 }
 
 void qxl_reinit_memslots(struct qxl_device *qdev)
index 886f61e94f24470c37feaf224974fb28d43d2e5b..36ea993aac07d47f815332ff455223d3d1229876 100644 (file)
@@ -100,6 +100,11 @@ static int qxl_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags)
 static int qxl_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
                             struct ttm_mem_type_manager *man)
 {
+       struct qxl_device *qdev = qxl_get_qdev(bdev);
+       unsigned int gpu_offset_shift =
+               64 - (qdev->rom->slot_gen_bits + qdev->rom->slot_id_bits + 8);
+       struct qxl_memslot *slot;
+
        switch (type) {
        case TTM_PL_SYSTEM:
                /* System memory */
@@ -110,8 +115,11 @@ static int qxl_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
        case TTM_PL_VRAM:
        case TTM_PL_PRIV:
                /* "On-card" video ram */
+               slot = (type == TTM_PL_VRAM) ?
+                       &qdev->main_slot : &qdev->surfaces_slot;
+               slot->gpu_offset = (uint64_t)type << gpu_offset_shift;
                man->func = &ttm_bo_manager_func;
-               man->gpu_offset = 0;
+               man->gpu_offset = slot->gpu_offset;
                man->flags = TTM_MEMTYPE_FLAG_FIXED |
                             TTM_MEMTYPE_FLAG_MAPPABLE;
                man->available_caching = TTM_PL_MASK_CACHING;