Commit 61ff410f authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'vmwgfx-next' of git://people.freedesktop.org/~thomash/linux into drm-next

vmwgfx updates + new logging uapi

https://patchwork.freedesktop.org/patch/349809/

 is appropriate userpsace patch.

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: =?UTF-8?q?Thomas=20Hellstr=C3=B6m=20=28VMware=29?=
Link: https://patchwork.freedesktop.org/patch/msgid/20200116092934.5276-1-thomas_os@shipmail.org
parents d7ca2d19 b2041425
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -209,8 +209,10 @@ int vmw_cmdbuf_res_add(struct vmw_cmdbuf_res_manager *man,

	cres->hash.key = user_key | (res_type << 24);
	ret = drm_ht_insert_item(&man->resources, &cres->hash);
	if (unlikely(ret != 0))
	if (unlikely(ret != 0)) {
		kfree(cres);
		goto out_invalid_key;
	}

	cres->state = VMW_CMDBUF_RES_ADD;
	cres->res = vmw_resource_reference(res);
+57 −19
Original line number Diff line number Diff line
@@ -28,10 +28,10 @@
#include <linux/console.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/pci.h>

#include <drm/drm_drv.h>
#include <drm/drm_ioctl.h>
#include <drm/drm_pci.h>
#include <drm/drm_sysfs.h>
#include <drm/ttm/ttm_bo_driver.h>
#include <drm/ttm/ttm_module.h>
@@ -150,6 +150,9 @@
#define DRM_IOCTL_VMW_GB_SURFACE_REF_EXT				\
	DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_GB_SURFACE_REF_EXT,		\
		union drm_vmw_gb_surface_reference_ext_arg)
#define DRM_IOCTL_VMW_MSG						\
	DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_MSG,			\
		struct drm_vmw_msg_arg)

/**
 * The core DRM version of this macro doesn't account for
@@ -165,9 +168,9 @@

static const struct drm_ioctl_desc vmw_ioctls[] = {
	VMW_IOCTL_DEF(VMW_GET_PARAM, vmw_getparam_ioctl,
		      DRM_AUTH | DRM_RENDER_ALLOW),
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_ALLOC_DMABUF, vmw_bo_alloc_ioctl,
		      DRM_AUTH | DRM_RENDER_ALLOW),
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_UNREF_DMABUF, vmw_bo_unref_ioctl,
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_CURSOR_BYPASS,
@@ -182,16 +185,16 @@ static const struct drm_ioctl_desc vmw_ioctls[] = {
		      DRM_MASTER),

	VMW_IOCTL_DEF(VMW_CREATE_CONTEXT, vmw_context_define_ioctl,
		      DRM_AUTH | DRM_RENDER_ALLOW),
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl,
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_CREATE_SURFACE, vmw_surface_define_ioctl,
		      DRM_AUTH | DRM_RENDER_ALLOW),
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl,
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_REF_SURFACE, vmw_surface_reference_ioctl,
		      DRM_AUTH | DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_EXECBUF, vmw_execbuf_ioctl, DRM_AUTH |
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_EXECBUF, vmw_execbuf_ioctl,
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_FENCE_WAIT, vmw_fence_obj_wait_ioctl,
		      DRM_RENDER_ALLOW),
@@ -201,9 +204,9 @@ static const struct drm_ioctl_desc vmw_ioctls[] = {
	VMW_IOCTL_DEF(VMW_FENCE_UNREF, vmw_fence_obj_unref_ioctl,
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_FENCE_EVENT, vmw_fence_event_ioctl,
		      DRM_AUTH | DRM_RENDER_ALLOW),
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_GET_3D_CAP, vmw_get_cap_3d_ioctl,
		      DRM_AUTH | DRM_RENDER_ALLOW),
		      DRM_RENDER_ALLOW),

	/* these allow direct access to the framebuffers mark as master only */
	VMW_IOCTL_DEF(VMW_PRESENT, vmw_present_ioctl,
@@ -221,28 +224,31 @@ static const struct drm_ioctl_desc vmw_ioctls[] = {
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_CREATE_SHADER,
		      vmw_shader_define_ioctl,
		      DRM_AUTH | DRM_RENDER_ALLOW),
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_UNREF_SHADER,
		      vmw_shader_destroy_ioctl,
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_GB_SURFACE_CREATE,
		      vmw_gb_surface_define_ioctl,
		      DRM_AUTH | DRM_RENDER_ALLOW),
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_GB_SURFACE_REF,
		      vmw_gb_surface_reference_ioctl,
		      DRM_AUTH | DRM_RENDER_ALLOW),
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_SYNCCPU,
		      vmw_user_bo_synccpu_ioctl,
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_CREATE_EXTENDED_CONTEXT,
		      vmw_extended_context_define_ioctl,
		      DRM_AUTH | DRM_RENDER_ALLOW),
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_GB_SURFACE_CREATE_EXT,
		      vmw_gb_surface_define_ext_ioctl,
		      DRM_AUTH | DRM_RENDER_ALLOW),
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_GB_SURFACE_REF_EXT,
		      vmw_gb_surface_reference_ext_ioctl,
		      DRM_AUTH | DRM_RENDER_ALLOW),
		      DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_MSG,
		      vmw_msg_ioctl,
		      DRM_RENDER_ALLOW),
};

static const struct pci_device_id vmw_pci_id_list[] = {
@@ -1211,8 +1217,10 @@ static void vmw_remove(struct pci_dev *pdev)
{
	struct drm_device *dev = pci_get_drvdata(pdev);

	drm_dev_unregister(dev);
	vmw_driver_unload(dev);
	drm_dev_put(dev);
	pci_disable_device(pdev);
	drm_put_dev(dev);
}

static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
@@ -1391,8 +1399,6 @@ static const struct file_operations vmwgfx_driver_fops = {
static struct drm_driver driver = {
	.driver_features =
	DRIVER_MODESET | DRIVER_RENDER | DRIVER_ATOMIC,
	.load = vmw_driver_load,
	.unload = vmw_driver_unload,
	.get_vblank_counter = vmw_get_vblank_counter,
	.enable_vblank = vmw_enable_vblank,
	.disable_vblank = vmw_disable_vblank,
@@ -1431,7 +1437,39 @@ static struct pci_driver vmw_pci_driver = {

static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	return drm_get_pci_dev(pdev, ent, &driver);
	struct drm_device *dev;
	int ret;

	ret = pci_enable_device(pdev);
	if (ret)
		return ret;

	dev = drm_dev_alloc(&driver, &pdev->dev);
	if (IS_ERR(dev)) {
		ret = PTR_ERR(dev);
		goto err_pci_disable_device;
	}

	dev->pdev = pdev;
	pci_set_drvdata(pdev, dev);

	ret = vmw_driver_load(dev, ent->driver_data);
	if (ret)
		goto err_drm_dev_put;

	ret = drm_dev_register(dev, ent->driver_data);
	if (ret)
		goto err_vmw_driver_unload;

	return 0;

err_vmw_driver_unload:
	vmw_driver_unload(dev);
err_drm_dev_put:
	drm_dev_put(dev);
err_pci_disable_device:
	pci_disable_device(pdev);
	return ret;
}

static int __init vmwgfx_init(void)
+4 −2
Original line number Diff line number Diff line
@@ -56,9 +56,9 @@


#define VMWGFX_DRIVER_NAME "vmwgfx"
#define VMWGFX_DRIVER_DATE "20190328"
#define VMWGFX_DRIVER_DATE "20200114"
#define VMWGFX_DRIVER_MAJOR 2
#define VMWGFX_DRIVER_MINOR 16
#define VMWGFX_DRIVER_MINOR 17
#define VMWGFX_DRIVER_PATCHLEVEL 0
#define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
#define VMWGFX_MAX_RELOCATIONS 2048
@@ -1403,6 +1403,8 @@ int vmw_bo_cpu_blit(struct ttm_buffer_object *dst,
int vmw_host_get_guestinfo(const char *guest_info_param,
			   char *buffer, size_t *length);
int vmw_host_log(const char *log);
int vmw_msg_ioctl(struct drm_device *dev, void *data,
		  struct drm_file *file_priv);

/* VMW logging */

+15 −6
Original line number Diff line number Diff line
@@ -2377,9 +2377,12 @@ static int vmw_cmd_dx_clear_rendertarget_view(struct vmw_private *dev_priv,
{
	VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXClearRenderTargetView) =
		container_of(header, typeof(*cmd), header);
	struct vmw_resource *ret;

	return PTR_RET(vmw_view_id_val_add(sw_context, vmw_view_rt,
					   cmd->body.renderTargetViewId));
	ret = vmw_view_id_val_add(sw_context, vmw_view_rt,
				  cmd->body.renderTargetViewId);

	return PTR_ERR_OR_ZERO(ret);
}

/**
@@ -2396,9 +2399,12 @@ static int vmw_cmd_dx_clear_depthstencil_view(struct vmw_private *dev_priv,
{
	VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXClearDepthStencilView) =
		container_of(header, typeof(*cmd), header);
	struct vmw_resource *ret;

	ret = vmw_view_id_val_add(sw_context, vmw_view_ds,
				  cmd->body.depthStencilViewId);

	return PTR_RET(vmw_view_id_val_add(sw_context, vmw_view_ds,
					   cmd->body.depthStencilViewId));
	return PTR_ERR_OR_ZERO(ret);
}

static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv,
@@ -2741,9 +2747,12 @@ static int vmw_cmd_dx_genmips(struct vmw_private *dev_priv,
{
	VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXGenMips) =
		container_of(header, typeof(*cmd), header);
	struct vmw_resource *ret;

	ret = vmw_view_id_val_add(sw_context, vmw_view_sr,
				  cmd->body.shaderResourceViewId);

	return PTR_RET(vmw_view_id_val_add(sw_context, vmw_view_sr,
					   cmd->body.shaderResourceViewId));
	return PTR_ERR_OR_ZERO(ret);
}

/**
+88 −2
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mem_encrypt.h>

#include <asm/hypervisor.h>

@@ -56,6 +57,8 @@

#define HIGH_WORD(X) ((X & 0xFFFF0000) >> 16)

#define MAX_USER_MSG_LENGTH	PAGE_SIZE

static u32 vmw_msg_enabled = 1;

enum rpc_msg_type {
@@ -148,7 +151,8 @@ static unsigned long vmw_port_hb_out(struct rpc_channel *channel,
	unsigned long si, di, eax, ebx, ecx, edx;
	unsigned long msg_len = strlen(msg);

	if (hb) {
	/* HB port can't access encrypted memory. */
	if (hb && !mem_encrypt_active()) {
		unsigned long bp = channel->cookie_high;

		si = (uintptr_t) msg;
@@ -202,7 +206,8 @@ static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply,
{
	unsigned long si, di, eax, ebx, ecx, edx;

	if (hb) {
	/* HB port can't access encrypted memory */
	if (hb && !mem_encrypt_active()) {
		unsigned long bp = channel->cookie_low;

		si = channel->cookie_high;
@@ -514,3 +519,84 @@ out_open:

	return -EINVAL;
}


/**
 * vmw_msg_ioctl: Sends and receveives a message to/from host from/to user-space
 *
 * Sends a message from user-space to host.
 * Can also receive a result from host and return that to user-space.
 *
 * @dev: Identifies the drm device.
 * @data: Pointer to the ioctl argument.
 * @file_priv: Identifies the caller.
 * Return: Zero on success, negative error code on error.
 */

int vmw_msg_ioctl(struct drm_device *dev, void *data,
		  struct drm_file *file_priv)
{
	struct drm_vmw_msg_arg *arg =
		(struct drm_vmw_msg_arg *) data;
	struct rpc_channel channel;
	char *msg;
	int length;

	msg = kmalloc(MAX_USER_MSG_LENGTH, GFP_KERNEL);
	if (!msg) {
		DRM_ERROR("Cannot allocate memory for log message.\n");
		return -ENOMEM;
	}

	length = strncpy_from_user(msg, (void __user *)((unsigned long)arg->send),
				   MAX_USER_MSG_LENGTH);
	if (length < 0 || length >= MAX_USER_MSG_LENGTH) {
		DRM_ERROR("Userspace message access failure.\n");
		kfree(msg);
		return -EINVAL;
	}


	if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM)) {
		DRM_ERROR("Failed to open channel.\n");
		goto out_open;
	}

	if (vmw_send_msg(&channel, msg)) {
		DRM_ERROR("Failed to send message to host.\n");
		goto out_msg;
	}

	if (!arg->send_only) {
		char *reply = NULL;
		size_t reply_len = 0;

		if (vmw_recv_msg(&channel, (void *) &reply, &reply_len)) {
			DRM_ERROR("Failed to receive message from host.\n");
			goto out_msg;
		}
		if (reply && reply_len > 0) {
			if (copy_to_user((void __user *)((unsigned long)arg->receive),
							 reply, reply_len)) {
				DRM_ERROR("Failed to copy message to userspace.\n");
				kfree(reply);
				goto out_msg;
			}
			arg->receive_len = (__u32)reply_len;
		}
		kfree(reply);
	}

	vmw_close_channel(&channel);
	kfree(msg);

	return 0;

out_msg:
	vmw_close_channel(&channel);
out_open:
	kfree(msg);

	return -EINVAL;
}
Loading