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
|
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _GSP_SEMA_SERVICE_H_
#define _GSP_SEMA_SERVICE_H_
/*
* Emulated-GPU progress service: discovers the guest's GPU-VA -> guest-PA
* mapping and applies the copy-engine semaphore releases found in mapped
* pages, so that the guest's UVM progress waits complete.
*
* See gsp_sema_service.c for the full description.
*/
/*
* A guest channel, registered when the driver allocates it. The service uses
* the channel's GPFIFO + USERD to notice submissions as they happen (instead
* of discovering the pushed work by scanning guest RAM) and to run the pushed
* work promptly.
*
* All addresses are guest-physical except gpfifo_va, which is the GPU VA of
* the channel's GPFIFO ring (translated through the discovered VA->PA map).
*/
struct sema_channel_desc {
u32 h_object;
u32 engine_type;
u32 cid; /* RM channel id (the doorbell token vector) */
u64 gpfifo_va;
u32 gpfifo_entries;
u64 userd_pa; /* NvA06FControl: GPGet @0x88, GPPut @0x8c */
u32 userd_as; /* NV_ADDR_SYSMEM(1) / NV_ADDR_FBMEM(2) */
u64 instance_pa;
u64 notifier_pa;
u32 notifier_as; /* NV_ADDR_SYSMEM(1) / NV_ADDR_FBMEM(2) */
};
void gsp_sema_service_channel_add(const struct sema_channel_desc *desc);
void gsp_sema_service_channel_del(u32 h_object);
/*
* A GPU VA space whose top-level page directory the driver has published (the
* driver builds its own page tables for the address spaces it owns, then hands
* the directory's physical address to the GPU through SET_PAGE_DIRECTORY).
*
* pdb is the directory base in the aperture selected by b_vidmem (false =
* guest RAM, true = emulated vidmem); num_entries is the root entry count and
* fixes the number of VA bits the root covers.
*/
struct sema_vaspace_desc {
u32 h_vaspace;
u64 pdb;
u32 num_entries;
bool b_vidmem;
};
void gsp_sema_service_vaspace_add(const struct sema_vaspace_desc *desc);
void gsp_sema_service_vaspace_del(u32 h_vaspace);
int gsp_sema_service_start(void);
void gsp_sema_service_stop(void);
int gsp_sema_service_probe(u64 gpu_va, u32 count);
int gsp_sema_service_walk_probe(u64 gpu_va);
int gsp_sema_service_dump_channels(void);
int gsp_sema_service_add_map(u64 gpu_va, u64 pa, u64 len, u32 ap);
int gsp_sema_service_dump_vidmem(u64 addr, u64 len);
int gsp_sema_service_find_vidmem(u64 pattern, u64 max_hits);
int gsp_sema_service_counter_add(u32 h_object, u64 pa);
void gsp_sema_service_doorbell(u32 token);
/*
* Discover and pin GR (compute) channel rings after the CE region of the
* channel video-memory allocation. Set false to leave GR rings untranslated
* (the pump then only runs the CE channels).
*/
extern bool gsp_sema_gr_rings;
/*
* Acknowledge tracking-semaphore releases from CE pushes the pump could not
* read: write the expected payload into the channel's pool semaphore so the
* driver's wait clears immediately instead of after the content sweep.
*/
extern bool gsp_sema_fake_rel;
extern bool gsp_sema_rel_recover;
/*
* Master diagnostic switch for the per-push/per-doorbell/per-op tracing
* (module parameter sema_dbg). Off by default so a healthy boot leaves the
* kernel log quiet; the watch knobs below only take effect while it is on.
*/
extern bool gsp_sema_dbg;
/*
* Skip executing a push's collected work (CE memsets/copies) while still
* applying its release; see the definition for the trade-off.
*/
extern bool gsp_sema_skip_ops;
/*
* How many executed CE ops to log with full operands (diagnostic bound; the
* default keeps a healthy run quiet, raise it to audit a data path).
*/
extern unsigned gsp_sema_ops_log;
/*
* Data-path watch: for copies of exactly this many bytes, log the first 8
* source/destination bytes before the copy (0 = off).
*/
extern unsigned gsp_sema_copy_watch;
/* Data-path watch: 8-byte value matched in copy src/dst and push bytes. */
extern u64 gsp_sema_copy_pat;
/* Data-path watch: dump copies landing in this page (source bytes). */
extern u64 gsp_sema_copy_dst;
/* Second destination window for the same watch (0 = off). */
extern u64 gsp_sema_copy_dst2;
/* CE pending-entry grace window in ms before the release fallback fires. */
extern unsigned gsp_sema_ce_grace_ms;
/*
* Grace window (ms) an untranslatable GR GPFIFO entry is left pending before
* the pump consumes it as stale. The GR push pages are pinned from guest
* truth a moment after the channels appear; the window lets those pins land
* so the releases inside the pushes are applied.
*/
extern unsigned gsp_sema_gr_grace_ms;
#endif /* _GSP_SEMA_SERVICE_H_ */
|