Commit 961fb597 authored by Jerome Glisse's avatar Jerome Glisse Committed by Dave Airlie

drm/radeon/kms: r600/r700 command stream checker

This patch add cs checker to r600/r700 hw. Command stream checking
will rewrite some of the cs value in order to restrict GPU access
to BO size. This doesn't break old userspace but just enforce safe
value. It should break any things that was using the r600/r700 cs
ioctl to do forbidden things (malicious software), though we are
not aware of such things.

Here is the list of thing we check :
- enforcing resource size
- enforcing color buffer slice tile max, will restrict cb access
- enforcing db buffer slice tile max, will restrict db access

We don't check for shader bigger than the BO in which they are
supposed to be, such use would lead to GPU lockup and is harmless
from security POV, as far as we can tell (note that even checking
for this wouldn't prevent someone to write bogus shader that lead
to lockup).

This patch has received as much testing as humanly possible with
old userspace to check that it didn't break such configuration.
However not all the applications out there were tested, thus it
might broke some odd, rare applications.

[airlied: fix rules for cs checker for parallel builds]
Signed-off-by: default avatarJerome Glisse <jglisse@redhat.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 4c36b678
...@@ -30,6 +30,9 @@ $(obj)/r420_reg_safe.h: $(src)/reg_srcs/r420 $(obj)/mkregtable ...@@ -30,6 +30,9 @@ $(obj)/r420_reg_safe.h: $(src)/reg_srcs/r420 $(obj)/mkregtable
$(obj)/rs600_reg_safe.h: $(src)/reg_srcs/rs600 $(obj)/mkregtable $(obj)/rs600_reg_safe.h: $(src)/reg_srcs/rs600 $(obj)/mkregtable
$(call if_changed,mkregtable) $(call if_changed,mkregtable)
$(obj)/r600_reg_safe.h: $(src)/reg_srcs/r600 $(obj)/mkregtable
$(call if_changed,mkregtable)
$(obj)/r100.o: $(obj)/r100_reg_safe.h $(obj)/rn50_reg_safe.h $(obj)/r100.o: $(obj)/r100_reg_safe.h $(obj)/rn50_reg_safe.h
$(obj)/r200.o: $(obj)/r200_reg_safe.h $(obj)/r200.o: $(obj)/r200_reg_safe.h
...@@ -42,6 +45,8 @@ $(obj)/r420.o: $(obj)/r420_reg_safe.h ...@@ -42,6 +45,8 @@ $(obj)/r420.o: $(obj)/r420_reg_safe.h
$(obj)/rs600.o: $(obj)/rs600_reg_safe.h $(obj)/rs600.o: $(obj)/rs600_reg_safe.h
$(obj)/r600_cs.o: $(obj)/r600_reg_safe.h
radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \ radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \
radeon_irq.o r300_cmdbuf.o r600_cp.o radeon_irq.o r300_cmdbuf.o r600_cp.o
# add KMS driver # add KMS driver
......
...@@ -1077,21 +1077,27 @@ void r600_gpu_init(struct radeon_device *rdev) ...@@ -1077,21 +1077,27 @@ void r600_gpu_init(struct radeon_device *rdev)
switch (rdev->config.r600.max_tile_pipes) { switch (rdev->config.r600.max_tile_pipes) {
case 1: case 1:
tiling_config |= PIPE_TILING(0); tiling_config |= PIPE_TILING(0);
rdev->config.r600.tiling_npipes = 1;
break; break;
case 2: case 2:
tiling_config |= PIPE_TILING(1); tiling_config |= PIPE_TILING(1);
rdev->config.r600.tiling_npipes = 2;
break; break;
case 4: case 4:
tiling_config |= PIPE_TILING(2); tiling_config |= PIPE_TILING(2);
rdev->config.r600.tiling_npipes = 4;
break; break;
case 8: case 8:
tiling_config |= PIPE_TILING(3); tiling_config |= PIPE_TILING(3);
rdev->config.r600.tiling_npipes = 8;
break; break;
default: default:
break; break;
} }
rdev->config.r600.tiling_nbanks = 4 << ((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT);
tiling_config |= BANK_TILING((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); tiling_config |= BANK_TILING((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT);
tiling_config |= GROUP_SIZE(0); tiling_config |= GROUP_SIZE(0);
rdev->config.r600.tiling_group_size = 256;
tmp = (ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT; tmp = (ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT;
if (tmp > 3) { if (tmp > 3) {
tiling_config |= ROW_TILING(3); tiling_config |= ROW_TILING(3);
......
...@@ -873,6 +873,17 @@ static void r600_gfx_init(struct drm_device *dev, ...@@ -873,6 +873,17 @@ static void r600_gfx_init(struct drm_device *dev,
RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config); RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config);
RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff));
RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff));
if (gb_tiling_config & 0xc0) {
dev_priv->r600_group_size = 512;
} else {
dev_priv->r600_group_size = 256;
}
dev_priv->r600_npipes = 1 << ((gb_tiling_config >> 1) & 0x7);
if (gb_tiling_config & 0x30) {
dev_priv->r600_nbanks = 8;
} else {
dev_priv->r600_nbanks = 4;
}
RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable);
RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
...@@ -1444,6 +1455,17 @@ static void r700_gfx_init(struct drm_device *dev, ...@@ -1444,6 +1455,17 @@ static void r700_gfx_init(struct drm_device *dev,
RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config); RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config);
RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff));
RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff));
if (gb_tiling_config & 0xc0) {
dev_priv->r600_group_size = 512;
} else {
dev_priv->r600_group_size = 256;
}
dev_priv->r600_npipes = 1 << ((gb_tiling_config >> 1) & 0x7);
if (gb_tiling_config & 0x30) {
dev_priv->r600_nbanks = 8;
} else {
dev_priv->r600_nbanks = 4;
}
RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable);
RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
...@@ -2526,3 +2548,12 @@ int r600_cs_legacy_ioctl(struct drm_device *dev, void *data, struct drm_file *fp ...@@ -2526,3 +2548,12 @@ int r600_cs_legacy_ioctl(struct drm_device *dev, void *data, struct drm_file *fp
mutex_unlock(&dev_priv->cs_mutex); mutex_unlock(&dev_priv->cs_mutex);
return r; return r;
} }
void r600_cs_legacy_get_tiling_conf(struct drm_device *dev, u32 *npipes, u32 *nbanks, u32 *group_size)
{
struct drm_radeon_private *dev_priv = dev->dev_private;
*npipes = dev_priv->r600_npipes;
*nbanks = dev_priv->r600_nbanks;
*group_size = dev_priv->r600_group_size;
}
This diff is collapsed.
This diff is collapsed.
...@@ -808,6 +808,9 @@ struct r600_asic { ...@@ -808,6 +808,9 @@ struct r600_asic {
unsigned sx_max_export_pos_size; unsigned sx_max_export_pos_size;
unsigned sx_max_export_smx_size; unsigned sx_max_export_smx_size;
unsigned sq_num_cf_insts; unsigned sq_num_cf_insts;
unsigned tiling_nbanks;
unsigned tiling_npipes;
unsigned tiling_group_size;
}; };
struct rv770_asic { struct rv770_asic {
...@@ -828,6 +831,9 @@ struct rv770_asic { ...@@ -828,6 +831,9 @@ struct rv770_asic {
unsigned sc_prim_fifo_size; unsigned sc_prim_fifo_size;
unsigned sc_hiz_tile_fifo_size; unsigned sc_hiz_tile_fifo_size;
unsigned sc_earlyz_tile_fifo_fize; unsigned sc_earlyz_tile_fifo_fize;
unsigned tiling_nbanks;
unsigned tiling_npipes;
unsigned tiling_group_size;
}; };
union radeon_asic_config { union radeon_asic_config {
......
...@@ -294,6 +294,9 @@ typedef struct drm_radeon_private { ...@@ -294,6 +294,9 @@ typedef struct drm_radeon_private {
int r700_sc_prim_fifo_size; int r700_sc_prim_fifo_size;
int r700_sc_hiz_tile_fifo_size; int r700_sc_hiz_tile_fifo_size;
int r700_sc_earlyz_tile_fifo_fize; int r700_sc_earlyz_tile_fifo_fize;
int r600_group_size;
int r600_npipes;
int r600_nbanks;
struct mutex cs_mutex; struct mutex cs_mutex;
u32 cs_id_scnt; u32 cs_id_scnt;
......
This diff is collapsed.
...@@ -516,15 +516,19 @@ static void rv770_gpu_init(struct radeon_device *rdev) ...@@ -516,15 +516,19 @@ static void rv770_gpu_init(struct radeon_device *rdev)
switch (rdev->config.rv770.max_tile_pipes) { switch (rdev->config.rv770.max_tile_pipes) {
case 1: case 1:
gb_tiling_config |= PIPE_TILING(0); gb_tiling_config |= PIPE_TILING(0);
rdev->config.rv770.tiling_npipes = 1;
break; break;
case 2: case 2:
gb_tiling_config |= PIPE_TILING(1); gb_tiling_config |= PIPE_TILING(1);
rdev->config.rv770.tiling_npipes = 2;
break; break;
case 4: case 4:
gb_tiling_config |= PIPE_TILING(2); gb_tiling_config |= PIPE_TILING(2);
rdev->config.rv770.tiling_npipes = 4;
break; break;
case 8: case 8:
gb_tiling_config |= PIPE_TILING(3); gb_tiling_config |= PIPE_TILING(3);
rdev->config.rv770.tiling_npipes = 8;
break; break;
default: default:
break; break;
...@@ -534,8 +538,10 @@ static void rv770_gpu_init(struct radeon_device *rdev) ...@@ -534,8 +538,10 @@ static void rv770_gpu_init(struct radeon_device *rdev)
gb_tiling_config |= BANK_TILING(1); gb_tiling_config |= BANK_TILING(1);
else else
gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT);
rdev->config.rv770.tiling_nbanks = 4 << ((gb_tiling_config >> 4) & 0x3);
gb_tiling_config |= GROUP_SIZE(0); gb_tiling_config |= GROUP_SIZE(0);
rdev->config.rv770.tiling_group_size = 256;
if (((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT) > 3) { if (((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT) > 3) {
gb_tiling_config |= ROW_TILING(3); gb_tiling_config |= ROW_TILING(3);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment