diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/r100.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 76 |
1 files changed, 45 insertions, 31 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 64a692c0c319..c550932a108f 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -647,7 +647,7 @@ int r100_cp_reset(struct radeon_device *rdev) | |||
647 | */ | 647 | */ |
648 | int r100_cs_parse_packet0(struct radeon_cs_parser *p, | 648 | int r100_cs_parse_packet0(struct radeon_cs_parser *p, |
649 | struct radeon_cs_packet *pkt, | 649 | struct radeon_cs_packet *pkt, |
650 | unsigned *auth, unsigned n, | 650 | const unsigned *auth, unsigned n, |
651 | radeon_packet0_check_t check) | 651 | radeon_packet0_check_t check) |
652 | { | 652 | { |
653 | unsigned reg; | 653 | unsigned reg; |
@@ -657,6 +657,10 @@ int r100_cs_parse_packet0(struct radeon_cs_parser *p, | |||
657 | 657 | ||
658 | idx = pkt->idx + 1; | 658 | idx = pkt->idx + 1; |
659 | reg = pkt->reg; | 659 | reg = pkt->reg; |
660 | /* Check that register fall into register range | ||
661 | * determined by the number of entry (n) in the | ||
662 | * safe register bitmap. | ||
663 | */ | ||
660 | if (pkt->one_reg_wr) { | 664 | if (pkt->one_reg_wr) { |
661 | if ((reg >> 7) > n) { | 665 | if ((reg >> 7) > n) { |
662 | return -EINVAL; | 666 | return -EINVAL; |
@@ -686,24 +690,6 @@ int r100_cs_parse_packet0(struct radeon_cs_parser *p, | |||
686 | return 0; | 690 | return 0; |
687 | } | 691 | } |
688 | 692 | ||
689 | int r100_cs_parse_packet3(struct radeon_cs_parser *p, | ||
690 | struct radeon_cs_packet *pkt, | ||
691 | unsigned *auth, unsigned n, | ||
692 | radeon_packet3_check_t check) | ||
693 | { | ||
694 | unsigned i, m; | ||
695 | |||
696 | if ((pkt->opcode >> 5) > n) { | ||
697 | return -EINVAL; | ||
698 | } | ||
699 | i = pkt->opcode >> 5; | ||
700 | m = 1 << (pkt->opcode & 31); | ||
701 | if (auth[i] & m) { | ||
702 | return check(p, pkt); | ||
703 | } | ||
704 | return 0; | ||
705 | } | ||
706 | |||
707 | void r100_cs_dump_packet(struct radeon_cs_parser *p, | 693 | void r100_cs_dump_packet(struct radeon_cs_parser *p, |
708 | struct radeon_cs_packet *pkt) | 694 | struct radeon_cs_packet *pkt) |
709 | { | 695 | { |
@@ -904,6 +890,25 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
904 | return 0; | 890 | return 0; |
905 | } | 891 | } |
906 | 892 | ||
893 | int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, | ||
894 | struct radeon_cs_packet *pkt, | ||
895 | struct radeon_object *robj) | ||
896 | { | ||
897 | struct radeon_cs_chunk *ib_chunk; | ||
898 | unsigned idx; | ||
899 | |||
900 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
901 | idx = pkt->idx + 1; | ||
902 | if ((ib_chunk->kdata[idx+2] + 1) > radeon_object_size(robj)) { | ||
903 | DRM_ERROR("[drm] Buffer too small for PACKET3 INDX_BUFFER " | ||
904 | "(need %u have %lu) !\n", | ||
905 | ib_chunk->kdata[idx+2] + 1, | ||
906 | radeon_object_size(robj)); | ||
907 | return -EINVAL; | ||
908 | } | ||
909 | return 0; | ||
910 | } | ||
911 | |||
907 | static int r100_packet3_check(struct radeon_cs_parser *p, | 912 | static int r100_packet3_check(struct radeon_cs_parser *p, |
908 | struct radeon_cs_packet *pkt) | 913 | struct radeon_cs_packet *pkt) |
909 | { | 914 | { |
@@ -957,6 +962,10 @@ static int r100_packet3_check(struct radeon_cs_parser *p, | |||
957 | return r; | 962 | return r; |
958 | } | 963 | } |
959 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); | 964 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); |
965 | r = r100_cs_track_check_pkt3_indx_buffer(p, pkt, reloc->robj); | ||
966 | if (r) { | ||
967 | return r; | ||
968 | } | ||
960 | break; | 969 | break; |
961 | case 0x23: | 970 | case 0x23: |
962 | /* FIXME: cleanup */ | 971 | /* FIXME: cleanup */ |
@@ -1002,18 +1011,18 @@ int r100_cs_parse(struct radeon_cs_parser *p) | |||
1002 | } | 1011 | } |
1003 | p->idx += pkt.count + 2; | 1012 | p->idx += pkt.count + 2; |
1004 | switch (pkt.type) { | 1013 | switch (pkt.type) { |
1005 | case PACKET_TYPE0: | 1014 | case PACKET_TYPE0: |
1006 | r = r100_packet0_check(p, &pkt); | 1015 | r = r100_packet0_check(p, &pkt); |
1007 | break; | 1016 | break; |
1008 | case PACKET_TYPE2: | 1017 | case PACKET_TYPE2: |
1009 | break; | 1018 | break; |
1010 | case PACKET_TYPE3: | 1019 | case PACKET_TYPE3: |
1011 | r = r100_packet3_check(p, &pkt); | 1020 | r = r100_packet3_check(p, &pkt); |
1012 | break; | 1021 | break; |
1013 | default: | 1022 | default: |
1014 | DRM_ERROR("Unknown packet type %d !\n", | 1023 | DRM_ERROR("Unknown packet type %d !\n", |
1015 | pkt.type); | 1024 | pkt.type); |
1016 | return -EINVAL; | 1025 | return -EINVAL; |
1017 | } | 1026 | } |
1018 | if (r) { | 1027 | if (r) { |
1019 | return r; | 1028 | return r; |
@@ -1349,6 +1358,11 @@ void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | |||
1349 | } | 1358 | } |
1350 | } | 1359 | } |
1351 | 1360 | ||
1361 | int r100_init(struct radeon_device *rdev) | ||
1362 | { | ||
1363 | return 0; | ||
1364 | } | ||
1365 | |||
1352 | /* | 1366 | /* |
1353 | * Debugfs info | 1367 | * Debugfs info |
1354 | */ | 1368 | */ |