File Index
Files and directories
Sign in
FILE

errata.c

File preview with syntax highlighting.

linux-6.19.14/arch/riscv/errata/mips/errata.c C
 1// SPDX-License-Identifier: GPL-2.0-only
 2/*
 3 * Copyright (C) 2025 MIPS.
 4 */
 5
 6#include <linux/memory.h>
 7#include <linux/module.h>
 8#include <asm/text-patching.h>
 9#include <asm/alternative.h>
10#include <asm/errata_list.h>
11#include <asm/vendorid_list.h>
12#include <asm/vendor_extensions.h>
13#include <asm/vendor_extensions/mips.h>
14
15static inline bool errata_probe_pause(void)
16{
17	if (!IS_ENABLED(CONFIG_ERRATA_MIPS_P8700_PAUSE_OPCODE))
18		return false;
19
20	if (!riscv_isa_vendor_extension_available(MIPS_VENDOR_ID, XMIPSEXECTL))
21		return false;
22
23	return true;
24}
25
26static u32 mips_errata_probe(void)
27{
28	u32 cpu_req_errata = 0;
29
30	if (errata_probe_pause())
31		cpu_req_errata |= BIT(ERRATA_MIPS_P8700_PAUSE_OPCODE);
32
33	return cpu_req_errata;
34}
35
36void mips_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
37			    unsigned long archid, unsigned long impid,
38			    unsigned int stage)
39{
40	struct alt_entry *alt;
41	u32 cpu_req_errata = mips_errata_probe();
42	u32 tmp;
43
44	BUILD_BUG_ON(ERRATA_MIPS_NUMBER >= RISCV_VENDOR_EXT_ALTERNATIVES_BASE);
45
46	if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
47		return;
48
49	for (alt = begin; alt < end; alt++) {
50		if (alt->vendor_id != MIPS_VENDOR_ID)
51			continue;
52
53		if (alt->patch_id >= ERRATA_MIPS_NUMBER) {
54			WARN(1, "MIPS errata id:%d not in kernel errata list\n",
55			     alt->patch_id);
56			continue;
57		}
58
59		tmp = (1U << alt->patch_id);
60		if (cpu_req_errata && tmp) {
61			mutex_lock(&text_mutex);
62			patch_text_nosync(ALT_OLD_PTR(alt), ALT_ALT_PTR(alt),
63					  alt->alt_len);
64			mutex_unlock(&text_mutex);
65		}
66	}
67}
~/ Read-only file preview.