drm/radeon: fix AGP userptr handling

AGP mappings are not cache coherent, so userptr support
won't work. Additional to that the AGP implementation uses
a different ttm_tt container structure so we run into
problems if we cast the pointer without checking if it's
the right type.

Signed-off-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Christian König 2014-09-17 04:00:05 -06:00 committed by Alex Deucher
parent 8337486a8f
commit 3840a656f6

View File

@ -675,10 +675,17 @@ static struct ttm_tt *radeon_ttm_tt_create(struct ttm_bo_device *bdev,
return &gtt->ttm.ttm; return &gtt->ttm.ttm;
} }
static struct radeon_ttm_tt *radeon_ttm_tt_to_gtt(struct ttm_tt *ttm)
{
if (!ttm || ttm->func != &radeon_backend_func)
return NULL;
return (struct radeon_ttm_tt *)ttm;
}
static int radeon_ttm_tt_populate(struct ttm_tt *ttm) static int radeon_ttm_tt_populate(struct ttm_tt *ttm)
{ {
struct radeon_ttm_tt *gtt = radeon_ttm_tt_to_gtt(ttm);
struct radeon_device *rdev; struct radeon_device *rdev;
struct radeon_ttm_tt *gtt = (void *)ttm;
unsigned i; unsigned i;
int r; int r;
bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
@ -686,7 +693,7 @@ static int radeon_ttm_tt_populate(struct ttm_tt *ttm)
if (ttm->state != tt_unpopulated) if (ttm->state != tt_unpopulated)
return 0; return 0;
if (gtt->userptr) { if (gtt && gtt->userptr) {
ttm->sg = kcalloc(1, sizeof(struct sg_table), GFP_KERNEL); ttm->sg = kcalloc(1, sizeof(struct sg_table), GFP_KERNEL);
if (!ttm->sg) if (!ttm->sg)
return -ENOMEM; return -ENOMEM;
@ -741,11 +748,11 @@ static int radeon_ttm_tt_populate(struct ttm_tt *ttm)
static void radeon_ttm_tt_unpopulate(struct ttm_tt *ttm) static void radeon_ttm_tt_unpopulate(struct ttm_tt *ttm)
{ {
struct radeon_device *rdev; struct radeon_device *rdev;
struct radeon_ttm_tt *gtt = (void *)ttm; struct radeon_ttm_tt *gtt = radeon_ttm_tt_to_gtt(ttm);
unsigned i; unsigned i;
bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
if (gtt->userptr) { if (gtt && gtt->userptr) {
kfree(ttm->sg); kfree(ttm->sg);
ttm->page_flags &= ~TTM_PAGE_FLAG_SG; ttm->page_flags &= ~TTM_PAGE_FLAG_SG;
return; return;
@ -782,7 +789,7 @@ static void radeon_ttm_tt_unpopulate(struct ttm_tt *ttm)
int radeon_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, int radeon_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
uint32_t flags) uint32_t flags)
{ {
struct radeon_ttm_tt *gtt = (void *)ttm; struct radeon_ttm_tt *gtt = radeon_ttm_tt_to_gtt(ttm);
if (gtt == NULL) if (gtt == NULL)
return -EINVAL; return -EINVAL;
@ -795,7 +802,7 @@ int radeon_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
bool radeon_ttm_tt_has_userptr(struct ttm_tt *ttm) bool radeon_ttm_tt_has_userptr(struct ttm_tt *ttm)
{ {
struct radeon_ttm_tt *gtt = (void *)ttm; struct radeon_ttm_tt *gtt = radeon_ttm_tt_to_gtt(ttm);
if (gtt == NULL) if (gtt == NULL)
return false; return false;
@ -805,7 +812,7 @@ bool radeon_ttm_tt_has_userptr(struct ttm_tt *ttm)
bool radeon_ttm_tt_is_readonly(struct ttm_tt *ttm) bool radeon_ttm_tt_is_readonly(struct ttm_tt *ttm)
{ {
struct radeon_ttm_tt *gtt = (void *)ttm; struct radeon_ttm_tt *gtt = radeon_ttm_tt_to_gtt(ttm);
if (gtt == NULL) if (gtt == NULL)
return false; return false;