lkml.org 
[lkml]   [2013]   [Sep]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 006/104] drm/vmwgfx: Split GMR2_REMAP commands if they are to large
    Date
    3.5.7.22 -stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Jakob Bornecrantz <jakob@vmware.com>

    commit 6e4dcff3adbf25acb87e74500a58e3c07bdec40f upstream.

    This fixes the piglit test texturing/max-texture-size
    causing the VM to die due to a too large SVGA command.

    Signed-off-by: Jakob Bornecrantz <jakob@vmware.com>
    Reviewed-by: Biran Paul <brianp@vmware.com>
    Reviewed-by: Zack Rusin <zackr@vmware.com>
    Signed-off-by: Dave Airlie <airlied@gmail.com>
    Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
    ---
    drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c | 58 +++++++++++++++++++++++++------------
    1 file changed, 39 insertions(+), 19 deletions(-)

    diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
    index 21ee782..e1978a2 100644
    --- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
    +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
    @@ -29,7 +29,9 @@
    #include "drmP.h"
    #include "ttm/ttm_bo_driver.h"

    -#define VMW_PPN_SIZE sizeof(unsigned long)
    +#define VMW_PPN_SIZE (sizeof(unsigned long))
    +/* A future safe maximum remap size. */
    +#define VMW_PPN_PER_REMAP ((31 * 1024) / VMW_PPN_SIZE)

    static int vmw_gmr2_bind(struct vmw_private *dev_priv,
    struct page *pages[],
    @@ -38,43 +40,61 @@ static int vmw_gmr2_bind(struct vmw_private *dev_priv,
    {
    SVGAFifoCmdDefineGMR2 define_cmd;
    SVGAFifoCmdRemapGMR2 remap_cmd;
    - uint32_t define_size = sizeof(define_cmd) + 4;
    - uint32_t remap_size = VMW_PPN_SIZE * num_pages + sizeof(remap_cmd) + 4;
    uint32_t *cmd;
    uint32_t *cmd_orig;
    + uint32_t define_size = sizeof(define_cmd) + sizeof(*cmd);
    + uint32_t remap_num = num_pages / VMW_PPN_PER_REMAP + ((num_pages % VMW_PPN_PER_REMAP) > 0);
    + uint32_t remap_size = VMW_PPN_SIZE * num_pages + (sizeof(remap_cmd) + sizeof(*cmd)) * remap_num;
    + uint32_t remap_pos = 0;
    + uint32_t cmd_size = define_size + remap_size;
    uint32_t i;

    - cmd_orig = cmd = vmw_fifo_reserve(dev_priv, define_size + remap_size);
    + cmd_orig = cmd = vmw_fifo_reserve(dev_priv, cmd_size);
    if (unlikely(cmd == NULL))
    return -ENOMEM;

    define_cmd.gmrId = gmr_id;
    define_cmd.numPages = num_pages;

    + *cmd++ = SVGA_CMD_DEFINE_GMR2;
    + memcpy(cmd, &define_cmd, sizeof(define_cmd));
    + cmd += sizeof(define_cmd) / sizeof(*cmd);
    +
    + /*
    + * Need to split the command if there are too many
    + * pages that goes into the gmr.
    + */
    +
    remap_cmd.gmrId = gmr_id;
    remap_cmd.flags = (VMW_PPN_SIZE > sizeof(*cmd)) ?
    SVGA_REMAP_GMR2_PPN64 : SVGA_REMAP_GMR2_PPN32;
    - remap_cmd.offsetPages = 0;
    - remap_cmd.numPages = num_pages;

    - *cmd++ = SVGA_CMD_DEFINE_GMR2;
    - memcpy(cmd, &define_cmd, sizeof(define_cmd));
    - cmd += sizeof(define_cmd) / sizeof(uint32);
    + while (num_pages > 0) {
    + unsigned long nr = min(num_pages, (unsigned long)VMW_PPN_PER_REMAP);
    +
    + remap_cmd.offsetPages = remap_pos;
    + remap_cmd.numPages = nr;

    - *cmd++ = SVGA_CMD_REMAP_GMR2;
    - memcpy(cmd, &remap_cmd, sizeof(remap_cmd));
    - cmd += sizeof(remap_cmd) / sizeof(uint32);
    + *cmd++ = SVGA_CMD_REMAP_GMR2;
    + memcpy(cmd, &remap_cmd, sizeof(remap_cmd));
    + cmd += sizeof(remap_cmd) / sizeof(*cmd);

    - for (i = 0; i < num_pages; ++i) {
    - if (VMW_PPN_SIZE <= 4)
    - *cmd = page_to_pfn(*pages++);
    - else
    - *((uint64_t *)cmd) = page_to_pfn(*pages++);
    + for (i = 0; i < nr; ++i) {
    + if (VMW_PPN_SIZE <= 4)
    + *cmd = page_to_pfn(*pages++);
    + else
    + *((uint64_t *)cmd) = page_to_pfn(*pages++);

    - cmd += VMW_PPN_SIZE / sizeof(*cmd);
    + cmd += VMW_PPN_SIZE / sizeof(*cmd);
    + }
    +
    + num_pages -= nr;
    + remap_pos += nr;
    }

    - vmw_fifo_commit(dev_priv, define_size + remap_size);
    + BUG_ON(cmd != cmd_orig + cmd_size / sizeof(*cmd));
    +
    + vmw_fifo_commit(dev_priv, cmd_size);

    return 0;
    }
    --
    1.8.3.2


    \
     
     \ /
      Last update: 2013-09-30 13:21    [W:4.099 / U:0.068 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site