Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdkfd: Expose HDP registers to user space

Introduce a new memory type (KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP) and
expose mmio page of HDP registers to user space through this new
memory type.

v2: moved remapped hdp regs to adev struct
v3: rename the new memory type to ALLOC_MEM_FLAGS_MMIO_REMAP
v4: use more generic function name
v5: Fail remapped mmio allocation for asics before gfx9

Signed-off-by: Oak Zeng <Oak.Zeng@amd.com>
Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Oak Zeng and committed by
Alex Deucher
d8e408a8 88807dc8

+20 -3
+7
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
··· 519 519 return adev->gmc.xgmi.hive_id; 520 520 } 521 521 522 + uint64_t amdgpu_amdkfd_get_mmio_remap_phys_addr(struct kgd_dev *kgd) 523 + { 524 + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; 525 + 526 + return adev->rmmio_remap.bus_addr; 527 + } 528 + 522 529 int amdgpu_amdkfd_submit_ib(struct kgd_dev *kgd, enum kgd_engine_type engine, 523 530 uint32_t vmid, uint64_t gpu_addr, 524 531 uint32_t *ib_cmd, uint32_t ib_len)
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
··· 169 169 uint32_t *flags); 170 170 uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd); 171 171 uint64_t amdgpu_amdkfd_get_hive_id(struct kgd_dev *kgd); 172 + uint64_t amdgpu_amdkfd_get_mmio_remap_phys_addr(struct kgd_dev *kgd); 172 173 173 174 #define read_user_wptr(mmptr, wptr, dst) \ 174 175 ({ \
+4 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
··· 1109 1109 if (!offset || !*offset) 1110 1110 return -EINVAL; 1111 1111 user_addr = *offset; 1112 - } else if (flags & ALLOC_MEM_FLAGS_DOORBELL) { 1112 + } else if (flags & (ALLOC_MEM_FLAGS_DOORBELL | 1113 + ALLOC_MEM_FLAGS_MMIO_REMAP)) { 1113 1114 domain = AMDGPU_GEM_DOMAIN_GTT; 1114 1115 alloc_domain = AMDGPU_GEM_DOMAIN_CPU; 1115 1116 bo_type = ttm_bo_type_sg; ··· 1295 1294 /* Free the sync object */ 1296 1295 amdgpu_sync_free(&mem->sync); 1297 1296 1298 - /* If the SG is not NULL, it's one we created for a doorbell 1299 - * BO. We need to free it. 1297 + /* If the SG is not NULL, it's one we created for a doorbell or mmio 1298 + * remap BO. We need to free it. 1300 1299 */ 1301 1300 if (mem->bo->tbo.sg) { 1302 1301 sg_free_table(mem->bo->tbo.sg);
+6
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
··· 1272 1272 if (args->size != kfd_doorbell_process_slice(dev)) 1273 1273 return -EINVAL; 1274 1274 offset = kfd_get_process_doorbells(dev, p); 1275 + } else if (flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP) { 1276 + if (args->size != PAGE_SIZE) 1277 + return -EINVAL; 1278 + offset = amdgpu_amdkfd_get_mmio_remap_phys_addr(dev->kgd); 1279 + if (!offset) 1280 + return -ENOMEM; 1275 1281 } 1276 1282 1277 1283 mutex_lock(&p->mutex);
+1
drivers/gpu/drm/amd/include/kgd_kfd_interface.h
··· 174 174 #define ALLOC_MEM_FLAGS_GTT (1 << 1) 175 175 #define ALLOC_MEM_FLAGS_USERPTR (1 << 2) 176 176 #define ALLOC_MEM_FLAGS_DOORBELL (1 << 3) 177 + #define ALLOC_MEM_FLAGS_MMIO_REMAP (1 << 4) 177 178 178 179 /* 179 180 * Allocation flags attributes/access options.
+1
include/uapi/linux/kfd_ioctl.h
··· 338 338 #define KFD_IOC_ALLOC_MEM_FLAGS_GTT (1 << 1) 339 339 #define KFD_IOC_ALLOC_MEM_FLAGS_USERPTR (1 << 2) 340 340 #define KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL (1 << 3) 341 + #define KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP (1 << 4) 341 342 /* Allocation flags: attributes/access options */ 342 343 #define KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE (1 << 31) 343 344 #define KFD_IOC_ALLOC_MEM_FLAGS_EXECUTABLE (1 << 30)