Messages in this thread Patch in this message | | | From | Frederic Weisbecker <> | Subject | [PATCH 5/5] x86: Support reverse execution | Date | Wed, 1 Apr 2015 01:20:36 +0200 |
| |
Support reverse execution for negative number of CPUs. We might be able to implement that deeper with the function tracer.
No-Yet-Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> --- arch/x86/kernel/cpu/negative.c | 28 ++++++++++++++++++++++++++++ arch/x86/kernel/head64.c | 4 ++++ 2 files changed, 32 insertions(+) create mode 100644 arch/x86/kernel/cpu/negative.c
diff --git a/arch/x86/kernel/cpu/negative.c b/arch/x86/kernel/cpu/negative.c new file mode 100644 index 0000000..3aff473 --- /dev/null +++ b/arch/x86/kernel/cpu/negative.c @@ -0,0 +1,28 @@ +/* Execute function in reverse for negative CPUs */ + +#define _ASM_RET 0xc3 +#define FUNC_MAX_SIZE 4096 +static DEFINE_PER_CPU(char, reverse_func_buf[FUNC_MAX_SIZE]); + +void execute_reverse_function(void *func) +{ + char *opcode = (char *)func; + int i = 0, j = FUNC_MAX_SIZE - 1; + void (*reverse_func)(void); + + /* + * Reverse copy the function. + * This assumes that every opcode is sizeof(char), + * there might be a few situations where that won't work + * but we'll fix them as soon as they get reported by users. + */ + while (1) { + reverse_func_buf[j--] = opcode[i]; + if (opcode[i++] == _ASM_RET) + break; + } + + reverse_func = &reverse_func_buf[FUNC_MAX_SIZE - 1]; + reverse_func(); +} + diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index c4f8d46..9ed2c88 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -197,5 +197,9 @@ void __init x86_64_start_reservations(char *real_mode_data) reserve_ebda_region(); +#if CONFIG_NR_CPUS >= 0 start_kernel(); +#else + execute_reverse_function(start_kernel); +#endif } -- 2.1.4
| |