blob: 72f24802919086b64c491a51a5fc06053cf3c519 [file] [log] [blame]
In recent kernels, %pV will copy the va_list before using it.
This isn't true for all kernels, so copy the va_list for use
by the dev_*() functions, otherwise the kernel will crash if
the message is printed and traced.
--- a/drivers/net/wireless/iwlwifi/iwl-debug.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.c
@@ -76,13 +76,16 @@ void __iwl_ ##fn(struct device *dev, con
struct va_format vaf = { \
.fmt = fmt, \
}; \
- va_list args; \
+ va_list args1, args2; \
\
- va_start(args, fmt); \
- vaf.va = &args; \
+ va_start(args1, fmt); \
+ va_copy(args2, args1); \
+ vaf.va = &args2; \
dev_ ##fn(dev, "%pV", &vaf); \
+ va_end(args2); \
+ vaf.va = &args1; \
trace_iwlwifi_ ##fn(&vaf); \
- va_end(args); \
+ va_end(args1); \
}
__iwl_fn(warn)
@@ -101,13 +104,18 @@ void __iwl_err(struct device *dev, bool
va_list args;
va_start(args, fmt);
- vaf.va = &args;
if (!trace_only) {
+ va_list args2;
+
+ va_copy(args2, args);
+ vaf.va = &args2;
if (rfkill_prefix)
dev_err(dev, "(RFKILL) %pV", &vaf);
else
dev_err(dev, "%pV", &vaf);
+ va_end(args2);
}
+ vaf.va = &args;
trace_iwlwifi_err(&vaf);
va_end(args);
}
@@ -124,13 +132,19 @@ void __iwl_dbg(struct device *dev,
va_list args;
va_start(args, fmt);
- vaf.va = &args;
#ifdef CONFIG_IWLWIFI_DEBUG
if (iwl_have_debug_level(level) &&
- (!limit || net_ratelimit()))
+ (!limit || net_ratelimit())) {
+ va_list args2;
+
+ va_copy(args2, args);
+ vaf.va = &args2;
dev_dbg(dev, "%c %s %pV", in_interrupt() ? 'I' : 'U',
function, &vaf);
+ va_end(args2);
+ }
#endif
+ vaf.va = &args;
trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf);
va_end(args);
}