Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915: Allow the sysadmin to override security mitigations

The clear-residuals mitigation is a relatively heavy hammer and under some
circumstances the user may wish to forgo the context isolation in order
to meet some performance requirement. Introduce a generic module
parameter to allow selectively enabling/disabling different mitigations.

To disable just the clear-residuals mitigation (on Ivybridge, Baytrail,
or Haswell) use the module parameter: i915.mitigations=auto,!residuals

Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/1858
Fixes: 47f8253d2b89 ("drm/i915/gen7: Clear all EU/L3 residual contexts")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Jon Bloomfield <jon.bloomfield@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: stable@vger.kernel.org # v5.7
Reviewed-by: Jon Bloomfield <jon.bloomfield@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210111225220.3483-3-chris@chris-wilson.co.uk
(cherry picked from commit f7452c7cbd5b5dfb9a6c84cb20bea04c89be50cd)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>

authored by

Chris Wilson and committed by
Jani Nikula
984cadea 09aa9e45

+163 -1
+1
drivers/gpu/drm/i915/Makefile
··· 38 38 i915_config.o \ 39 39 i915_irq.o \ 40 40 i915_getparam.o \ 41 + i915_mitigations.o \ 41 42 i915_params.o \ 42 43 i915_pci.o \ 43 44 i915_scatterlist.o \
+3 -1
drivers/gpu/drm/i915/gt/intel_ring_submission.c
··· 32 32 #include "gen6_ppgtt.h" 33 33 #include "gen7_renderclear.h" 34 34 #include "i915_drv.h" 35 + #include "i915_mitigations.h" 35 36 #include "intel_breadcrumbs.h" 36 37 #include "intel_context.h" 37 38 #include "intel_gt.h" ··· 887 886 GEM_BUG_ON(HAS_EXECLISTS(engine->i915)); 888 887 889 888 if (engine->wa_ctx.vma && ce != engine->kernel_context) { 890 - if (engine->wa_ctx.vma->private != ce) { 889 + if (engine->wa_ctx.vma->private != ce && 890 + i915_mitigate_clear_residuals()) { 891 891 ret = clear_residuals(rq); 892 892 if (ret) 893 893 return ret;
+146
drivers/gpu/drm/i915/i915_mitigations.c
··· 1 + // SPDX-License-Identifier: MIT 2 + /* 3 + * Copyright © 2021 Intel Corporation 4 + */ 5 + 6 + #include <linux/kernel.h> 7 + #include <linux/moduleparam.h> 8 + #include <linux/slab.h> 9 + #include <linux/string.h> 10 + 11 + #include "i915_drv.h" 12 + #include "i915_mitigations.h" 13 + 14 + static unsigned long mitigations __read_mostly = ~0UL; 15 + 16 + enum { 17 + CLEAR_RESIDUALS = 0, 18 + }; 19 + 20 + static const char * const names[] = { 21 + [CLEAR_RESIDUALS] = "residuals", 22 + }; 23 + 24 + bool i915_mitigate_clear_residuals(void) 25 + { 26 + return READ_ONCE(mitigations) & BIT(CLEAR_RESIDUALS); 27 + } 28 + 29 + static int mitigations_set(const char *val, const struct kernel_param *kp) 30 + { 31 + unsigned long new = ~0UL; 32 + char *str, *sep, *tok; 33 + bool first = true; 34 + int err = 0; 35 + 36 + BUILD_BUG_ON(ARRAY_SIZE(names) >= BITS_PER_TYPE(mitigations)); 37 + 38 + str = kstrdup(val, GFP_KERNEL); 39 + if (!str) 40 + return -ENOMEM; 41 + 42 + for (sep = str; (tok = strsep(&sep, ","));) { 43 + bool enable = true; 44 + int i; 45 + 46 + /* Be tolerant of leading/trailing whitespace */ 47 + tok = strim(tok); 48 + 49 + if (first) { 50 + first = false; 51 + 52 + if (!strcmp(tok, "auto")) 53 + continue; 54 + 55 + new = 0; 56 + if (!strcmp(tok, "off")) 57 + continue; 58 + } 59 + 60 + if (*tok == '!') { 61 + enable = !enable; 62 + tok++; 63 + } 64 + 65 + if (!strncmp(tok, "no", 2)) { 66 + enable = !enable; 67 + tok += 2; 68 + } 69 + 70 + if (*tok == '\0') 71 + continue; 72 + 73 + for (i = 0; i < ARRAY_SIZE(names); i++) { 74 + if (!strcmp(tok, names[i])) { 75 + if (enable) 76 + new |= BIT(i); 77 + else 78 + new &= ~BIT(i); 79 + break; 80 + } 81 + } 82 + if (i == ARRAY_SIZE(names)) { 83 + pr_err("Bad \"%s.mitigations=%s\", '%s' is unknown\n", 84 + DRIVER_NAME, val, tok); 85 + err = -EINVAL; 86 + break; 87 + } 88 + } 89 + kfree(str); 90 + if (err) 91 + return err; 92 + 93 + WRITE_ONCE(mitigations, new); 94 + return 0; 95 + } 96 + 97 + static int mitigations_get(char *buffer, const struct kernel_param *kp) 98 + { 99 + unsigned long local = READ_ONCE(mitigations); 100 + int count, i; 101 + bool enable; 102 + 103 + if (!local) 104 + return scnprintf(buffer, PAGE_SIZE, "%s\n", "off"); 105 + 106 + if (local & BIT(BITS_PER_LONG - 1)) { 107 + count = scnprintf(buffer, PAGE_SIZE, "%s,", "auto"); 108 + enable = false; 109 + } else { 110 + enable = true; 111 + count = 0; 112 + } 113 + 114 + for (i = 0; i < ARRAY_SIZE(names); i++) { 115 + if ((local & BIT(i)) != enable) 116 + continue; 117 + 118 + count += scnprintf(buffer + count, PAGE_SIZE - count, 119 + "%s%s,", enable ? "" : "!", names[i]); 120 + } 121 + 122 + buffer[count - 1] = '\n'; 123 + return count; 124 + } 125 + 126 + static const struct kernel_param_ops ops = { 127 + .set = mitigations_set, 128 + .get = mitigations_get, 129 + }; 130 + 131 + module_param_cb_unsafe(mitigations, &ops, NULL, 0600); 132 + MODULE_PARM_DESC(mitigations, 133 + "Selectively enable security mitigations for all Intel® GPUs in the system.\n" 134 + "\n" 135 + " auto -- enables all mitigations required for the platform [default]\n" 136 + " off -- disables all mitigations\n" 137 + "\n" 138 + "Individual mitigations can be enabled by passing a comma-separated string,\n" 139 + "e.g. mitigations=residuals to enable only clearing residuals or\n" 140 + "mitigations=auto,noresiduals to disable only the clear residual mitigation.\n" 141 + "Either '!' or 'no' may be used to switch from enabling the mitigation to\n" 142 + "disabling it.\n" 143 + "\n" 144 + "Active mitigations for Ivybridge, Baytrail, Haswell:\n" 145 + " residuals -- clear all thread-local registers between contexts" 146 + );
+13
drivers/gpu/drm/i915/i915_mitigations.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Copyright © 2021 Intel Corporation 4 + */ 5 + 6 + #ifndef __I915_MITIGATIONS_H__ 7 + #define __I915_MITIGATIONS_H__ 8 + 9 + #include <linux/types.h> 10 + 11 + bool i915_mitigate_clear_residuals(void); 12 + 13 + #endif /* __I915_MITIGATIONS_H__ */