summaryrefslogtreecommitdiffstats
path: root/legacy-driver-guest/wpr
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-23 06:06:26 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-23 06:06:26 -0400
commit333d6de1e764edc176b0003af095cee4888ecd2c (patch)
tree0c6db46fe05f56e33ba13c3dd3c6e667c0ed8e42 /legacy-driver-guest/wpr
parent2302fc09080bad51c73f293294e19fd4db464eb0 (diff)
downloadopen-iov-333d6de1e764edc176b0003af095cee4888ecd2c.tar.gz
open-iov-333d6de1e764edc176b0003af095cee4888ecd2c.zip
Untrack legacy trees and purely legacy docs (kept locally)
- patches/ -> legacy-patches/ (gitignored) - legacy-driver-guest/ (old guest vGPU driver, gitignored) - docs/old/ (superseded architecture write-up, gitignored) - docs that only reference the legacy components stay tracked; their path references now point at legacy-patches/ - install.sh PATCH_DIR updated
Diffstat (limited to 'legacy-driver-guest/wpr')
-rw-r--r--legacy-driver-guest/wpr/gsp_wpr.c285
1 files changed, 0 insertions, 285 deletions
diff --git a/legacy-driver-guest/wpr/gsp_wpr.c b/legacy-driver-guest/wpr/gsp_wpr.c
deleted file mode 100644
index 91c5550..0000000
--- a/legacy-driver-guest/wpr/gsp_wpr.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * GSP vGPU-IO Driver - WPR (Write/Read Protect Region) Management
- */
-
-#include "gsp_core.h"
-#include <linux/slab.h>
-#include <linux/list.h>
-
-/* WPR Payload (for RPC) */
-struct gsp_wpr_payload {
- uint32_t vf_id;
- uint32_t op; /* 0=protect_write, 1=protect_read, 2=unprotect */
- uint64_t base;
- uint64_t size;
- uint32_t flags;
- uint64_t timeout_ns;
-} __attribute__((packed));
-
-struct gsp_wpr_response {
- int64_t status;
-} __attribute__((packed));
-
-/* WPR Initialization */
-int gsp_vf_wpr_init(struct gsp_vf *vf)
-{
- INIT_LIST_HEAD(&vf->wpr_list);
- mutex_init(&vf->wpr_lock);
- return 0;
-}
-
-void gsp_vf_wpr_fini(struct gsp_vf *vf)
-{
- struct gsp_wpr_region *rgn, *tmp;
-
- mutex_lock(&vf->wpr_lock);
- list_for_each_entry_safe(rgn, tmp, &vf->wpr_list, list) {
- list_del(&rgn->list);
- kfree(rgn);
- }
- mutex_unlock(&vf->wpr_lock);
-}
-
-/* Protect Region (Write) */
-int gsp_vf_wpr_protect_write(struct gsp_vf *vf, uint64_t base, uint64_t size)
-{
- return gsp_vf_wpr_protect(vf, base, size, GSP_WPR_WRITE);
-}
-
-/* Protect Region (Read) */
-int gsp_vf_wpr_protect_read(struct gsp_vf *vf, uint64_t base, uint64_t size)
-{
- return gsp_vf_wpr_protect(vf, base, size, GSP_WPR_READ);
-}
-
-/* Generic Protect */
-int gsp_vf_wpr_protect(struct gsp_vf *vf, uint64_t base, uint64_t size, uint32_t flags)
-{
- struct gsp_wpr_payload payload = {
- .vf_id = vf->id,
- .op = (flags & GSP_WPR_READ) ? 1 : 0,
- .base = base,
- .size = size,
- .flags = flags,
- .timeout_ns = 10000000, /* 10ms default */
- };
- struct gsp_wpr_response resp;
- size_t resp_size = sizeof(resp);
- struct gsp_wpr_region *rgn;
- int ret;
-
- /* Validate alignment */
- if (base & 0xFFF || size & 0xFFF)
- return -EINVAL;
-
- rgn = kzalloc(sizeof(*rgn), GFP_KERNEL);
- if (!rgn)
- return -ENOMEM;
-
- rgn->base = base;
- rgn->size = size;
- rgn->flags = flags;
- rgn->vf_id = vf->id;
- rgn->timeout_ns = payload.timeout_ns;
-
- /* In emulation mode, handle locally */
- if (emulation_mode) {
- mutex_lock(&vf->wpr_lock);
- list_add(&rgn->list, &vf->wpr_list);
- mutex_unlock(&vf->wpr_lock);
-
- dev_dbg(vf->gsp->dev, "VF %u: WPR protect [0x%llx, 0x%llx) flags=0x%x (emulation)\n",
- vf->id, base, base + size, flags);
-
- return 0;
- }
-
- /* Send to GSP WPR handler (0x04F00B0C/0x04F00C78) */
- ret = gsp_rpc_send_sync(vf->gsp->rpc, GSP_RPC_MAP, /* Uses MAP RPC for WPR */
- &payload, sizeof(payload), &resp, &resp_size);
- if (ret) {
- kfree(rgn);
- return ret;
- }
-
- if (resp.status != 0) {
- kfree(rgn);
- return gsp_errno_to_errno(resp.status);
- }
-
- mutex_lock(&vf->wpr_lock);
- list_add(&rgn->list, &vf->wpr_list);
- mutex_unlock(&vf->wpr_lock);
-
- dev_dbg(vf->gsp->dev, "VF %u: WPR protect [0x%llx, 0x%llx) flags=0x%x\n",
- vf->id, base, base + size, flags);
-
- return 0;
-}
-
-/* Unprotect Region */
-int gsp_vf_wpr_unprotect(struct gsp_vf *vf, uint64_t base)
-{
- struct gsp_wpr_payload payload = {
- .vf_id = vf->id,
- .op = 2, /* unprotect */
- .base = base,
- .size = 0,
- .flags = 0,
- };
- struct gsp_wpr_response resp;
- size_t resp_size = sizeof(resp);
- struct gsp_wpr_region *rgn, *tmp;
- bool found = false;
- int ret;
-
- /* In emulation mode, handle locally */
- if (emulation_mode) {
- mutex_lock(&vf->wpr_lock);
- list_for_each_entry_safe(rgn, tmp, &vf->wpr_list, list) {
- if (rgn->base == base) {
- list_del(&rgn->list);
- kfree(rgn);
- found = true;
- break;
- }
- }
- mutex_unlock(&vf->wpr_lock);
-
- dev_dbg(vf->gsp->dev, "VF %u: WPR unprotect 0x%llx (emulation)\n", vf->id, base);
-
- return found ? 0 : -ENOENT;
- }
-
- ret = gsp_rpc_send_sync(vf->gsp->rpc, GSP_RPC_UNMAP, /* Uses UNMAP for WPR */
- &payload, sizeof(payload), &resp, &resp_size);
- if (ret)
- return ret;
-
- if (resp.status != 0)
- return gsp_errno_to_errno(resp.status);
-
- mutex_lock(&vf->wpr_lock);
- list_for_each_entry_safe(rgn, tmp, &vf->wpr_list, list) {
- if (rgn->base == base) {
- list_del(&rgn->list);
- kfree(rgn);
- found = true;
- break;
- }
- }
- mutex_unlock(&vf->wpr_lock);
-
- if (!found)
- return -ENOENT;
-
- dev_dbg(vf->gsp->dev, "VF %u: WPR unprotect 0x%llx\n", vf->id, base);
-
- return 0;
-}
-
-/* Set Timeout */
-int gsp_vf_wpr_set_timeout(struct gsp_vf *vf, uint64_t timeout_ns)
-{
- /* Update timeout for all WPR regions */
- struct gsp_wpr_region *rgn;
-
- mutex_lock(&vf->wpr_lock);
- list_for_each_entry(rgn, &vf->wpr_list, list) {
- rgn->timeout_ns = timeout_ns;
- }
- mutex_unlock(&vf->wpr_lock);
-
- return 0;
-}
-
-/* Register Completion Callback */
-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)
-{
- struct gsp_wpr_region *rgn;
-
- mutex_lock(&vf->wpr_lock);
- list_for_each_entry(rgn, &vf->wpr_list, list) {
- switch (type) {
- case GSP_WPR_WRITE_COMPLETE:
- case GSP_WPR_WRITE_TIMEOUT:
- rgn->completion_cb = cb;
- break;
- case GSP_WPR_READ_COMPLETE:
- case GSP_WPR_READ_TIMEOUT:
- rgn->timeout_cb = cb;
- break;
- }
- }
- mutex_unlock(&vf->wpr_lock);
-
- return 0;
-}
-
-/* WPR Event Handler (called from notification) */
-void gsp_wpr_handle_event(struct gsp_device *gsp, struct gsp_rpc_message *msg)
-{
- struct gsp_rpc_response *resp = (struct gsp_rpc_response *)msg->payload;
- uint32_t event_type = resp->payload[0];
- uint32_t vf_id = resp->payload[1];
- uint64_t address = *(uint64_t *)&resp->payload[2];
- struct gsp_vf *vf;
- struct gsp_wpr_region *rgn;
-
- vf = gsp_vf_get(gsp, vf_id);
- if (!vf)
- return;
-
- atomic64_inc(&gsp->wpr_events);
-
- mutex_lock(&vf->wpr_lock);
- list_for_each_entry(rgn, &vf->wpr_list, list) {
- if (address >= rgn->base && address < rgn->base + rgn->size) {
- switch (event_type) {
- case GSP_WPR_WRITE_COMPLETE:
- case GSP_WPR_READ_COMPLETE:
- if (rgn->completion_cb)
- rgn->completion_cb(vf, address, event_type);
- break;
- case GSP_WPR_WRITE_TIMEOUT:
- case GSP_WPR_READ_TIMEOUT:
- if (rgn->timeout_cb)
- rgn->timeout_cb(vf, address, event_type);
- break;
- }
- break;
- }
- }
- mutex_unlock(&vf->wpr_lock);
-
- gsp_vf_put(vf);
-}
-
-/* Default Completion Callback */
-void gsp_wpr_default_complete_cb(struct gsp_vf *vf, uint64_t addr, uint32_t type)
-{
- dev_dbg(vf->gsp->dev, "VF %u: WPR %s complete at 0x%llx\n",
- vf->id, type == GSP_WPR_WRITE_COMPLETE ? "write" : "read", addr);
-
- /* If this was a page table write, invalidate TLB */
- if (addr >= vf->pt_base && addr < vf->pt_base + vf->pt_size) {
- /* TODO: TLB invalidate */
- }
-}
-
-/* Default Timeout Callback */
-void gsp_wpr_default_timeout_cb(struct gsp_vf *vf, uint64_t addr, uint32_t type)
-{
- dev_warn(vf->gsp->dev, "VF %u: WPR %s timeout at 0x%llx\n",
- vf->id, type == GSP_WPR_WRITE_TIMEOUT ? "write" : "read", addr);
-
- /* Throttle or reset VF */
- if (type == GSP_WPR_WRITE_TIMEOUT) {
- /* TODO: VF throttle */
- } else {
- /* TODO: VF reset */
- }
-} \ No newline at end of file