[PATCH v2 2/2] drm/xe/sysctrl: Add fwctl support for System Controller
"Anoop, Vijay" <[email protected]>
| Newsgroups | org.freedesktop.lists.intel-xe |
|---|---|
| Message-ID | <[email protected]> |
From: Anoop Vijay <[email protected]> Add fwctl support for Xe System Controller (sysctrl), a firmware-managed entity that provides platform-level control and coordination on Intel Xe3p discrete GPUs. Register a XE_SYSCTRL device to allow userspace to query sysctrl capabilities and issue RPCs through /dev/fwctl/fwctlN. Initial RPCs support ECC status queries and RAS error injection. Signed-off-by: Anoop Vijay <[email protected]> --- v2: (Rodrigo) - Rename FWCTL_DEVICE_TYPE_XE to FWCTL_DEVICE_TYPE_XE_SYSCTRL, one type per firmware instead of a shared Xe-wide type - Rename xe.h to xe_sysctrl.h to match - Squash uapi and type definitions into a single patch - Replace validate_scope() with explicit per-op scope/capability checks in xe_sysctrl_fwctl_rpc() --- Documentation/userspace-api/fwctl/index.rst | 1 + .../userspace-api/fwctl/xe_sysctrl.rst | 120 +++++++++ drivers/gpu/drm/xe/Kconfig | 1 + drivers/gpu/drm/xe/Makefile | 1 + drivers/gpu/drm/xe/xe_device.c | 5 + drivers/gpu/drm/xe/xe_sysctrl_fwctl.c | 251 ++++++++++++++++++ drivers/gpu/drm/xe/xe_sysctrl_fwctl.h | 13 + drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h | 86 ++++++ include/uapi/fwctl/fwctl.h | 1 + include/uapi/fwctl/xe_sysctrl.h | 117 ++++++++ 10 files changed, 596 insertions(+) create mode 100644 Documentation/userspace-api/fwctl/xe_sysctrl.rst create mode 100644 drivers/gpu/drm/xe/xe_sysctrl_fwctl.c create mode 100644 drivers/gpu/drm/xe/xe_sysctrl_fwctl.h create mode 100644 include/uapi/fwctl/xe_sysctrl.h diff --git a/Documentation/userspace-api/fwctl/index.rst b/Documentation/userspace-api/fwctl/index.rst index 8062f7629654..f6fca11e6aac 100644 --- a/Documentation/userspace-api/fwctl/index.rst +++ b/Documentation/userspace-api/fwctl/index.rst @@ -13,3 +13,4 @@ to securely construct and execute RPCs inside device firmware. bnxt_fwctl fwctl-cxl pds_fwctl + xe_sysctrl diff --git a/Documentation/userspace-api/fwctl/xe_sysctrl.rst b/Documentation/userspace-api/fwctl/xe_sysctrl.rst new file mode 100644 index 000000000000..6dfc9e70b683 --- /dev/null +++ b/Documentation/userspace-api/fwctl/xe_sysctrl.rst @@ -0,0 +1,120 @@ +.. SPDX-License-Identifier: GPL-2.0 + +======================= +fwctl xe_sysctrl driver +======================= + +:Author: Intel Corporation + +Overview +======== + +The Xe System Controller (sysctrl) firmware exposes a fwctl service that +the xe driver registers as a ``FWCTL_DEVICE_TYPE_XE_SYSCTRL`` device. +Userspace opens the resulting ``/dev/fwctl/fwctlN`` node to query ECC +status and RAS error injection capabilities and to issue RAS error +injection requests to the sysctrl firmware. + +xe_sysctrl User API +==================== + +.. kernel-doc:: include/uapi/fwctl/xe_sysctrl.h + +1. Driver info query +--------------------- + +The application issues ``FWCTL_INFO`` to retrieve a +``struct fwctl_info_xe_sysctrl`` and inspect ``uctx_caps`` to determine +which of the ``FWCTL_XE_SYSCTRL_CAP_*`` capabilities are available on this +platform and in this security context. + +2. Send RPC requests +--------------------- + +Each RPC uses a single ``struct fwctl_rpc_xe_sysctrl`` as both the +``FWCTL_RPC`` ``in`` and ``out`` buffer; the driver fills in ``data`` in +place. ``op`` selects one of the ``enum fwctl_xe_sysctrl_op`` operations. +The kernel rejects the request if the scope of the ``FWCTL_RPC`` call is +lower than the minimum required by the requested ``op``, as documented above. + +Code example of querying ECC status +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: c + + static int xe_sysctrl_get_ecc(int fd, __u32 *supported, __u32 *enabled) + { + struct fwctl_rpc_xe_sysctrl sysctrl_rpc = { + .op = FWCTL_XE_SYSCTRL_OP_ECC_STATUS_GET, + }; + struct fwctl_rpc rpc = { + .size = sizeof(rpc), + .scope = FWCTL_RPC_CONFIGURATION, + .in_len = sizeof(sysctrl_rpc), + .out_len = sizeof(sysctrl_rpc), + .in = (__aligned_u64)&sysctrl_rpc, + .out = (__aligned_u64)&sysctrl_rpc, + }; + int ret; + + ret = ioctl(fd, FWCTL_RPC, &rpc); + if (ret) + return ret; + + *supported = sysctrl_rpc.data[0]; + *enabled = sysctrl_rpc.data[1]; + return 0; + } + +Code example of querying RAS injection capabilities and injecting an error +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: c + + static int xe_sysctrl_get_ras_caps(int fd, __u32 *capability_mask, __u32 *flags) + { + struct fwctl_rpc_xe_sysctrl sysctrl_rpc = { + .op = FWCTL_XE_SYSCTRL_OP_RAS_GET_CAPS, + }; + struct fwctl_rpc rpc = { + .size = sizeof(rpc), + .scope = FWCTL_RPC_CONFIGURATION, + .in_len = sizeof(sysctrl_rpc), + .out_len = sizeof(sysctrl_rpc), + .in = (__aligned_u64)&sysctrl_rpc, + .out = (__aligned_u64)&sysctrl_rpc, + }; + int ret; + + ret = ioctl(fd, FWCTL_RPC, &rpc); + if (ret) + return ret; + + *capability_mask = sysctrl_rpc.data[0]; + *flags = sysctrl_rpc.data[1]; + return 0; + } + + static int xe_sysctrl_ras_inject(int fd, __u32 error_inj) + { + struct fwctl_rpc_xe_sysctrl sysctrl_rpc = { + .op = FWCTL_XE_SYSCTRL_OP_RAS_INJECT, + .data[0] = error_inj, + }; + struct fwctl_rpc rpc = { + .size = sizeof(rpc), + .scope = FWCTL_RPC_DEBUG_WRITE, + .in_len = sizeof(sysctrl_rpc), + .out_len = sizeof(sysctrl_rpc), + .in = (__aligned_u64)&sysctrl_rpc, + .out = (__aligned_u64)&sysctrl_rpc, + }; + + /* + * Callers should confirm error_inj is set in capability_mask, + * and that flags allows injection (FWCTL_XE_SYSCTRL_RAS_INJ_ALLOWED), + * as returned by xe_sysctrl_get_ras_caps() above, before injecting. + */ + return ioctl(fd, FWCTL_RPC, &rpc); + } + diff --git a/drivers/gpu/drm/xe/Kconfig b/drivers/gpu/drm/xe/Kconfig index 4d7dcaff2b91..a472cb52dded 100644 --- a/drivers/gpu/drm/xe/Kconfig +++ b/drivers/gpu/drm/xe/Kconfig @@ -25,6 +25,7 @@ config DRM_XE select DRM_MIPI_DSI select RELAY select IRQ_WORK + select FWCTL # xe depends on ACPI_VIDEO when ACPI is enabled # but for select to work, need to select ACPI_VIDEO's dependencies, ick select BACKLIGHT_CLASS_DEVICE if ACPI diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index 44ed055439d4..6560185c0ca7 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -128,6 +128,7 @@ xe-y += xe_bb.o \ xe_sync.o \ xe_sysctrl.o \ xe_sysctrl_event.o \ + xe_sysctrl_fwctl.o \ xe_sysctrl_mailbox.o \ xe_tile.o \ xe_tile_sysfs.o \ diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index d25d02b24898..dc7df793d4b9 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -68,6 +68,7 @@ #include "xe_sriov.h" #include "xe_svm.h" #include "xe_sysctrl.h" +#include "xe_sysctrl_fwctl.h" #include "xe_tile.h" #include "xe_ttm_stolen_mgr.h" #include "xe_ttm_sys_mgr.h" @@ -1028,6 +1029,10 @@ int xe_device_probe(struct xe_device *xe) if (err) return err; + err = xe_sysctrl_fwctl_init(xe); + if (err) + return err; + xe_ras_init(xe); /* diff --git a/drivers/gpu/drm/xe/xe_sysctrl_fwctl.c b/drivers/gpu/drm/xe/xe_sysctrl_fwctl.c new file mode 100644 index 000000000000..27a40efa0787 --- /dev/null +++ b/drivers/gpu/drm/xe/xe_sysctrl_fwctl.c @@ -0,0 +1,251 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2026 Intel Corporation + */ + +#include <linux/errno.h> +#include <linux/fwctl.h> +#include <linux/slab.h> + +#include <uapi/fwctl/xe_sysctrl.h> + +#include "xe_device.h" +#include "xe_pm.h" +#include "xe_printk.h" +#include "xe_sysctrl.h" +#include "xe_sysctrl_fwctl.h" +#include "xe_sysctrl_mailbox.h" +#include "xe_sysctrl_mailbox_types.h" + +struct xe_sysctrl_fwctl_dev { + struct fwctl_device fwctl; + struct xe_device *xe; +}; + +DEFINE_FREE(xe_sysctrl_fwctl, struct xe_sysctrl_fwctl_dev *, if (_T) fwctl_put(&_T->fwctl)) + +struct xe_sysctrl_fwctl_uctx { + struct fwctl_uctx uctx; + u32 uctx_caps; +}; + +static int xe_sysctrl_fwctl_uctx_open(struct fwctl_uctx *uctx) +{ + struct xe_sysctrl_fwctl_dev *fwctl_dev = + container_of(uctx->fwctl, struct xe_sysctrl_fwctl_dev, fwctl); + struct xe_sysctrl_fwctl_uctx *sc_uctx = + container_of(uctx, struct xe_sysctrl_fwctl_uctx, uctx); + struct xe_device *xe = fwctl_dev->xe; + + xe_pm_runtime_get(xe); + + sc_uctx->uctx_caps = FWCTL_XE_SYSCTRL_CAP_ECC; + if (xe_sysctrl_is_diag_fw_ready(xe)) + sc_uctx->uctx_caps |= FWCTL_XE_SYSCTRL_CAP_RAS_ERROR_INJECT; + + return 0; +} + +static void xe_sysctrl_fwctl_uctx_close(struct fwctl_uctx *uctx) +{ + struct xe_sysctrl_fwctl_dev *fwctl_dev = + container_of(uctx->fwctl, struct xe_sysctrl_fwctl_dev, fwctl); + + xe_pm_runtime_put(fwctl_dev->xe); +} + +static void *xe_sysctrl_fwctl_info(struct fwctl_uctx *uctx, size_t *length) +{ + struct xe_sysctrl_fwctl_uctx *sc_uctx = + container_of(uctx, struct xe_sysctrl_fwctl_uctx, uctx); + struct fwctl_info_xe_sysctrl *info; + + info = kzalloc_obj(*info); + if (!info) + return ERR_PTR(-ENOMEM); + + info->uctx_caps = sc_uctx->uctx_caps; + + *length = sizeof(*info); + return info; +} + +static int sysctrl_rpc_ecc_status_get(struct xe_device *xe, + struct fwctl_rpc_xe_sysctrl *rpc) +{ + struct xe_sysctrl_feature_cap_resp resp = {}; + struct xe_sysctrl_mailbox_command cmd = {0}; + size_t out_len = 0; + int ret; + + xe_sysctrl_create_command(&cmd, XE_SYSCTRL_GROUP_GFSP_RUNTIME, + XE_SYSCTRL_CMD_GET_FEATURE_CAPABILITY_STATE_INFO, + NULL, 0, &resp, sizeof(resp)); + + ret = xe_sysctrl_send_command(&xe->sc, &cmd, &out_len); + if (ret) + return ret; + + if (out_len < 2 * sizeof(u32)) { + xe_err(xe, "sysctrl fwctl: ECC status response too short (%zu B)\n", + out_len); + return -EIO; + } + + rpc->data[0] = resp.supported_features & XE_SYSCTRL_FEATURE_ECC ? 1 : 0; + rpc->data[1] = resp.enabled_features & XE_SYSCTRL_FEATURE_ECC ? 1 : 0; + return 0; +} + +static int sysctrl_rpc_ras_get_caps(struct xe_device *xe, + struct fwctl_rpc_xe_sysctrl *rpc) +{ + struct xe_sysctrl_ras_err_inj_cap_resp resp = {}; + struct xe_sysctrl_mailbox_command cmd = {0}; + size_t out_len = 0; + int ret; + + xe_sysctrl_create_command(&cmd, XE_SYSCTRL_GROUP_DIAG, + XE_SYSCTRL_CMD_RAS_ERR_INJ_CAPABILITY, + NULL, 0, &resp, sizeof(resp)); + + ret = xe_sysctrl_send_command(&xe->sc, &cmd, &out_len); + if (ret) + return ret; + + rpc->data[0] = resp.capability_mask; + rpc->data[1] = resp.flags; + return 0; +} + +static int sysctrl_rpc_ras_inject(struct xe_device *xe, + struct fwctl_rpc_xe_sysctrl *rpc) +{ + struct xe_sysctrl_ras_err_inj_req req = { + .error_inj = rpc->data[0], + .additional_params = rpc->data[1], + }; + struct xe_sysctrl_mailbox_command cmd = {0}; + size_t out_len = 0; + + xe_sysctrl_create_command(&cmd, XE_SYSCTRL_GROUP_DIAG, + XE_SYSCTRL_CMD_RAS_ERR_INJECT, + &req, sizeof(req), NULL, 0); + + return xe_sysctrl_send_command(&xe->sc, &cmd, &out_len); +} + +static void *xe_sysctrl_fwctl_rpc(struct fwctl_uctx *uctx, + enum fwctl_rpc_scope scope, + void *rpc_in, size_t in_len, + size_t *out_len) +{ + struct xe_sysctrl_fwctl_dev *fwctl_dev = + container_of(uctx->fwctl, struct xe_sysctrl_fwctl_dev, fwctl); + struct xe_sysctrl_fwctl_uctx *sc_uctx = + container_of(uctx, struct xe_sysctrl_fwctl_uctx, uctx); + struct xe_device *xe = fwctl_dev->xe; + struct fwctl_rpc_xe_sysctrl *rpc; + int ret; + + if (in_len != sizeof(*rpc) || *out_len < sizeof(*rpc)) + return ERR_PTR(-EMSGSIZE); + + rpc = rpc_in; + + if (rpc->flags) + return ERR_PTR(-EINVAL); + + switch (rpc->op) { + case FWCTL_XE_SYSCTRL_OP_ECC_STATUS_GET: + if (!(sc_uctx->uctx_caps & FWCTL_XE_SYSCTRL_CAP_ECC)) + return ERR_PTR(-EPERM); + if (scope < FWCTL_RPC_CONFIGURATION) + return ERR_PTR(-EBADMSG); + ret = sysctrl_rpc_ecc_status_get(xe, rpc); + if (ret) + return ERR_PTR(ret); + break; + + case FWCTL_XE_SYSCTRL_OP_RAS_GET_CAPS: + if (!(sc_uctx->uctx_caps & FWCTL_XE_SYSCTRL_CAP_RAS_ERROR_INJECT)) + return ERR_PTR(-EPERM); + if (scope < FWCTL_RPC_CONFIGURATION) + return ERR_PTR(-EBADMSG); + ret = sysctrl_rpc_ras_get_caps(xe, rpc); + if (ret) + return ERR_PTR(ret); + break; + + case FWCTL_XE_SYSCTRL_OP_RAS_INJECT: + if (!(sc_uctx->uctx_caps & FWCTL_XE_SYSCTRL_CAP_RAS_ERROR_INJECT)) + return ERR_PTR(-EPERM); + if (scope < FWCTL_RPC_DEBUG_WRITE) + return ERR_PTR(-EBADMSG); + ret = sysctrl_rpc_ras_inject(xe, rpc); + if (ret) + return ERR_PTR(ret); + break; + + default: + return ERR_PTR(-EBADMSG); + } + + *out_len = sizeof(*rpc); + return rpc_in; +} + +static const struct fwctl_ops xe_sysctrl_fwctl_ops = { + .device_type = FWCTL_DEVICE_TYPE_XE_SYSCTRL, + .uctx_size = sizeof(struct xe_sysctrl_fwctl_uctx), + .open_uctx = xe_sysctrl_fwctl_uctx_open, + .close_uctx = xe_sysctrl_fwctl_uctx_close, + .info = xe_sysctrl_fwctl_info, + .fw_rpc = xe_sysctrl_fwctl_rpc, +}; + +static void xe_sysctrl_fwctl_fini(void *arg) +{ + struct fwctl_device *fwctl = arg; + + fwctl_unregister(fwctl); + fwctl_put(fwctl); +} + +/** + * xe_sysctrl_fwctl_init() - Initialize fwctl interface for System Controller + * @xe: xe device instance + * + * Registers a fwctl device that exposes System Controller debug and + * diagnostic functionality to userspace, on platforms where System + * Controller is supported. + * + * Return: 0 on success, error code on failure + */ +int xe_sysctrl_fwctl_init(struct xe_device *xe) +{ + struct xe_sysctrl_fwctl_dev *fwctl_dev __free(xe_sysctrl_fwctl) = + fwctl_alloc_device(xe->drm.dev, &xe_sysctrl_fwctl_ops, + struct xe_sysctrl_fwctl_dev, fwctl); + int err; + + if (!xe->info.has_soc_remapper_sysctrl) + return 0; + + if (!xe->info.has_sysctrl) + return 0; + + if (!fwctl_dev) + return -ENOMEM; + + fwctl_dev->xe = xe; + + err = fwctl_register(&fwctl_dev->fwctl); + if (err) + return err; + + return devm_add_action_or_reset(xe->drm.dev, xe_sysctrl_fwctl_fini, + &no_free_ptr(fwctl_dev)->fwctl); +} + +MODULE_IMPORT_NS("FWCTL"); diff --git a/drivers/gpu/drm/xe/xe_sysctrl_fwctl.h b/drivers/gpu/drm/xe/xe_sysctrl_fwctl.h new file mode 100644 index 000000000000..730f31e0d697 --- /dev/null +++ b/drivers/gpu/drm/xe/xe_sysctrl_fwctl.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2026 Intel Corporation + */ + +#ifndef _XE_SYSCTRL_FWCTL_H_ +#define _XE_SYSCTRL_FWCTL_H_ + +struct xe_device; + +int xe_sysctrl_fwctl_init(struct xe_device *xe); + +#endif diff --git a/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h b/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h index b507e1553cbb..7f39fd1a418a 100644 --- a/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h +++ b/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h @@ -14,10 +14,14 @@ * enum xe_sysctrl_group - System Controller command groups * * @XE_SYSCTRL_GROUP_GFSP: GFSP group + * @XE_SYSCTRL_GROUP_DIAG: Diag group + * @XE_SYSCTRL_GROUP_GFSP_RUNTIME: GFSP runtime group * @XE_SYSCTRL_GROUP_CORE: Core group */ enum xe_sysctrl_group { XE_SYSCTRL_GROUP_GFSP = 0x01, + XE_SYSCTRL_GROUP_DIAG = 0x02, + XE_SYSCTRL_GROUP_GFSP_RUNTIME = 0x31, XE_SYSCTRL_GROUP_CORE = 0xFF, }; @@ -103,6 +107,88 @@ enum xe_sysctrl_app_id { XE_SYSCTRL_APP_DIAG = 0x0D, }; +/** + * enum xe_sysctrl_diag_cmd - Commands supported by DIAG group + * + * @XE_SYSCTRL_CMD_RAS_ERR_INJ_CAPABILITY: Query supported RAS injection types + * @XE_SYSCTRL_CMD_RAS_ERR_INJECT: Inject a RAS error into an IP block + */ +enum xe_sysctrl_diag_cmd { + XE_SYSCTRL_CMD_RAS_ERR_INJ_CAPABILITY = 0x01, + XE_SYSCTRL_CMD_RAS_ERR_INJECT = 0x02, +}; + +/** + * struct xe_sysctrl_ras_err_inj_cap_resp - RAS_ERR_INJ_CAPABILITY response payload + * + * Response payload for XE_SYSCTRL_CMD_RAS_ERR_INJ_CAPABILITY. The mailbox + * layer strips the application message header before writing to this buffer. + * + * @capability_mask: OR of firmware-defined capability values indicating which + * injection classes are supported on this platform (see + * enum fwctl_xe_sysctrl_ras_inj_cap in + * include/uapi/fwctl/xe_sysctrl.h for bit definitions) + * @flags: Bitmask; bit FWCTL_XE_SYSCTRL_RAS_INJ_ALLOWED (see + * include/uapi/fwctl/xe_sysctrl.h) indicates whether RAS + * error injection is currently allowed by hardware + * security policy. + * @reserved: Must be zero + */ +struct xe_sysctrl_ras_err_inj_cap_resp { + u32 capability_mask; + u32 flags; + u32 reserved[2]; +} __packed; + +/** + * struct xe_sysctrl_ras_err_inj_req - RAS_ERR_INJECT request payload + * + * Request payload for XE_SYSCTRL_CMD_RAS_ERR_INJECT. The mailbox layer + * prepends the application message header before sending. + * + * @error_inj: One of the enum fwctl_xe_sysctrl_ras_inj_cap bit values + * (include/uapi/fwctl/xe_sysctrl.h), selecting the class of + * error to inject. + * @additional_params: Reserved for future use; must be 0 for most injection + * types + */ +struct xe_sysctrl_ras_err_inj_req { + u32 error_inj; + u32 additional_params; +} __packed; + +/** + * enum xe_sysctrl_gfsp_runtime_cmd - Commands for the GFSP runtime group (0x31) + * + * @XE_SYSCTRL_CMD_GET_FEATURE_CAPABILITY_STATE_INFO: Read ECC feature state. + * No input payload. Response: struct xe_sysctrl_feature_cap_resp. + */ +enum xe_sysctrl_gfsp_runtime_cmd { + XE_SYSCTRL_CMD_GET_FEATURE_CAPABILITY_STATE_INFO = 0x10, +}; + +/** XE_SYSCTRL_FEATURE_ECC - ECC feature bit in FSP runtime capability bitmasks */ +#define XE_SYSCTRL_FEATURE_ECC BIT(0) + +/** + * struct xe_sysctrl_feature_cap_resp - ECC feature state + * + * Response layout for XE_SYSCTRL_CMD_GET_FEATURE_CAPABILITY_STATE_INFO. + * + * @supported_features: Features supported by the product + * @enabled_features: Features currently enabled + * @configurable_features: Features modifiable by software + * @pending_features: Feature state pending after next reboot + * @default_features: Default feature state from build configuration + */ +struct xe_sysctrl_feature_cap_resp { + u32 supported_features; + u32 enabled_features; + u32 configurable_features; + u32 pending_features; + u32 default_features; +} __packed; + /** * struct xe_sysctrl_mailbox_command - System Controller mailbox command */ diff --git a/include/uapi/fwctl/fwctl.h b/include/uapi/fwctl/fwctl.h index 2d6d4049c205..34901d36cd51 100644 --- a/include/uapi/fwctl/fwctl.h +++ b/include/uapi/fwctl/fwctl.h @@ -46,6 +46,7 @@ enum fwctl_device_type { FWCTL_DEVICE_TYPE_CXL = 2, FWCTL_DEVICE_TYPE_BNXT = 3, FWCTL_DEVICE_TYPE_PDS = 4, + FWCTL_DEVICE_TYPE_XE_SYSCTRL = 5, }; /** diff --git a/include/uapi/fwctl/xe_sysctrl.h b/include/uapi/fwctl/xe_sysctrl.h new file mode 100644 index 000000000000..a4d117d906e3 --- /dev/null +++ b/include/uapi/fwctl/xe_sysctrl.h @@ -0,0 +1,117 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* Copyright © 2026 Intel Corporation */ +#ifndef _UAPI_FWCTL_XE_SYSCTRL_H_ +#define _UAPI_FWCTL_XE_SYSCTRL_H_ + +#include <linux/bits.h> +#include <linux/types.h> + +/** + * enum fwctl_xe_sysctrl_uctx_caps - capability flags in fwctl_info_xe_sysctrl.uctx_caps + * + * @FWCTL_XE_SYSCTRL_CAP_ECC: ECC status query is supported on this platform + * @FWCTL_XE_SYSCTRL_CAP_RAS_ERROR_INJECT: RAS error injection is supported; + * requires diag firmware to be loaded and ready + */ +enum fwctl_xe_sysctrl_uctx_caps { + FWCTL_XE_SYSCTRL_CAP_ECC = (1U << 0), + FWCTL_XE_SYSCTRL_CAP_RAS_ERROR_INJECT = (1U << 1), +}; + +/** + * struct fwctl_info_xe_sysctrl - device data returned by FWCTL_INFO + * @uctx_caps: Bitmask of available capabilities (see %fwctl_xe_sysctrl_uctx_caps) + * @rsvd: Reserved, must be zero + */ +struct fwctl_info_xe_sysctrl { + __u32 uctx_caps; + __u32 rsvd[7]; +}; + +/** + * enum fwctl_xe_sysctrl_ras_inj_cap - RAS error injection capability bits + * + * Used both in the @capability_mask output of %FWCTL_XE_SYSCTRL_OP_RAS_GET_CAPS + * and as the @error_inj input of %FWCTL_XE_SYSCTRL_OP_RAS_INJECT. Userspace + * must confirm a bit is set in @capability_mask before injecting that class. + * + * @FWCTL_XE_SYSCTRL_RAS_INJ_CAP_COMPUTE_CORR: Compute block correctable error + * @FWCTL_XE_SYSCTRL_RAS_INJ_CAP_COMPUTE_UCORR: Compute block uncorrectable error + * @FWCTL_XE_SYSCTRL_RAS_INJ_CAP_MEMORY_UCORR: Memory subsystem uncorrectable error + * @FWCTL_XE_SYSCTRL_RAS_INJ_CAP_FABRIC_UCORR: Fabric interconnect uncorrectable error + * @FWCTL_XE_SYSCTRL_RAS_INJ_CAP_PCIE_CORR: PCIe subsystem correctable error + * @FWCTL_XE_SYSCTRL_RAS_INJ_CAP_PCIE_UCORR: PCIe subsystem uncorrectable error + * @FWCTL_XE_SYSCTRL_RAS_INJ_CAP_PLATFORM_UCORR: Platform-level uncorrectable error + */ +enum fwctl_xe_sysctrl_ras_inj_cap { + FWCTL_XE_SYSCTRL_RAS_INJ_CAP_COMPUTE_CORR = 0x0001U, + FWCTL_XE_SYSCTRL_RAS_INJ_CAP_COMPUTE_UCORR = 0x0002U, + FWCTL_XE_SYSCTRL_RAS_INJ_CAP_MEMORY_UCORR = 0x0004U, + FWCTL_XE_SYSCTRL_RAS_INJ_CAP_FABRIC_UCORR = 0x0008U, + FWCTL_XE_SYSCTRL_RAS_INJ_CAP_PCIE_CORR = 0x0010U, + FWCTL_XE_SYSCTRL_RAS_INJ_CAP_PCIE_UCORR = 0x0020U, + FWCTL_XE_SYSCTRL_RAS_INJ_CAP_PLATFORM_UCORR = 0x0040U, +}; + +/* FWCTL_XE_SYSCTRL_RAS_INJ_ALLOWED - bit in the RAS_GET_CAPS flags field + * indicating RAS error injection is currently allowed by hardware security + * policy. + */ +#define FWCTL_XE_SYSCTRL_RAS_INJ_ALLOWED (1U << 0) + +/** + * enum fwctl_xe_sysctrl_op - RPC operation codes for xe_sysctrl fwctl + * + * @FWCTL_XE_SYSCTRL_OP_ECC_STATUS_GET: Read ECC feature state from GFSP firmware + * (GFSP runtime group, GET_FEATURE_CAPABILITY_STATE_INFO, BIT(0) = ECC). + * Requires: %FWCTL_XE_SYSCTRL_CAP_ECC in uctx_caps. + * Scope: %FWCTL_RPC_CONFIGURATION. + * in: op, flags=0, data[0..13] ignored. + * out: data[0] = 1 if ECC is supported by this product, 0 otherwise. + * data[1] = 1 if ECC is currently enabled, 0 otherwise. + * + * @FWCTL_XE_SYSCTRL_OP_RAS_GET_CAPS: Query RAS error injection capability from + * diag firmware (DIAG group, RAS_ERR_INJ_CAPABILITY command). + * Requires: %FWCTL_XE_SYSCTRL_CAP_RAS_ERROR_INJECT in uctx_caps. + * Scope: %FWCTL_RPC_CONFIGURATION. + * in: op, flags=0, data[0..13] ignored. + * out: data[0] = capability_mask, an OR of %fwctl_xe_sysctrl_ras_inj_cap + * bits indicating which injection classes are supported, + * data[1] = flags; bit %FWCTL_XE_SYSCTRL_RAS_INJ_ALLOWED indicates + * whether RAS error injection is currently allowed by + * hardware security policy, other bits are reserved for + * future use. + * + * @FWCTL_XE_SYSCTRL_OP_RAS_INJECT: Inject a RAS error via diag firmware + * (DIAG group, RAS_ERR_INJECT command). + * Requires: %FWCTL_XE_SYSCTRL_CAP_RAS_ERROR_INJECT in uctx_caps. + * Scope: %FWCTL_RPC_DEBUG_WRITE. + * in: data[0] = error_inj, one of the %fwctl_xe_sysctrl_ras_inj_cap + * bit values. Userspace must confirm this bit is set in + * the capability_mask returned by + * %FWCTL_XE_SYSCTRL_OP_RAS_GET_CAPS (and that its flags + * field currently allows injection) before issuing this + * request; behavior for an unsupported value is + * firmware-defined, + * data[1] = additional_params (reserved; 0 for most injection types). + * out: no additional output data (success indicated by ioctl return code). + */ +enum fwctl_xe_sysctrl_op { + FWCTL_XE_SYSCTRL_OP_ECC_STATUS_GET = 1, + FWCTL_XE_SYSCTRL_OP_RAS_GET_CAPS = 2, + FWCTL_XE_SYSCTRL_OP_RAS_INJECT = 3, +}; + +/** + * struct fwctl_rpc_xe_sysctrl - RPC request/response envelope + * @op: Operation code (see %fwctl_xe_sysctrl_op) + * @flags: Must be 0 + * @data: Operation-specific payload (see %fwctl_xe_sysctrl_op for layout) + */ +struct fwctl_rpc_xe_sysctrl { + __u32 op; + __u32 flags; + __u32 data[14]; +}; + +#endif -- 2.43.0