From patchwork Wed Nov 13 09:51:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Hellstr=C3=B6m_=28Intel=29?= X-Patchwork-Id: 11241569 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0B23A1850 for ; Wed, 13 Nov 2019 09:52:05 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E78AE20818 for ; Wed, 13 Nov 2019 09:52:04 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E78AE20818 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=shipmail.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E50EB6ECB7; Wed, 13 Nov 2019 09:52:02 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from ste-pvt-msa2.bahnhof.se (ste-pvt-msa2.bahnhof.se [213.80.101.71]) by gabe.freedesktop.org (Postfix) with ESMTPS id 878EE6ECB7 for ; Wed, 13 Nov 2019 09:52:01 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by ste-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 913CC401A9; Wed, 13 Nov 2019 10:51:59 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -2.099 X-Spam-Level: X-Spam-Status: No, score=-2.099 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from ste-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (ste-ftg-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Q3AcM91Xy1Vc; Wed, 13 Nov 2019 10:51:58 +0100 (CET) Received: from mail1.shipmail.org (h-205-35.A357.priv.bahnhof.se [155.4.205.35]) (Authenticated sender: mb878879) by ste-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id CB55F3FBF5; Wed, 13 Nov 2019 10:51:56 +0100 (CET) Received: from localhost.localdomain.localdomain (h-205-35.A357.priv.bahnhof.se [155.4.205.35]) by mail1.shipmail.org (Postfix) with ESMTPSA id 2B3DA3600C4; Wed, 13 Nov 2019 10:51:56 +0100 (CET) From: =?utf-8?q?Thomas_Hellstr=C3=B6m_=28VMware=29?= To: dri-devel@lists.freedesktop.org Subject: [PATCH] drm/vmwgfx: Use dma-coherent memory for high-bandwidth port messaging Date: Wed, 13 Nov 2019 10:51:42 +0100 Message-Id: <20191113095144.2981-1-thomas_os@shipmail.org> X-Mailer: git-send-email 2.21.0 MIME-Version: 1.0 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=shipmail.org; s=mail; t=1573638716; bh=DkRihfVCAlmEAjKBCN62DFX1Ofg8bBUVqG257hUVyVY=; h=From:To:Cc:Subject:Date:From; b=m9JaC5ArSuYqKlnF9agWU9WUEY40OPWDsuWdw5LJGZc3Z0NFquXgX7mmVR9CZ+fA+ TPie2fffp729xLTL+VUG1QzoFtjPabUU+2iFNg4XxsN3uY+l+C3k3UIec2LOSvFSns B7zxcSrzKmkmm2jVPsKbmPqJwmJl/2WflNK3lVo0= X-Mailman-Original-Authentication-Results: ste-pvt-msa2.bahnhof.se; dkim=pass (1024-bit key; unprotected) header.d=shipmail.org header.i=@shipmail.org header.b=m9JaC5Ar; dkim-atps=neutral X-Mailman-Original-Authentication-Results: ste-ftg-msa2.bahnhof.se (amavisd-new); dkim=pass (1024-bit key) header.d=shipmail.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Hellstrom , Brian Paul Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Thomas Hellstrom With AMD-SEV high-bandwidth port messaging runs into trouble since the message content is encrypted using the vm-specific key, and the hypervisor is unable to read it. So use unencrypted dma-coherent bounce buffers for temporary message storage space. Allocating that memory is expensive so a future optimization might include a static unencrypted memory area for messages. Signed-off-by: Thomas Hellstrom Reviewed-by: Brian Paul --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 4 +-- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 4 +-- drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 45 +++++++++++++++++------------ 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 81a95651643f..fc0283659c41 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -908,13 +908,13 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) snprintf(host_log, sizeof(host_log), "vmwgfx: %s-%s", VMWGFX_REPO, VMWGFX_GIT_VERSION); - vmw_host_log(host_log); + vmw_host_log(dev->dev, host_log); memset(host_log, 0, sizeof(host_log)); snprintf(host_log, sizeof(host_log), "vmwgfx: Module Version: %d.%d.%d", VMWGFX_DRIVER_MAJOR, VMWGFX_DRIVER_MINOR, VMWGFX_DRIVER_PATCHLEVEL); - vmw_host_log(host_log); + vmw_host_log(dev->dev, host_log); if (dev_priv->enable_fb) { vmw_fifo_resource_inc(dev_priv); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index b18842f73081..a77bf72cb9ac 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -1389,9 +1389,9 @@ int vmw_bo_cpu_blit(struct ttm_buffer_object *dst, struct vmw_diff_cpy *diff); /* Host messaging -vmwgfx_msg.c: */ -int vmw_host_get_guestinfo(const char *guest_info_param, +int vmw_host_get_guestinfo(struct device *dev, const char *guest_info_param, char *buffer, size_t *length); -int vmw_host_log(const char *log); +int vmw_host_log(struct device *dev, const char *log); /* VMW logging */ diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c index b6c5e4c2ac3c..f439b7afa3a5 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c @@ -304,8 +304,8 @@ STACK_FRAME_NON_STANDARD(vmw_send_msg); * @msg: [OUT] message received from the host * @msg_len: message length */ -static int vmw_recv_msg(struct rpc_channel *channel, void **msg, - size_t *msg_len) +static int vmw_recv_msg(struct device *dev, struct rpc_channel *channel, + void **msg, size_t *msg_len, dma_addr_t *dma_handle) { unsigned long eax, ebx, ecx, edx, si, di; char *reply; @@ -339,7 +339,8 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg, return 0; reply_len = ebx; - reply = kzalloc(reply_len + 1, GFP_KERNEL); + reply = dma_alloc_coherent(dev, reply_len + 1, dma_handle, + GFP_KERNEL); if (!reply) { DRM_ERROR("Cannot allocate memory for host message reply.\n"); return -ENOMEM; @@ -350,7 +351,7 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg, ebx = vmw_port_hb_in(channel, reply, reply_len, !!(HIGH_WORD(ecx) & MESSAGE_STATUS_HB)); if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) == 0) { - kfree(reply); + dma_free_coherent(dev, reply_len + 1, reply, *dma_handle); reply = NULL; if ((HIGH_WORD(ebx) & MESSAGE_STATUS_CPT) != 0) { /* A checkpoint occurred. Retry. */ @@ -374,7 +375,7 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg, eax, ebx, ecx, edx, si, di); if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) { - kfree(reply); + dma_free_coherent(dev, reply_len + 1, reply, *dma_handle); reply = NULL; if ((HIGH_WORD(ecx) & MESSAGE_STATUS_CPT) != 0) { /* A checkpoint occurred. Retry. */ @@ -404,18 +405,21 @@ STACK_FRAME_NON_STANDARD(vmw_recv_msg); * Gets the value of a GuestInfo.* parameter. The value returned will be in * a string, and it is up to the caller to post-process. * + * @dev: Pointer to struct device used for coherent memory allocation * @guest_info_param: Parameter to get, e.g. GuestInfo.svga.gl3 * @buffer: if NULL, *reply_len will contain reply size. * @length: size of the reply_buf. Set to size of reply upon return * * Returns: 0 on success */ -int vmw_host_get_guestinfo(const char *guest_info_param, +int vmw_host_get_guestinfo(struct device *dev, const char *guest_info_param, char *buffer, size_t *length) { struct rpc_channel channel; char *msg, *reply = NULL; size_t reply_len = 0; + dma_addr_t req_handle, reply_handle; + int req_len = strlen("info-get ") + strlen(guest_info_param) + 1; if (!vmw_msg_enabled) return -ENODEV; @@ -423,18 +427,20 @@ int vmw_host_get_guestinfo(const char *guest_info_param, if (!guest_info_param || !length) return -EINVAL; - msg = kasprintf(GFP_KERNEL, "info-get %s", guest_info_param); + msg = dma_alloc_coherent(dev, req_len, &req_handle, GFP_KERNEL); if (!msg) { DRM_ERROR("Cannot allocate memory to get guest info \"%s\".", guest_info_param); return -ENOMEM; } + snprintf(msg, req_len, "info-get %s", guest_info_param); if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM)) goto out_open; if (vmw_send_msg(&channel, msg) || - vmw_recv_msg(&channel, (void *) &reply, &reply_len)) + vmw_recv_msg(dev, &channel, (void *) &reply, &reply_len, + &reply_handle)) goto out_msg; vmw_close_channel(&channel); @@ -451,19 +457,19 @@ int vmw_host_get_guestinfo(const char *guest_info_param, *length = reply_len; - kfree(reply); - kfree(msg); + dma_free_coherent(dev, reply_len + 1, reply, reply_handle); + dma_free_coherent(dev, req_len, msg, req_handle); return 0; out_msg: vmw_close_channel(&channel); - kfree(reply); + dma_free_coherent(dev, reply_len + 1, reply, reply_handle); out_open: *length = 0; - kfree(msg); - DRM_ERROR("Failed to get guest info \"%s\".", guest_info_param); + DRM_ERROR("Failed to get guest info \"%s\".", guest_info_param); + dma_free_coherent(dev, req_len, msg, req_handle); return -EINVAL; } @@ -472,16 +478,18 @@ int vmw_host_get_guestinfo(const char *guest_info_param, /** * vmw_host_log: Sends a log message to the host * + * @dev: Pointer to struct device used for coherent memory allocation * @log: NULL terminated string * * Returns: 0 on success */ -int vmw_host_log(const char *log) +int vmw_host_log(struct device *dev, const char *log) { struct rpc_channel channel; char *msg; int ret = 0; - + dma_addr_t log_handle; + int log_len = strlen("log ") + strlen(log) + 1; if (!vmw_msg_enabled) return -ENODEV; @@ -489,11 +497,12 @@ int vmw_host_log(const char *log) if (!log) return ret; - msg = kasprintf(GFP_KERNEL, "log %s", log); + msg = dma_alloc_coherent(dev, log_len, &log_handle, GFP_KERNEL); if (!msg) { DRM_ERROR("Cannot allocate memory for host log message.\n"); return -ENOMEM; } + snprintf(msg, log_len, "log %s", log); if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM)) goto out_open; @@ -502,14 +511,14 @@ int vmw_host_log(const char *log) goto out_msg; vmw_close_channel(&channel); - kfree(msg); + dma_free_coherent(dev, log_len, msg, log_handle); return 0; out_msg: vmw_close_channel(&channel); out_open: - kfree(msg); + dma_free_coherent(dev, log_len, msg, log_handle); DRM_ERROR("Failed to send host log message.\n"); return -EINVAL;