Commit 32807063 authored by Martin Krastev's avatar Martin Krastev Committed by Zack Rusin
Browse files

drm/vmwgfx: Fix frame-size warning in vmw_mksstat_add_ioctl



Function vmw_mksstat_add_ioctl allocates three big arrays on stack.
That triggers frame-size [-Wframe-larger-than=] warning. Refactor
that function to use kmalloc_array instead.

v2: Initialize page to null to avoid possible uninitialized use of it,
    spotted by the kernel test robot <lkp@intel.com>

Signed-off-by: default avatarMartin Krastev <krastevm@vmware.com>
Reviewed-by: default avatarZack Rusin <zackr@vmware.com>
Reviewed-by: default avatarMaaz Mombasawala <mombasawalam@vmware.com>
Signed-off-by: default avatarZack Rusin <zackr@vmware.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20221022040236.616490-3-zack@kde.org
parent 7f4c3377
Loading
Loading
Loading
Loading
+29 −14
Original line number Diff line number Diff line
@@ -1014,8 +1014,6 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data,

	struct vmw_private *const dev_priv = vmw_priv(dev);

	struct page *page;
	MKSGuestStatInstanceDescriptor *pdesc;
	const size_t num_pages_stat = PFN_UP(arg->stat_len);
	const size_t num_pages_info = PFN_UP(arg->info_len);
	const size_t num_pages_strs = PFN_UP(arg->strs_len);
@@ -1023,10 +1021,13 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data,
	long nr_pinned_stat;
	long nr_pinned_info;
	long nr_pinned_strs;
	struct page *pages_stat[ARRAY_SIZE(pdesc->statPPNs)];
	struct page *pages_info[ARRAY_SIZE(pdesc->infoPPNs)];
	struct page *pages_strs[ARRAY_SIZE(pdesc->strsPPNs)];
	MKSGuestStatInstanceDescriptor *pdesc;
	struct page *page = NULL;
	struct page **pages_stat = NULL;
	struct page **pages_info = NULL;
	struct page **pages_strs = NULL;
	size_t i, slot;
	int ret_err = -ENOMEM;

	arg->id = -1;

@@ -1054,13 +1055,23 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data,

	BUG_ON(dev_priv->mksstat_user_pages[slot]);

	/* Allocate statically-sized temp arrays for pages -- too big to keep in frame */
	pages_stat = (struct page **)kmalloc_array(
		ARRAY_SIZE(pdesc->statPPNs) +
		ARRAY_SIZE(pdesc->infoPPNs) +
		ARRAY_SIZE(pdesc->strsPPNs), sizeof(*pages_stat), GFP_KERNEL);

	if (!pages_stat)
		goto err_nomem;

	pages_info = pages_stat + ARRAY_SIZE(pdesc->statPPNs);
	pages_strs = pages_info + ARRAY_SIZE(pdesc->infoPPNs);

	/* Allocate a page for the instance descriptor */
	page = alloc_page(GFP_KERNEL | __GFP_ZERO);

	if (!page) {
		atomic_set(&dev_priv->mksstat_user_pids[slot], 0);
		return -ENOMEM;
	}
	if (!page)
		goto err_nomem;

	/* Set up the instance descriptor */
	pdesc = page_address(page);
@@ -1075,9 +1086,8 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data,
		ARRAY_SIZE(pdesc->description) - 1);

	if (desc_len < 0) {
		atomic_set(&dev_priv->mksstat_user_pids[slot], 0);
		__free_page(page);
		return -EFAULT;
		ret_err = -EFAULT;
		goto err_nomem;
	}

	reset_ppn_array(pdesc->statPPNs, ARRAY_SIZE(pdesc->statPPNs));
@@ -1118,6 +1128,7 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data,

	DRM_DEV_INFO(dev->dev, "pid=%d arg.description='%.*s' id=%zu\n", current->pid, (int)desc_len, pdesc->description, slot);

	kfree(pages_stat);
	return 0;

err_pin_strs:
@@ -1132,9 +1143,13 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data,
	if (nr_pinned_stat > 0)
		unpin_user_pages(pages_stat, nr_pinned_stat);

err_nomem:
	atomic_set(&dev_priv->mksstat_user_pids[slot], 0);
	if (page)
		__free_page(page);
	return -ENOMEM;
	kfree(pages_stat);

	return ret_err;
}

/**