mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-13 06:06:24 +07:00
3847dab774
This patch adds the necessary code to patch a running kernel at runtime to improve performance. The current implementation offers a few optimizations variants: - When running a SMP kernel on a single UP processor, unwanted assembler statements like locking functions are overwritten with NOPs. When multiple instructions shall be skipped, one branch instruction is used instead of multiple nop instructions. - In the UP case, some pdtlb and pitlb instructions are patched to become pdtlb,l and pitlb,l which only flushes the CPU-local tlb entries instead of broadcasting the flush to other CPUs in the system and thus may improve performance. - fic and fdc instructions are skipped if no I- or D-caches are installed. This should speed up qemu emulation and cacheless systems. - If no cache coherence is needed for IO operations, the relevant fdc and sync instructions in the sba and ccio drivers are replaced by nops. - On systems which share I- and D-TLBs and thus don't have a seperate instruction TLB, the pitlb instruction is replaced by a nop. Live-patching is done early in the boot process, just after having run the system inventory. No drivers are running and thus no external interrupts should arrive. So the hope is that no TLB exceptions will occur during the patching. If this turns out to be wrong we will probably need to do the patching in real-mode. Signed-off-by: Helge Deller <deller@gmx.de>
48 lines
1.4 KiB
C
48 lines
1.4 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef __ASM_PARISC_ALTERNATIVE_H
|
|
#define __ASM_PARISC_ALTERNATIVE_H
|
|
|
|
#define ALT_COND_NO_SMP 0x01 /* when running UP instead of SMP */
|
|
#define ALT_COND_NO_DCACHE 0x02 /* if system has no d-cache */
|
|
#define ALT_COND_NO_ICACHE 0x04 /* if system has no i-cache */
|
|
#define ALT_COND_NO_SPLIT_TLB 0x08 /* if split_tlb == 0 */
|
|
#define ALT_COND_NO_IOC_FDC 0x10 /* if I/O cache does not need flushes */
|
|
|
|
#define INSN_PxTLB 0x02 /* modify pdtlb, pitlb */
|
|
#define INSN_NOP 0x08000240 /* nop */
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
#include <linux/init.h>
|
|
#include <linux/types.h>
|
|
#include <linux/stddef.h>
|
|
#include <linux/stringify.h>
|
|
|
|
struct alt_instr {
|
|
s32 orig_offset; /* offset to original instructions */
|
|
u32 len; /* end of original instructions */
|
|
u32 cond; /* see ALT_COND_XXX */
|
|
u32 replacement; /* replacement instruction or code */
|
|
};
|
|
|
|
void set_kernel_text_rw(int enable_read_write);
|
|
|
|
/* Alternative SMP implementation. */
|
|
#define ALTERNATIVE(cond, replacement) "!0:" \
|
|
".section .altinstructions, \"aw\" !" \
|
|
".word (0b-4-.), 1, " __stringify(cond) "," \
|
|
__stringify(replacement) " !" \
|
|
".previous"
|
|
|
|
#else
|
|
|
|
#define ALTERNATIVE(from, to, cond, replacement)\
|
|
.section .altinstructions, "aw" ! \
|
|
.word (from - .), (to - from)/4 ! \
|
|
.word cond, replacement ! \
|
|
.previous
|
|
|
|
#endif /* __ASSEMBLY__ */
|
|
|
|
#endif /* __ASM_PARISC_ALTERNATIVE_H */
|