summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_gpu.h
blob: 70b98e48b99c42dd46c670d190629d59772b6d6f (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
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
#ifndef GSP_PHYS_GPU_H
#define GSP_PHYS_GPU_H

#include <linux/types.h>

/*
 * Physical GPU ownership (real-GSP execution backend, bring-up rung 1).
 * Claim is disabled unless the gsp_phys_gpu module parameter is set.
 */
bool gsp_phys_gpu_claimed(void);
int gsp_phys_gpu_claim(void);
void gsp_phys_gpu_release(void);
void __iomem *gsp_phys_gpu_bar0(void);
u32 gsp_phys_gpu_fw_crc32(void);

/*
 * Read by the backend session to enforce the mdev-owned start gate; the
 * gsp_phys_gpu module parameter itself is owned by main.c.
 */
bool gsp_phys_gpu_enabled(void);

/*
 * Backend session state (P0 skeleton + P1 lifecycle; one physical GPU, one
 * live claim). OFF until a start claims the device; READY is the only state
 * in which live RPC forwarding is legal. The refcount and owner flag decide
 * who releases: the load-time module-owned claim is joined, never released,
 * by a stop(); an mdev-owned claim is released by the last stop().
 */
enum gsp_phys_backend_state {
	GSP_PHYS_BACKEND_OFF = 0,
	GSP_PHYS_BACKEND_CLAIMING,
	GSP_PHYS_BACKEND_BOOTING,
	GSP_PHYS_BACKEND_READY,
	GSP_PHYS_BACKEND_STOPPING,
};

/*
 * Refcounted session start/stop around gsp_phys_gpu_claim()/_release(); safe
 * (and idempotent) in any state. gsp_phys_backend_start() never blocks on the
 * claim/boot: an mdev-owned start schedules a work item and returns, and a
 * failed claim leaves the session OFF (fail-open: the caller keeps using the
 * emulation path). The generation counter is bumped when the session leaves
 * READY; a forward that captured the previous value re-checks it under
 * gsp_phys_rm_lock and refuses, so a stop cannot race an in-flight forward.
 * The lock itself stays private to gsp_phys_gpu.c; the state and generation
 * accessors are lock-free reads for use from the RPC path.
 *
 * Module exit uses the two-phase form so the §1.4 ordering can be kept:
 * begin_stop() gates the session (STOPPING + generation bump) before the
 * caller drains the emulation threads, then end_stop() runs the release.
 */
int gsp_phys_backend_start(void);
void gsp_phys_backend_stop(void);
void gsp_phys_backend_begin_stop(void);
void gsp_phys_backend_end_stop(void);
int gsp_phys_backend_state(void);
u32 gsp_phys_backend_generation(void);

/*
 * True when the gsp_phys_mdev_owned module parameter is set (default 0:
 * load-time module-owned claim/boot, today's behavior).
 */
bool gsp_phys_mdev_owned_enabled(void);

/*
 * True when the gsp_phys_static_live module parameter is set (default 0:
 * the guest GET_GSP_STATIC_INFO reply is the emulated model unchanged). When
 * set, the handler overlays the live GPU name/short-name/VBIOS identity from
 * the backend snapshot, failing open to the emulated reply on any miss.
 */
bool gsp_phys_static_live_enabled(void);

/*
 * True when the gsp_phys_ctrl_forward module parameter is set (default 0:
 * guest GSP_RM_CONTROL replies are the emulated answers unchanged). When set,
 * a whitelist of side-effect-free control queries is forwarded to the live
 * backend with the snapshot's adopted internal handles, falling back to the
 * emulated per-command handler on any miss.
 */
bool gsp_phys_ctrl_forward_enabled(void);

/*
 * True when the gsp_phys_work_forward module parameter is set (default 0: the
 * guest's CE pushes stay software-emulated exactly as before). When set, the
 * sema service shadows each decoded CE push as one copy on the debugfs ladder's
 * real channel using only module-owned ladder buffers; the software release
 * remains authoritative and is applied unchanged either way, unless
 * gsp_phys_work_defer_release moves a forwarded push's release after its
 * hardware copy (see below).
 */
bool gsp_phys_work_forward_enabled(void);

/*
 * True when the gsp_phys_guest_mem module parameter is set (default 0: the
 * debugfs rm-call ladder stays entirely on module-owned buffers, exactly as
 * before). When set, ladder triggers 6 (W2G) and 7 (G2H) may point the real
 * CE engine at one pinned guest RAM page identified by GPA, proving the
 * translation path and both copy directions.
 */
bool gsp_phys_guest_mem_enabled(void);

/*
 * True when the gsp_phys_work_defer_release module parameter is set (default
 * 0: a forwarded guest CE push's release is applied inline with the software
 * copy, byte-identical to wave 1). When set with gsp_phys_work_forward and
 * gsp_phys_guest_mem, the release(s) a forwarded push decoded are held on the
 * service thread until the hardware copy completes, its bounded timeout
 * expires, or the forwarding is aborted; they are then applied from the
 * service thread. One-line rollback: gsp_phys_work_defer_release=0.
 */
bool gsp_phys_work_defer_release_enabled(void);

/*
 * True when the gsp_phys_work_hw_primary module parameter is set (default
 * 0: byte-identical to wave 1.5, the software copy always runs inline). When
 * set with gsp_phys_work_forward, gsp_phys_guest_mem and
 * gsp_phys_work_defer_release, a forwarded guest CE copy skips the software
 * copy (the hardware authors the data) and the release still lands only
 * after hardware completion through the wave-1.5 hold. Any hardware failure,
 * timeout, abort or failed guest queue falls back to exactly one software
 * copy in the service thread before the releases are applied, so the guest
 * always reads correct data. One-line rollback: gsp_phys_work_hw_primary=0.
 */
bool gsp_phys_work_hw_primary_enabled(void);

/*
 * Translate a guest GPA to the pinned host PA (gsp_phys_guest_mem ladder
 * support). The mdev is registered with vfio_register_emulated_iommu_dev():
 * its VFIO type-1 container keeps the guest DMA mappings privately, so
 * iommu_get_domain_for_dev() returns NULL there and the original
 * IOMMU-domain path cannot resolve a GPA at runtime. The authoritative
 * translation is the guest RAM backing file configured through debugfs
 * gsp-phys-guest-ram (QEMU memory-backend-file, share=yes): the range's
 * file page is pinned with read_cache_page() and page_to_phys() gives the
 * host PA. Returns 0 and stores the PA on success; -ENODEV with no active
 * mdev, -ENOENT when the file page cannot be read or the GPA is not mapped
 * by the fallback IOMMU path, -ERANGE when the result is not a valid RAM
 * PFN (so a caller never treats MMIO/dead space as RAM), and -EINVAL for a
 * NULL output. The caller must hold no guest or rm lock; this helper takes
 * nv_vgpu_driver.lock only for the mdev lookup and guest_ram_lock across
 * the range walk/read.
 */
int gsp_phys_gpa_to_hpa(u64 gpa, u64 *hpa_out);

/*
 * Guest RAM backing-file configuration (debugfs gsp-phys-guest-ram). One
 * shared file per module cycle, up to four GPA->file-offset ranges keyed by
 * gpa_base. The first configure opens the file; the same path adds/replaces
 * ranges, a different path is refused -EBUSY, and the ranges are dropped and
 * the file closed by gsp_phys_guest_ram_clear() on physical-GPU release. The
 * state accessor is lock-safe and writes "active=0" or the active path,
 * range count and per-range gpa/off/size into the caller's buffer.
 */
int gsp_phys_guest_ram_configure(const char *path, u64 gpa_base,
				 u64 file_offset, u64 size);
void gsp_phys_guest_ram_clear(void);
bool gsp_phys_guest_ram_active(void);
void gsp_phys_guest_ram_state(char *buf, size_t len);

/*
 * Domain shape of the physical (claimed) device, as the P6a engine path
 * needs it: the module programs raw host PAs into the CE page tables, so the
 * engine may only run when the physical device's DMA addresses ARE host PAs.
 * Returns 1 when the claimed device's IOMMU domain is
 * IOMMU_DOMAIN_IDENTITY, 0 when another domain type, and -1 when the device
 * is not claimed or has no domain (either way the caller must refuse).
 */
int gsp_phys_dma_domain_identity(void);

#endif /* GSP_PHYS_GPU_H */