1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright 2016-17 IBM Corp.
*/
#ifndef _ASM_POWERPC_VAS_H
#define _ASM_POWERPC_VAS_H
#include <linux/sched/mm.h>
#include <linux/mmu_context.h>
#include <asm/icswx.h>
#include <uapi/asm/vas-api.h>
/*
* Min and max FIFO sizes are based on Version 1.05 Section 3.1.4.25
* (Local FIFO Size Register) of the VAS workbook.
*/
#define VAS_RX_FIFO_SIZE_MIN (1 << 10) /* 1KB */
#define VAS_RX_FIFO_SIZE_MAX (8 << 20) /* 8MB */
/*
* Threshold Control Mode: Have paste operation fail if the number of
* requests in receive FIFO exceeds a threshold.
*
* NOTE: No special error code yet if paste is rejected because of these
* limits. So users can't distinguish between this and other errors.
*/
#define VAS_THRESH_DISABLED 0
#define VAS_THRESH_FIFO_GT_HALF_FULL 1
#define VAS_THRESH_FIFO_GT_QTR_FULL 2
#define VAS_THRESH_FIFO_GT_EIGHTH_FULL 3
/*
* VAS window Linux status bits
*/
#define VAS_WIN_ACTIVE 0x0 /* Used in platform independent */
/* vas mmap() */
/* Window is closed in the hypervisor due to lost credit */
#define VAS_WIN_NO_CRED_CLOSE 0x00000001
/* Window is closed due to migration */
#define VAS_WIN_MIGRATE_CLOSE 0x00000002
/*
* Get/Set bit fields
*/
#define GET_FIELD(m, v) (((v) & (m)) >> MASK_LSH(m))
#define MASK_LSH(m) (__builtin_ffsl(m) - 1)
#define SET_FIELD(m, v, val) \
(((v) & ~(m)) | ((((typeof(v))(val)) << MASK_LSH(m)) & (m)))
/*
* Co-processor Engine type.
*/
enum vas_cop_type {
VAS_COP_TYPE_FAULT,
VAS_COP_TYPE_842,
VAS_COP_TYPE_842_HIPRI,
VAS_COP_TYPE_GZIP,
VAS_COP_TYPE_GZIP_HIPRI,
VAS_COP_TYPE_FTW,
VAS_COP_TYPE_MAX,
};
/*
* User space VAS windows are opened by tasks and take references
* to pid and mm until windows are closed.
* Stores pid, mm, and tgid for each window.
*/
struct vas_user_win_ref {
struct pid *pid; /* PID of owner */
struct pid *tgid; /* Thread group ID of owner */
struct mm_struct *mm; /* Linux process mm_struct */
struct mutex mmap_mutex; /* protects paste address mmap() */
/* with DLPAR close/open windows */
struct vm_area_struct *vma; /* Save VMA and used in DLPAR ops */
};
/*
* Common VAS window struct on PowerNV and PowerVM
*/
struct vas_window {
u32 winid;
u32 wcreds_max; /* Window credits */
u32 status; /* Window status used in OS */
enum vas_cop_type cop;
struct vas_user_win_ref task_ref;
char *dbgname;
struct dentry *dbgdir;
};
/*
* User space window operations used for powernv and powerVM
*/
struct vas_user_win_ops {
struct vas_window * (*open_win)(int vas_id, u64 flags,
enum vas_cop_type);
u64 (*paste_addr)(struct vas_window *);
int (*close_win)(struct vas_window *);
};
static inline void put_vas_user_win_ref(struct vas_user_win_ref *ref)
{
/* Drop references to pid, tgid, and mm */
put_pid(ref->pid);
put_pid(ref->tgid);
if (ref->mm)
mmdrop(ref->mm);
}
static inline void vas_user_win_add_mm_context(struct vas_user_win_ref *ref)
{
mm_context_add_vas_window(ref->mm);
/*
* Even a process that has no foreign real address mapping can
* use an unpaired COPY instruction (to no real effect). Issue
* CP_ABORT to clear any pending COPY and prevent a covert
* channel.
*
* __switch_to() will issue CP_ABORT on future context switches
* if process / thread has any open VAS window (Use
* current->mm->context.vas_windows).
*/
asm volatile(PPC_CP_ABORT);
}
/*
* Receive window attributes specified by the (in-kernel) owner of window.
*/
struct vas_rx_win_attr {
u64 rx_fifo;
int rx_fifo_size;
int wcreds_max;
bool pin_win;
bool rej_no_credit;
bool tx_wcred_mode;
bool rx_wcred_mode;
bool tx_win_ord_mode;
bool rx_win_ord_mode;
bool data_stamp;
bool nx_win;
bool fault_win;
bool user_win;
bool notify_disable;
bool intr_disable;
bool notify_early;
int lnotify_lpid;
int lnotify_pid;
int lnotify_tid;
u32 pswid;
int tc_mode;
};
/*
* Window attributes specified by the in-kernel owner of a send window.
*/
struct vas_tx_win_attr {
enum vas_cop_type cop;
int wcreds_max;
int lpid;
int pidr; /* hardware PID (from SPRN_PID) */
int pswid;
int rsvd_txbuf_count;
int tc_mode;
bool user_win;
bool pin_win;
bool rej_no_credit;
bool rsvd_txbuf_enable;
bool tx_wcred_mode;
bool rx_wcred_mode;
bool tx_win_ord_mode;
bool rx_win_ord_mode;
};
#ifdef CONFIG_PPC_POWERNV
/*
* Helper to map a chip id to VAS id.
* For POWER9, this is a 1:1 mapping. In the future this maybe a 1:N
* mapping in which case, we will need to update this helper.
*
* Return the VAS id or -1 if no matching vasid is found.
*/
int chip_to_vas_id(int chipid);
/*
* Helper to initialize receive window attributes to defaults for an
* NX window.
*/
void vas_init_rx_win_attr(struct vas_rx_win_attr *rxattr, enum vas_cop_type cop);
/*
* Open a VAS receive window for the instance of VAS identified by @vasid
* Use @attr to initialize the attributes of the window.
*
* Return a handle to the window or ERR_PTR() on error.
*/
struct vas_window *vas_rx_win_open(int vasid, enum vas_cop_type cop,
struct vas_rx_win_attr *attr);
/*
* Helper to initialize send window attributes to defaults for an NX window.
*/
extern void vas_init_tx_win_attr(struct vas_tx_win_attr *txattr,
enum vas_cop_type cop);
/*
* Open a VAS send window for the instance of VAS identified by @vasid
* and the co-processor type @cop. Use @attr to initialize attributes
* of the window.
*
* Note: The instance of VAS must already have an open receive window for
* the coprocessor type @cop.
*
* Return a handle to the send window or ERR_PTR() on error.
*/
struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop,
struct vas_tx_win_attr *attr);
/*
* Close the send or receive window identified by @win. For receive windows
* return -EAGAIN if there are active send windows attached to this receive
* window.
*/
int vas_win_close(struct vas_window *win);
/*
* Copy the co-processor request block (CRB) @crb into the local L2 cache.
*/
int vas_copy_crb(void *crb, int offset);
/*
* Paste a previously copied CRB (see vas_copy_crb()) from the L2 cache to
* the hardware address associated with the window @win. @re is expected/
* assumed to be true for NX windows.
*/
int vas_paste_crb(struct vas_window *win, int offset, bool re);
int vas_register_api_powernv(struct module *mod, enum vas_cop_type cop_type,
const char *name);
void vas_unregister_api_powernv(void);
#endif
#ifdef CONFIG_PPC_PSERIES
/* VAS Capabilities */
#define VAS_GZIP_QOS_FEAT 0x1
#define VAS_GZIP_DEF_FEAT 0x2
#define VAS_GZIP_QOS_FEAT_BIT PPC_BIT(VAS_GZIP_QOS_FEAT) /* Bit 1 */
#define VAS_GZIP_DEF_FEAT_BIT PPC_BIT(VAS_GZIP_DEF_FEAT) /* Bit 2 */
/* NX Capabilities */
#define VAS_NX_GZIP_FEAT 0x1
#define VAS_NX_GZIP_FEAT_BIT PPC_BIT(VAS_NX_GZIP_FEAT) /* Bit 1 */
/*
* These structs are used to retrieve overall VAS capabilities that
* the hypervisor provides.
*/
struct hv_vas_all_caps {
__be64 descriptor;
__be64 feat_type;
} __packed __aligned(0x1000);
struct vas_all_caps {
u64 descriptor;
u64 feat_type;
};
int h_query_vas_capabilities(const u64 hcall, u8 query_type, u64 result);
int vas_register_api_pseries(struct module *mod,
enum vas_cop_type cop_type, const char *name);
void vas_unregister_api_pseries(void);
#endif
/*
* Register / unregister coprocessor type to VAS API which will be exported
* to user space. Applications can use this API to open / close window
* which can be used to send / receive requests directly to cooprcessor.
*
* Only NX GZIP coprocessor type is supported now, but this API can be
* used for others in future.
*/
int vas_register_coproc_api(struct module *mod, enum vas_cop_type cop_type,
const char *name,
const struct vas_user_win_ops *vops);
void vas_unregister_coproc_api(void);
int get_vas_user_win_ref(struct vas_user_win_ref *task_ref);
void vas_update_csb(struct coprocessor_request_block *crb,
struct vas_user_win_ref *task_ref);
void vas_dump_crb(struct coprocessor_request_block *crb);
#endif /* __ASM_POWERPC_VAS_H */
|