From patchwork Fri Sep 20 06:57:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 1987668 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4X939T0pdjz1y27 for ; Fri, 20 Sep 2024 16:57:33 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1srXa0-0007SQ-9K; Fri, 20 Sep 2024 06:57:24 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1srXZx-0007RW-BA for kernel-team@lists.ubuntu.com; Fri, 20 Sep 2024 06:57:21 +0000 Received: from mail-pg1-f199.google.com (mail-pg1-f199.google.com [209.85.215.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 07FC33F078 for ; Fri, 20 Sep 2024 06:57:21 +0000 (UTC) Received: by mail-pg1-f199.google.com with SMTP id 41be03b00d2f7-7db1762d70fso1957088a12.2 for ; Thu, 19 Sep 2024 23:57:20 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726815439; x=1727420239; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1QqLtLVwvWfeQvEB+MdiFaoOrxR1j28t3xdN2VmqrGU=; b=S+zD5O3uSoSWLcK/Umi7QHXR73fUC/SiJdIYE/MkGE4WIMSKbfm1jrRUr3xJiknUq+ m81wqAJPFt9+IvgP+8k4fMXz3KtLHZlJI76magntMIhPOi3DCRDVHyZn1DSo7LTz10qv sjmVnFlRpHBDmw5j1UUWoiWERcPIyshD8skvjJk/Ou9UztmREn9GAwJL3vzWWbawrrne xUh35Ji1lH5lVh1zluw7Xw/1B0D73HZ/b6V1Xr53A/YyoZInu8F8OZFwTaD1Yd3jzsqn Sn2QvA0Hu5VKzbpi4+v5ZphhGBly+NN80FjupIHgeoaxWkUS1cDoxjD+N3s8XYpjwXWn bRLg== X-Gm-Message-State: AOJu0YwMHIOnXAuBQYmKt81qdburUNPtIAhZkDmHToQPjQFjsyyikzh8 2EUQTCo3YTdiLOOf1O7/LLB3UkTISLEwijW63R0vUJDxVmbqd7lWeTS9HI6i4yQYqoVWfemy0/j KiWdq09SZLdFB7C16r2d4H1Cebw8K84AbPItyeAj9GxFA32XpXvVJ1083spGL5IhS8DVScuEd+4 6yFWBNeKyUnQ== X-Received: by 2002:a05:6a20:cfa4:b0:1d2:e987:c343 with SMTP id adf61e73a8af0-1d30a925578mr3365201637.24.1726815439266; Thu, 19 Sep 2024 23:57:19 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGyvy9zXnjFIWU59bXiCaHbIjJ2XA2U3v09nezEyPBp/UShwMyxwhlLnsAzZBOCMOETbRxvyg== X-Received: by 2002:a05:6a20:cfa4:b0:1d2:e987:c343 with SMTP id adf61e73a8af0-1d30a925578mr3365168637.24.1726815438653; Thu, 19 Sep 2024 23:57:18 -0700 (PDT) Received: from z790sl.. ([240f:74:7be:1:2047:317d:d246:e876]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-71944bc3275sm9212428b3a.198.2024.09.19.23.57.16 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2024 23:57:17 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][F][PATCH 1/2] drm/vmwgfx: Use enum to represent graphics context capabilities Date: Fri, 20 Sep 2024 15:57:05 +0900 Message-ID: <20240920065711.8902-2-koichiro.den@canonical.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240920065711.8902-1-koichiro.den@canonical.com> References: <20240920065711.8902-1-koichiro.den@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Deepak Rawat Instead of having different bool in device private to represent incremental graphics context capabilities, add a new sm type enum. v2: Use enum instead of bit flag. v3: Incorporated review comments. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellström (VMware) Reviewed-by: Roland Scheidegger Signed-off-by: Roland Scheidegger (backported from commit 878c6ecd3e24dc215a9f5e1c32b9873be35c1ff0) [koichiroden: Adjusted context due to missing commits: 2bdb7380fe12 ("drm/vmwgfx: Remove a few unused functions") ef7c7b7497d6 ("drm/vmwgfx: Also check for SVGA_CAP_DX before reading DX context support")] CVE-2022-36402 Signed-off-by: Koichiro Den --- drivers/gpu/drm/vmwgfx/vmwgfx_context.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 34 ++++++++++----------- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 40 +++++++++++++++++++++++-- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 6 ++-- drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 4 +-- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_mob.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 10 +++---- 8 files changed, 69 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c index a56c9d802382..0477d9a74fe8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c @@ -731,7 +731,7 @@ static int vmw_context_define(struct drm_device *dev, void *data, }; int ret; - if (!dev_priv->has_dx && dx) { + if (!has_sm4_context(dev_priv) && dx) { VMW_DEBUG_USER("DX contexts not supported by device.\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index b38bcb032c99..20b726e0a936 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -442,7 +442,7 @@ static int vmw_request_device(struct vmw_private *dev_priv) dev_priv->cman = vmw_cmdbuf_man_create(dev_priv); if (IS_ERR(dev_priv->cman)) { dev_priv->cman = NULL; - dev_priv->has_dx = false; + dev_priv->sm_type = VMW_SM_LEGACY; } ret = vmw_request_device_late(dev_priv); @@ -870,11 +870,22 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) if (dev_priv->has_mob) { spin_lock(&dev_priv->cap_lock); vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_DXCONTEXT); - dev_priv->has_dx = !!vmw_read(dev_priv, SVGA_REG_DEV_CAP); + if (vmw_read(dev_priv, SVGA_REG_DEV_CAP)) + dev_priv->sm_type = VMW_SM_4; spin_unlock(&dev_priv->cap_lock); } vmw_validation_mem_init_ttm(dev_priv, VMWGFX_VALIDATION_MEM_GRAN); + + /* SVGA_CAP2_DX2 (DefineGBSurface_v3) is needed for SM4_1 support */ + if (has_sm4_context(dev_priv) && + (dev_priv->capabilities2 & SVGA_CAP2_DX2)) { + vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_SM41); + + if (vmw_read(dev_priv, SVGA_REG_DEV_CAP)) + dev_priv->sm_type = VMW_SM_4_1; + } + ret = vmw_kms_init(dev_priv); if (unlikely(ret != 0)) goto out_no_kms; @@ -884,23 +895,12 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) if (ret) goto out_no_fifo; - if (dev_priv->has_dx) { - /* - * SVGA_CAP2_DX2 (DefineGBSurface_v3) is needed for SM4_1 - * support - */ - if ((dev_priv->capabilities2 & SVGA_CAP2_DX2) != 0) { - vmw_write(dev_priv, SVGA_REG_DEV_CAP, - SVGA3D_DEVCAP_SM41); - dev_priv->has_sm4_1 = vmw_read(dev_priv, - SVGA_REG_DEV_CAP); - } - } - - DRM_INFO("DX: %s\n", dev_priv->has_dx ? "yes." : "no."); DRM_INFO("Atomic: %s\n", (dev->driver->driver_features & DRIVER_ATOMIC) ? "yes." : "no."); - DRM_INFO("SM4_1: %s\n", dev_priv->has_sm4_1 ? "yes." : "no."); + if (dev_priv->sm_type == VMW_SM_4_1) + DRM_INFO("SM4_1 support available.\n"); + if (dev_priv->sm_type == VMW_SM_4) + DRM_INFO("SM4 support available.\n"); snprintf(host_log, sizeof(host_log), "vmwgfx: %s-%s", VMWGFX_REPO, VMWGFX_GIT_VERSION); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 765f7a62870d..e65cba552e05 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -432,6 +432,20 @@ enum { VMW_IRQTHREAD_MAX }; +/** + * enum vmw_sm_type - Graphics context capability supported by device. + * @VMW_SM_LEGACY: Pre DX context. + * @VMW_SM_4: Context support upto SM4. + * @VMW_SM_4_1: Context support upto SM4_1. + * @VMW_SM_MAX: Should be the last. + */ +enum vmw_sm_type { + VMW_SM_LEGACY = 0, + VMW_SM_4, + VMW_SM_4_1, + VMW_SM_MAX +}; + struct vmw_private { struct ttm_bo_device bdev; @@ -465,9 +479,9 @@ struct vmw_private { bool has_mob; spinlock_t hw_lock; spinlock_t cap_lock; - bool has_dx; bool assume_16bpp; - bool has_sm4_1; + + enum vmw_sm_type sm_type; /* * VGA registers. @@ -651,6 +665,28 @@ static inline uint32_t vmw_read(struct vmw_private *dev_priv, return val; } +/** + * has_sm4_context - Does the device support SM4 context. + * @dev_priv: Device private. + * + * Return: Bool value if device support SM4 context or not. + */ +static inline bool has_sm4_context(const struct vmw_private *dev_priv) +{ + return (dev_priv->sm_type >= VMW_SM_4); +} + +/** + * has_sm4_1_context - Does the device support SM4_1 context. + * @dev_priv: Device private. + * + * Return: Bool value if device support SM4_1 context or not. + */ +static inline bool has_sm4_1_context(const struct vmw_private *dev_priv) +{ + return (dev_priv->sm_type >= VMW_SM_4_1); +} + extern void vmw_svga_enable(struct vmw_private *dev_priv); extern void vmw_svga_disable(struct vmw_private *dev_priv); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 8db3b3ddbb64..6f0c060a8726 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -461,7 +461,8 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, u32 i; /* Add all cotables to the validation list. */ - if (dev_priv->has_dx && vmw_res_type(ctx) == vmw_res_dx_context) { + if (has_sm4_context(dev_priv) && + vmw_res_type(ctx) == vmw_res_dx_context) { for (i = 0; i < SVGA_COTABLE_DX10_MAX; ++i) { res = vmw_context_cotable(ctx, i); if (IS_ERR(res)) @@ -489,7 +490,8 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, break; } - if (dev_priv->has_dx && vmw_res_type(ctx) == vmw_res_dx_context) { + if (has_sm4_context(dev_priv) && + vmw_res_type(ctx) == vmw_res_dx_context) { struct vmw_buffer_object *dx_query_mob; dx_query_mob = vmw_context_get_dx_query_mob(ctx); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index a15375eb476e..8812cf341ced 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -114,10 +114,10 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, (dev_priv->active_display_unit == vmw_du_screen_target); break; case DRM_VMW_PARAM_DX: - param->value = dev_priv->has_dx; + param->value = has_sm4_context(dev_priv); break; case DRM_VMW_PARAM_SM4_1: - param->value = dev_priv->has_sm4_1; + param->value = has_sm4_1_context(dev_priv); break; default: return -EINVAL; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 2492d3a19f36..3f57492059e1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -942,7 +942,7 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, * For DX, surface format validation is done when surface->scanout * is set. */ - if (!dev_priv->has_dx && format != surface->format) { + if (!has_sm4_context(dev_priv) && format != surface->format) { DRM_ERROR("Invalid surface format for requested mode.\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c index 0a6bbac00896..e8eb42933ca2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c @@ -320,7 +320,7 @@ int vmw_otables_setup(struct vmw_private *dev_priv) struct vmw_otable **otables = &dev_priv->otable_batch.otables; int ret; - if (dev_priv->has_dx) { + if (has_sm4_context(dev_priv)) { *otables = kmemdup(dx_tables, sizeof(dx_tables), GFP_KERNEL); if (!(*otables)) return -ENOMEM; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index 29d8794f0421..e36848a40c7f 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -1059,12 +1059,12 @@ static int vmw_gb_surface_create(struct vmw_resource *res) goto out_no_fifo; } - if (dev_priv->has_sm4_1 && srf->array_size > 0) { + if (has_sm4_1_context(dev_priv) && srf->array_size > 0) { cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V3; cmd_len = sizeof(cmd3->body); submit_len = sizeof(*cmd3); } else if (srf->array_size > 0) { - /* has_dx checked on creation time. */ + /* VMW_SM_4 support verified at creation time. */ cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V2; cmd_len = sizeof(cmd2->body); submit_len = sizeof(*cmd2); @@ -1082,7 +1082,7 @@ static int vmw_gb_surface_create(struct vmw_resource *res) goto out_no_fifo; } - if (dev_priv->has_sm4_1 && srf->array_size > 0) { + if (has_sm4_1_context(dev_priv) && srf->array_size > 0) { cmd3->header.id = cmd_id; cmd3->header.size = cmd_len; cmd3->body.sid = srf->res.id; @@ -1404,7 +1404,7 @@ int vmw_surface_gb_priv_define(struct drm_device *dev, } /* array_size must be null for non-GL3 host. */ - if (array_size > 0 && !dev_priv->has_dx) { + if (array_size > 0 && !has_sm4_context(dev_priv)) { VMW_DEBUG_USER("Tried to create DX surface on non-DX host.\n"); return -EINVAL; } @@ -1562,7 +1562,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev, SVGA3D_FLAGS_64(req->svga3d_flags_upper_32_bits, req->base.svga3d_flags); - if (!dev_priv->has_sm4_1) { + if (!has_sm4_1_context(dev_priv)) { /* * If SM4_1 is not support then cannot send 64-bit flag to * device. From patchwork Fri Sep 20 06:57:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 1987669 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4X939T1cjgz1y2j for ; Fri, 20 Sep 2024 16:57:33 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1srXa1-0007Sr-4H; Fri, 20 Sep 2024 06:57:25 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1srXZy-0007Rt-I7 for kernel-team@lists.ubuntu.com; Fri, 20 Sep 2024 06:57:22 +0000 Received: from mail-pg1-f200.google.com (mail-pg1-f200.google.com [209.85.215.200]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 5E6663F193 for ; Fri, 20 Sep 2024 06:57:22 +0000 (UTC) Received: by mail-pg1-f200.google.com with SMTP id 41be03b00d2f7-7d1fe1dd173so1426320a12.0 for ; Thu, 19 Sep 2024 23:57:22 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726815440; x=1727420240; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=mSKhzjnMPyA3b/sv+0BnYtcUhIRKmhX2wrmfhvcFFcw=; b=AE2/TP8KMtw5SX0YZeYoyEQsIZxILntA4iuSTfj5SUwFrDhNJnQtGnmkbazZCAa8jz zv0apTo3hn4f+/EnuRbr0Y8cmlerMUJOfH5r3viDm5VQyNtyEFSqrLzQEnHYZvZfpZNR ma4Q94YnnQ+NKlUQ8VncBlYVh/untXDdXRKw4FmWqaszZWGPcTrD29Vp2BBp6Faqbzpe 2ix81ewWpi54feu/Hu6LyXaXGflUiN/hbsEs8WrlTUcdKA9Z4lCHrmCQpPUrpkFC2V5F rY4Tx6Mdtd4+Lm4XUzqRe0Xtz6GPw/RjA1rIE7NWquGHEL/6jmNe+6P93sy/PgIdIGU0 T53Q== X-Gm-Message-State: AOJu0Yznl/fnRp6Vb1Q7vtD47cQP3qw6Wm9dKbPO9P7ZBnZY2csFt8+j GaK5DaF8fun5k+BmqY0C20XXvWlcBsTRCxp+Vqwz3+XWx+AnN/RVupwO01RAqFARMpOaWpdWRQw ZxJzpK/y7XutU6D0oeCfuqPjfR2+jAYQAUlhDGwtjyzDtR3NtyOEoZMcD5AzQHq62WKccPsdgc9 hnTQ5geuw93g== X-Received: by 2002:a05:6a20:9d92:b0:1d0:3a28:d2a7 with SMTP id adf61e73a8af0-1d30cb6b158mr2834107637.41.1726815440549; Thu, 19 Sep 2024 23:57:20 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFheFxboAG60tl/Ow5Q9L0GtHL4Euz+Sqmy+RZPvmFPu1b1c+KkMRF+HUop/Y31mnfarKxXng== X-Received: by 2002:a05:6a20:9d92:b0:1d0:3a28:d2a7 with SMTP id adf61e73a8af0-1d30cb6b158mr2834091637.41.1726815440049; Thu, 19 Sep 2024 23:57:20 -0700 (PDT) Received: from z790sl.. ([240f:74:7be:1:2047:317d:d246:e876]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-71944bc3275sm9212428b3a.198.2024.09.19.23.57.18 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2024 23:57:19 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][F][PATCH 2/2] drm/vmwgfx: Fix shader stage validation Date: Fri, 20 Sep 2024 15:57:06 +0900 Message-ID: <20240920065711.8902-3-koichiro.den@canonical.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240920065711.8902-1-koichiro.den@canonical.com> References: <20240920065711.8902-1-koichiro.den@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Zack Rusin For multiple commands the driver was not correctly validating the shader stages resulting in possible kernel oopses. The validation code was only. if ever, checking the upper bound on the shader stages but never a lower bound (valid shader stages start at 1 not 0). Fixes kernel oopses ending up in vmw_binding_add, e.g.: Oops: 0000 [#1] PREEMPT SMP PTI CPU: 1 PID: 2443 Comm: testcase Not tainted 6.3.0-rc4-vmwgfx #1 Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020 RIP: 0010:vmw_binding_add+0x4c/0x140 [vmwgfx] Code: 7e 30 49 83 ff 0e 0f 87 ea 00 00 00 4b 8d 04 7f 89 d2 89 cb 48 c1 e0 03 4c 8b b0 40 3d 93 c0 48 8b 80 48 3d 93 c0 49 0f af de <48> 03 1c d0 4c 01 e3 49 8> RSP: 0018:ffffb8014416b968 EFLAGS: 00010206 RAX: ffffffffc0933ec0 RBX: 0000000000000000 RCX: 0000000000000000 RDX: 00000000ffffffff RSI: ffffb8014416b9c0 RDI: ffffb8014316f000 RBP: ffffb8014416b998 R08: 0000000000000003 R09: 746f6c735f726564 R10: ffffffffaaf2bda0 R11: 732e676e69646e69 R12: ffffb8014316f000 R13: ffffb8014416b9c0 R14: 0000000000000040 R15: 0000000000000006 FS: 00007fba8c0af740(0000) GS:ffff8a1277c80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000007c0933eb8 CR3: 0000000118244001 CR4: 00000000003706e0 Call Trace: vmw_view_bindings_add+0xf5/0x1b0 [vmwgfx] ? ___drm_dbg+0x8a/0xb0 [drm] vmw_cmd_dx_set_shader_res+0x8f/0xc0 [vmwgfx] vmw_execbuf_process+0x590/0x1360 [vmwgfx] vmw_execbuf_ioctl+0x173/0x370 [vmwgfx] ? __drm_dev_dbg+0xb4/0xe0 [drm] ? __pfx_vmw_execbuf_ioctl+0x10/0x10 [vmwgfx] drm_ioctl_kernel+0xbc/0x160 [drm] drm_ioctl+0x2d2/0x580 [drm] ? __pfx_vmw_execbuf_ioctl+0x10/0x10 [vmwgfx] ? do_fault+0x1a6/0x420 vmw_generic_ioctl+0xbd/0x180 [vmwgfx] vmw_unlocked_ioctl+0x19/0x20 [vmwgfx] __x64_sys_ioctl+0x96/0xd0 do_syscall_64+0x5d/0x90 ? handle_mm_fault+0xe4/0x2f0 ? debug_smp_processor_id+0x1b/0x30 ? fpregs_assert_state_consistent+0x2e/0x50 ? exit_to_user_mode_prepare+0x40/0x180 ? irqentry_exit_to_user_mode+0xd/0x20 ? irqentry_exit+0x3f/0x50 ? exc_page_fault+0x8b/0x180 entry_SYSCALL_64_after_hwframe+0x72/0xdc Signed-off-by: Zack Rusin Cc: security@openanolis.org Reported-by: Ziming Zhang Testcase-found-by: Niels De Graef Fixes: d80efd5cb3de ("drm/vmwgfx: Initial DX support") Cc: # v4.3+ Reviewed-by: Maaz Mombasawala Reviewed-by: Martin Krastev Link: https://patchwork.freedesktop.org/patch/msgid/20230616190934.54828-1-zack@kde.org (backported from commit 14abdfae508228a7307f7491b5c4215ae70c6542) [koichiroden: Adjusted context due to missing commits: c593197b6ece ("drm/vmwgfx: Fix fencing on SVGAv3") d2e90ab3744f ("drm/vmwgfx: Support SM5 shader type in command buffer")] CVE-2022-36402 Signed-off-by: Koichiro Den --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 11 +++++++++++ drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 24 ++++++++++++------------ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index e65cba552e05..b8906f8357ee 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -1522,4 +1522,15 @@ static inline void vmw_mmio_write(u32 value, u32 *addr) { WRITE_ONCE(*addr, value); } + +static inline bool vmw_shadertype_is_valid(enum vmw_sm_type shader_model, + u32 shader_type) +{ + SVGA3dShaderType max_allowed = SVGA3D_SHADERTYPE_PREDX_MAX; + + if (shader_model >= VMW_SM_4) + max_allowed = SVGA3D_SHADERTYPE_DX10_MAX; + return shader_type >= SVGA3D_SHADERTYPE_MIN && shader_type < max_allowed; +} + #endif diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 6f0c060a8726..69998c51ee0b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -1996,7 +1996,7 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, cmd = container_of(header, typeof(*cmd), header); - if (cmd->body.type >= SVGA3D_SHADERTYPE_PREDX_MAX) { + if (!vmw_shadertype_is_valid(VMW_SM_LEGACY, cmd->body.type)) { VMW_DEBUG_USER("Illegal shader type %u.\n", (unsigned int) cmd->body.type); return -EINVAL; @@ -2133,6 +2133,14 @@ vmw_cmd_dx_set_single_constant_buffer(struct vmw_private *dev_priv, if (unlikely(ret != 0)) return ret; + if (!vmw_shadertype_is_valid(dev_priv->sm_type, cmd->body.type) || + cmd->body.slot >= SVGA3D_DX_MAX_CONSTBUFFERS) { + VMW_DEBUG_USER("Illegal const buffer shader %u slot %u.\n", + (unsigned int) cmd->body.type, + (unsigned int) cmd->body.slot); + return -EINVAL; + } + binding.bi.ctx = ctx_node->ctx; binding.bi.res = res; binding.bi.bt = vmw_ctx_binding_cb; @@ -2141,14 +2149,6 @@ vmw_cmd_dx_set_single_constant_buffer(struct vmw_private *dev_priv, binding.size = cmd->body.sizeInBytes; binding.slot = cmd->body.slot; - if (binding.shader_slot >= SVGA3D_NUM_SHADERTYPE_DX10 || - binding.slot >= SVGA3D_DX_MAX_CONSTBUFFERS) { - VMW_DEBUG_USER("Illegal const buffer shader %u slot %u.\n", - (unsigned int) cmd->body.type, - (unsigned int) binding.slot); - return -EINVAL; - } - vmw_binding_add(ctx_node->staged, &binding.bi, binding.shader_slot, binding.slot); @@ -2169,12 +2169,13 @@ static int vmw_cmd_dx_set_shader_res(struct vmw_private *dev_priv, { VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetShaderResources) = container_of(header, typeof(*cmd), header); + u32 num_sr_view = (cmd->header.size - sizeof(cmd->body)) / sizeof(SVGA3dShaderResourceViewId); if ((u64) cmd->body.startView + (u64) num_sr_view > (u64) SVGA3D_DX_MAX_SRVIEWS || - cmd->body.type >= SVGA3D_SHADERTYPE_DX10_MAX) { + !vmw_shadertype_is_valid(dev_priv->sm_type, cmd->body.type)) { VMW_DEBUG_USER("Invalid shader binding.\n"); return -EINVAL; } @@ -2208,8 +2209,7 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv, cmd = container_of(header, typeof(*cmd), header); - if (cmd->body.type >= SVGA3D_SHADERTYPE_DX10_MAX || - cmd->body.type < SVGA3D_SHADERTYPE_MIN) { + if (!vmw_shadertype_is_valid(dev_priv->sm_type, cmd->body.type)) { VMW_DEBUG_USER("Illegal shader type %u.\n", (unsigned int) cmd->body.type); return -EINVAL;