summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.h
blob: ae9b7da03cdcd1f597f7534f3f4f5a02067ed1fa (plain)
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
/* 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);

/*
 * P5 wave-1 shadow work lifetime hooks. The backend release path must call
 * gsp_sema_service_work_quiesce() before it frees the ladder buffers: it
 * pauses new shadow requests and waits (bounded by the submit's 200 ms poll
 * cap) for the in-flight one to finish, so no poll ever touches freed memory.
 * gsp_sema_service_work_resume() re-enables requests when a new backend
 * session starts.
 */
void gsp_sema_service_work_quiesce(void);
void gsp_sema_service_work_resume(void);

/*
 * 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_ */