--- a/sys/dev/drm/radeon/radeon_gart.c +++ b/sys/dev/drm/radeon/radeon_gart.c @@ -65,10 +65,30 @@ * gart table to be in system memory. * Returns 0 for success, -ENOMEM for failure. */ +static int radeon_gart_table_size_ok(struct radeon_device *rdev) +{ + /* The table must be able to hold one entry (>= 4 bytes) per GPU page. + * Both the per-asic table_size computation (num_gpu_pages * 4 or * 8, + * 32-bit unsigned multiply) and the u32 num_gpu_pages field itself can + * wrap for oversized GTT configurations - reject those here instead of + * trusting the caller. + */ + if (rdev->gart.num_gpu_pages == 0 || + (uint64_t)rdev->gart.table_size / rdev->gart.num_gpu_pages < 4) + return 0; + return 1; +} + int radeon_gart_table_ram_alloc(struct radeon_device *rdev) { void *ptr; + if (!radeon_gart_table_size_ok(rdev)) { + dev_err(rdev->dev, "GART table size %u too small for %u GPU pages\n", + rdev->gart.table_size, rdev->gart.num_gpu_pages); + return -EINVAL; + } + ptr = pci_alloc_consistent(rdev->pdev, rdev->gart.table_size, &rdev->gart.table_addr); if (ptr == NULL) { @@ -128,6 +148,12 @@ { int r; + if (!radeon_gart_table_size_ok(rdev)) { + dev_err(rdev->dev, "GART table size %u too small for %u GPU pages\n", + rdev->gart.table_size, rdev->gart.num_gpu_pages); + return -EINVAL; + } + if (rdev->gart.robj == NULL) { r = radeon_bo_create(rdev, rdev->gart.table_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,