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

errata.c (3073B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2021 Sifive.
      4 */
      5
      6#include <linux/kernel.h>
      7#include <linux/module.h>
      8#include <linux/string.h>
      9#include <linux/bug.h>
     10#include <asm/patch.h>
     11#include <asm/alternative.h>
     12#include <asm/vendorid_list.h>
     13#include <asm/errata_list.h>
     14
     15struct errata_info_t {
     16	char name[ERRATA_STRING_LENGTH_MAX];
     17	bool (*check_func)(unsigned long  arch_id, unsigned long impid);
     18};
     19
     20static bool errata_cip_453_check_func(unsigned long  arch_id, unsigned long impid)
     21{
     22	/*
     23	 * Affected cores:
     24	 * Architecture ID: 0x8000000000000007
     25	 * Implement ID: 0x20181004 <= impid <= 0x20191105
     26	 */
     27	if (arch_id != 0x8000000000000007 ||
     28	    (impid < 0x20181004 || impid > 0x20191105))
     29		return false;
     30	return true;
     31}
     32
     33static bool errata_cip_1200_check_func(unsigned long  arch_id, unsigned long impid)
     34{
     35	/*
     36	 * Affected cores:
     37	 * Architecture ID: 0x8000000000000007 or 0x1
     38	 * Implement ID: mimpid[23:0] <= 0x200630 and mimpid != 0x01200626
     39	 */
     40	if (arch_id != 0x8000000000000007 && arch_id != 0x1)
     41		return false;
     42	if ((impid & 0xffffff) > 0x200630 || impid == 0x1200626)
     43		return false;
     44	return true;
     45}
     46
     47static struct errata_info_t errata_list[ERRATA_SIFIVE_NUMBER] = {
     48	{
     49		.name = "cip-453",
     50		.check_func = errata_cip_453_check_func
     51	},
     52	{
     53		.name = "cip-1200",
     54		.check_func = errata_cip_1200_check_func
     55	},
     56};
     57
     58static u32 __init_or_module sifive_errata_probe(unsigned long archid,
     59						unsigned long impid)
     60{
     61	int idx;
     62	u32 cpu_req_errata = 0;
     63
     64	for (idx = 0; idx < ERRATA_SIFIVE_NUMBER; idx++)
     65		if (errata_list[idx].check_func(archid, impid))
     66			cpu_req_errata |= (1U << idx);
     67
     68	return cpu_req_errata;
     69}
     70
     71static void __init_or_module warn_miss_errata(u32 miss_errata)
     72{
     73	int i;
     74
     75	pr_warn("----------------------------------------------------------------\n");
     76	pr_warn("WARNING: Missing the following errata may cause potential issues\n");
     77	for (i = 0; i < ERRATA_SIFIVE_NUMBER; i++)
     78		if (miss_errata & 0x1 << i)
     79			pr_warn("\tSiFive Errata[%d]:%s\n", i, errata_list[i].name);
     80	pr_warn("Please enable the corresponding Kconfig to apply them\n");
     81	pr_warn("----------------------------------------------------------------\n");
     82}
     83
     84void __init_or_module sifive_errata_patch_func(struct alt_entry *begin,
     85					       struct alt_entry *end,
     86					       unsigned long archid,
     87					       unsigned long impid,
     88					       unsigned int stage)
     89{
     90	struct alt_entry *alt;
     91	u32 cpu_req_errata;
     92	u32 cpu_apply_errata = 0;
     93	u32 tmp;
     94
     95	if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
     96		return;
     97
     98	cpu_req_errata = sifive_errata_probe(archid, impid);
     99
    100	for (alt = begin; alt < end; alt++) {
    101		if (alt->vendor_id != SIFIVE_VENDOR_ID)
    102			continue;
    103		if (alt->errata_id >= ERRATA_SIFIVE_NUMBER) {
    104			WARN(1, "This errata id:%d is not in kernel errata list", alt->errata_id);
    105			continue;
    106		}
    107
    108		tmp = (1U << alt->errata_id);
    109		if (cpu_req_errata & tmp) {
    110			patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len);
    111			cpu_apply_errata |= tmp;
    112		}
    113	}
    114	if (cpu_apply_errata != cpu_req_errata)
    115		warn_miss_errata(cpu_req_errata - cpu_apply_errata);
    116}