Commit 47e3c4c9 authored by Dave Airlie's avatar Dave Airlie

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

A couple of fixes for vmwgfx. Two fixes for a DMA sg-list debug warning
message. These are not cc'd stable since there is no evidence of actual
breakage.
On fix for the high-bandwidth backdoor port which is cc'd stable due to
upcoming hardware, on which the code would otherwise break.
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Thomas Hellstrom <VMware> <thomas@shipmail.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20190618072255.2720-1-thomas@shipmail.org
parents 9e0babf2 39916897
...@@ -747,6 +747,9 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) ...@@ -747,6 +747,9 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
if (unlikely(ret != 0)) if (unlikely(ret != 0))
goto out_err0; goto out_err0;
dma_set_max_seg_size(dev->dev, min_t(unsigned int, U32_MAX & PAGE_MASK,
SCATTERLIST_MAX_SEGMENT));
if (dev_priv->capabilities & SVGA_CAP_GMR2) { if (dev_priv->capabilities & SVGA_CAP_GMR2) {
DRM_INFO("Max GMR ids is %u\n", DRM_INFO("Max GMR ids is %u\n",
(unsigned)dev_priv->max_gmr_ids); (unsigned)dev_priv->max_gmr_ids);
......
...@@ -136,6 +136,114 @@ static int vmw_close_channel(struct rpc_channel *channel) ...@@ -136,6 +136,114 @@ static int vmw_close_channel(struct rpc_channel *channel)
return 0; return 0;
} }
/**
* vmw_port_hb_out - Send the message payload either through the
* high-bandwidth port if available, or through the backdoor otherwise.
* @channel: The rpc channel.
* @msg: NULL-terminated message.
* @hb: Whether the high-bandwidth port is available.
*
* Return: The port status.
*/
static unsigned long vmw_port_hb_out(struct rpc_channel *channel,
const char *msg, bool hb)
{
unsigned long si, di, eax, ebx, ecx, edx;
unsigned long msg_len = strlen(msg);
if (hb) {
unsigned long bp = channel->cookie_high;
si = (uintptr_t) msg;
di = channel->cookie_low;
VMW_PORT_HB_OUT(
(MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
msg_len, si, di,
VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16),
VMW_HYPERVISOR_MAGIC, bp,
eax, ebx, ecx, edx, si, di);
return ebx;
}
/* HB port not available. Send the message 4 bytes at a time. */
ecx = MESSAGE_STATUS_SUCCESS << 16;
while (msg_len && (HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS)) {
unsigned int bytes = min_t(size_t, msg_len, 4);
unsigned long word = 0;
memcpy(&word, msg, bytes);
msg_len -= bytes;
msg += bytes;
si = channel->cookie_high;
di = channel->cookie_low;
VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_SENDPAYLOAD << 16),
word, si, di,
VMW_HYPERVISOR_PORT | (channel->channel_id << 16),
VMW_HYPERVISOR_MAGIC,
eax, ebx, ecx, edx, si, di);
}
return ecx;
}
/**
* vmw_port_hb_in - Receive the message payload either through the
* high-bandwidth port if available, or through the backdoor otherwise.
* @channel: The rpc channel.
* @reply: Pointer to buffer holding reply.
* @reply_len: Length of the reply.
* @hb: Whether the high-bandwidth port is available.
*
* Return: The port status.
*/
static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply,
unsigned long reply_len, bool hb)
{
unsigned long si, di, eax, ebx, ecx, edx;
if (hb) {
unsigned long bp = channel->cookie_low;
si = channel->cookie_high;
di = (uintptr_t) reply;
VMW_PORT_HB_IN(
(MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
reply_len, si, di,
VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16),
VMW_HYPERVISOR_MAGIC, bp,
eax, ebx, ecx, edx, si, di);
return ebx;
}
/* HB port not available. Retrieve the message 4 bytes at a time. */
ecx = MESSAGE_STATUS_SUCCESS << 16;
while (reply_len) {
unsigned int bytes = min_t(unsigned long, reply_len, 4);
si = channel->cookie_high;
di = channel->cookie_low;
VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_RECVPAYLOAD << 16),
MESSAGE_STATUS_SUCCESS, si, di,
VMW_HYPERVISOR_PORT | (channel->channel_id << 16),
VMW_HYPERVISOR_MAGIC,
eax, ebx, ecx, edx, si, di);
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0)
break;
memcpy(reply, &ebx, bytes);
reply_len -= bytes;
reply += bytes;
}
return ecx;
}
/** /**
...@@ -148,11 +256,10 @@ static int vmw_close_channel(struct rpc_channel *channel) ...@@ -148,11 +256,10 @@ static int vmw_close_channel(struct rpc_channel *channel)
*/ */
static int vmw_send_msg(struct rpc_channel *channel, const char *msg) static int vmw_send_msg(struct rpc_channel *channel, const char *msg)
{ {
unsigned long eax, ebx, ecx, edx, si, di, bp; unsigned long eax, ebx, ecx, edx, si, di;
size_t msg_len = strlen(msg); size_t msg_len = strlen(msg);
int retries = 0; int retries = 0;
while (retries < RETRIES) { while (retries < RETRIES) {
retries++; retries++;
...@@ -166,23 +273,14 @@ static int vmw_send_msg(struct rpc_channel *channel, const char *msg) ...@@ -166,23 +273,14 @@ static int vmw_send_msg(struct rpc_channel *channel, const char *msg)
VMW_HYPERVISOR_MAGIC, VMW_HYPERVISOR_MAGIC,
eax, ebx, ecx, edx, si, di); eax, ebx, ecx, edx, si, di);
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0 || if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) {
(HIGH_WORD(ecx) & MESSAGE_STATUS_HB) == 0) { /* Expected success. Give up. */
/* Expected success + high-bandwidth. Give up. */
return -EINVAL; return -EINVAL;
} }
/* Send msg */ /* Send msg */
si = (uintptr_t) msg; ebx = vmw_port_hb_out(channel, msg,
di = channel->cookie_low; !!(HIGH_WORD(ecx) & MESSAGE_STATUS_HB));
bp = channel->cookie_high;
VMW_PORT_HB_OUT(
(MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
msg_len, si, di,
VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16),
VMW_HYPERVISOR_MAGIC, bp,
eax, ebx, ecx, edx, si, di);
if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) != 0) { if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) != 0) {
return 0; return 0;
...@@ -211,7 +309,7 @@ STACK_FRAME_NON_STANDARD(vmw_send_msg); ...@@ -211,7 +309,7 @@ STACK_FRAME_NON_STANDARD(vmw_send_msg);
static int vmw_recv_msg(struct rpc_channel *channel, void **msg, static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
size_t *msg_len) size_t *msg_len)
{ {
unsigned long eax, ebx, ecx, edx, si, di, bp; unsigned long eax, ebx, ecx, edx, si, di;
char *reply; char *reply;
size_t reply_len; size_t reply_len;
int retries = 0; int retries = 0;
...@@ -233,8 +331,7 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg, ...@@ -233,8 +331,7 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
VMW_HYPERVISOR_MAGIC, VMW_HYPERVISOR_MAGIC,
eax, ebx, ecx, edx, si, di); eax, ebx, ecx, edx, si, di);
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0 || if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) {
(HIGH_WORD(ecx) & MESSAGE_STATUS_HB) == 0) {
DRM_ERROR("Failed to get reply size for host message.\n"); DRM_ERROR("Failed to get reply size for host message.\n");
return -EINVAL; return -EINVAL;
} }
...@@ -252,17 +349,8 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg, ...@@ -252,17 +349,8 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
/* Receive buffer */ /* Receive buffer */
si = channel->cookie_high; ebx = vmw_port_hb_in(channel, reply, reply_len,
di = (uintptr_t) reply; !!(HIGH_WORD(ecx) & MESSAGE_STATUS_HB));
bp = channel->cookie_low;
VMW_PORT_HB_IN(
(MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
reply_len, si, di,
VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16),
VMW_HYPERVISOR_MAGIC, bp,
eax, ebx, ecx, edx, si, di);
if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) == 0) { if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) == 0) {
kfree(reply); kfree(reply);
......
...@@ -441,11 +441,11 @@ static int vmw_ttm_map_dma(struct vmw_ttm_tt *vmw_tt) ...@@ -441,11 +441,11 @@ static int vmw_ttm_map_dma(struct vmw_ttm_tt *vmw_tt)
if (unlikely(ret != 0)) if (unlikely(ret != 0))
return ret; return ret;
ret = sg_alloc_table_from_pages(&vmw_tt->sgt, vsgt->pages, ret = __sg_alloc_table_from_pages
vsgt->num_pages, 0, (&vmw_tt->sgt, vsgt->pages, vsgt->num_pages, 0,
(unsigned long) (unsigned long) vsgt->num_pages << PAGE_SHIFT,
vsgt->num_pages << PAGE_SHIFT, dma_get_max_seg_size(dev_priv->dev->dev),
GFP_KERNEL); GFP_KERNEL);
if (unlikely(ret != 0)) if (unlikely(ret != 0))
goto out_sg_alloc_fail; goto out_sg_alloc_fail;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment