brintos

brintos / linux-shallow public Read only

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