From: Gerd Hoffmann Date: Fri, 18 Jan 2019 12:20:03 +0000 (+0100) Subject: drm/qxl: use separate offset spaces for the two slots / ttm memory types. X-Git-Tag: v5.1-rc1~117^2~17^2~45 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=96e8f153964aa0cc0ebb21576974a723f2b03cd5;p=thirdparty%2Fkernel%2Flinux.git drm/qxl: use separate offset spaces for the two slots / ttm memory types. 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 Acked-by: Noralf Trønnes Link: http://patchwork.freedesktop.org/patch/msgid/20190118122020.27596-7-kraxel@redhat.com --- diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 3ebe66abf259b..27e0a3fc08e61 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -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 */ diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index 9936b3111bb22..bee61fa2c9bcb 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c @@ -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) diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index 886f61e94f244..36ea993aac07d 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -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;