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

intel_tcc_cooling.c (2942B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * cooling device driver that activates the processor throttling by
      4 * programming the TCC Offset register.
      5 * Copyright (c) 2021, Intel Corporation.
      6 */
      7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      8
      9#include <linux/device.h>
     10#include <linux/module.h>
     11#include <linux/thermal.h>
     12#include <asm/cpu_device_id.h>
     13
     14#define TCC_SHIFT 24
     15#define TCC_MASK	(0x3fULL<<24)
     16#define TCC_PROGRAMMABLE	BIT(30)
     17
     18static struct thermal_cooling_device *tcc_cdev;
     19
     20static int tcc_get_max_state(struct thermal_cooling_device *cdev, unsigned long
     21			     *state)
     22{
     23	*state = TCC_MASK >> TCC_SHIFT;
     24	return 0;
     25}
     26
     27static int tcc_offset_update(int tcc)
     28{
     29	u64 val;
     30	int err;
     31
     32	err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
     33	if (err)
     34		return err;
     35
     36	val &= ~TCC_MASK;
     37	val |= tcc << TCC_SHIFT;
     38
     39	err = wrmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, val);
     40	if (err)
     41		return err;
     42
     43	return 0;
     44}
     45
     46static int tcc_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
     47			     *state)
     48{
     49	u64 val;
     50	int err;
     51
     52	err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
     53	if (err)
     54		return err;
     55
     56	*state = (val & TCC_MASK) >> TCC_SHIFT;
     57	return 0;
     58}
     59
     60static int tcc_set_cur_state(struct thermal_cooling_device *cdev, unsigned long
     61			     state)
     62{
     63	return tcc_offset_update(state);
     64}
     65
     66static const struct thermal_cooling_device_ops tcc_cooling_ops = {
     67	.get_max_state = tcc_get_max_state,
     68	.get_cur_state = tcc_get_cur_state,
     69	.set_cur_state = tcc_set_cur_state,
     70};
     71
     72static const struct x86_cpu_id tcc_ids[] __initconst = {
     73	X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE, NULL),
     74	X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, NULL),
     75	X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, NULL),
     76	X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L, NULL),
     77	X86_MATCH_INTEL_FAM6_MODEL(ICELAKE, NULL),
     78	X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L, NULL),
     79	X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, NULL),
     80	X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, NULL),
     81	X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE, NULL),
     82	X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, NULL),
     83	X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, NULL),
     84	X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, NULL),
     85	{}
     86};
     87
     88MODULE_DEVICE_TABLE(x86cpu, tcc_ids);
     89
     90static int __init tcc_cooling_init(void)
     91{
     92	int ret;
     93	u64 val;
     94	const struct x86_cpu_id *id;
     95
     96	int err;
     97
     98	id = x86_match_cpu(tcc_ids);
     99	if (!id)
    100		return -ENODEV;
    101
    102	err = rdmsrl_safe(MSR_PLATFORM_INFO, &val);
    103	if (err)
    104		return err;
    105
    106	if (!(val & TCC_PROGRAMMABLE))
    107		return -ENODEV;
    108
    109	pr_info("Programmable TCC Offset detected\n");
    110
    111	tcc_cdev =
    112	    thermal_cooling_device_register("TCC Offset", NULL,
    113					    &tcc_cooling_ops);
    114	if (IS_ERR(tcc_cdev)) {
    115		ret = PTR_ERR(tcc_cdev);
    116		return ret;
    117	}
    118	return 0;
    119}
    120
    121module_init(tcc_cooling_init)
    122
    123static void __exit tcc_cooling_exit(void)
    124{
    125	thermal_cooling_device_unregister(tcc_cdev);
    126}
    127
    128module_exit(tcc_cooling_exit)
    129
    130MODULE_DESCRIPTION("TCC offset cooling device Driver");
    131MODULE_AUTHOR("Zhang Rui <rui.zhang@intel.com>");
    132MODULE_LICENSE("GPL v2");