.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright 2016-17 IBM Corp. |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or |
---|
5 | | - * modify it under the terms of the GNU General Public License |
---|
6 | | - * as published by the Free Software Foundation; either version |
---|
7 | | - * 2 of the License, or (at your option) any later version. |
---|
8 | 4 | */ |
---|
9 | 5 | |
---|
10 | 6 | #ifndef _VAS_H |
---|
.. | .. |
---|
105 | 101 | /* |
---|
106 | 102 | * Initial per-process credits. |
---|
107 | 103 | * Max send window credits: 4K-1 (12-bits in VAS_TX_WCRED) |
---|
108 | | - * Max receive window credits: 64K-1 (16 bits in VAS_LRX_WCRED) |
---|
109 | 104 | * |
---|
110 | 105 | * TODO: Needs tuning for per-process credits |
---|
111 | 106 | */ |
---|
112 | | -#define VAS_RX_WCREDS_MAX ((64 << 10) - 1) |
---|
113 | 107 | #define VAS_TX_WCREDS_MAX ((4 << 10) - 1) |
---|
114 | 108 | #define VAS_WCREDS_DEFAULT (1 << 10) |
---|
115 | 109 | |
---|
.. | .. |
---|
300 | 294 | }; |
---|
301 | 295 | |
---|
302 | 296 | /* |
---|
| 297 | + * NX can generate an interrupt for multiple faults and expects kernel |
---|
| 298 | + * to process all of them. So read all valid CRB entries until find the |
---|
| 299 | + * invalid one. So use pswid which is pasted by NX and ccw[0] (reserved |
---|
| 300 | + * bit in BE) to check valid CRB. CCW[0] will not be touched by user |
---|
| 301 | + * space. Application gets CRB formt error if it updates this bit. |
---|
| 302 | + * |
---|
| 303 | + * Invalidate FIFO during allocation and process all entries from last |
---|
| 304 | + * successful read until finds invalid pswid and ccw[0] values. |
---|
| 305 | + * After reading each CRB entry from fault FIFO, the kernel invalidate |
---|
| 306 | + * it by updating pswid with FIFO_INVALID_ENTRY and CCW[0] with |
---|
| 307 | + * CCW0_INVALID. |
---|
| 308 | + */ |
---|
| 309 | +#define FIFO_INVALID_ENTRY 0xffffffff |
---|
| 310 | +#define CCW0_INVALID 1 |
---|
| 311 | + |
---|
| 312 | +/* |
---|
303 | 313 | * One per instance of VAS. Each instance will have a separate set of |
---|
304 | 314 | * receive windows, one per coprocessor type. |
---|
305 | 315 | * |
---|
.. | .. |
---|
316 | 326 | u64 uwc_bar_start; |
---|
317 | 327 | u64 paste_base_addr; |
---|
318 | 328 | u64 paste_win_id_shift; |
---|
| 329 | + |
---|
| 330 | + u64 irq_port; |
---|
| 331 | + int virq; |
---|
| 332 | + int fault_crbs; |
---|
| 333 | + int fault_fifo_size; |
---|
| 334 | + int fifo_in_progress; /* To wake up thread or return IRQ_HANDLED */ |
---|
| 335 | + spinlock_t fault_lock; /* Protects fifo_in_progress update */ |
---|
| 336 | + void *fault_fifo; |
---|
| 337 | + struct vas_window *fault_win; /* Fault window */ |
---|
319 | 338 | |
---|
320 | 339 | struct mutex mutex; |
---|
321 | 340 | struct vas_window *rxwin[VAS_COP_TYPE_MAX]; |
---|
.. | .. |
---|
337 | 356 | bool user_win; /* True if user space window */ |
---|
338 | 357 | void *hvwc_map; /* HV window context */ |
---|
339 | 358 | void *uwc_map; /* OS/User window context */ |
---|
340 | | - pid_t pid; /* Linux process id of owner */ |
---|
| 359 | + struct pid *pid; /* Linux process id of owner */ |
---|
| 360 | + struct pid *tgid; /* Thread group ID of owner */ |
---|
| 361 | + struct mm_struct *mm; /* Linux process mm_struct */ |
---|
341 | 362 | int wcreds_max; /* Window credits */ |
---|
342 | 363 | |
---|
343 | 364 | char *dbgname; |
---|
.. | .. |
---|
362 | 383 | * is a container for the register fields in the window context. |
---|
363 | 384 | */ |
---|
364 | 385 | struct vas_winctx { |
---|
365 | | - void *rx_fifo; |
---|
| 386 | + u64 rx_fifo; |
---|
366 | 387 | int rx_fifo_size; |
---|
367 | 388 | int wcreds_max; |
---|
368 | 389 | int rsvd_txbuf_count; |
---|
.. | .. |
---|
410 | 431 | extern void vas_instance_init_dbgdir(struct vas_instance *vinst); |
---|
411 | 432 | extern void vas_window_init_dbgdir(struct vas_window *win); |
---|
412 | 433 | extern void vas_window_free_dbgdir(struct vas_window *win); |
---|
| 434 | +extern int vas_setup_fault_window(struct vas_instance *vinst); |
---|
| 435 | +extern irqreturn_t vas_fault_thread_fn(int irq, void *data); |
---|
| 436 | +extern irqreturn_t vas_fault_handler(int irq, void *dev_id); |
---|
| 437 | +extern void vas_return_credit(struct vas_window *window, bool tx); |
---|
| 438 | +extern struct vas_window *vas_pswid_to_window(struct vas_instance *vinst, |
---|
| 439 | + uint32_t pswid); |
---|
| 440 | +extern void vas_win_paste_addr(struct vas_window *window, u64 *addr, |
---|
| 441 | + int *len); |
---|
| 442 | + |
---|
| 443 | +static inline int vas_window_pid(struct vas_window *window) |
---|
| 444 | +{ |
---|
| 445 | + return pid_vnr(window->pid); |
---|
| 446 | +} |
---|
413 | 447 | |
---|
414 | 448 | static inline void vas_log_write(struct vas_window *win, char *name, |
---|
415 | 449 | void *regptr, u64 val) |
---|
.. | .. |
---|
460 | 494 | */ |
---|
461 | 495 | static inline u32 encode_pswid(int vasid, int winid) |
---|
462 | 496 | { |
---|
463 | | - u32 pswid = 0; |
---|
464 | | - |
---|
465 | | - pswid |= vasid << (31 - 7); |
---|
466 | | - pswid |= winid; |
---|
467 | | - |
---|
468 | | - return pswid; |
---|
| 497 | + return ((u32)winid | (vasid << (31 - 7))); |
---|
469 | 498 | } |
---|
470 | 499 | |
---|
471 | 500 | static inline void decode_pswid(u32 pswid, int *vasid, int *winid) |
---|