RE: [PATCH v3 4/4] drm/xe/sysctrl: Add RAS error injection debugfs interface
"Gupta, Anshuman" <[email protected]>
| Newsgroups | org.freedesktop.lists.intel-xe |
|---|---|
| Message-ID | <BN9PR11MB5242AF76995E0453ABF7878A95D12@BN9PR11MB5242.namprd11.prod.outlook.com> |
> -----Original Message----- > From: Vijay, Anoop C <[email protected]> > Sent: Friday, August 7, 2026 8:26 PM > To: [email protected] > Cc: Nerlige Ramappa, Umesh <[email protected]>; Nilawar, > Badal <[email protected]>; Vivi, Rodrigo <[email protected]>; > Iddamsetty, Aravind <[email protected]>; Tauro, Riana > <[email protected]>; Gupta, Anshuman <[email protected]>; > Roper, Matthew D <[email protected]>; Ruhl, Michael J > <[email protected]>; Luse, Paul E <[email protected]>; V, > Mohamed Mansoor <[email protected]>; Nasim, Kam > <[email protected]>; Vijay, Anoop C <[email protected]> > Subject: [PATCH v3 4/4] drm/xe/sysctrl: Add RAS error injection debugfs > interface > > From: Anoop Vijay <[email protected]> > > Add debugfs interface for exercising System Controller's RAS error injection > command, used to validate RAS error detection and recovery paths. > > Command details: > - Group ID: 0x02 (diag group) > - Command ID: 0x7E (XE_SYSCTRL_CMD_DIAG_RAS_ERR_INJECT) > - Usage: echo "<ras_block_id> <ras_sub_block_id> <err_type> [params]" \ > > /sys/kernel/debug/dri/0/sc/ras_error_inject > cat /sys/kernel/debug/dri/0/sc/ras_error_inject > > This command requires the diag application to have completed firmware > boot and initialization (late-bind loaded); writes are rejected with -ENODEV > until xe_sysctrl_is_diag_fw_ready() reports the diag firmware as ready. > > Signed-off-by: Anoop Vijay <[email protected]> > --- > drivers/gpu/drm/xe/xe_sysctrl_debugfs.c | 123 ++++++++++++++++++ > drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h | 31 +++++ > drivers/gpu/drm/xe/xe_sysctrl_types.h | 3 + > 3 files changed, 157 insertions(+) > > diff --git a/drivers/gpu/drm/xe/xe_sysctrl_debugfs.c > b/drivers/gpu/drm/xe/xe_sysctrl_debugfs.c > index 2144d9d43fba..7b8846d739cb 100644 > --- a/drivers/gpu/drm/xe/xe_sysctrl_debugfs.c > +++ b/drivers/gpu/drm/xe/xe_sysctrl_debugfs.c > @@ -10,6 +10,7 @@ > #include <linux/seq_file.h> > #include <linux/slab.h> > #include <linux/string.h> > +#include <linux/string_choices.h> > #include <linux/uaccess.h> > > #include "xe_device.h" > @@ -122,6 +123,124 @@ static const struct file_operations > xe_sysctrl_loopback_fops = { > .release = single_release, > }; > > +static ssize_t xe_sysctrl_ras_error_inject_write(struct file *file, const char > __user *ubuf, > + size_t len, loff_t *offp) > +{ > + char *kbuf __free(kfree) = NULL; > + struct seq_file *m = file->private_data; > + struct xe_sysctrl_debugfs_entry *entry = m->private; > + struct xe_device *xe = sc_to_xe(entry->sc); > + struct xe_sysctrl_diag_ras_err_inj_req req = {}; > + struct xe_sysctrl_mailbox_command cmd = {}; > + u8 resp_hdr_only[sizeof(u32)]; > + unsigned int nfields = 0; > + char *token, *tmp; > + unsigned long val; > + size_t out_len = 0; > + > + if (!xe_sysctrl_is_diag_fw_ready(xe)) { > + xe_err(xe, "sysctrl: diag firmware not ready, cannot inject RAS > error\n"); Wild thought, How it would be register the debugfs only if diag firmware is loaded ? That way nobody will be having access to these debugfs ? Thanks, Anshuman. > + return -ENODEV; > + } > + > + if (len == 0 || len >= PAGE_SIZE) > + return -EINVAL; > + > + kbuf = kmalloc(len + 1, GFP_KERNEL); > + if (!kbuf) > + return -ENOMEM; > + > + if (copy_from_user(kbuf, ubuf, len)) > + return -EFAULT; > + kbuf[len] = '\0'; > + > + tmp = kbuf; > + while ((token = strsep(&tmp, " \t\n")) != NULL) { > + if (*token == '\0') > + continue; > + > + if (kstrtoul(token, 0, &val)) > + goto inval; > + > + switch (nfields) { > + case 0: > + if (val > U16_MAX) > + goto inval; > + req.ras_block_id = val; > + break; > + case 1: > + if (val > U16_MAX) > + goto inval; > + req.ras_sub_block_id = val; > + break; > + case 2: > + if (val > U16_MAX) > + goto inval; > + req.err_type = val; > + break; > + case 3: > + if (val > U32_MAX) > + goto inval; > + req.params = val; > + break; > + default: > + xe_err(xe, "sysctrl: too many ras_error_inject > arguments\n"); > + return -EINVAL; > + } > + nfields++; > + } > + > + if (nfields < 3) { > + xe_err(xe, > + "sysctrl: usage: <ras_block_id> <ras_sub_block_id> > <err_type> [params]\n"); > + return -EINVAL; > + } > + > + xe_sysctrl_create_command(&cmd, entry->group, entry->command, > + &req, sizeof(req), resp_hdr_only, > + sizeof(resp_hdr_only)); > + > + guard(xe_pm_runtime)(xe); > + entry->status = xe_sysctrl_send_command(entry->sc, &cmd, > &out_len); > + > + return entry->status ? entry->status : len; > + > +inval: > + xe_err(xe, "sysctrl: invalid ras_error_inject token '%s'\n", token); > + return -EINVAL; > +} > + > +static int xe_sysctrl_ras_error_inject_show(struct seq_file *m, void > +*data) { > + struct xe_sysctrl_debugfs_entry *entry = m->private; > + struct xe_device *xe = sc_to_xe(entry->sc); > + > + seq_printf(m, "Command: group=0x%02x cmd=0x%02x\n", entry- > >group, entry->command); > + seq_printf(m, "Diag firmware ready: %s\n", > + str_yes_no(xe_sysctrl_is_diag_fw_ready(xe))); > + seq_printf(m, "Status: %d (%s)\n", entry->status, entry->status ? > +"FAILED" : "SUCCESS"); > + > + seq_puts(m, "\nUsage:\n"); > + seq_puts(m, " echo \"<ras_block_id> <ras_sub_block_id> > <err_type> [params]\" > ras_error_inject\n"); > + seq_puts(m, " cat ras_error_inject\n"); > + > + return 0; > +} > + > +static int xe_sysctrl_ras_error_inject_open(struct inode *inode, struct > +file *file) { > + return single_open(file, xe_sysctrl_ras_error_inject_show, > +inode->i_private); } > + > +static const struct file_operations xe_sysctrl_ras_error_inject_fops = { > + .owner = THIS_MODULE, > + .open = xe_sysctrl_ras_error_inject_open, > + .read = seq_read, > + .write = xe_sysctrl_ras_error_inject_write, > + .llseek = seq_lseek, > + .release = single_release, > +}; > + > static void xe_sysctrl_register_entry(struct dentry *root, struct > xe_sysctrl_debugfs_entry *entry, > struct xe_sysctrl *sc, const char *name, > u8 group, u8 command, > @@ -154,4 +273,8 @@ void xe_sysctrl_debugfs_register(struct xe_sysctrl > *sc, struct dentry *parent) > xe_sysctrl_register_entry(root, &sc->debugfs.loopback, sc, > "loopback", > XE_SYSCTRL_GROUP_CORE, > XE_SYSCTRL_CMD_LOOPBACK, > &xe_sysctrl_loopback_fops); > + > + xe_sysctrl_register_entry(root, &sc->debugfs.ras_error_inject, sc, > "ras_error_inject", > + XE_SYSCTRL_GROUP_DIAG, > XE_SYSCTRL_CMD_DIAG_RAS_ERR_INJECT, > + &xe_sysctrl_ras_error_inject_fops); > } > diff --git a/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h > b/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h > index ed80fe63e1c4..43ae0049b316 100644 > --- a/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h > +++ b/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h > @@ -14,10 +14,12 @@ > * enum xe_sysctrl_group - System Controller command groups > * > * @XE_SYSCTRL_GROUP_GFSP: GFSP group > + * @XE_SYSCTRL_GROUP_DIAG: Diag group > * @XE_SYSCTRL_GROUP_CORE: Core group > */ > enum xe_sysctrl_group { > XE_SYSCTRL_GROUP_GFSP = 0x01, > + XE_SYSCTRL_GROUP_DIAG = 0x02, > XE_SYSCTRL_GROUP_CORE = 0xFF, > }; > > @@ -51,6 +53,35 @@ enum xe_sysctrl_core_cmd { > XE_SYSCTRL_CMD_GET_APP_STATUS_BY_ID = 0x05, > }; > > +/** > + * enum xe_sysctrl_diag_cmd - Commands supported by Diag group > + * > + * @XE_SYSCTRL_CMD_DIAG_RAS_ERR_INJECT: RAS error injection */ > enum > +xe_sysctrl_diag_cmd { > + XE_SYSCTRL_CMD_DIAG_RAS_ERR_INJECT = 0x7E, > +}; > + > +/** > + * struct xe_sysctrl_diag_ras_err_inj_req - DIAG_RAS_ERR_INJECT request > +payload > + * > + * Request payload for XE_SYSCTRL_CMD_DIAG_RAS_ERR_INJECT. The > mailbox > +layer > + * prepends the application message header before sending. > + * > + * @ras_block_id: RAS block (subsystem) to inject the error into > + * @ras_sub_block_id: RAS sub-block (IP) within @ras_block_id > + * @err_type: Type of test error to inject > + * @reserved: Must be zero > + * @params: Optional injection parameters (default 0) */ struct > +xe_sysctrl_diag_ras_err_inj_req { > + u16 ras_block_id; > + u16 ras_sub_block_id; > + u16 err_type; > + u16 reserved; > + u32 params; > +} __packed; > + > /** > * struct xe_sysctrl_app_status_req - Get application status request > * > diff --git a/drivers/gpu/drm/xe/xe_sysctrl_types.h > b/drivers/gpu/drm/xe/xe_sysctrl_types.h > index 53d82e61383a..3a97a10d1b7d 100644 > --- a/drivers/gpu/drm/xe/xe_sysctrl_types.h > +++ b/drivers/gpu/drm/xe/xe_sysctrl_types.h > @@ -68,6 +68,9 @@ struct xe_sysctrl { > > /** @debugfs.loopback: Loopback test entry */ > struct xe_sysctrl_debugfs_entry loopback; > + > + /** @debugfs.ras_error_inject: RAS error injection test entry > */ > + struct xe_sysctrl_debugfs_entry ras_error_inject; > } debugfs; > }; > > -- > 2.43.0