1358c855cSJani Nikula // SPDX-License-Identifier: MIT
2358c855cSJani Nikula /*
3358c855cSJani Nikula * Copyright © 2019 Intel Corporation
4358c855cSJani Nikula */
5358c855cSJani Nikula
6*a7f46d5bSTvrtko Ursulin #include <linux/device.h>
7*a7f46d5bSTvrtko Ursulin
8358c855cSJani Nikula #include <drm/drm_drv.h>
9358c855cSJani Nikula
10358c855cSJani Nikula #include "i915_drv.h"
11358c855cSJani Nikula #include "i915_utils.h"
12358c855cSJani Nikula
13ddae4d7aSJani Nikula #define FDO_BUG_MSG "Please file a bug on drm/i915; see " FDO_BUG_URL " for details."
14358c855cSJani Nikula
15358c855cSJani Nikula void
__i915_printk(struct drm_i915_private * dev_priv,const char * level,const char * fmt,...)16358c855cSJani Nikula __i915_printk(struct drm_i915_private *dev_priv, const char *level,
17358c855cSJani Nikula const char *fmt, ...)
18358c855cSJani Nikula {
19358c855cSJani Nikula static bool shown_bug_once;
20358c855cSJani Nikula struct device *kdev = dev_priv->drm.dev;
21358c855cSJani Nikula bool is_error = level[1] <= KERN_ERR[1];
22358c855cSJani Nikula bool is_debug = level[1] == KERN_DEBUG[1];
23358c855cSJani Nikula struct va_format vaf;
24358c855cSJani Nikula va_list args;
25358c855cSJani Nikula
26bdbf43d7SJani Nikula if (is_debug && !drm_debug_enabled(DRM_UT_DRIVER))
27358c855cSJani Nikula return;
28358c855cSJani Nikula
29358c855cSJani Nikula va_start(args, fmt);
30358c855cSJani Nikula
31358c855cSJani Nikula vaf.fmt = fmt;
32358c855cSJani Nikula vaf.va = &args;
33358c855cSJani Nikula
34358c855cSJani Nikula if (is_error)
35358c855cSJani Nikula dev_printk(level, kdev, "%pV", &vaf);
36358c855cSJani Nikula else
37358c855cSJani Nikula dev_printk(level, kdev, "[" DRM_NAME ":%ps] %pV",
38358c855cSJani Nikula __builtin_return_address(0), &vaf);
39358c855cSJani Nikula
40358c855cSJani Nikula va_end(args);
41358c855cSJani Nikula
42358c855cSJani Nikula if (is_error && !shown_bug_once) {
43358c855cSJani Nikula /*
44358c855cSJani Nikula * Ask the user to file a bug report for the error, except
45358c855cSJani Nikula * if they may have caused the bug by fiddling with unsafe
46358c855cSJani Nikula * module parameters.
47358c855cSJani Nikula */
48358c855cSJani Nikula if (!test_taint(TAINT_USER))
49358c855cSJani Nikula dev_notice(kdev, "%s", FDO_BUG_MSG);
50358c855cSJani Nikula shown_bug_once = true;
51358c855cSJani Nikula }
52358c855cSJani Nikula }
53358c855cSJani Nikula
add_taint_for_CI(struct drm_i915_private * i915,unsigned int taint)5465706203SMichał Winiarski void add_taint_for_CI(struct drm_i915_private *i915, unsigned int taint)
5565706203SMichał Winiarski {
5665706203SMichał Winiarski __i915_printk(i915, KERN_NOTICE, "CI tainted:%#x by %pS\n",
5765706203SMichał Winiarski taint, (void *)_RET_IP_);
58fcab594aSMichał Winiarski
59fcab594aSMichał Winiarski /* Failures that occur during fault injection testing are expected */
60fcab594aSMichał Winiarski if (!i915_error_injected())
6165706203SMichał Winiarski __add_taint_for_CI(taint);
6265706203SMichał Winiarski }
6365706203SMichał Winiarski
64358c855cSJani Nikula #if IS_ENABLED(CONFIG_DRM_I915_DEBUG)
65358c855cSJani Nikula static unsigned int i915_probe_fail_count;
66358c855cSJani Nikula
__i915_inject_probe_error(struct drm_i915_private * i915,int err,const char * func,int line)67dd6e38dfSJanusz Krzysztofik int __i915_inject_probe_error(struct drm_i915_private *i915, int err,
68358c855cSJani Nikula const char *func, int line)
69358c855cSJani Nikula {
704ec37538SJanusz Krzysztofik if (i915_probe_fail_count >= i915_modparams.inject_probe_failure)
71358c855cSJani Nikula return 0;
72358c855cSJani Nikula
734ec37538SJanusz Krzysztofik if (++i915_probe_fail_count < i915_modparams.inject_probe_failure)
74358c855cSJani Nikula return 0;
75358c855cSJani Nikula
76358c855cSJani Nikula __i915_printk(i915, KERN_INFO,
77358c855cSJani Nikula "Injecting failure %d at checkpoint %u [%s:%d]\n",
784ec37538SJanusz Krzysztofik err, i915_modparams.inject_probe_failure, func, line);
794ec37538SJanusz Krzysztofik i915_modparams.inject_probe_failure = 0;
80358c855cSJani Nikula return err;
81358c855cSJani Nikula }
82358c855cSJani Nikula
i915_error_injected(void)83358c855cSJani Nikula bool i915_error_injected(void)
84358c855cSJani Nikula {
854ec37538SJanusz Krzysztofik return i915_probe_fail_count && !i915_modparams.inject_probe_failure;
86358c855cSJani Nikula }
87358c855cSJani Nikula
88358c855cSJani Nikula #endif
893a7a92abSChris Wilson
cancel_timer(struct timer_list * t)903a7a92abSChris Wilson void cancel_timer(struct timer_list *t)
913a7a92abSChris Wilson {
92c185a16eSChris Wilson if (!timer_active(t))
933a7a92abSChris Wilson return;
943a7a92abSChris Wilson
953a7a92abSChris Wilson del_timer(t);
963a7a92abSChris Wilson WRITE_ONCE(t->expires, 0);
973a7a92abSChris Wilson }
983a7a92abSChris Wilson
set_timer_ms(struct timer_list * t,unsigned long timeout)993a7a92abSChris Wilson void set_timer_ms(struct timer_list *t, unsigned long timeout)
1003a7a92abSChris Wilson {
1013a7a92abSChris Wilson if (!timeout) {
1023a7a92abSChris Wilson cancel_timer(t);
1033a7a92abSChris Wilson return;
1043a7a92abSChris Wilson }
1053a7a92abSChris Wilson
106f4bb45f7SChris Wilson timeout = msecs_to_jiffies(timeout);
1073a7a92abSChris Wilson
1083a7a92abSChris Wilson /*
1093a7a92abSChris Wilson * Paranoia to make sure the compiler computes the timeout before
1103a7a92abSChris Wilson * loading 'jiffies' as jiffies is volatile and may be updated in
1113a7a92abSChris Wilson * the background by a timer tick. All to reduce the complexity
1123a7a92abSChris Wilson * of the addition and reduce the risk of losing a jiffie.
1133a7a92abSChris Wilson */
1143a7a92abSChris Wilson barrier();
1153a7a92abSChris Wilson
116bfae03feSChris Wilson /* Keep t->expires = 0 reserved to indicate a canceled timer. */
117bfae03feSChris Wilson mod_timer(t, jiffies + timeout ?: 1);
1183a7a92abSChris Wilson }
119*a7f46d5bSTvrtko Ursulin
i915_vtd_active(struct drm_i915_private * i915)120*a7f46d5bSTvrtko Ursulin bool i915_vtd_active(struct drm_i915_private *i915)
121*a7f46d5bSTvrtko Ursulin {
122*a7f46d5bSTvrtko Ursulin if (device_iommu_mapped(i915->drm.dev))
123*a7f46d5bSTvrtko Ursulin return true;
124*a7f46d5bSTvrtko Ursulin
125*a7f46d5bSTvrtko Ursulin /* Running as a guest, we assume the host is enforcing VT'd */
126*a7f46d5bSTvrtko Ursulin return i915_run_as_guest();
127*a7f46d5bSTvrtko Ursulin }
128