Commit | Line | Data |
---|---|---|
358c855c JN |
1 | // SPDX-License-Identifier: MIT |
2 | /* | |
3 | * Copyright © 2019 Intel Corporation | |
4 | */ | |
5 | ||
a7f46d5b TU |
6 | #include <linux/device.h> |
7 | ||
358c855c JN |
8 | #include <drm/drm_drv.h> |
9 | ||
10 | #include "i915_drv.h" | |
11 | #include "i915_utils.h" | |
12 | ||
ddae4d7a | 13 | #define FDO_BUG_MSG "Please file a bug on drm/i915; see " FDO_BUG_URL " for details." |
358c855c JN |
14 | |
15 | void | |
16 | __i915_printk(struct drm_i915_private *dev_priv, const char *level, | |
17 | const char *fmt, ...) | |
18 | { | |
19 | static bool shown_bug_once; | |
20 | struct device *kdev = dev_priv->drm.dev; | |
21 | bool is_error = level[1] <= KERN_ERR[1]; | |
22 | bool is_debug = level[1] == KERN_DEBUG[1]; | |
23 | struct va_format vaf; | |
24 | va_list args; | |
25 | ||
bdbf43d7 | 26 | if (is_debug && !drm_debug_enabled(DRM_UT_DRIVER)) |
358c855c JN |
27 | return; |
28 | ||
29 | va_start(args, fmt); | |
30 | ||
31 | vaf.fmt = fmt; | |
32 | vaf.va = &args; | |
33 | ||
34 | if (is_error) | |
35 | dev_printk(level, kdev, "%pV", &vaf); | |
36 | else | |
37 | dev_printk(level, kdev, "[" DRM_NAME ":%ps] %pV", | |
38 | __builtin_return_address(0), &vaf); | |
39 | ||
40 | va_end(args); | |
41 | ||
42 | if (is_error && !shown_bug_once) { | |
43 | /* | |
44 | * Ask the user to file a bug report for the error, except | |
45 | * if they may have caused the bug by fiddling with unsafe | |
46 | * module parameters. | |
47 | */ | |
48 | if (!test_taint(TAINT_USER)) | |
49 | dev_notice(kdev, "%s", FDO_BUG_MSG); | |
50 | shown_bug_once = true; | |
51 | } | |
52 | } | |
53 | ||
65706203 MW |
54 | void add_taint_for_CI(struct drm_i915_private *i915, unsigned int taint) |
55 | { | |
56 | __i915_printk(i915, KERN_NOTICE, "CI tainted:%#x by %pS\n", | |
57 | taint, (void *)_RET_IP_); | |
fcab594a MW |
58 | |
59 | /* Failures that occur during fault injection testing are expected */ | |
60 | if (!i915_error_injected()) | |
61 | __add_taint_for_CI(taint); | |
65706203 MW |
62 | } |
63 | ||
358c855c JN |
64 | #if IS_ENABLED(CONFIG_DRM_I915_DEBUG) |
65 | static unsigned int i915_probe_fail_count; | |
66 | ||
dd6e38df JK |
67 | int __i915_inject_probe_error(struct drm_i915_private *i915, int err, |
68 | const char *func, int line) | |
358c855c | 69 | { |
4ec37538 | 70 | if (i915_probe_fail_count >= i915_modparams.inject_probe_failure) |
358c855c JN |
71 | return 0; |
72 | ||
4ec37538 | 73 | if (++i915_probe_fail_count < i915_modparams.inject_probe_failure) |
358c855c JN |
74 | return 0; |
75 | ||
76 | __i915_printk(i915, KERN_INFO, | |
77 | "Injecting failure %d at checkpoint %u [%s:%d]\n", | |
4ec37538 JK |
78 | err, i915_modparams.inject_probe_failure, func, line); |
79 | i915_modparams.inject_probe_failure = 0; | |
358c855c JN |
80 | return err; |
81 | } | |
82 | ||
83 | bool i915_error_injected(void) | |
84 | { | |
4ec37538 | 85 | return i915_probe_fail_count && !i915_modparams.inject_probe_failure; |
358c855c JN |
86 | } |
87 | ||
88 | #endif | |
3a7a92ab CW |
89 | |
90 | void cancel_timer(struct timer_list *t) | |
91 | { | |
c185a16e | 92 | if (!timer_active(t)) |
3a7a92ab CW |
93 | return; |
94 | ||
95 | del_timer(t); | |
96 | WRITE_ONCE(t->expires, 0); | |
97 | } | |
98 | ||
99 | void set_timer_ms(struct timer_list *t, unsigned long timeout) | |
100 | { | |
101 | if (!timeout) { | |
102 | cancel_timer(t); | |
103 | return; | |
104 | } | |
105 | ||
f4bb45f7 | 106 | timeout = msecs_to_jiffies(timeout); |
3a7a92ab CW |
107 | |
108 | /* | |
109 | * Paranoia to make sure the compiler computes the timeout before | |
110 | * loading 'jiffies' as jiffies is volatile and may be updated in | |
111 | * the background by a timer tick. All to reduce the complexity | |
112 | * of the addition and reduce the risk of losing a jiffie. | |
113 | */ | |
114 | barrier(); | |
115 | ||
bfae03fe CW |
116 | /* Keep t->expires = 0 reserved to indicate a canceled timer. */ |
117 | mod_timer(t, jiffies + timeout ?: 1); | |
3a7a92ab | 118 | } |
a7f46d5b TU |
119 | |
120 | bool i915_vtd_active(struct drm_i915_private *i915) | |
121 | { | |
122 | if (device_iommu_mapped(i915->drm.dev)) | |
123 | return true; | |
124 | ||
125 | /* Running as a guest, we assume the host is enforcing VT'd */ | |
126 | return i915_run_as_guest(); | |
127 | } |