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

alternative.c (1740B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <linux/module.h>
      3#include <linux/cpu.h>
      4#include <linux/smp.h>
      5#include <asm/text-patching.h>
      6#include <asm/alternative.h>
      7#include <asm/facility.h>
      8#include <asm/nospec-branch.h>
      9
     10static int __initdata_or_module alt_instr_disabled;
     11
     12static int __init disable_alternative_instructions(char *str)
     13{
     14	alt_instr_disabled = 1;
     15	return 0;
     16}
     17
     18early_param("noaltinstr", disable_alternative_instructions);
     19
     20static void __init_or_module __apply_alternatives(struct alt_instr *start,
     21						  struct alt_instr *end)
     22{
     23	struct alt_instr *a;
     24	u8 *instr, *replacement;
     25
     26	/*
     27	 * The scan order should be from start to end. A later scanned
     28	 * alternative code can overwrite previously scanned alternative code.
     29	 */
     30	for (a = start; a < end; a++) {
     31		instr = (u8 *)&a->instr_offset + a->instr_offset;
     32		replacement = (u8 *)&a->repl_offset + a->repl_offset;
     33
     34		if (!__test_facility(a->facility, alt_stfle_fac_list))
     35			continue;
     36
     37		if (unlikely(a->instrlen % 2)) {
     38			WARN_ONCE(1, "cpu alternatives instructions length is "
     39				     "odd, skipping patching\n");
     40			continue;
     41		}
     42
     43		s390_kernel_write(instr, replacement, a->instrlen);
     44	}
     45}
     46
     47void __init_or_module apply_alternatives(struct alt_instr *start,
     48					 struct alt_instr *end)
     49{
     50	if (!alt_instr_disabled)
     51		__apply_alternatives(start, end);
     52}
     53
     54extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
     55void __init apply_alternative_instructions(void)
     56{
     57	apply_alternatives(__alt_instructions, __alt_instructions_end);
     58}
     59
     60static void do_sync_core(void *info)
     61{
     62	sync_core();
     63}
     64
     65void text_poke_sync(void)
     66{
     67	on_each_cpu(do_sync_core, NULL, 1);
     68}
     69
     70void text_poke_sync_lock(void)
     71{
     72	cpus_read_lock();
     73	text_poke_sync();
     74	cpus_read_unlock();
     75}