This just sets things up so that the ARCH_HAS_RAI symbol gets selected, and prepare the arch-specific headers and support functions.
Signed-off-by: Rasmus Villemoes <li...@rasmusvillemoes.dk> --- arch/x86/Kconfig | 1 + arch/x86/include/asm/rai.S | 18 ++++++++++++++++++ arch/x86/include/asm/rai.h | 25 ++++++++++++++++++++++++ arch/x86/kernel/Makefile | 1 + arch/x86/kernel/macros.S | 1 + arch/x86/kernel/rai.c | 39 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 85 insertions(+) create mode 100644 arch/x86/include/asm/rai.S create mode 100644 arch/x86/include/asm/rai.h create mode 100644 arch/x86/kernel/rai.c diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 5136a1281870..3f1679f258c9 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -62,6 +62,7 @@ config X86 select ARCH_HAS_MEMBARRIER_SYNC_CORE select ARCH_HAS_PMEM_API if X86_64 select ARCH_HAS_PTE_SPECIAL + select ARCH_HAS_RAI if X86_64 select ARCH_HAS_REFCOUNT select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64 select ARCH_HAS_UACCESS_MCSAFE if X86_64 && X86_MCE diff --git a/arch/x86/include/asm/rai.S b/arch/x86/include/asm/rai.S new file mode 100644 index 000000000000..253d27453416 --- /dev/null +++ b/arch/x86/include/asm/rai.S @@ -0,0 +1,18 @@ +#ifdef __ASSEMBLY__ + +.macro rai_entry type instr instr_end templ templ_end thunk + .long \type + .long \instr - . + .long \instr_end - \instr + .long \templ - . + .long \templ_end - \templ + .long \thunk - . +.endm + +.macro rai_entry_pad start end + .ifgt STRUCT_RAI_ENTRY_SIZE-(\end-\start) + .skip STRUCT_RAI_ENTRY_SIZE-(\end-\start), 0x00 + .endif +.endm + +#endif diff --git a/arch/x86/include/asm/rai.h b/arch/x86/include/asm/rai.h new file mode 100644 index 000000000000..269d696255b0 --- /dev/null +++ b/arch/x86/include/asm/rai.h @@ -0,0 +1,25 @@ +#ifndef _ASM_X86_RAI_H +#define _ASM_X86_RAI_H + +#define STRUCT_RAI_ENTRY_SIZE 24 + +/* Put the asm macros in a separate file for easier editing. */ +#include <asm/rai.S> + +#ifndef __ASSEMBLY__ + +struct rai_entry { + int type; /* RAI_xxx constant */ + s32 instr_offset; /* member-relative offset to instructions-to-be-patched */ + s32 instr_len; /* size of area, >= templ_len */ + s32 templ_offset; /* member-relative offset to template */ + s32 templ_len; /* length of template */ + s32 thunk_offset; /* member-relative offset to ool thunk */ + /* type-specific data follows */ +}; +_Static_assert(sizeof(struct rai_entry) == STRUCT_RAI_ENTRY_SIZE, + "please update STRUCT_RAI_ENTRY_SIZE"); + +#endif /* !__ASSEMBLY */ + +#endif /* _ASM_X86_RAI_H */ diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 8824d01c0c35..b4dea4e72081 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -58,6 +58,7 @@ obj-$(CONFIG_SYSFS) += ksysfs.o obj-y += bootflag.o e820.o obj-y += pci-dma.o quirks.o topology.o kdebugfs.o obj-y += alternative.o i8253.o hw_breakpoint.o +obj-$(CONFIG_ARCH_HAS_RAI) += rai.o obj-y += tsc.o tsc_msr.o io_delay.o rtc.o obj-y += pci-iommu_table.o obj-y += resource.o diff --git a/arch/x86/kernel/macros.S b/arch/x86/kernel/macros.S index 161c95059044..af5672a302d4 100644 --- a/arch/x86/kernel/macros.S +++ b/arch/x86/kernel/macros.S @@ -14,3 +14,4 @@ #include <asm/asm.h> #include <asm/cpufeature.h> #include <asm/jump_label.h> +#include <asm/rai.h> diff --git a/arch/x86/kernel/rai.c b/arch/x86/kernel/rai.c new file mode 100644 index 000000000000..2c6ff06f7a34 --- /dev/null +++ b/arch/x86/kernel/rai.c @@ -0,0 +1,39 @@ +#include <linux/memory.h> +#include <linux/mutex.h> +#include <linux/rai.h> +#include <asm/text-patching.h> + +extern struct rai_entry __start_rai_data[]; +extern struct rai_entry __stop_rai_data[]; + +static void +rai_patch_one(const struct rai_entry *r) +{ + u8 *instr = (u8*)&r->instr_offset + r->instr_offset; + u8 *templ = (u8*)&r->templ_offset + r->templ_offset; + u8 *thunk = (u8*)&r->thunk_offset + r->thunk_offset; + + switch (r->type) { + default: + WARN_ONCE(1, "unhandled RAI type %d\n", r->type); + return; + } + text_poke_bp(instr, templ, r->templ_len, thunk); +} + +static void +rai_patch(const struct rai_entry *start, const struct rai_entry *stop) +{ + const struct rai_entry *r; + + for (r = start; r < stop; ++r) + rai_patch_one(r); +} + +void +update_rai_access(void) +{ + mutex_lock(&text_mutex); + rai_patch(__start_rai_data, __stop_rai_data); + mutex_unlock(&text_mutex); +} -- 2.19.1.6.gbde171bbf5