cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

selftest_slpc.c (7173B)


      1// SPDX-License-Identifier: MIT
      2/*
      3 * Copyright © 2021 Intel Corporation
      4 */
      5
      6#define NUM_STEPS 5
      7#define H2G_DELAY 50000
      8#define delay_for_h2g() usleep_range(H2G_DELAY, H2G_DELAY + 10000)
      9#define FREQUENCY_REQ_UNIT	DIV_ROUND_CLOSEST(GT_FREQUENCY_MULTIPLIER, \
     10						  GEN9_FREQ_SCALER)
     11
     12static int slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 freq)
     13{
     14	int ret;
     15
     16	ret = intel_guc_slpc_set_min_freq(slpc, freq);
     17	if (ret)
     18		pr_err("Could not set min frequency to [%u]\n", freq);
     19	else /* Delay to ensure h2g completes */
     20		delay_for_h2g();
     21
     22	return ret;
     23}
     24
     25static int slpc_set_max_freq(struct intel_guc_slpc *slpc, u32 freq)
     26{
     27	int ret;
     28
     29	ret = intel_guc_slpc_set_max_freq(slpc, freq);
     30	if (ret)
     31		pr_err("Could not set maximum frequency [%u]\n",
     32		       freq);
     33	else /* Delay to ensure h2g completes */
     34		delay_for_h2g();
     35
     36	return ret;
     37}
     38
     39static int live_slpc_clamp_min(void *arg)
     40{
     41	struct drm_i915_private *i915 = arg;
     42	struct intel_gt *gt = to_gt(i915);
     43	struct intel_guc_slpc *slpc = &gt->uc.guc.slpc;
     44	struct intel_rps *rps = &gt->rps;
     45	struct intel_engine_cs *engine;
     46	enum intel_engine_id id;
     47	struct igt_spinner spin;
     48	u32 slpc_min_freq, slpc_max_freq;
     49	int err = 0;
     50
     51	if (!intel_uc_uses_guc_slpc(&gt->uc))
     52		return 0;
     53
     54	if (igt_spinner_init(&spin, gt))
     55		return -ENOMEM;
     56
     57	if (intel_guc_slpc_get_max_freq(slpc, &slpc_max_freq)) {
     58		pr_err("Could not get SLPC max freq\n");
     59		return -EIO;
     60	}
     61
     62	if (intel_guc_slpc_get_min_freq(slpc, &slpc_min_freq)) {
     63		pr_err("Could not get SLPC min freq\n");
     64		return -EIO;
     65	}
     66
     67	if (slpc_min_freq == slpc_max_freq) {
     68		pr_err("Min/Max are fused to the same value\n");
     69		return -EINVAL;
     70	}
     71
     72	intel_gt_pm_wait_for_idle(gt);
     73	intel_gt_pm_get(gt);
     74	for_each_engine(engine, gt, id) {
     75		struct i915_request *rq;
     76		u32 step, min_freq, req_freq;
     77		u32 act_freq, max_act_freq;
     78
     79		if (!intel_engine_can_store_dword(engine))
     80			continue;
     81
     82		/* Go from min to max in 5 steps */
     83		step = (slpc_max_freq - slpc_min_freq) / NUM_STEPS;
     84		max_act_freq = slpc_min_freq;
     85		for (min_freq = slpc_min_freq; min_freq < slpc_max_freq;
     86					min_freq += step) {
     87			err = slpc_set_min_freq(slpc, min_freq);
     88			if (err)
     89				break;
     90
     91			st_engine_heartbeat_disable(engine);
     92
     93			rq = igt_spinner_create_request(&spin,
     94							engine->kernel_context,
     95							MI_NOOP);
     96			if (IS_ERR(rq)) {
     97				err = PTR_ERR(rq);
     98				st_engine_heartbeat_enable(engine);
     99				break;
    100			}
    101
    102			i915_request_add(rq);
    103
    104			if (!igt_wait_for_spinner(&spin, rq)) {
    105				pr_err("%s: Spinner did not start\n",
    106				       engine->name);
    107				igt_spinner_end(&spin);
    108				st_engine_heartbeat_enable(engine);
    109				intel_gt_set_wedged(engine->gt);
    110				err = -EIO;
    111				break;
    112			}
    113
    114			/* Wait for GuC to detect business and raise
    115			 * requested frequency if necessary.
    116			 */
    117			delay_for_h2g();
    118
    119			req_freq = intel_rps_read_punit_req_frequency(rps);
    120
    121			/* GuC requests freq in multiples of 50/3 MHz */
    122			if (req_freq < (min_freq - FREQUENCY_REQ_UNIT)) {
    123				pr_err("SWReq is %d, should be at least %d\n", req_freq,
    124				       min_freq - FREQUENCY_REQ_UNIT);
    125				igt_spinner_end(&spin);
    126				st_engine_heartbeat_enable(engine);
    127				err = -EINVAL;
    128				break;
    129			}
    130
    131			act_freq =  intel_rps_read_actual_frequency(rps);
    132			if (act_freq > max_act_freq)
    133				max_act_freq = act_freq;
    134
    135			igt_spinner_end(&spin);
    136			st_engine_heartbeat_enable(engine);
    137		}
    138
    139		pr_info("Max actual frequency for %s was %d\n",
    140			engine->name, max_act_freq);
    141
    142		/* Actual frequency should rise above min */
    143		if (max_act_freq == slpc_min_freq) {
    144			pr_err("Actual freq did not rise above min\n");
    145			err = -EINVAL;
    146		}
    147
    148		if (err)
    149			break;
    150	}
    151
    152	/* Restore min/max frequencies */
    153	slpc_set_max_freq(slpc, slpc_max_freq);
    154	slpc_set_min_freq(slpc, slpc_min_freq);
    155
    156	if (igt_flush_test(gt->i915))
    157		err = -EIO;
    158
    159	intel_gt_pm_put(gt);
    160	igt_spinner_fini(&spin);
    161	intel_gt_pm_wait_for_idle(gt);
    162
    163	return err;
    164}
    165
    166static int live_slpc_clamp_max(void *arg)
    167{
    168	struct drm_i915_private *i915 = arg;
    169	struct intel_gt *gt = to_gt(i915);
    170	struct intel_guc_slpc *slpc;
    171	struct intel_rps *rps;
    172	struct intel_engine_cs *engine;
    173	enum intel_engine_id id;
    174	struct igt_spinner spin;
    175	int err = 0;
    176	u32 slpc_min_freq, slpc_max_freq;
    177
    178	slpc = &gt->uc.guc.slpc;
    179	rps = &gt->rps;
    180
    181	if (!intel_uc_uses_guc_slpc(&gt->uc))
    182		return 0;
    183
    184	if (igt_spinner_init(&spin, gt))
    185		return -ENOMEM;
    186
    187	if (intel_guc_slpc_get_max_freq(slpc, &slpc_max_freq)) {
    188		pr_err("Could not get SLPC max freq\n");
    189		return -EIO;
    190	}
    191
    192	if (intel_guc_slpc_get_min_freq(slpc, &slpc_min_freq)) {
    193		pr_err("Could not get SLPC min freq\n");
    194		return -EIO;
    195	}
    196
    197	if (slpc_min_freq == slpc_max_freq) {
    198		pr_err("Min/Max are fused to the same value\n");
    199		return -EINVAL;
    200	}
    201
    202	intel_gt_pm_wait_for_idle(gt);
    203	intel_gt_pm_get(gt);
    204	for_each_engine(engine, gt, id) {
    205		struct i915_request *rq;
    206		u32 max_freq, req_freq;
    207		u32 act_freq, max_act_freq;
    208		u32 step;
    209
    210		if (!intel_engine_can_store_dword(engine))
    211			continue;
    212
    213		/* Go from max to min in 5 steps */
    214		step = (slpc_max_freq - slpc_min_freq) / NUM_STEPS;
    215		max_act_freq = slpc_min_freq;
    216		for (max_freq = slpc_max_freq; max_freq > slpc_min_freq;
    217					max_freq -= step) {
    218			err = slpc_set_max_freq(slpc, max_freq);
    219			if (err)
    220				break;
    221
    222			st_engine_heartbeat_disable(engine);
    223
    224			rq = igt_spinner_create_request(&spin,
    225							engine->kernel_context,
    226							MI_NOOP);
    227			if (IS_ERR(rq)) {
    228				st_engine_heartbeat_enable(engine);
    229				err = PTR_ERR(rq);
    230				break;
    231			}
    232
    233			i915_request_add(rq);
    234
    235			if (!igt_wait_for_spinner(&spin, rq)) {
    236				pr_err("%s: SLPC spinner did not start\n",
    237				       engine->name);
    238				igt_spinner_end(&spin);
    239				st_engine_heartbeat_enable(engine);
    240				intel_gt_set_wedged(engine->gt);
    241				err = -EIO;
    242				break;
    243			}
    244
    245			delay_for_h2g();
    246
    247			/* Verify that SWREQ indeed was set to specific value */
    248			req_freq = intel_rps_read_punit_req_frequency(rps);
    249
    250			/* GuC requests freq in multiples of 50/3 MHz */
    251			if (req_freq > (max_freq + FREQUENCY_REQ_UNIT)) {
    252				pr_err("SWReq is %d, should be at most %d\n", req_freq,
    253				       max_freq + FREQUENCY_REQ_UNIT);
    254				igt_spinner_end(&spin);
    255				st_engine_heartbeat_enable(engine);
    256				err = -EINVAL;
    257				break;
    258			}
    259
    260			act_freq =  intel_rps_read_actual_frequency(rps);
    261			if (act_freq > max_act_freq)
    262				max_act_freq = act_freq;
    263
    264			st_engine_heartbeat_enable(engine);
    265			igt_spinner_end(&spin);
    266
    267			if (err)
    268				break;
    269		}
    270
    271		pr_info("Max actual frequency for %s was %d\n",
    272			engine->name, max_act_freq);
    273
    274		/* Actual frequency should rise above min */
    275		if (max_act_freq == slpc_min_freq) {
    276			pr_err("Actual freq did not rise above min\n");
    277			err = -EINVAL;
    278		}
    279
    280		if (igt_flush_test(gt->i915)) {
    281			err = -EIO;
    282			break;
    283		}
    284
    285		if (err)
    286			break;
    287	}
    288
    289	/* Restore min/max freq */
    290	slpc_set_max_freq(slpc, slpc_max_freq);
    291	slpc_set_min_freq(slpc, slpc_min_freq);
    292
    293	intel_gt_pm_put(gt);
    294	igt_spinner_fini(&spin);
    295	intel_gt_pm_wait_for_idle(gt);
    296
    297	return err;
    298}
    299
    300int intel_slpc_live_selftests(struct drm_i915_private *i915)
    301{
    302	static const struct i915_subtest tests[] = {
    303		SUBTEST(live_slpc_clamp_max),
    304		SUBTEST(live_slpc_clamp_min),
    305	};
    306
    307	if (intel_gt_is_wedged(to_gt(i915)))
    308		return 0;
    309
    310	return i915_live_subtests(tests, i915);
    311}