mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00

around the fallout from the new CONFIG_OBJTOOL_WERROR=y feature, which, despite its default-off nature, increased the profile/impact of objtool warnings: - Improve error handling and the presentation of warnings/errors. - Revert the new summary warning line that some test-bot tools interpreted as new regressions. - Fix a number of objtool warnings in various drivers, core kernel code and architecture code. About half of them are potential problems related to out-of-bounds accesses or potential undefined behavior, the other half are additional objtool annotations. - Update objtool to latest (known) compiler quirks and objtool bugs triggered by compiler code generation - Misc fixes Signed-off-by: Ingo Molnar <mingo@kernel.org> -----BEGIN PGP SIGNATURE----- iQJFBAABCgAvFiEEBpT5eoXrXCwVQwEKEnMQ0APhK1gFAmfsRJMRHG1pbmdvQGtl cm5lbC5vcmcACgkQEnMQ0APhK1g0YRAApiCylIv+0ucdKiDVAiI+cU7dqAggFp9h ULcTuuCtVkfjYzIBw6y1Iw9JeYsyngYaI0VEMmLasJPt8o93K0vwBXGArXJKoMeu UPcVS8N6+LqrHsWBXk919t1wgBZ7csgUxsCa1K47NKa3eCijrqI0N8PtcoYqKd+M tOuyEcTCTfS0E2STv6Gpdp6VfDKms3Cn4MffLbcNWJXAsd1dwzDIG8IvAHUW9yG3 /ezVjm46thneNrRd9j/qU3mqNmhsec9NemHG7URaTznRKleWULhpmhGmcPYCh4Rj AqGjmPtqprPELtgezeV+LIcmIm5UWF/f+0tzzBrsRy1MiY8ED2w+J51DHsLoHg8t IfIkPyYX/zu9StXoRIwx/7C5NQqBlUfXGp6TuOOwzgbKOt+uRJOU6SnSQ06ZDwsa l2brQ+NDfvF7EvGnvi18wIM+iqMc2jSuWl0AT94ATDuAZGCyzlmwluIYmDuLfyZM JuYOogojt5vgHXDN6Ro3rDfK+tYckwez+Txx4oByGB3IJy75osBihtvHiYno7FgW KXDbiAfLZ4SlfPzqxI6PPzaj3py6hG9LICEiL0U8VecC7bZ/22BZQCpdKko+/E/Y PwlqCatqz/25U7GlsnfBISJO2VAyyUcbymvjnVXzZCi+IPAfeih6WcsTPJ96jxsa LULLCnuvmoY= =KkiI -----END PGP SIGNATURE----- Merge tag 'objtool-urgent-2025-04-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull objtool fixes from Ingo Molnar: "These are objtool fixes and updates by Josh Poimboeuf, centered around the fallout from the new CONFIG_OBJTOOL_WERROR=y feature, which, despite its default-off nature, increased the profile/impact of objtool warnings: - Improve error handling and the presentation of warnings/errors - Revert the new summary warning line that some test-bot tools interpreted as new regressions - Fix a number of objtool warnings in various drivers, core kernel code and architecture code. About half of them are potential problems related to out-of-bounds accesses or potential undefined behavior, the other half are additional objtool annotations - Update objtool to latest (known) compiler quirks and objtool bugs triggered by compiler code generation - Misc fixes" * tag 'objtool-urgent-2025-04-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (36 commits) objtool/loongarch: Add unwind hints in prepare_frametrace() rcu-tasks: Always inline rcu_irq_work_resched() context_tracking: Always inline ct_{nmi,irq}_{enter,exit}() sched/smt: Always inline sched_smt_active() objtool: Fix verbose disassembly if CROSS_COMPILE isn't set objtool: Change "warning:" to "error: " for fatal errors objtool: Always fail on fatal errors Revert "objtool: Increase per-function WARN_FUNC() rate limit" objtool: Append "()" to function name in "unexpected end of section" warning objtool: Ignore end-of-section jumps for KCOV/GCOV objtool: Silence more KCOV warnings, part 2 objtool, drm/vmwgfx: Don't ignore vmw_send_msg() for ORC objtool: Fix STACK_FRAME_NON_STANDARD for cold subfunctions objtool: Fix segfault in ignore_unreachable_insn() objtool: Fix NULL printf() '%s' argument in builtin-check.c:save_argv() objtool, lkdtm: Obfuscate the do_nothing() pointer objtool, regulator: rk808: Remove potential undefined behavior in rk806_set_mode_dcdc() objtool, ASoC: codecs: wcd934x: Remove potential undefined behavior in wcd934x_slim_irq_handler() objtool, Input: cyapa - Remove undefined behavior in cyapa_update_fw_store() objtool, panic: Disable SMAP in __stack_chk_fail() ...
229 lines
5.5 KiB
C
229 lines
5.5 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* DebugFS interface for the NVMe target.
|
|
* Copyright (c) 2022-2024 Shadow
|
|
* Copyright (c) 2024 SUSE LLC
|
|
*/
|
|
|
|
#include <linux/debugfs.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/init.h>
|
|
#include <linux/kernel.h>
|
|
|
|
#include "nvmet.h"
|
|
#include "debugfs.h"
|
|
|
|
static struct dentry *nvmet_debugfs;
|
|
|
|
#define NVMET_DEBUGFS_ATTR(field) \
|
|
static int field##_open(struct inode *inode, struct file *file) \
|
|
{ return single_open(file, field##_show, inode->i_private); } \
|
|
\
|
|
static const struct file_operations field##_fops = { \
|
|
.open = field##_open, \
|
|
.read = seq_read, \
|
|
.release = single_release, \
|
|
}
|
|
|
|
#define NVMET_DEBUGFS_RW_ATTR(field) \
|
|
static int field##_open(struct inode *inode, struct file *file) \
|
|
{ return single_open(file, field##_show, inode->i_private); } \
|
|
\
|
|
static const struct file_operations field##_fops = { \
|
|
.open = field##_open, \
|
|
.read = seq_read, \
|
|
.write = field##_write, \
|
|
.release = single_release, \
|
|
}
|
|
|
|
static int nvmet_ctrl_hostnqn_show(struct seq_file *m, void *p)
|
|
{
|
|
struct nvmet_ctrl *ctrl = m->private;
|
|
|
|
seq_puts(m, ctrl->hostnqn);
|
|
return 0;
|
|
}
|
|
NVMET_DEBUGFS_ATTR(nvmet_ctrl_hostnqn);
|
|
|
|
static int nvmet_ctrl_kato_show(struct seq_file *m, void *p)
|
|
{
|
|
struct nvmet_ctrl *ctrl = m->private;
|
|
|
|
seq_printf(m, "%d\n", ctrl->kato);
|
|
return 0;
|
|
}
|
|
NVMET_DEBUGFS_ATTR(nvmet_ctrl_kato);
|
|
|
|
static int nvmet_ctrl_port_show(struct seq_file *m, void *p)
|
|
{
|
|
struct nvmet_ctrl *ctrl = m->private;
|
|
|
|
seq_printf(m, "%d\n", le16_to_cpu(ctrl->port->disc_addr.portid));
|
|
return 0;
|
|
}
|
|
NVMET_DEBUGFS_ATTR(nvmet_ctrl_port);
|
|
|
|
static const char *const csts_state_names[] = {
|
|
[NVME_CSTS_RDY] = "ready",
|
|
[NVME_CSTS_CFS] = "fatal",
|
|
[NVME_CSTS_NSSRO] = "reset",
|
|
[NVME_CSTS_SHST_OCCUR] = "shutdown",
|
|
[NVME_CSTS_SHST_CMPLT] = "completed",
|
|
[NVME_CSTS_PP] = "paused",
|
|
};
|
|
|
|
static int nvmet_ctrl_state_show(struct seq_file *m, void *p)
|
|
{
|
|
struct nvmet_ctrl *ctrl = m->private;
|
|
bool sep = false;
|
|
int i;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(csts_state_names); i++) {
|
|
int state = BIT(i);
|
|
|
|
if (!(ctrl->csts & state))
|
|
continue;
|
|
if (sep)
|
|
seq_puts(m, "|");
|
|
sep = true;
|
|
if (csts_state_names[state])
|
|
seq_puts(m, csts_state_names[state]);
|
|
else
|
|
seq_printf(m, "%d", state);
|
|
}
|
|
if (sep)
|
|
seq_printf(m, "\n");
|
|
return 0;
|
|
}
|
|
|
|
static ssize_t nvmet_ctrl_state_write(struct file *file, const char __user *buf,
|
|
size_t count, loff_t *ppos)
|
|
{
|
|
struct seq_file *m = file->private_data;
|
|
struct nvmet_ctrl *ctrl = m->private;
|
|
char reset[16];
|
|
|
|
if (count >= sizeof(reset))
|
|
return -EINVAL;
|
|
if (copy_from_user(reset, buf, count))
|
|
return -EFAULT;
|
|
if (!memcmp(reset, "fatal", 5))
|
|
nvmet_ctrl_fatal_error(ctrl);
|
|
else
|
|
return -EINVAL;
|
|
return count;
|
|
}
|
|
NVMET_DEBUGFS_RW_ATTR(nvmet_ctrl_state);
|
|
|
|
static int nvmet_ctrl_host_traddr_show(struct seq_file *m, void *p)
|
|
{
|
|
struct nvmet_ctrl *ctrl = m->private;
|
|
ssize_t size;
|
|
char buf[NVMF_TRADDR_SIZE + 1];
|
|
|
|
size = nvmet_ctrl_host_traddr(ctrl, buf, NVMF_TRADDR_SIZE);
|
|
if (size < 0) {
|
|
buf[0] = '\0';
|
|
size = 0;
|
|
}
|
|
buf[size] = '\0';
|
|
seq_printf(m, "%s\n", buf);
|
|
return 0;
|
|
}
|
|
NVMET_DEBUGFS_ATTR(nvmet_ctrl_host_traddr);
|
|
|
|
#ifdef CONFIG_NVME_TARGET_TCP_TLS
|
|
static int nvmet_ctrl_tls_key_show(struct seq_file *m, void *p)
|
|
{
|
|
struct nvmet_ctrl *ctrl = m->private;
|
|
key_serial_t keyid = nvmet_queue_tls_keyid(ctrl->sqs[0]);
|
|
|
|
seq_printf(m, "%08x\n", keyid);
|
|
return 0;
|
|
}
|
|
NVMET_DEBUGFS_ATTR(nvmet_ctrl_tls_key);
|
|
|
|
static int nvmet_ctrl_tls_concat_show(struct seq_file *m, void *p)
|
|
{
|
|
struct nvmet_ctrl *ctrl = m->private;
|
|
|
|
seq_printf(m, "%d\n", ctrl->concat);
|
|
return 0;
|
|
}
|
|
NVMET_DEBUGFS_ATTR(nvmet_ctrl_tls_concat);
|
|
#endif
|
|
|
|
int nvmet_debugfs_ctrl_setup(struct nvmet_ctrl *ctrl)
|
|
{
|
|
char name[32];
|
|
struct dentry *parent = ctrl->subsys->debugfs_dir;
|
|
int ret;
|
|
|
|
if (!parent)
|
|
return -ENODEV;
|
|
snprintf(name, sizeof(name), "ctrl%d", ctrl->cntlid);
|
|
ctrl->debugfs_dir = debugfs_create_dir(name, parent);
|
|
if (IS_ERR(ctrl->debugfs_dir)) {
|
|
ret = PTR_ERR(ctrl->debugfs_dir);
|
|
ctrl->debugfs_dir = NULL;
|
|
return ret;
|
|
}
|
|
debugfs_create_file("port", S_IRUSR, ctrl->debugfs_dir, ctrl,
|
|
&nvmet_ctrl_port_fops);
|
|
debugfs_create_file("hostnqn", S_IRUSR, ctrl->debugfs_dir, ctrl,
|
|
&nvmet_ctrl_hostnqn_fops);
|
|
debugfs_create_file("kato", S_IRUSR, ctrl->debugfs_dir, ctrl,
|
|
&nvmet_ctrl_kato_fops);
|
|
debugfs_create_file("state", S_IRUSR | S_IWUSR, ctrl->debugfs_dir, ctrl,
|
|
&nvmet_ctrl_state_fops);
|
|
debugfs_create_file("host_traddr", S_IRUSR, ctrl->debugfs_dir, ctrl,
|
|
&nvmet_ctrl_host_traddr_fops);
|
|
#ifdef CONFIG_NVME_TARGET_TCP_TLS
|
|
debugfs_create_file("tls_concat", S_IRUSR, ctrl->debugfs_dir, ctrl,
|
|
&nvmet_ctrl_tls_concat_fops);
|
|
debugfs_create_file("tls_key", S_IRUSR, ctrl->debugfs_dir, ctrl,
|
|
&nvmet_ctrl_tls_key_fops);
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
void nvmet_debugfs_ctrl_free(struct nvmet_ctrl *ctrl)
|
|
{
|
|
debugfs_remove_recursive(ctrl->debugfs_dir);
|
|
}
|
|
|
|
int nvmet_debugfs_subsys_setup(struct nvmet_subsys *subsys)
|
|
{
|
|
int ret = 0;
|
|
|
|
subsys->debugfs_dir = debugfs_create_dir(subsys->subsysnqn,
|
|
nvmet_debugfs);
|
|
if (IS_ERR(subsys->debugfs_dir)) {
|
|
ret = PTR_ERR(subsys->debugfs_dir);
|
|
subsys->debugfs_dir = NULL;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void nvmet_debugfs_subsys_free(struct nvmet_subsys *subsys)
|
|
{
|
|
debugfs_remove_recursive(subsys->debugfs_dir);
|
|
}
|
|
|
|
int __init nvmet_init_debugfs(void)
|
|
{
|
|
struct dentry *parent;
|
|
|
|
parent = debugfs_create_dir("nvmet", NULL);
|
|
if (IS_ERR(parent)) {
|
|
pr_warn("%s: failed to create debugfs directory\n", "nvmet");
|
|
return PTR_ERR(parent);
|
|
}
|
|
nvmet_debugfs = parent;
|
|
return 0;
|
|
}
|
|
|
|
void nvmet_exit_debugfs(void)
|
|
{
|
|
debugfs_remove_recursive(nvmet_debugfs);
|
|
}
|