mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-04-18 03:23:53 -04:00
drm/vmwgfx: Use VMware hypercall API
Switch from VMWARE_HYPERCALL macro to vmware_hypercall API. Eliminate arch specific code. drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h: implement arm64 variant of vmware_hypercall. And keep it here until introduction of ARM64 VMWare hypervisor interface. Signed-off-by: Alexey Makhalov <alexey.makhalov@broadcom.com> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Link: https://lore.kernel.org/r/20240613191650.9913-5-alexey.makhalov@broadcom.com
This commit is contained in:
committed by
Borislav Petkov (AMD)
parent
f0db90b412
commit
90328eaaff
@@ -48,8 +48,6 @@
|
||||
|
||||
#define RETRIES 3
|
||||
|
||||
#define VMW_HYPERVISOR_MAGIC 0x564D5868
|
||||
|
||||
#define VMW_PORT_CMD_MSG 30
|
||||
#define VMW_PORT_CMD_HB_MSG 0
|
||||
#define VMW_PORT_CMD_OPEN_CHANNEL (MSG_TYPE_OPEN << 16 | VMW_PORT_CMD_MSG)
|
||||
@@ -104,20 +102,18 @@ static const char* const mksstat_kern_name_desc[MKSSTAT_KERN_COUNT][2] =
|
||||
*/
|
||||
static int vmw_open_channel(struct rpc_channel *channel, unsigned int protocol)
|
||||
{
|
||||
unsigned long eax, ebx, ecx, edx, si = 0, di = 0;
|
||||
u32 ecx, edx, esi, edi;
|
||||
|
||||
VMW_PORT(VMW_PORT_CMD_OPEN_CHANNEL,
|
||||
(protocol | GUESTMSG_FLAG_COOKIE), si, di,
|
||||
0,
|
||||
VMW_HYPERVISOR_MAGIC,
|
||||
eax, ebx, ecx, edx, si, di);
|
||||
vmware_hypercall6(VMW_PORT_CMD_OPEN_CHANNEL,
|
||||
(protocol | GUESTMSG_FLAG_COOKIE), 0,
|
||||
&ecx, &edx, &esi, &edi);
|
||||
|
||||
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0)
|
||||
return -EINVAL;
|
||||
|
||||
channel->channel_id = HIGH_WORD(edx);
|
||||
channel->cookie_high = si;
|
||||
channel->cookie_low = di;
|
||||
channel->cookie_high = esi;
|
||||
channel->cookie_low = edi;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -133,17 +129,13 @@ static int vmw_open_channel(struct rpc_channel *channel, unsigned int protocol)
|
||||
*/
|
||||
static int vmw_close_channel(struct rpc_channel *channel)
|
||||
{
|
||||
unsigned long eax, ebx, ecx, edx, si, di;
|
||||
u32 ecx;
|
||||
|
||||
/* Set up additional parameters */
|
||||
si = channel->cookie_high;
|
||||
di = channel->cookie_low;
|
||||
|
||||
VMW_PORT(VMW_PORT_CMD_CLOSE_CHANNEL,
|
||||
0, si, di,
|
||||
channel->channel_id << 16,
|
||||
VMW_HYPERVISOR_MAGIC,
|
||||
eax, ebx, ecx, edx, si, di);
|
||||
vmware_hypercall5(VMW_PORT_CMD_CLOSE_CHANNEL,
|
||||
0, channel->channel_id << 16,
|
||||
channel->cookie_high,
|
||||
channel->cookie_low,
|
||||
&ecx);
|
||||
|
||||
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0)
|
||||
return -EINVAL;
|
||||
@@ -163,24 +155,18 @@ static int vmw_close_channel(struct rpc_channel *channel)
|
||||
static unsigned long vmw_port_hb_out(struct rpc_channel *channel,
|
||||
const char *msg, bool hb)
|
||||
{
|
||||
unsigned long si, di, eax, ebx, ecx, edx;
|
||||
u32 ebx, ecx;
|
||||
unsigned long msg_len = strlen(msg);
|
||||
|
||||
/* HB port can't access encrypted memory. */
|
||||
if (hb && !cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
|
||||
unsigned long bp = channel->cookie_high;
|
||||
u32 channel_id = (channel->channel_id << 16);
|
||||
|
||||
si = (uintptr_t) msg;
|
||||
di = channel->cookie_low;
|
||||
|
||||
VMW_PORT_HB_OUT(
|
||||
vmware_hypercall_hb_out(
|
||||
(MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
|
||||
msg_len, si, di,
|
||||
VMWARE_HYPERVISOR_HB | channel_id |
|
||||
VMWARE_HYPERVISOR_OUT,
|
||||
VMW_HYPERVISOR_MAGIC, bp,
|
||||
eax, ebx, ecx, edx, si, di);
|
||||
msg_len,
|
||||
channel->channel_id << 16,
|
||||
(uintptr_t) msg, channel->cookie_low,
|
||||
channel->cookie_high,
|
||||
&ebx);
|
||||
|
||||
return ebx;
|
||||
}
|
||||
@@ -194,14 +180,13 @@ static unsigned long vmw_port_hb_out(struct rpc_channel *channel,
|
||||
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,
|
||||
channel->channel_id << 16,
|
||||
VMW_HYPERVISOR_MAGIC,
|
||||
eax, ebx, ecx, edx, si, di);
|
||||
vmware_hypercall5(VMW_PORT_CMD_MSG |
|
||||
(MSG_TYPE_SENDPAYLOAD << 16),
|
||||
word, channel->channel_id << 16,
|
||||
channel->cookie_high,
|
||||
channel->cookie_low,
|
||||
&ecx);
|
||||
}
|
||||
|
||||
return ecx;
|
||||
@@ -220,22 +205,17 @@ static unsigned long vmw_port_hb_out(struct rpc_channel *channel,
|
||||
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;
|
||||
u32 ebx, ecx, edx;
|
||||
|
||||
/* HB port can't access encrypted memory */
|
||||
if (hb && !cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
|
||||
unsigned long bp = channel->cookie_low;
|
||||
u32 channel_id = (channel->channel_id << 16);
|
||||
|
||||
si = channel->cookie_high;
|
||||
di = (uintptr_t) reply;
|
||||
|
||||
VMW_PORT_HB_IN(
|
||||
vmware_hypercall_hb_in(
|
||||
(MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
|
||||
reply_len, si, di,
|
||||
VMWARE_HYPERVISOR_HB | channel_id,
|
||||
VMW_HYPERVISOR_MAGIC, bp,
|
||||
eax, ebx, ecx, edx, si, di);
|
||||
reply_len,
|
||||
channel->channel_id << 16,
|
||||
channel->cookie_high,
|
||||
(uintptr_t) reply, channel->cookie_low,
|
||||
&ebx);
|
||||
|
||||
return ebx;
|
||||
}
|
||||
@@ -245,14 +225,13 @@ static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply,
|
||||
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,
|
||||
channel->channel_id << 16,
|
||||
VMW_HYPERVISOR_MAGIC,
|
||||
eax, ebx, ecx, edx, si, di);
|
||||
vmware_hypercall7(VMW_PORT_CMD_MSG |
|
||||
(MSG_TYPE_RECVPAYLOAD << 16),
|
||||
MESSAGE_STATUS_SUCCESS,
|
||||
channel->channel_id << 16,
|
||||
channel->cookie_high,
|
||||
channel->cookie_low,
|
||||
&ebx, &ecx, &edx);
|
||||
|
||||
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0)
|
||||
break;
|
||||
@@ -276,22 +255,18 @@ static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply,
|
||||
*/
|
||||
static int vmw_send_msg(struct rpc_channel *channel, const char *msg)
|
||||
{
|
||||
unsigned long eax, ebx, ecx, edx, si, di;
|
||||
u32 ebx, ecx;
|
||||
size_t msg_len = strlen(msg);
|
||||
int retries = 0;
|
||||
|
||||
while (retries < RETRIES) {
|
||||
retries++;
|
||||
|
||||
/* Set up additional parameters */
|
||||
si = channel->cookie_high;
|
||||
di = channel->cookie_low;
|
||||
|
||||
VMW_PORT(VMW_PORT_CMD_SENDSIZE,
|
||||
msg_len, si, di,
|
||||
channel->channel_id << 16,
|
||||
VMW_HYPERVISOR_MAGIC,
|
||||
eax, ebx, ecx, edx, si, di);
|
||||
vmware_hypercall5(VMW_PORT_CMD_SENDSIZE,
|
||||
msg_len, channel->channel_id << 16,
|
||||
channel->cookie_high,
|
||||
channel->cookie_low,
|
||||
&ecx);
|
||||
|
||||
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) {
|
||||
/* Expected success. Give up. */
|
||||
@@ -329,7 +304,7 @@ STACK_FRAME_NON_STANDARD(vmw_send_msg);
|
||||
static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
|
||||
size_t *msg_len)
|
||||
{
|
||||
unsigned long eax, ebx, ecx, edx, si, di;
|
||||
u32 ebx, ecx, edx;
|
||||
char *reply;
|
||||
size_t reply_len;
|
||||
int retries = 0;
|
||||
@@ -341,15 +316,11 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
|
||||
while (retries < RETRIES) {
|
||||
retries++;
|
||||
|
||||
/* Set up additional parameters */
|
||||
si = channel->cookie_high;
|
||||
di = channel->cookie_low;
|
||||
|
||||
VMW_PORT(VMW_PORT_CMD_RECVSIZE,
|
||||
0, si, di,
|
||||
channel->channel_id << 16,
|
||||
VMW_HYPERVISOR_MAGIC,
|
||||
eax, ebx, ecx, edx, si, di);
|
||||
vmware_hypercall7(VMW_PORT_CMD_RECVSIZE,
|
||||
0, channel->channel_id << 16,
|
||||
channel->cookie_high,
|
||||
channel->cookie_low,
|
||||
&ebx, &ecx, &edx);
|
||||
|
||||
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) {
|
||||
DRM_ERROR("Failed to get reply size for host message.\n");
|
||||
@@ -384,16 +355,12 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
|
||||
|
||||
reply[reply_len] = '\0';
|
||||
|
||||
|
||||
/* Ack buffer */
|
||||
si = channel->cookie_high;
|
||||
di = channel->cookie_low;
|
||||
|
||||
VMW_PORT(VMW_PORT_CMD_RECVSTATUS,
|
||||
MESSAGE_STATUS_SUCCESS, si, di,
|
||||
channel->channel_id << 16,
|
||||
VMW_HYPERVISOR_MAGIC,
|
||||
eax, ebx, ecx, edx, si, di);
|
||||
vmware_hypercall5(VMW_PORT_CMD_RECVSTATUS,
|
||||
MESSAGE_STATUS_SUCCESS,
|
||||
channel->channel_id << 16,
|
||||
channel->cookie_high,
|
||||
channel->cookie_low,
|
||||
&ecx);
|
||||
|
||||
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) {
|
||||
kfree(reply);
|
||||
@@ -652,13 +619,7 @@ static inline void reset_ppn_array(PPN64 *arr, size_t size)
|
||||
*/
|
||||
static inline void hypervisor_ppn_reset_all(void)
|
||||
{
|
||||
unsigned long eax, ebx, ecx, edx, si = 0, di = 0;
|
||||
|
||||
VMW_PORT(VMW_PORT_CMD_MKSGS_RESET,
|
||||
0, si, di,
|
||||
0,
|
||||
VMW_HYPERVISOR_MAGIC,
|
||||
eax, ebx, ecx, edx, si, di);
|
||||
vmware_hypercall1(VMW_PORT_CMD_MKSGS_RESET, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -669,13 +630,7 @@ static inline void hypervisor_ppn_reset_all(void)
|
||||
*/
|
||||
static inline void hypervisor_ppn_add(PPN64 pfn)
|
||||
{
|
||||
unsigned long eax, ebx, ecx, edx, si = 0, di = 0;
|
||||
|
||||
VMW_PORT(VMW_PORT_CMD_MKSGS_ADD_PPN,
|
||||
(unsigned long)pfn, si, di,
|
||||
0,
|
||||
VMW_HYPERVISOR_MAGIC,
|
||||
eax, ebx, ecx, edx, si, di);
|
||||
vmware_hypercall1(VMW_PORT_CMD_MKSGS_ADD_PPN, (unsigned long)pfn);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -686,13 +641,7 @@ static inline void hypervisor_ppn_add(PPN64 pfn)
|
||||
*/
|
||||
static inline void hypervisor_ppn_remove(PPN64 pfn)
|
||||
{
|
||||
unsigned long eax, ebx, ecx, edx, si = 0, di = 0;
|
||||
|
||||
VMW_PORT(VMW_PORT_CMD_MKSGS_REMOVE_PPN,
|
||||
(unsigned long)pfn, si, di,
|
||||
0,
|
||||
VMW_HYPERVISOR_MAGIC,
|
||||
eax, ebx, ecx, edx, si, di);
|
||||
vmware_hypercall1(VMW_PORT_CMD_MKSGS_REMOVE_PPN, (unsigned long)pfn);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_VMWGFX_MKSSTATS)
|
||||
|
||||
Reference in New Issue
Block a user