| .. | .. |
|---|
| 3 | 3 | * Private stuff for vfio_ccw driver |
|---|
| 4 | 4 | * |
|---|
| 5 | 5 | * Copyright IBM Corp. 2017 |
|---|
| 6 | + * Copyright Red Hat, Inc. 2019 |
|---|
| 6 | 7 | * |
|---|
| 7 | 8 | * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> |
|---|
| 8 | 9 | * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com> |
|---|
| 10 | + * Cornelia Huck <cohuck@redhat.com> |
|---|
| 9 | 11 | */ |
|---|
| 10 | 12 | |
|---|
| 11 | 13 | #ifndef _VFIO_CCW_PRIVATE_H_ |
|---|
| .. | .. |
|---|
| 15 | 17 | #include <linux/eventfd.h> |
|---|
| 16 | 18 | #include <linux/workqueue.h> |
|---|
| 17 | 19 | #include <linux/vfio_ccw.h> |
|---|
| 20 | +#include <asm/crw.h> |
|---|
| 21 | +#include <asm/debug.h> |
|---|
| 18 | 22 | |
|---|
| 19 | 23 | #include "css.h" |
|---|
| 20 | 24 | #include "vfio_ccw_cp.h" |
|---|
| 25 | + |
|---|
| 26 | +#define VFIO_CCW_OFFSET_SHIFT 10 |
|---|
| 27 | +#define VFIO_CCW_OFFSET_TO_INDEX(off) (off >> VFIO_CCW_OFFSET_SHIFT) |
|---|
| 28 | +#define VFIO_CCW_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_CCW_OFFSET_SHIFT) |
|---|
| 29 | +#define VFIO_CCW_OFFSET_MASK (((u64)(1) << VFIO_CCW_OFFSET_SHIFT) - 1) |
|---|
| 30 | + |
|---|
| 31 | +/* capability chain handling similar to vfio-pci */ |
|---|
| 32 | +struct vfio_ccw_private; |
|---|
| 33 | +struct vfio_ccw_region; |
|---|
| 34 | + |
|---|
| 35 | +struct vfio_ccw_regops { |
|---|
| 36 | + ssize_t (*read)(struct vfio_ccw_private *private, char __user *buf, |
|---|
| 37 | + size_t count, loff_t *ppos); |
|---|
| 38 | + ssize_t (*write)(struct vfio_ccw_private *private, |
|---|
| 39 | + const char __user *buf, size_t count, loff_t *ppos); |
|---|
| 40 | + void (*release)(struct vfio_ccw_private *private, |
|---|
| 41 | + struct vfio_ccw_region *region); |
|---|
| 42 | +}; |
|---|
| 43 | + |
|---|
| 44 | +struct vfio_ccw_region { |
|---|
| 45 | + u32 type; |
|---|
| 46 | + u32 subtype; |
|---|
| 47 | + const struct vfio_ccw_regops *ops; |
|---|
| 48 | + void *data; |
|---|
| 49 | + size_t size; |
|---|
| 50 | + u32 flags; |
|---|
| 51 | +}; |
|---|
| 52 | + |
|---|
| 53 | +int vfio_ccw_register_dev_region(struct vfio_ccw_private *private, |
|---|
| 54 | + unsigned int subtype, |
|---|
| 55 | + const struct vfio_ccw_regops *ops, |
|---|
| 56 | + size_t size, u32 flags, void *data); |
|---|
| 57 | +void vfio_ccw_unregister_dev_regions(struct vfio_ccw_private *private); |
|---|
| 58 | + |
|---|
| 59 | +int vfio_ccw_register_async_dev_regions(struct vfio_ccw_private *private); |
|---|
| 60 | +int vfio_ccw_register_schib_dev_regions(struct vfio_ccw_private *private); |
|---|
| 61 | +int vfio_ccw_register_crw_dev_regions(struct vfio_ccw_private *private); |
|---|
| 62 | + |
|---|
| 63 | +struct vfio_ccw_crw { |
|---|
| 64 | + struct list_head next; |
|---|
| 65 | + struct crw crw; |
|---|
| 66 | +}; |
|---|
| 21 | 67 | |
|---|
| 22 | 68 | /** |
|---|
| 23 | 69 | * struct vfio_ccw_private |
|---|
| .. | .. |
|---|
| 28 | 74 | * @mdev: pointer to the mediated device |
|---|
| 29 | 75 | * @nb: notifier for vfio events |
|---|
| 30 | 76 | * @io_region: MMIO region to input/output I/O arguments/results |
|---|
| 77 | + * @io_mutex: protect against concurrent update of I/O regions |
|---|
| 78 | + * @region: additional regions for other subchannel operations |
|---|
| 79 | + * @cmd_region: MMIO region for asynchronous I/O commands other than START |
|---|
| 80 | + * @schib_region: MMIO region for SCHIB information |
|---|
| 81 | + * @crw_region: MMIO region for getting channel report words |
|---|
| 82 | + * @num_regions: number of additional regions |
|---|
| 31 | 83 | * @cp: channel program for the current I/O operation |
|---|
| 32 | 84 | * @irb: irb info received from interrupt |
|---|
| 33 | 85 | * @scsw: scsw info |
|---|
| .. | .. |
|---|
| 42 | 94 | struct mdev_device *mdev; |
|---|
| 43 | 95 | struct notifier_block nb; |
|---|
| 44 | 96 | struct ccw_io_region *io_region; |
|---|
| 97 | + struct mutex io_mutex; |
|---|
| 98 | + struct vfio_ccw_region *region; |
|---|
| 99 | + struct ccw_cmd_region *cmd_region; |
|---|
| 100 | + struct ccw_schib_region *schib_region; |
|---|
| 101 | + struct ccw_crw_region *crw_region; |
|---|
| 102 | + int num_regions; |
|---|
| 45 | 103 | |
|---|
| 46 | 104 | struct channel_program cp; |
|---|
| 47 | 105 | struct irb irb; |
|---|
| 48 | 106 | union scsw scsw; |
|---|
| 107 | + struct list_head crw; |
|---|
| 49 | 108 | |
|---|
| 50 | 109 | struct eventfd_ctx *io_trigger; |
|---|
| 110 | + struct eventfd_ctx *crw_trigger; |
|---|
| 51 | 111 | struct work_struct io_work; |
|---|
| 112 | + struct work_struct crw_work; |
|---|
| 52 | 113 | } __aligned(8); |
|---|
| 53 | 114 | |
|---|
| 54 | 115 | extern int vfio_ccw_mdev_reg(struct subchannel *sch); |
|---|
| .. | .. |
|---|
| 63 | 124 | VFIO_CCW_STATE_NOT_OPER, |
|---|
| 64 | 125 | VFIO_CCW_STATE_STANDBY, |
|---|
| 65 | 126 | VFIO_CCW_STATE_IDLE, |
|---|
| 66 | | - VFIO_CCW_STATE_BOXED, |
|---|
| 67 | | - VFIO_CCW_STATE_BUSY, |
|---|
| 127 | + VFIO_CCW_STATE_CP_PROCESSING, |
|---|
| 128 | + VFIO_CCW_STATE_CP_PENDING, |
|---|
| 68 | 129 | /* last element! */ |
|---|
| 69 | 130 | NR_VFIO_CCW_STATES |
|---|
| 70 | 131 | }; |
|---|
| .. | .. |
|---|
| 76 | 137 | VFIO_CCW_EVENT_NOT_OPER, |
|---|
| 77 | 138 | VFIO_CCW_EVENT_IO_REQ, |
|---|
| 78 | 139 | VFIO_CCW_EVENT_INTERRUPT, |
|---|
| 140 | + VFIO_CCW_EVENT_ASYNC_REQ, |
|---|
| 79 | 141 | /* last element! */ |
|---|
| 80 | 142 | NR_VFIO_CCW_EVENTS |
|---|
| 81 | 143 | }; |
|---|
| .. | .. |
|---|
| 89 | 151 | static inline void vfio_ccw_fsm_event(struct vfio_ccw_private *private, |
|---|
| 90 | 152 | int event) |
|---|
| 91 | 153 | { |
|---|
| 154 | + trace_vfio_ccw_fsm_event(private->sch->schid, private->state, event); |
|---|
| 92 | 155 | vfio_ccw_jumptable[private->state][event](private, event); |
|---|
| 93 | 156 | } |
|---|
| 94 | 157 | |
|---|
| 95 | 158 | extern struct workqueue_struct *vfio_ccw_work_q; |
|---|
| 96 | 159 | |
|---|
| 160 | + |
|---|
| 161 | +/* s390 debug feature, similar to base cio */ |
|---|
| 162 | +extern debug_info_t *vfio_ccw_debug_msg_id; |
|---|
| 163 | +extern debug_info_t *vfio_ccw_debug_trace_id; |
|---|
| 164 | + |
|---|
| 165 | +#define VFIO_CCW_TRACE_EVENT(imp, txt) \ |
|---|
| 166 | + debug_text_event(vfio_ccw_debug_trace_id, imp, txt) |
|---|
| 167 | + |
|---|
| 168 | +#define VFIO_CCW_MSG_EVENT(imp, args...) \ |
|---|
| 169 | + debug_sprintf_event(vfio_ccw_debug_msg_id, imp, ##args) |
|---|
| 170 | + |
|---|
| 171 | +static inline void VFIO_CCW_HEX_EVENT(int level, void *data, int length) |
|---|
| 172 | +{ |
|---|
| 173 | + debug_event(vfio_ccw_debug_trace_id, level, data, length); |
|---|
| 174 | +} |
|---|
| 175 | + |
|---|
| 97 | 176 | #endif |
|---|