summaryrefslogtreecommitdiffstats
path: root/legacy-driver-guest/include
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-21 13:06:51 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-21 13:06:51 -0400
commitc3a295efd1b1132bbaa5d422cd05b3fa8e89a8bf (patch)
treef74bd7724153cd9d870688df3ff75274cd5000da /legacy-driver-guest/include
parent5d4d26f8e773f2871c1b5c9266b82495d390970e (diff)
downloadopen-iov-c3a295efd1b1132bbaa5d422cd05b3fa8e89a8bf.tar.gz
open-iov-c3a295efd1b1132bbaa5d422cd05b3fa8e89a8bf.zip
kernel: Fix GSP emulation shadow binding, eventfd wiring, RPC livelocks + docs suite + repo reorg
CRITICAL FIXES (guest driver bring-up): - gsp_emulation.c: emulation engine bound to the WRONG BAR0 - it polled the host physical BAR0 (bars[0].vaddr ioremap) for the doorbell and read RPCs from a local dma_alloc_wc buffer, while the guest writes land in the vzalloc'd bar0_shadow. The RPC path could never work; PBA writes even corrupted the host GPU's physical BAR0+0x3000. gsp_emu_init now binds exclusively to bar0_shadow (doorbell/mailbox/PBA aliases; shared_mem_dma==0 marks the alias so cleanup never dma_free's it). - main.c SET_IRQS: DATA_EVENTFD eventfds were DISCARDED ('TODO' + kfree) - the guest never received MSI-X completions. Full wiring now: eventfd_ctx_fdget per vector, fd -1 clears, dev_close releases refs. gsp_emu_inject_completion_interrupt looks up vgpu->irqs[0].trigger LIVE (init-time copy was permanently NULL since QEMU wires after gsp_emu_init). - gsp_rpc_client.c: BAR_TRAP/MIGRATE in emulation mode called gsp_rpc_submit_raw which rings the SAME doorbell the thread polls - self-triggered RPC livelock + multi-second stalls. Now fail fast with -ENOTSUPP + pr_warn_ratelimited (guest BAR access is direct MMIO). MORE FIXES: - main.c: nv_vgpu_config_write returned SIZE_MAX (while(count--) wrap) and was dead code while the VFIO write handler did unfiltered byte copies (guest could rewrite vendor ID/BARs). Return fixed; VFIO write handler now routes through the per-register filter. - kernel/Makefile: M=$(PWD) used the env var which is stale when invoked via the top-level make (pointed at repo root -> kbuild silently built NOTHING; explains every 'stale .ko' incident). Now M=$(CURDIR). - Warnings sweep: header prototypes for mdev/type functions, format casts in gsp_comm.c DRY-RUN logs, unused variable. ROBUSTNESS (harness/tooling): - vgpu_vm.py: run had no timeout (start could block forever); guest_shell recv could block forever on a wedged guest. Both now bounded; guest_shell pre-flights guest-ping and reports wedge diagnostics. - stack_manager.sh: qemu/qemu-debug now launch via the vgpu_vm.py harness (workflow rule: never raw QEMU). REPO REORGANIZATION: - driver/ (legacy guest-side gsp-vgpu.ko) moved to legacy-driver-guest/ (reference only, not built; README explains). 3 legacy un-buildable test files moved to legacy-driver-guest/kernel-tests/. Top-level Makefile cleaned of the dead DRIVER_DIR reference. DOCUMENTATION SUITE (new): - docs/GSP_EMULATION_ARCHITECTURE.md - emulator deep-dive: shadow BAR0 model, doorbell protocol, dispatch table, MSI-X path, lifecycle, memory- model caveats - docs/DEBUGGING.md - QEMU GDB stub workflow, serial console, QMP NMI, failure taxonomy, full bring-up validation checklist, EPT-livelock case study, version-matrix discipline - docs/ONBOARDING.md - repo tour, coding standards (incl. virt_to_phys / dma_addr_t / get-put rules), first build & test - docs/VERSION_UPGRADE.md - end-to-end new-driver-version procedure (firmware fetch, Ghidra analysis, configs, signatures, validation) - docs/PERFORMANCE.md - bare-metal A/B methodology + targets - README.md doc index; STATE.md refreshed; DEVELOPMENT_WORKFLOW.md corrected (load order: open-iov-vfio BEFORE nvidia; stock-driver blacklist note)
Diffstat (limited to 'legacy-driver-guest/include')
-rw-r--r--legacy-driver-guest/include/gsp_core.h613
1 files changed, 613 insertions, 0 deletions
diff --git a/legacy-driver-guest/include/gsp_core.h b/legacy-driver-guest/include/gsp_core.h
new file mode 100644
index 0000000..569d6f8
--- /dev/null
+++ b/legacy-driver-guest/include/gsp_core.h
@@ -0,0 +1,613 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * GSP vGPU-IO Driver - Core Definitions
+ * NVIDIA GSP 570.144W (TU102/TU104) Firmware Interface
+ */
+
+#ifndef _GSP_CORE_H_
+#define _GSP_CORE_H_
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/mutex.h>
+#include <linux/idr.h>
+#include <linux/list.h>
+#include <linux/kref.h>
+#include <linux/completion.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/miscdevice.h>
+
+/* Firmware Constants */
+#define GSP_FW_BASE_ADDR 0x04000000ULL
+#define GSP_FW_SIZE 0x02000000ULL
+#define GSP_ENTRY_POINT 0x04009000ULL
+#define GSP_PRIMARY_DISPATCHER 0x057A1AC0ULL
+#define GSP_SECONDARY_DISPATCHER 0x04ED39DCULL
+#define GSP_RPC_JUMP_TABLE 0x059BFEB0ULL
+
+/* PCIe BAR Offsets */
+#define GSP_BAR0_FALCON_ENGINE 0x1103c0
+#define GSP_BAR0_FALCON_MAILBOX0 0x110040
+#define GSP_BAR0_FALCON_MAILBOX1 0x110044
+#define GSP_BAR0_MAILBOX(i) (0x110804 + (i) * 4)
+#define GSP_BAR0_QUEUE_HEAD(i) (0x110c00 + (i) * 8)
+
+/* IOCTL definitions (must match userspace libvgpu.h) */
+#define GSP_IOCTL_MAGIC 'G'
+#define GSP_IOCTL_CREATE_VF _IOW(GSP_IOCTL_MAGIC, 0x01, struct gsp_vf_config)
+#define GSP_IOCTL_DESTROY_VF _IOW(GSP_IOCTL_MAGIC, 0x02, uint32_t)
+#define GSP_IOCTL_ALLOC _IOWR(GSP_IOCTL_MAGIC, 0x10, struct gsp_alloc_args)
+#define GSP_IOCTL_FREE _IOW(GSP_IOCTL_MAGIC, 0x11, struct gsp_free_args)
+#define GSP_IOCTL_MAP _IOWR(GSP_IOCTL_MAGIC, 0x12, struct gsp_map_args)
+#define GSP_IOCTL_UNMAP _IOW(GSP_IOCTL_MAGIC, 0x13, struct gsp_unmap_args)
+#define GSP_IOCTL_PIN _IOWR(GSP_IOCTL_MAGIC, 0x14, struct gsp_pin_args)
+#define GSP_IOCTL_UNPIN _IOW(GSP_IOCTL_MAGIC, 0x15, struct gsp_unpin_args)
+#define GSP_IOCTL_BAR_CONFIG _IOWR(GSP_IOCTL_MAGIC, 0x16, struct gsp_bar_config_args)
+#define GSP_IOCTL_BAR_FORCE _IOW(GSP_IOCTL_MAGIC, 0x17, struct gsp_bar_force_args)
+#define GSP_IOCTL_BAR_SAVE _IOWR(GSP_IOCTL_MAGIC, 0x18, struct gsp_bar_save_args)
+#define GSP_IOCTL_BAR_RESTORE _IOWR(GSP_IOCTL_MAGIC, 0x19, struct gsp_bar_restore_args)
+#define GSP_IOCTL_WPR_PROTECT _IOWR(GSP_IOCTL_MAGIC, 0x1A, struct gsp_wpr_args)
+#define GSP_IOCTL_WPR_UNPROTECT _IOW(GSP_IOCTL_MAGIC, 0x1B, struct gsp_wpr_args)
+#define GSP_IOCTL_WPR_TIMEOUT _IOW(GSP_IOCTL_MAGIC, 0x1C, struct gsp_wpr_timeout_args)
+#define GSP_IOCTL_SCHEDULE _IOW(GSP_IOCTL_MAGIC, 0x1D, struct gsp_schedule_args)
+#define GSP_IOCTL_YIELD _IOW(GSP_IOCTL_MAGIC, 0x1E, uint32_t)
+#define GSP_IOCTL_MIGRATE _IOWR(GSP_IOCTL_MAGIC, 0x1F, struct gsp_migrate_args)
+#define GSP_IOCTL_GET_INFO _IOR(GSP_IOCTL_MAGIC, 0x20, char[256])
+
+/* Kernel argument structures (matching userspace) */
+struct gsp_vf_config {
+ uint32_t id;
+ uint64_t bar1_offset;
+ uint64_t bar1_size;
+ uint64_t pt_base;
+ uint64_t pt_size;
+ uint64_t cmd_base;
+ uint64_t cmd_size;
+ uint32_t max_memory_mb;
+ uint32_t num_engines;
+};
+
+struct gsp_alloc_args {
+ uint32_t vf_id;
+ uint64_t size;
+ uint32_t type;
+ uint64_t alignment;
+ uint64_t va_hint;
+ uint32_t flags;
+ uint32_t pid;
+ uint64_t handle;
+ uint64_t va;
+ uint64_t actual_size;
+};
+
+struct gsp_free_args {
+ uint32_t vf_id;
+ uint64_t handle;
+};
+
+struct gsp_map_args {
+ uint32_t vf_id;
+ uint64_t handle;
+ uint64_t gpu_va;
+ uint64_t size;
+ uint32_t prot;
+ uint32_t flags;
+ uint64_t offset;
+ uint64_t mapped_va;
+};
+
+struct gsp_unmap_args {
+ uint32_t vf_id;
+ uint64_t handle;
+ uint64_t gpu_va;
+ uint64_t size;
+};
+
+struct gsp_pin_args {
+ uint32_t vf_id;
+ uint64_t handle;
+ uint64_t offset;
+ uint64_t size;
+ uint32_t flags;
+ uint64_t dma_addr;
+ uint32_t num_pages;
+};
+
+struct gsp_unpin_args {
+ uint32_t vf_id;
+ uint64_t handle;
+ uint64_t offset;
+ uint64_t size;
+};
+
+struct gsp_bar_config_args {
+ uint32_t vf_id;
+ uint64_t aperture_offset;
+ uint64_t aperture_size;
+};
+
+struct gsp_bar_force_args {
+ uint32_t vf_id;
+ uint32_t enable;
+};
+
+struct gsp_bar_save_args {
+ uint32_t vf_id;
+ void *buf;
+ size_t *size;
+};
+
+struct gsp_bar_restore_args {
+ uint32_t vf_id;
+ void *buf;
+ size_t size;
+};
+
+struct gsp_wpr_args {
+ uint32_t vf_id;
+ uint64_t base;
+ uint64_t size;
+ uint32_t flags;
+};
+
+struct gsp_wpr_timeout_args {
+ uint32_t vf_id;
+ uint64_t timeout_ns;
+};
+
+struct gsp_schedule_args {
+ uint32_t vf_id;
+ uint32_t priority;
+ uint64_t time_slice_ns;
+};
+
+struct gsp_migrate_args {
+ uint32_t vf_id;
+ uint64_t dst_vf;
+ uint32_t phase;
+ uint32_t flags;
+ uint64_t token;
+};
+
+/* Message Ring */
+#define GSP_MSG_RING_SIZE 256
+#define GSP_MSG_MAX_SIZE 256
+#define GSP_MAX_PENDING 64
+
+/* RPC Types */
+enum gsp_rpc_type {
+ GSP_RPC_ALLOC = 0x01,
+ GSP_RPC_FREE = 0x02,
+ GSP_RPC_MAP = 0x03,
+ GSP_RPC_UNMAP = 0x04,
+ GSP_RPC_PIN = 0x05,
+ GSP_RPC_UNPIN = 0x06,
+ GSP_RPC_SCHEDULE = 0x07,
+ GSP_RPC_YIELD = 0x08,
+ GSP_RPC_NOTIFY = 0x09,
+ GSP_RPC_BAR_TRAP = 0x0A,
+ GSP_RPC_MIGRATE = 0x0B,
+ GSP_RPC_DEBUG = 0x0C,
+};
+
+/* RPC Message Flags */
+#define GSP_MSG_SYNC (1 << 0)
+#define GSP_MSG_ASYNC (1 << 1)
+#define GSP_MSG_NOREPLY (1 << 2)
+
+/* Memory Types */
+enum gsp_mem_type {
+ GSP_MEM_VRAM = 0,
+ GSP_MEM_SYSMEM = 1,
+ GSP_MEM_UNCACHED = 2,
+};
+
+/* Pin Flags */
+#define GSP_PIN_READ (1 << 0)
+#define GSP_PIN_WRITE (1 << 1)
+#define GSP_PIN_LONGTERM (1 << 2)
+
+/* BAR Trap Types */
+#define GSP_BAR_READ 0
+#define GSP_BAR_WRITE 1
+#define GSP_BAR_ATOMIC 2
+
+/* Migration Phases */
+enum gsp_migrate_phase {
+ GSP_MIG_QUERY = 0,
+ GSP_MIG_PREPARE = 1,
+ GSP_MIG_TRANSFER = 2,
+ GSP_MIG_COMMIT = 3,
+ GSP_MIG_CLEANUP = 4,
+};
+
+/* Migration Flags */
+#define GSP_MIG_LIVE (1 << 0)
+#define GSP_MIG_POSTCOPY (1 << 1)
+#define GSP_MIG_AUTO_COMMIT (1 << 2)
+#define GSP_MIG_VERIFY (1 << 3)
+
+/* Error Codes (from firmware) */
+#define GSP_OK 0
+#define GSP_EPERM 0xFFFFFFFF
+#define GSP_ENOENT 0xFFFFFFFE
+#define GSP_EINVAL 0xFFFFFFFD
+#define GSP_ENODEV 0xFFFFFFFA
+#define GSP_ENOMEM 0xFFFFFFF4
+#define GSP_EBUSY 0xFFFFFFEE
+#define GSP_ENOSPC 0xFFFFFFE4
+#define GSP_ETIMEDOUT 0x0000001E
+#define GSP_EOVERFLOW 0x00000025
+#define GSP_EDEV 0x0000001F
+
+/* Forward Declarations */
+struct gsp_device;
+struct gsp_vf;
+struct gsp_rpc_client;
+struct gsp_migration;
+struct gsp_wpr_region;
+
+/* WPR Region */
+struct gsp_wpr_region {
+ struct list_head list;
+ uint64_t base;
+ uint64_t size;
+ uint32_t flags;
+ uint32_t vf_id;
+ void (*completion_cb)(struct gsp_vf *, uint64_t, uint32_t);
+ void (*timeout_cb)(struct gsp_vf *, uint64_t, uint32_t);
+ uint64_t timeout_ns;
+};
+
+/* WPR Flags */
+#define GSP_WPR_WRITE (1 << 0)
+#define GSP_WPR_READ (1 << 1)
+#define GSP_WPR_EXECUTE (1 << 2)
+
+/* WPR Event Types */
+enum gsp_wpr_event {
+ GSP_WPR_WRITE_COMPLETE = 0,
+ GSP_WPR_READ_COMPLETE = 1,
+ GSP_WPR_WRITE_TIMEOUT = 2,
+ GSP_WPR_READ_TIMEOUT = 3,
+};
+
+/* Migration State */
+enum gsp_mig_state {
+ GSP_MIG_S_IDLE = 0,
+ GSP_MIG_S_QUERY = 1,
+ GSP_MIG_S_PREPARE = 2,
+ GSP_MIG_S_TRANSFER = 3,
+ GSP_MIG_S_COMMIT = 4,
+ GSP_MIG_S_CLEANUP = 5,
+ GSP_MIG_S_FAILED = 6,
+ GSP_MIG_S_COMPLETED = 7,
+};
+
+/* Migration Context */
+struct gsp_migration {
+ struct gsp_vf *vf;
+ struct mutex lock;
+ enum gsp_mig_state state;
+ uint64_t token;
+ uint64_t dst_vf;
+ uint32_t flags;
+
+ struct {
+ uint64_t pages_transferred;
+ uint64_t bytes_transferred;
+ uint64_t dirty_pages;
+ uint64_t *page_list;
+ uint32_t page_count;
+ } progress;
+
+ struct {
+ void *buf;
+ size_t size;
+ } bar_state;
+
+ struct task_struct *thread;
+ struct completion comp;
+ bool cancelled;
+ int error;
+};
+
+/* Emulation mode: skip GSP RPC for BAR/WPR when GSP lacks vGPU handlers */
+extern bool emulation_mode;
+
+/* RPC Message Header (64 bytes) */
+struct gsp_rpc_header {
+ uint32_t magic; /* 0x47535052 "GSPR" */
+ uint32_t version; /* Protocol version */
+ uint32_t rpc_type; /* enum gsp_rpc_type */
+ uint32_t sequence; /* Monotonic sequence */
+ uint64_t timestamp_ns; /* Submission timestamp */
+ uint32_t payload_size; /* Payload size in bytes */
+ uint32_t flags; /* GSP_MSG_* */
+ uint64_t correlation_id; /* Async matching */
+ uint64_t reserved[3]; /* Padding to 64 bytes */
+} __attribute__((packed));
+
+/* Complete RPC Message */
+struct gsp_rpc_message {
+ struct gsp_rpc_header hdr;
+ uint8_t payload[GSP_MSG_MAX_SIZE - sizeof(struct gsp_rpc_header)];
+} __attribute__((packed));
+
+/* RPC Response Header */
+struct gsp_rpc_response {
+ int64_t status; /* 0 = success, negative = error */
+ uint32_t rpc_type; /* Echo of request */
+ uint32_t sequence; /* Echo of request */
+ uint64_t timestamp_ns; /* Completion timestamp */
+ uint32_t payload_size; /* Response payload size */
+ uint32_t reserved;
+ uint8_t payload[];
+} __attribute__((packed));
+
+/* Primary Dispatcher Sub-Command Descriptor */
+struct gsp_subcmd_desc {
+ uint32_t subcmd_id; /* Constant ID (e.g., 0x10, 0x14, 0x40) */
+ uint8_t echo_flags_b; /* Copy of input flags_b */
+ uint8_t echo_flags_a; /* Copy of input flags_a */
+ uint8_t echo_flags_c; /* Copy of input flags_c */
+ uint8_t reserved;
+} __attribute__((packed));
+
+/* ALLOC Payload */
+struct gsp_alloc_payload {
+ uint64_t size;
+ uint32_t type; /* enum gsp_mem_type */
+ uint32_t alignment;
+ uint64_t va_hint;
+ uint32_t flags;
+ uint32_t pid;
+ uint32_t vf_id;
+ uint32_t reserved;
+} __attribute__((packed));
+
+struct gsp_alloc_response {
+ uint64_t handle;
+ uint64_t va;
+ uint64_t pa;
+} __attribute__((packed));
+
+/* PIN Payload */
+struct gsp_pin_payload {
+ uint64_t handle;
+ uint64_t offset;
+ uint64_t size;
+ uint32_t vf_id;
+ uint32_t flags; /* GSP_PIN_* */
+ uint32_t reserved[2];
+} __attribute__((packed));
+
+struct gsp_pin_response {
+ uint64_t dma_addr;
+} __attribute__((packed));
+
+/* BAR Trap Payload */
+struct gsp_bar_trap_payload {
+ uint32_t bar_index;
+ uint32_t trap_type; /* GSP_BAR_* */
+ uint64_t offset;
+ uint64_t value;
+ uint32_t size;
+ uint32_t vf_id;
+ uint32_t reserved;
+} __attribute__((packed));
+
+struct gsp_bar_trap_response {
+ uint64_t value;
+} __attribute__((packed));
+
+/* Migration Payload */
+struct gsp_migrate_payload {
+ uint32_t phase; /* enum gsp_migrate_phase */
+ uint32_t subcmd; /* Sub-command index */
+ uint64_t src_vf;
+ uint64_t dst_vf;
+ uint64_t data_ptr;
+ uint64_t data_size;
+ uint32_t flags; /* GSP_MIG_* */
+ uint32_t reserved;
+ uint64_t token;
+} __attribute__((packed));
+
+/* Message Ring Buffer */
+struct gsp_msg_ring {
+ void *base;
+ size_t size;
+ uint32_t head;
+ uint32_t tail;
+ spinlock_t lock;
+};
+
+/* RPC Client */
+struct gsp_rpc_client {
+ struct gsp_device *gsp;
+ struct mutex lock;
+ atomic_t seq;
+ wait_queue_head_t wq;
+ struct gsp_msg_ring *tx_ring;
+ struct gsp_msg_ring *rx_ring;
+ dma_addr_t tx_ring_dma;
+ dma_addr_t rx_ring_dma;
+ struct completion *pending[GSP_MAX_PENDING];
+ struct gsp_rpc_response *resp_buf[GSP_MAX_PENDING];
+};
+
+/* BAR State per VF */
+struct gsp_bar_state {
+ uint64_t aperture_offset;
+ uint64_t aperture_size;
+ bool force_access;
+ uint32_t force_vf;
+ void *backing_store;
+ size_t backing_size;
+};
+
+/* VF State */
+enum gsp_vf_state {
+ GSP_VF_CREATING = 0,
+ GSP_VF_ACTIVE,
+ GSP_VF_MIGRATING,
+ GSP_VF_SUSPENDED,
+ GSP_VF_DESTROYING,
+};
+
+/* GSP Virtual Function */
+struct gsp_vf {
+ struct gsp_device *gsp;
+ uint32_t id;
+ struct kref ref;
+ struct mutex lock;
+ enum gsp_vf_state state;
+ struct gsp_migration *migration;
+
+ /* Resource configuration */
+ uint64_t bar1_offset;
+ uint64_t bar1_size;
+ uint64_t pt_base;
+ uint64_t pt_size;
+ uint64_t cmd_base;
+ uint64_t cmd_size;
+
+ /* WPR regions */
+ struct list_head wpr_list;
+ struct mutex wpr_lock;
+
+ /* BAR state */
+ struct gsp_bar_state bar_state;
+
+ atomic_t refcount;
+ bool active;
+ struct list_head list;
+};
+
+/* GSP Device */
+struct gsp_device {
+ struct pci_dev *pdev;
+ struct device *dev;
+ void __iomem *bar0;
+ void __iomem *bar1;
+
+ /* Firmware */
+ const struct firmware *fw;
+ bool fw_loaded;
+
+ /* RPC */
+ struct gsp_rpc_client *rpc;
+
+ /* VF Management */
+ struct mutex vf_lock;
+ struct idr vf_idr;
+ struct list_head vf_list;
+ uint32_t max_vfs;
+
+ /* IRQ */
+ int irq;
+ bool msix_enabled;
+ struct msix_entry msix_entries[1];
+
+ /* Debug */
+ struct dentry *debugfs_root;
+ struct dentry *debugfs_vfs_dir;
+
+ /* Char device */
+ struct miscdevice miscdev;
+ struct mutex chardev_lock;
+
+ /* Statistics */
+ atomic64_t rpc_total;
+ atomic64_t rpc_errors;
+ atomic64_t bar_traps;
+ atomic64_t wpr_events;
+ atomic64_t migrations;
+};
+
+/* Function Prototypes */
+
+/* Core */
+int gsp_probe(struct pci_dev *pdev, const struct pci_device_id *id);
+void gsp_remove(struct pci_dev *pdev);
+int gsp_firmware_load(struct gsp_device *gsp);
+int gsp_rpc_init(struct gsp_device *gsp);
+void gsp_shutdown(struct gsp_device *gsp);
+
+/* RPC Client */
+struct gsp_rpc_client *gsp_rpc_client_init(struct gsp_device *gsp);
+void gsp_rpc_client_fini(struct gsp_rpc_client *rpc);
+int gsp_rpc_send_sync(struct gsp_rpc_client *rpc,
+ enum gsp_rpc_type type,
+ void *payload, size_t payload_size,
+ void *response, size_t *response_size);
+int gsp_rpc_send_async(struct gsp_rpc_client *rpc,
+ enum gsp_rpc_type type,
+ void *payload, size_t payload_size,
+ void (*callback)(struct gsp_rpc_client *,
+ struct gsp_rpc_response *,
+ void *),
+ void *ctx);
+irqreturn_t gsp_isr(int irq, void *data);
+void gsp_handle_notification(struct gsp_device *gsp, struct gsp_rpc_message *msg);
+int gsp_errno_to_errno(int gsp_err);
+
+/* VF Management */
+int gsp_vf_create(struct gsp_device *gsp, const struct gsp_vf_config *config);
+void gsp_vf_destroy(struct gsp_vf *vf);
+struct gsp_vf *gsp_vf_get(struct gsp_device *gsp, uint32_t id);
+void gsp_vf_put(struct gsp_vf *vf);
+
+/* Memory Management */
+int gsp_vf_mem_alloc(struct gsp_vf *vf, uint64_t size, uint32_t flags,
+ uint64_t *handle, uint64_t *va);
+int gsp_vf_mem_free(struct gsp_vf *vf, uint64_t handle);
+int gsp_vf_mem_pin(struct gsp_vf *vf, uint64_t handle,
+ uint64_t offset, uint64_t size,
+ uint64_t *dma_addr);
+int gsp_vf_mem_unpin(struct gsp_vf *vf, uint64_t handle);
+int gsp_vf_mem_map(struct gsp_vf *vf, uint64_t handle, uint64_t gpu_va,
+ uint64_t size, uint32_t prot, uint32_t flags,
+ uint64_t offset, uint64_t *mapped_va);
+int gsp_vf_mem_unmap(struct gsp_vf *vf, uint64_t handle, uint64_t gpu_va, uint64_t size);
+
+/* BAR Emulation */
+int gsp_vf_bar_init(struct gsp_vf *vf);
+void gsp_vf_bar_fini(struct gsp_vf *vf);
+int gsp_vf_bar_trap(struct gsp_vf *vf, struct gsp_bar_trap_payload *trap);
+int gsp_bar_force_access(struct gsp_vf *vf, bool enable);
+int gsp_migration_bar_save(struct gsp_vf *vf, void *buf, size_t *size);
+int gsp_migration_bar_restore(struct gsp_vf *vf, void *buf, size_t size);
+
+/* WPR Management */
+int gsp_vf_wpr_init(struct gsp_vf *vf);
+void gsp_vf_wpr_fini(struct gsp_vf *vf);
+int gsp_vf_wpr_protect(struct gsp_vf *vf, uint64_t base, uint64_t size,
+ uint32_t flags);
+int gsp_vf_wpr_unprotect(struct gsp_vf *vf, uint64_t base);
+int gsp_vf_wpr_protect_write(struct gsp_vf *vf, uint64_t base, uint64_t size);
+int gsp_vf_wpr_protect_read(struct gsp_vf *vf, uint64_t base, uint64_t size);
+int gsp_vf_wpr_set_timeout(struct gsp_vf *vf, uint64_t timeout_ns);
+int gsp_vf_wpr_register_callback(struct gsp_vf *vf, enum gsp_wpr_event type,
+ void (*cb)(struct gsp_vf *, uint64_t, uint32_t),
+ void *ctx);
+void gsp_wpr_handle_event(struct gsp_device *gsp, struct gsp_rpc_message *msg);
+
+/* Scheduling */
+int gsp_vf_schedule(struct gsp_vf *vf, uint32_t priority, uint64_t time_slice_ns);
+int gsp_vf_yield(struct gsp_vf *vf);
+
+/* Migration */
+int gsp_migration_start(struct gsp_vf *vf, uint64_t dst_vf);
+void gsp_migration_cancel(struct gsp_migration *mig);
+int gsp_migration_status(struct gsp_migration *mig);
+
+/* Debugfs */
+int gsp_debugfs_init(struct gsp_device *gsp);
+void gsp_debugfs_fini(struct gsp_device *gsp);
+void gsp_debugfs_vf_add(struct gsp_vf *vf);
+void gsp_debugfs_vf_remove(struct gsp_vf *vf);
+
+#endif /* _GSP_CORE_H_ */ \ No newline at end of file