gunyah: virtual io: Porting Gunyah Secure Virtual io backend driver to Pineapple

Add gunyah secure virtual io backend driver for Pineapple.

This is just snapshot of kalama's secure virtual io backend driver
from 'commit 5beb98404269 ("Merge "i3c: i3c-master-msm-geni: Fix
IBI for invalid device OR handler"")'from msm-5.15 branch.

Change-Id: Ie4cb1c30a42a2465c37b1fe1f47850b95ac4eb24
Signed-off-by: Peng Yang <quic_penyan@quicinc.com>
This commit is contained in:
Peng Yang 2022-07-03 04:08:02 -07:00
parent 4919ab2b83
commit 7327a7facf
6 changed files with 1864 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _GH_SECURE_VM_VIRTIO_BACKEND_H
#define _GH_SECURE_VM_VIRTIO_BACKEND_H
#include <linux/gunyah/gh_common.h>
int gh_virtio_backend_mmap(const char *vm_name, struct vm_area_struct *vma);
long gh_virtio_backend_ioctl(const char *vm_name, unsigned int cmd,
unsigned long arg);
int gh_parse_virtio_properties(struct device *dev, const char *vm_name);
int gh_virtio_backend_remove(const char *vm_name);
int gh_virtio_mmio_exit(gh_vmid_t vmid, const char *vm_name);
int gh_virtio_backend_init(void);
void gh_virtio_backend_exit(void);
#endif /* _GH_SECURE_VM_VIRTIO_BACKEND_H */

View File

@ -0,0 +1,124 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*/
#ifndef __GH_HCALL_VIRTIO_H
#define __GH_HCALL_VIRTIO_H
#include <linux/err.h>
#include <linux/types.h>
#include <linux/gunyah/hcall_common.h>
#include <linux/gunyah/gh_common.h>
#include <asm/gunyah/hcall.h>
static inline int
gh_hcall_virtio_mmio_backend_assert_virq(gh_capid_t capid, u64 int_status)
{
struct gh_hcall_resp _resp = {0};
return _gh_hcall(0x604e, (struct gh_hcall_args){ capid, int_status, 0 },
&_resp);
}
static inline int
gh_hcall_virtio_mmio_backend_set_dev_features(gh_capid_t capid,
u64 features_sel, u64 features)
{
struct gh_hcall_resp _resp = {0};
return _gh_hcall(0x604f,
(struct gh_hcall_args){ capid, features_sel, features,
0 },
&_resp);
}
static inline int
gh_hcall_virtio_mmio_backend_set_queue_num_max(gh_capid_t capid,
u64 queue_sel, u64 queue_num_max)
{
struct gh_hcall_resp _resp = {0};
return _gh_hcall(0x6050,
(struct gh_hcall_args){ capid, queue_sel,
queue_num_max, 0 },
&_resp);
}
static inline int
gh_hcall_virtio_mmio_backend_get_drv_features(gh_capid_t capid,
u64 features_sel, u64 *features)
{
int ret;
struct gh_hcall_resp _resp = {0};
ret = _gh_hcall(0x6051,
(struct gh_hcall_args){ capid, features_sel, 0},
&_resp);
if (!ret && features)
*features = _resp.resp1;
return ret;
}
struct gh_hcall_virtio_queue_info {
u64 queue_num;
u64 queue_ready;
u64 queue_desc;
u64 queue_driver;
u64 queue_device;
};
static inline int
gh_hcall_virtio_mmio_backend_get_queue_info(gh_capid_t capid,
u64 queue_sel, struct gh_hcall_virtio_queue_info *queue_info)
{
int ret;
struct gh_hcall_resp _resp = {0};
ret = _gh_hcall(0x6052,
(struct gh_hcall_args){ capid, queue_sel, 0},
&_resp);
if (!ret && queue_info) {
queue_info->queue_num = _resp.resp1;
queue_info->queue_ready = _resp.resp2;
queue_info->queue_desc = _resp.resp3;
queue_info->queue_driver = _resp.resp4;
queue_info->queue_device = _resp.resp5;
}
return ret;
}
static inline int
gh_hcall_virtio_mmio_backend_get_event(gh_capid_t capid,
u64 *event_data, u64 *event)
{
int ret;
struct gh_hcall_resp _resp = {0};
ret = _gh_hcall(0x6053,
(struct gh_hcall_args){ capid, 0},
&_resp);
if (!ret && event_data)
*event_data = _resp.resp1;
if (!ret && event)
*event = _resp.resp2;
return ret;
}
static inline int
gh_hcall_virtio_mmio_backend_ack_reset(gh_capid_t capid)
{
struct gh_hcall_resp _resp = {0};
return _gh_hcall(0x6054,
(struct gh_hcall_args){ capid, 0},
&_resp);
}
#endif

View File

@ -0,0 +1,106 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*/
#undef TRACE_SYSTEM
#define TRACE_SYSTEM gh_virtio_backend
#if !defined(_TRACE_GH_VIRTIO_BACKEND_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_GH_VIRTIO_BACKEND_H
#include <linux/tracepoint.h>
TRACE_EVENT(gh_virtio_backend_irq_inj,
TP_PROTO(int label, int rc),
TP_ARGS(label, rc),
TP_STRUCT__entry(
__field(int, label)
__field(int, rc)
),
TP_fast_assign(
__entry->label = label;
__entry->rc = rc;
),
TP_printk("device %d inj_irq rc %d", __entry->label, __entry->rc)
);
TRACE_EVENT(gh_virtio_backend_queue_notify,
TP_PROTO(int label, int qno),
TP_ARGS(label, qno),
TP_STRUCT__entry(
__field(int, label)
__field(int, qno)
),
TP_fast_assign(
__entry->label = label;
__entry->qno = qno;
),
TP_printk("device %d queue_notify on %d", __entry->label, __entry->qno)
);
TRACE_EVENT(gh_virtio_backend_wait_event,
TP_PROTO(int label, int cur_event, int org_event, int cur_event_data, int org_event_data),
TP_ARGS(label, cur_event, org_event, cur_event_data, org_event_data),
TP_STRUCT__entry(
__field(int, label)
__field(int, cur_event)
__field(int, org_event)
__field(int, cur_event_data)
__field(int, org_event_data)
),
TP_fast_assign(
__entry->label = label;
__entry->cur_event = cur_event;
__entry->cur_event_data = cur_event_data;
__entry->org_event = org_event;
__entry->org_event_data = org_event_data;
),
TP_printk("device %d cur_evt/org_evt %x/%x, cur_evt_data/org_evt_data %x/%x",
__entry->label, __entry->cur_event, __entry->org_event,
__entry->cur_event_data, __entry->org_event_data)
);
TRACE_EVENT(gh_virtio_backend_irq,
TP_PROTO(int label, int event, int event_data, int rc),
TP_ARGS(label, event, event_data, rc),
TP_STRUCT__entry(
__field(int, label)
__field(int, event)
__field(int, event_data)
__field(int, rc)
),
TP_fast_assign(
__entry->label = label;
__entry->event = event;
__entry->event_data = event_data;
__entry->rc = rc;
),
TP_printk("device %d irq (rc %d) event %x event_data %x",
__entry->label, __entry->rc, __entry->event, __entry->event_data)
);
#endif /* _TRACE_GH_VIRTIO_BACKEND_H */
/* This part must be outside protection */
#include <trace/define_trace.h>

View File

@ -0,0 +1,179 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*/
#undef TRACE_SYSTEM
#define TRACE_SYSTEM gh_virtio_frontend
#if !defined(_TRACE_GH_VIRTIO_FRONTEND_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_GH_VIRTIO_FRONTEND_H
#include <linux/tracepoint.h>
TRACE_EVENT(virtio_mmio_vm_notify,
TP_PROTO(unsigned int dev_index, unsigned int qindex),
TP_ARGS(dev_index, qindex),
TP_STRUCT__entry(
__field(unsigned int, dev_index)
__field(unsigned int, qindex)
),
TP_fast_assign(
__entry->dev_index = dev_index;
__entry->qindex = qindex;
),
TP_printk("virtio%u qindex %u", __entry->dev_index, __entry->qindex)
);
TRACE_EVENT(virtio_mmio_vm_interrupt,
TP_PROTO(unsigned int dev_index, unsigned int status),
TP_ARGS(dev_index, status),
TP_STRUCT__entry(
__field(unsigned int, dev_index)
__field(unsigned int, status)
),
TP_fast_assign(
__entry->dev_index = dev_index;
__entry->status = status;
),
TP_printk("virtio%u status %x", __entry->dev_index, __entry->status)
);
TRACE_EVENT(virtio_vring_split_add,
TP_PROTO(unsigned int dev_index, int qhead, unsigned int avail_idx_shadow,
unsigned int descs_used, unsigned int num_free),
TP_ARGS(dev_index, qhead, avail_idx_shadow, descs_used, num_free),
TP_STRUCT__entry(
__field(unsigned int, dev_index)
__field(unsigned int, qhead)
__field(unsigned int, avail_idx_shadow)
__field(unsigned int, descs_used)
__field(unsigned int, num_free)
),
TP_fast_assign(
__entry->dev_index = dev_index;
__entry->qhead = qhead;
__entry->avail_idx_shadow = avail_idx_shadow;
__entry->descs_used = descs_used;
__entry->num_free = num_free;
),
TP_printk("virtio%u qhead %u avail_idx_shadow %u descs_used %u num_free %u",
__entry->dev_index, __entry->qhead, __entry->avail_idx_shadow,
__entry->descs_used, __entry->num_free)
);
TRACE_EVENT(virtio_detach_buf,
TP_PROTO(unsigned int dev_index, unsigned int free_head, unsigned int num_free),
TP_ARGS(dev_index, free_head, num_free),
TP_STRUCT__entry(
__field(unsigned int, dev_index)
__field(unsigned int, free_head)
__field(unsigned int, num_free)
),
TP_fast_assign(
__entry->dev_index = dev_index;
__entry->free_head = free_head;
__entry->num_free = num_free;
),
TP_printk("virtio%u free_head %u num_free %u", __entry->dev_index,
__entry->free_head, __entry->num_free)
);
TRACE_EVENT(virtio_get_buf_ctx_split,
TP_PROTO(unsigned int dev_index, unsigned int last_used_idx, unsigned int ring_used_idx),
TP_ARGS(dev_index, last_used_idx, ring_used_idx),
TP_STRUCT__entry(
__field(unsigned int, dev_index)
__field(unsigned int, last_used_idx)
__field(unsigned int, ring_used_idx)
),
TP_fast_assign(
__entry->dev_index = dev_index;
__entry->last_used_idx = last_used_idx;
__entry->ring_used_idx = ring_used_idx;
),
TP_printk("virtio%u last_used_idx %u ring_used_idx %u", __entry->dev_index,
__entry->last_used_idx, __entry->ring_used_idx)
);
TRACE_EVENT(virtio_block_done,
TP_PROTO(unsigned int dev_index, unsigned int req_op, unsigned int sector),
TP_ARGS(dev_index, req_op, sector),
TP_STRUCT__entry(
__field(unsigned int, dev_index)
__field(unsigned int, req_op)
__field(unsigned int, sector)
),
TP_fast_assign(
__entry->dev_index = dev_index;
__entry->req_op = req_op;
__entry->sector = sector;
),
TP_printk("virtio%u req_op %u sector %u", __entry->dev_index,
__entry->req_op, __entry->sector)
);
TRACE_EVENT(virtio_block_submit,
TP_PROTO(unsigned int dev_index, unsigned int type, unsigned int sector,
unsigned int ioprio, int err, unsigned int num),
TP_ARGS(dev_index, type, sector, ioprio, err, num),
TP_STRUCT__entry(
__field(unsigned int, dev_index)
__field(unsigned int, type)
__field(unsigned int, sector)
__field(unsigned int, ioprio)
__field(int, err)
__field(unsigned int, num)
),
TP_fast_assign(
__entry->dev_index = dev_index;
__entry->type = type;
__entry->sector = sector;
__entry->ioprio = ioprio;
__entry->err = err;
__entry->num = num;
),
TP_printk("virtio%u type %x sector %u ioprio %u num %d err %d",
__entry->dev_index, __entry->type, __entry->sector,
__entry->ioprio, __entry->num, __entry->err)
);
#endif /* _TRACE_GH_VIRTIO_FRONTEND_H */
/* This part must be outside protection */
#include <trace/define_trace.h>

View File

@ -0,0 +1,117 @@
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _UAPI_LINUX_VIRTIO_BACKEND_H
#define _UAPI_LINUX_VIRTIO_BACKEND_H
#include <linux/virtio_types.h>
#define VIRTIO_BE_IOC_MAGIC 0xBC
#define VBE_ASSIGN_IOEVENTFD 1
#define VBE_DEASSIGN_IOEVENTFD 2
#define VBE_ASSIGN_IRQFD 1
#define VBE_DEASSIGN_IRQFD 2
#define EVENT_NEW_BUFFER 1
#define EVENT_RESET_RQST 2
#define EVENT_INTERRUPT_ACK 4
#define EVENT_DRIVER_OK 8
#define EVENT_DRIVER_FAILED 0x10
#define EVENT_MODULE_EXIT 0x20
#define EVENT_VM_EXIT 0x40
#define EVENT_APP_EXIT 0x100
/*
* IOCTLs supported by virtio backend driver
*/
#define GH_GET_SHARED_MEMORY_SIZE _IOR(VIRTIO_BE_IOC_MAGIC, 1, __u64)
#define GH_IOEVENTFD _IOW(VIRTIO_BE_IOC_MAGIC, 2, \
struct virtio_eventfd)
#define GH_IRQFD _IOW(VIRTIO_BE_IOC_MAGIC, 3, \
struct virtio_irqfd)
#define GH_WAIT_FOR_EVENT _IOWR(VIRTIO_BE_IOC_MAGIC, 4, \
struct virtio_event)
#define GH_SET_DEVICE_FEATURES _IOW(VIRTIO_BE_IOC_MAGIC, 5, \
struct virtio_dev_features)
#define GH_SET_QUEUE_NUM_MAX _IOW(VIRTIO_BE_IOC_MAGIC, 6, \
struct virtio_queue_max)
#define GH_SET_DEVICE_CONFIG_DATA _IOW(VIRTIO_BE_IOC_MAGIC, 7, \
struct virtio_config_data)
#define GH_GET_DRIVER_CONFIG_DATA _IOWR(VIRTIO_BE_IOC_MAGIC, 8, \
struct virtio_config_data)
#define GH_GET_QUEUE_INFO _IOWR(VIRTIO_BE_IOC_MAGIC, 9, \
struct virtio_queue_info)
#define GH_GET_DRIVER_FEATURES _IOWR(VIRTIO_BE_IOC_MAGIC, 10, \
struct virtio_driver_features)
#define GH_ACK_DRIVER_OK _IOWR(VIRTIO_BE_IOC_MAGIC, 11, __u32)
#define GH_SET_APP_READY _IO(VIRTIO_BE_IOC_MAGIC, 12)
#define GH_ACK_RESET _IOW(VIRTIO_BE_IOC_MAGIC, 13, struct virtio_ack_reset)
struct virtio_ack_reset {
__u32 label;
__u32 reserved;
};
struct virtio_driver_features {
__u32 label;
__u32 reserved;
__u32 features_sel;
__u32 features;
};
struct virtio_queue_info {
__u32 label;
__u32 queue_sel;
__u32 queue_num;
__u32 queue_ready;
__u64 queue_desc;
__u64 queue_driver;
__u64 queue_device;
};
struct virtio_config_data {
__u32 label;
__u32 config_size;
__u64 config_data;
};
struct virtio_dev_features {
__u32 label;
__u32 reserved;
__u32 features_sel;
__u32 features;
};
struct virtio_queue_max {
__u32 label;
__u32 reserved;
__u32 queue_sel;
__u32 queue_num_max;
};
struct virtio_event {
__u32 label;
__u32 event;
__u32 event_data;
__u32 reserved;
};
struct virtio_eventfd {
__u32 label;
__u32 flags;
__u32 queue_num;
__s32 fd;
};
struct virtio_irqfd {
__u32 label;
__u32 flags;
__s32 fd;
__u32 reserved;
};
#endif /* _UAPI_LINUX_VIRTIO_BACKEND_H */