OSDN Git Service

Changed unsigned to uint32_t in some ioctl parameters. Introduced first
authorThomas Hellstrom <unichrome@shipmail.org>
Fri, 8 Oct 2004 21:11:02 +0000 (21:11 +0000)
committerThomas Hellstrom <unichrome@shipmail.org>
Fri, 8 Oct 2004 21:11:02 +0000 (21:11 +0000)
    rudimentary command verifier for dma buffers. Changed the decoder futex
    ioctl parameters. Bumped the via major version number.

shared-core/via_dma.c
shared-core/via_drm.h
shared-core/via_drv.c
shared-core/via_map.c
shared-core/via_mm.c
shared/via_dma.c
shared/via_drm.h
shared/via_drv.c
shared/via_map.c
shared/via_mm.c

index a48cb88..773356f 100644 (file)
@@ -23,6 +23,57 @@ static void via_cmdbuf_reset(drm_via_private_t * dev_priv);
 static void via_cmdbuf_rewind(drm_via_private_t * dev_priv);
 static int via_wait_idle(drm_via_private_t * dev_priv);
 
+
+/*
+ * This function needs to be extended whenever a new command set
+ * is implemented. Currently it works only for the 2D engine
+ * command, which on the Unichrome allows writing to
+ * at least the 2D engine and the mpeg engine, but not the
+ * video engine.
+ *
+ * If you update this function with new commands, please also
+ * consider implementing these commands in 
+ * via_parse_pci_cmdbuffer below.
+ *
+ * Carefully review this function for security holes 
+ * after an update!!!!!!!!!
+ */
+
+static int via_check_command_stream(const uint32_t *buf,
+                                   unsigned int size) 
+{
+
+       uint32_t offset;
+       unsigned int i;
+
+       if (size & 7) {
+               DRM_ERROR("Illegal command buffer size.\n");
+               return DRM_ERR( EINVAL );
+       }
+       size >>=3;
+       for (i=0; i<size; ++i) {
+               offset = *buf; 
+               buf += 2;
+               if ((offset > ((0x3FF >> 2) | VIA_2D_CMD)) && 
+                   (offset < ((0xC00 >> 2) | VIA_2D_CMD)) ) {
+                       DRM_ERROR("Attempt to access Burst Command / 3D Area.\n");
+                       return DRM_ERR( EINVAL );
+               } else if (offset > ((0xDFF >> 2) | VIA_2D_CMD)) {
+                       DRM_ERROR("Attempt to access DMA or VGA registers.\n");
+                       return DRM_ERR( EINVAL );
+               }
+
+               /*
+                * ...
+                * A volunteer should complete this to allow non-root
+                * usage of accelerated 3D OpenGL.
+                */
+
+       }
+       return 0;
+}
+  
+
 static inline int
 via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size)
 {
@@ -160,6 +211,8 @@ static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd)
 {
        drm_via_private_t *dev_priv = dev->dev_private;
        uint32_t *vb;
+       int ret;
+
        vb = via_check_dma(dev_priv, cmd->size);
        if (vb == NULL) {
                return DRM_ERR(EAGAIN);
@@ -167,6 +220,10 @@ static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd)
        if (DRM_COPY_FROM_USER(vb, cmd->buf, cmd->size)) {
                return DRM_ERR(EFAULT);
        }
+         
+       if ((ret = via_check_command_stream( vb, cmd->size)))
+               return ret;
+
        dev_priv->dma_low += cmd->size;
        via_cmdbuf_pause(dev_priv);
 
@@ -226,22 +283,12 @@ static int via_parse_pci_cmdbuffer(drm_device_t * dev, const char *buf,
        uint32_t offset, value;
        const uint32_t *regbuf = (uint32_t *) buf;
        unsigned int i;
+       int ret;
 
-       size >>= 3;
-       for (i = 0; i < size; ++i) {
-               offset = *regbuf;
-               regbuf += 2;
-               if ((offset > ((0x7FF >> 2) | VIA_2D_CMD)) &&
-                   (offset < ((0xC00 >> 2) | VIA_2D_CMD))) {
-                       DRM_DEBUG("Attempt to access Burst Command Area.\n");
-                       return DRM_ERR(EINVAL);
-               } else if (offset > ((0xDFF >> 2) | VIA_2D_CMD)) {
-                       DRM_DEBUG("Attempt to access DMA or VGA registers.\n");
-                       return DRM_ERR(EINVAL);
-               }
-       }
+       if ((ret = via_check_command_stream( regbuf, size)))
+               return ret;
 
-       regbuf = (uint32_t *) buf;
+       size >>= 3;
        for (i = 0; i < size; ++i) {
                offset = (*regbuf++ & ~VIA_2D_CMD) << 2;
                value = *regbuf++;
index 5b12149..a90366f 100644 (file)
 #define VIDEO 0
 #define AGP 1
 typedef struct {
-       unsigned int offset;
-       unsigned int size;
+       uint32_t offset;
+       uint32_t size;
 } drm_via_agp_t;
 
 typedef struct {
-       unsigned int offset;
-       unsigned int size;
+       uint32_t offset;
+       uint32_t size;
 } drm_via_fb_t;
 
 typedef struct {
-       unsigned int context;
-       unsigned int type;
-       unsigned int size;
+        uint32_t context;
+       uint32_t type;
+       uint32_t size;
        unsigned long index;
        unsigned long offset;
 } drm_via_mem_t;
@@ -134,11 +134,10 @@ typedef struct _drm_via_futex {
        enum {
                VIA_FUTEX_WAIT = 0x00,
                VIA_FUTEX_WAKE = 0X01
-       } fut;
-       unsigned int op;
-       unsigned int ms;
-       unsigned int lock;
-       unsigned int val;
+       } func;
+       uint32_t ms;
+       uint32_t lock;
+       uint32_t val;
 } drm_via_futex_t;
 
 typedef struct _drm_via_dma_init {
index 291cc76..4ec0124 100644 (file)
 
 #define DRIVER_NAME            "via"
 #define DRIVER_DESC            "VIA Unichrome"
-#define DRIVER_DATE            "20040907"
+#define DRIVER_DATE            "20041010"
 
-#define DRIVER_MAJOR           1
-#define DRIVER_MINOR           5
+#define DRIVER_MAJOR           2
+#define DRIVER_MINOR           0
 #define DRIVER_PATCHLEVEL      0
 
 #include "drm_pciids.h"
index 096e3e1..84b818b 100644 (file)
@@ -124,7 +124,7 @@ int via_decoder_futex(DRM_IOCTL_ARGS)
 
        lock = XVMCLOCKPTR(sAPriv, fx.lock);
 
-       switch (fx.op) {
+       switch (fx.func) {
        case VIA_FUTEX_WAIT:
                DRM_WAIT_ON(ret, dev_priv->decoder_queue[fx.lock],
                            (fx.ms / 10) * (DRM_HZ / 100), *lock != fx.val);
index c08385c..169ad26 100644 (file)
@@ -77,7 +77,7 @@ int via_agp_init(DRM_IOCTL_ARGS)
 
        AgpHeap = via_mmInit(agp.offset, agp.size);
 
-       DRM_DEBUG("offset = %u, size = %u", agp.offset, agp.size);
+       DRM_DEBUG("offset = %lu, size = %lu", agp.offset, agp.size);
 
        return 0;
 }
@@ -93,7 +93,7 @@ int via_fb_init(DRM_IOCTL_ARGS)
 
        FBHeap = via_mmInit(fb.offset, fb.size);
 
-       DRM_DEBUG("offset = %u, size = %u", fb.offset, fb.size);
+       DRM_DEBUG("offset = %lu, size = %lu", fb.offset, fb.size);
 
        return 0;
 }
index 4afc521..d9a1fb1 100644 (file)
@@ -24,6 +24,57 @@ static void via_cmdbuf_reset(drm_via_private_t * dev_priv);
 static void via_cmdbuf_rewind(drm_via_private_t * dev_priv);
 static int  via_wait_idle(drm_via_private_t * dev_priv);
 
+
+/*
+ * This function needs to be extended whenever a new command set
+ * is implemented. Currently it works only for the 2D engine
+ * command, which on the Unichrome allows writing to
+ * at least the 2D engine and the mpeg engine, but not the
+ * video engine.
+ *
+ * If you update this function with new commands, please also
+ * consider implementing these commands in 
+ * via_parse_pci_cmdbuffer below.
+ *
+ * Carefully review this function for security holes 
+ * after an update!!!!!!!!!
+ */
+
+static int via_check_command_stream(const uint32_t *buf,
+                                   unsigned int size) 
+{
+
+       uint32_t offset;
+       unsigned int i;
+
+       if (size & 7) {
+               DRM_ERROR("Illegal command buffer size.\n");
+               return DRM_ERR( EINVAL );
+       }
+       size >>=3;
+       for (i=0; i<size; ++i) {
+               offset = *buf; 
+               buf += 2;
+               if ((offset > ((0x3FF >> 2) | VIA_2D_CMD)) && 
+                   (offset < ((0xC00 >> 2) | VIA_2D_CMD)) ) {
+                       DRM_ERROR("Attempt to access Burst Command / 3D Area.\n");
+                       return DRM_ERR( EINVAL );
+               } else if (offset > ((0xDFF >> 2) | VIA_2D_CMD)) {
+                       DRM_ERROR("Attempt to access DMA or VGA registers.\n");
+                       return DRM_ERR( EINVAL );
+               }
+
+               /*
+                * ...
+                * A volunteer should complete this to allow non-root
+                * usage of accelerated 3D OpenGL.
+                */
+
+       }
+       return 0;
+}
+  
+
 static inline int
 via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size)
 {
@@ -163,6 +214,8 @@ static int via_dispatch_cmdbuffer(drm_device_t *dev,
 {
        drm_via_private_t *dev_priv = dev->dev_private;
        uint32_t * vb;
+       int ret;
+
        vb = via_check_dma(dev_priv, cmd->size);
        if (vb == NULL) {
                return DRM_ERR(EAGAIN);
@@ -170,6 +223,10 @@ static int via_dispatch_cmdbuffer(drm_device_t *dev,
        if (DRM_COPY_FROM_USER(vb, cmd->buf, cmd->size)) {
                return DRM_ERR(EFAULT);
        }
+         
+       if ((ret = via_check_command_stream( vb, cmd->size)))
+               return ret;
+
        dev_priv->dma_low += cmd->size;
        via_cmdbuf_pause(dev_priv);
 
@@ -225,6 +282,7 @@ int via_cmdbuffer( DRM_IOCTL_ARGS )
        return 0;
 }
 
+
 static int via_parse_pci_cmdbuffer( drm_device_t *dev, const char *buf, 
                                    unsigned int size )
 {
@@ -232,22 +290,12 @@ static int via_parse_pci_cmdbuffer( drm_device_t *dev, const char *buf,
        uint32_t offset, value;
        const uint32_t *regbuf = (uint32_t *)buf;
        unsigned int i;
+       int ret;
 
+       if ((ret = via_check_command_stream( regbuf, size)))
+               return ret;
+               
        size >>=3 ;
-       for (i=0; i<size; ++i) {
-               offset = *regbuf; 
-               regbuf += 2;
-               if ((offset > ((0x7FF >> 2) | VIA_2D_CMD)) && 
-                   (offset < ((0xC00 >> 2) | VIA_2D_CMD)) ) {
-                       DRM_DEBUG("Attempt to access Burst Command Area.\n");
-                       return DRM_ERR( EINVAL );
-               } else if (offset > ((0xDFF >> 2) | VIA_2D_CMD)) {
-                       DRM_DEBUG("Attempt to access DMA or VGA registers.\n");
-                       return DRM_ERR( EINVAL );
-               }
-       }
-                       
-       regbuf = (uint32_t *)buf;
        for ( i=0; i<size; ++i ) {
                offset = (*regbuf++ & ~VIA_2D_CMD) << 2;
                value = *regbuf++;
index ddc89f8..52adade 100644 (file)
 #define VIDEO 0
 #define AGP 1
 typedef struct {
-        unsigned int offset;
-        unsigned int size;
+        unsigned long offset;
+        unsigned long size;
 } drm_via_agp_t;    
 
 typedef struct {
-        unsigned int offset;
-        unsigned int size;
+        unsigned long offset;
+        unsigned long size;
 } drm_via_fb_t;    
 
 typedef struct {
-        unsigned int context;
-        unsigned int type;
-        unsigned int size;
+        uint32_t context;
+        uint32_t type;
+        unsigned long size;
         unsigned long index;
         unsigned long offset;
 } drm_via_mem_t;    
@@ -123,11 +123,10 @@ typedef struct _drm_via_futex {
         enum {
                 VIA_FUTEX_WAIT = 0x00,
                 VIA_FUTEX_WAKE = 0X01
-        }fut;
-        unsigned int op;
-        unsigned int ms;
-        unsigned int lock;
-        unsigned int val;
+        } func;
+        uint32_t ms;
+        uint32_t lock;
+        uint32_t val;
 } drm_via_futex_t;
 
 typedef struct _drm_via_dma_init {
index 7b6e1b9..ebff300 100644 (file)
 
 #define DRIVER_NAME            "via"
 #define DRIVER_DESC            "VIA Unichrome"
-#define DRIVER_DATE            "20040907"
+#define DRIVER_DATE            "20041010"
 
-#define DRIVER_MAJOR           1
-#define DRIVER_MINOR           5
+#define DRIVER_MAJOR           2
+#define DRIVER_MINOR           0
 #define DRIVER_PATCHLEVEL      0
 
 
index f08503d..7d3ebf2 100644 (file)
@@ -127,7 +127,7 @@ int via_decoder_futex( DRM_IOCTL_ARGS )
 
         lock = XVMCLOCKPTR(sAPriv,fx.lock);
 
-        switch(fx.op) {
+        switch(fx.func) {
         case VIA_FUTEX_WAIT:
                 DRM_WAIT_ON(ret, dev_priv->decoder_queue[fx.lock], 
                             (fx.ms / 10)*(DRM_HZ/100), 
index 2a9be68..5a30e30 100644 (file)
@@ -80,7 +80,7 @@ int via_agp_init( DRM_IOCTL_ARGS )
 
         AgpHeap = via_mmInit(agp.offset, agp.size);
 
-        DRM_DEBUG("offset = %u, size = %u", agp.offset, agp.size);
+        DRM_DEBUG("offset = %lu, size = %lu", agp.offset, agp.size);
   
         return 0;
 }
@@ -97,7 +97,7 @@ int via_fb_init( DRM_IOCTL_ARGS )
 
         FBHeap = via_mmInit(fb.offset, fb.size);
 
-        DRM_DEBUG("offset = %u, size = %u", fb.offset, fb.size);
+        DRM_DEBUG("offset = %lu, size = %lu", fb.offset, fb.size);
 
         return 0;
 }