hc
2023-12-11 1f93a7dfd1f8d5ff7a5c53246c7534fe2332d6f4
kernel/arch/powerpc/platforms/powernv/vas.h
....@@ -1,10 +1,6 @@
1
+/* SPDX-License-Identifier: GPL-2.0-or-later */
12 /*
23 * 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.
84 */
95
106 #ifndef _VAS_H
....@@ -105,11 +101,9 @@
105101 /*
106102 * Initial per-process credits.
107103 * 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)
109104 *
110105 * TODO: Needs tuning for per-process credits
111106 */
112
-#define VAS_RX_WCREDS_MAX ((64 << 10) - 1)
113107 #define VAS_TX_WCREDS_MAX ((4 << 10) - 1)
114108 #define VAS_WCREDS_DEFAULT (1 << 10)
115109
....@@ -300,6 +294,22 @@
300294 };
301295
302296 /*
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
+/*
303313 * One per instance of VAS. Each instance will have a separate set of
304314 * receive windows, one per coprocessor type.
305315 *
....@@ -316,6 +326,15 @@
316326 u64 uwc_bar_start;
317327 u64 paste_base_addr;
318328 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 */
319338
320339 struct mutex mutex;
321340 struct vas_window *rxwin[VAS_COP_TYPE_MAX];
....@@ -337,7 +356,9 @@
337356 bool user_win; /* True if user space window */
338357 void *hvwc_map; /* HV window context */
339358 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 */
341362 int wcreds_max; /* Window credits */
342363
343364 char *dbgname;
....@@ -362,7 +383,7 @@
362383 * is a container for the register fields in the window context.
363384 */
364385 struct vas_winctx {
365
- void *rx_fifo;
386
+ u64 rx_fifo;
366387 int rx_fifo_size;
367388 int wcreds_max;
368389 int rsvd_txbuf_count;
....@@ -410,6 +431,19 @@
410431 extern void vas_instance_init_dbgdir(struct vas_instance *vinst);
411432 extern void vas_window_init_dbgdir(struct vas_window *win);
412433 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
+}
413447
414448 static inline void vas_log_write(struct vas_window *win, char *name,
415449 void *regptr, u64 val)
....@@ -460,12 +494,7 @@
460494 */
461495 static inline u32 encode_pswid(int vasid, int winid)
462496 {
463
- u32 pswid = 0;
464
-
465
- pswid |= vasid << (31 - 7);
466
- pswid |= winid;
467
-
468
- return pswid;
497
+ return ((u32)winid | (vasid << (31 - 7)));
469498 }
470499
471500 static inline void decode_pswid(u32 pswid, int *vasid, int *winid)