Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Private stuff for vfio_ccw driver
0004  *
0005  * Copyright IBM Corp. 2017
0006  * Copyright Red Hat, Inc. 2019
0007  *
0008  * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
0009  *            Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
0010  *            Cornelia Huck <cohuck@redhat.com>
0011  */
0012 
0013 #ifndef _VFIO_CCW_PRIVATE_H_
0014 #define _VFIO_CCW_PRIVATE_H_
0015 
0016 #include <linux/completion.h>
0017 #include <linux/eventfd.h>
0018 #include <linux/workqueue.h>
0019 #include <linux/vfio_ccw.h>
0020 #include <linux/vfio.h>
0021 #include <asm/crw.h>
0022 #include <asm/debug.h>
0023 
0024 #include "css.h"
0025 #include "vfio_ccw_cp.h"
0026 
0027 #define VFIO_CCW_OFFSET_SHIFT   10
0028 #define VFIO_CCW_OFFSET_TO_INDEX(off)   (off >> VFIO_CCW_OFFSET_SHIFT)
0029 #define VFIO_CCW_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_CCW_OFFSET_SHIFT)
0030 #define VFIO_CCW_OFFSET_MASK    (((u64)(1) << VFIO_CCW_OFFSET_SHIFT) - 1)
0031 
0032 /* capability chain handling similar to vfio-pci */
0033 struct vfio_ccw_private;
0034 struct vfio_ccw_region;
0035 
0036 struct vfio_ccw_regops {
0037     ssize_t (*read)(struct vfio_ccw_private *private, char __user *buf,
0038             size_t count, loff_t *ppos);
0039     ssize_t (*write)(struct vfio_ccw_private *private,
0040              const char __user *buf, size_t count, loff_t *ppos);
0041     void    (*release)(struct vfio_ccw_private *private,
0042                struct vfio_ccw_region *region);
0043 };
0044 
0045 struct vfio_ccw_region {
0046     u32             type;
0047     u32             subtype;
0048     const struct vfio_ccw_regops    *ops;
0049     void                *data;
0050     size_t              size;
0051     u32             flags;
0052 };
0053 
0054 int vfio_ccw_register_dev_region(struct vfio_ccw_private *private,
0055                  unsigned int subtype,
0056                  const struct vfio_ccw_regops *ops,
0057                  size_t size, u32 flags, void *data);
0058 void vfio_ccw_unregister_dev_regions(struct vfio_ccw_private *private);
0059 
0060 int vfio_ccw_register_async_dev_regions(struct vfio_ccw_private *private);
0061 int vfio_ccw_register_schib_dev_regions(struct vfio_ccw_private *private);
0062 int vfio_ccw_register_crw_dev_regions(struct vfio_ccw_private *private);
0063 
0064 struct vfio_ccw_crw {
0065     struct list_head    next;
0066     struct crw      crw;
0067 };
0068 
0069 /**
0070  * struct vfio_ccw_private
0071  * @vdev: Embedded VFIO device
0072  * @sch: pointer to the subchannel
0073  * @state: internal state of the device
0074  * @completion: synchronization helper of the I/O completion
0075  * @avail: available for creating a mediated device
0076  * @io_region: MMIO region to input/output I/O arguments/results
0077  * @io_mutex: protect against concurrent update of I/O regions
0078  * @region: additional regions for other subchannel operations
0079  * @cmd_region: MMIO region for asynchronous I/O commands other than START
0080  * @schib_region: MMIO region for SCHIB information
0081  * @crw_region: MMIO region for getting channel report words
0082  * @num_regions: number of additional regions
0083  * @cp: channel program for the current I/O operation
0084  * @irb: irb info received from interrupt
0085  * @scsw: scsw info
0086  * @io_trigger: eventfd ctx for signaling userspace I/O results
0087  * @crw_trigger: eventfd ctx for signaling userspace CRW information
0088  * @req_trigger: eventfd ctx for signaling userspace to return device
0089  * @io_work: work for deferral process of I/O handling
0090  * @crw_work: work for deferral process of CRW handling
0091  */
0092 struct vfio_ccw_private {
0093     struct vfio_device vdev;
0094     struct subchannel   *sch;
0095     int         state;
0096     struct completion   *completion;
0097     atomic_t        avail;
0098     struct ccw_io_region    *io_region;
0099     struct mutex        io_mutex;
0100     struct vfio_ccw_region *region;
0101     struct ccw_cmd_region   *cmd_region;
0102     struct ccw_schib_region *schib_region;
0103     struct ccw_crw_region   *crw_region;
0104     int num_regions;
0105 
0106     struct channel_program  cp;
0107     struct irb      irb;
0108     union scsw      scsw;
0109     struct list_head    crw;
0110 
0111     struct eventfd_ctx  *io_trigger;
0112     struct eventfd_ctx  *crw_trigger;
0113     struct eventfd_ctx  *req_trigger;
0114     struct work_struct  io_work;
0115     struct work_struct  crw_work;
0116 } __aligned(8);
0117 
0118 int vfio_ccw_sch_quiesce(struct subchannel *sch);
0119 
0120 extern struct mdev_driver vfio_ccw_mdev_driver;
0121 
0122 /*
0123  * States of the device statemachine.
0124  */
0125 enum vfio_ccw_state {
0126     VFIO_CCW_STATE_NOT_OPER,
0127     VFIO_CCW_STATE_STANDBY,
0128     VFIO_CCW_STATE_IDLE,
0129     VFIO_CCW_STATE_CP_PROCESSING,
0130     VFIO_CCW_STATE_CP_PENDING,
0131     /* last element! */
0132     NR_VFIO_CCW_STATES
0133 };
0134 
0135 /*
0136  * Asynchronous events of the device statemachine.
0137  */
0138 enum vfio_ccw_event {
0139     VFIO_CCW_EVENT_NOT_OPER,
0140     VFIO_CCW_EVENT_IO_REQ,
0141     VFIO_CCW_EVENT_INTERRUPT,
0142     VFIO_CCW_EVENT_ASYNC_REQ,
0143     VFIO_CCW_EVENT_OPEN,
0144     VFIO_CCW_EVENT_CLOSE,
0145     /* last element! */
0146     NR_VFIO_CCW_EVENTS
0147 };
0148 
0149 /*
0150  * Action called through jumptable.
0151  */
0152 typedef void (fsm_func_t)(struct vfio_ccw_private *, enum vfio_ccw_event);
0153 extern fsm_func_t *vfio_ccw_jumptable[NR_VFIO_CCW_STATES][NR_VFIO_CCW_EVENTS];
0154 
0155 static inline void vfio_ccw_fsm_event(struct vfio_ccw_private *private,
0156                       enum vfio_ccw_event event)
0157 {
0158     trace_vfio_ccw_fsm_event(private->sch->schid, private->state, event);
0159     vfio_ccw_jumptable[private->state][event](private, event);
0160 }
0161 
0162 extern struct workqueue_struct *vfio_ccw_work_q;
0163 
0164 
0165 /* s390 debug feature, similar to base cio */
0166 extern debug_info_t *vfio_ccw_debug_msg_id;
0167 extern debug_info_t *vfio_ccw_debug_trace_id;
0168 
0169 #define VFIO_CCW_TRACE_EVENT(imp, txt) \
0170         debug_text_event(vfio_ccw_debug_trace_id, imp, txt)
0171 
0172 #define VFIO_CCW_MSG_EVENT(imp, args...) \
0173         debug_sprintf_event(vfio_ccw_debug_msg_id, imp, ##args)
0174 
0175 static inline void VFIO_CCW_HEX_EVENT(int level, void *data, int length)
0176 {
0177     debug_event(vfio_ccw_debug_trace_id, level, data, length);
0178 }
0179 
0180 #endif