Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp33413imu; Thu, 8 Nov 2018 13:19:45 -0800 (PST) X-Google-Smtp-Source: AJdET5cylHs+Yiat63M0SmpWxxDuY+CThHuCjAsaxxMhHJb5hbq4xkYhW4EFQ2C85p7O3CWP/37A X-Received: by 2002:a65:430b:: with SMTP id j11-v6mr5121817pgq.269.1541711984964; Thu, 08 Nov 2018 13:19:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1541711984; cv=none; d=google.com; s=arc-20160816; b=Y43KJQYbEE8XFFxVQzZUYYGCFD3BvofW+STDZPq2p78j/DPUpvpA/K6rpjWK8cOqx/ wVjawDlenF+VRHLlBci1n1qV6ytv8UVe/kSzShF188QeoSsTpX28uXIcu6/T8Ao/ujZE 4iYcYJoH2P2/MNSIopnKsMfzTmmxOg3N3jZF9N94YjUpqJuUtc1BecI5B+zGBfG88g5v 5bIM0DipjIFe16ZlI7hc/BuXiEg3FqPl+A+Q+jTqCyCepEin1z26lszXXeRzPestOXjc WY/unQCH5LSgOuUV25E0t9kQPELk4F+Svgw3Zt5FqXmJEmo1TQF8MLc7VgTb+fQG9uwf IOBg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=bRd45w8G7i53u08wp3FmpNOgMP8nF5LDMkOysbMaoxI=; b=w41jemMlJxi0fxSyUjkcjrXqQpDELSf8j6nwH4HFJH9XBcrQwD88YiRBCv9HpuhGys z9WgL7xdNIpFnvanJ4H0VIImjRNkrOY20afp/ruyftOYb6JjkFlmfHTKGb+2Rg/VsODi yZkD/FvAsoIeTBXyR5Hsq1X13E+ZpNh0W5ZfHaKo2JjkITIWSV1FmrnRyYYU3JW/lt9K VocURIIFei0xkZ3quSQjjM7erjnILcMKj+qX1WwUx/Y185ofBSSosKnhfaxmgsIiBS9C soi14B0t2y78Z9zYRn3w1lqWZGmQHJYl1izuLVCFqM2/5qCnybemi7XVGwYMaT+ACNBD fQtA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l6-v6si5676264pfi.179.2018.11.08.13.19.22; Thu, 08 Nov 2018 13:19:44 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727427AbeKIGzW (ORCPT + 99 others); Fri, 9 Nov 2018 01:55:22 -0500 Received: from mx1.redhat.com ([209.132.183.28]:47756 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727082AbeKIGzV (ORCPT ); Fri, 9 Nov 2018 01:55:21 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BF969300286E; Thu, 8 Nov 2018 21:18:02 +0000 (UTC) Received: from treble.redhat.com (ovpn-124-61.rdu2.redhat.com [10.10.124.61]) by smtp.corp.redhat.com (Postfix) with ESMTP id 56E8D6871F; Thu, 8 Nov 2018 21:18:01 +0000 (UTC) From: Josh Poimboeuf To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, Ard Biesheuvel , Andy Lutomirski , Steven Rostedt , Peter Zijlstra , Ingo Molnar , Thomas Gleixner , Linus Torvalds , Masami Hiramatsu , Jason Baron , Jiri Kosina , David Laight , Borislav Petkov Subject: [RFC PATCH 2/3] x86/static_call: Add x86 unoptimized static call implementation Date: Thu, 8 Nov 2018 15:15:52 -0600 Message-Id: <606e3af9f66b1d27f7a9885d9d6171b2585c2fe4.1541711457.git.jpoimboe@redhat.com> In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Thu, 08 Nov 2018 21:18:03 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add the x86 unoptimized static call implementation. For each key, it creates a permanent trampoline which is the destination for all static calls for the given key. The trampoline has a direct jump which gets patched by static_call_update() when the destination changes. Signed-off-by: Josh Poimboeuf --- arch/x86/Kconfig | 1 + arch/x86/include/asm/static_call.h | 18 +++++++++++ arch/x86/kernel/Makefile | 1 + arch/x86/kernel/static_call.c | 51 ++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+) create mode 100644 arch/x86/include/asm/static_call.h create mode 100644 arch/x86/kernel/static_call.c diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index b5286ad2a982..9a83c3edd839 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -189,6 +189,7 @@ config X86 select HAVE_FUNCTION_ARG_ACCESS_API select HAVE_STACKPROTECTOR if CC_HAS_SANE_STACKPROTECTOR select HAVE_STACK_VALIDATION if X86_64 + select HAVE_STATIC_CALL_UNOPTIMIZED select HAVE_RSEQ select HAVE_SYSCALL_TRACEPOINTS select HAVE_UNSTABLE_SCHED_CLOCK diff --git a/arch/x86/include/asm/static_call.h b/arch/x86/include/asm/static_call.h new file mode 100644 index 000000000000..de6b032cf809 --- /dev/null +++ b/arch/x86/include/asm/static_call.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_STATIC_CALL_H +#define _ASM_STATIC_CALL_H + +/* + * This is a permanent trampoline which is the destination for all static calls + * for the given key. The direct jump gets patched by static_call_update(). + */ +#define ARCH_STATIC_CALL_TRAMP(key, func) \ + asm(".pushsection .text, \"ax\" \n" \ + ".align 4 \n" \ + ".globl " STATIC_CALL_TRAMP_STR(key) " \n" \ + ".type " STATIC_CALL_TRAMP_STR(key) ", @function \n" \ + STATIC_CALL_TRAMP_STR(key) ": \n" \ + "jmp " #func " \n" \ + ".popsection \n") + +#endif /* _ASM_STATIC_CALL_H */ diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 8824d01c0c35..82acc8a28429 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -62,6 +62,7 @@ obj-y += tsc.o tsc_msr.o io_delay.o rtc.o obj-y += pci-iommu_table.o obj-y += resource.o obj-y += irqflags.o +obj-y += static_call.o obj-y += process.o obj-y += fpu/ diff --git a/arch/x86/kernel/static_call.c b/arch/x86/kernel/static_call.c new file mode 100644 index 000000000000..47ddc655ccda --- /dev/null +++ b/arch/x86/kernel/static_call.c @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include +#include +#include +#include +#include + +#define CALL_INSN_SIZE 5 + +void static_call_bp_handler(void); +void *bp_handler_dest; + +asm(".pushsection .text, \"ax\" \n" + ".globl static_call_bp_handler \n" + ".type static_call_bp_handler, @function \n" + "static_call_bp_handler: \n" + "ANNOTATE_RETPOLINE_SAFE \n" + "jmp *bp_handler_dest \n" + ".popsection \n"); + +void arch_static_call_transform(unsigned long insn, void *dest) +{ + s32 dest_relative; + unsigned char insn_opcode; + unsigned char opcodes[CALL_INSN_SIZE]; + + mutex_lock(&text_mutex); + + insn_opcode = *(unsigned char *)insn; + if (insn_opcode != 0xe8 && insn_opcode != 0xe9) { + WARN_ONCE(1, "unexpected static call insn opcode 0x%x at %pS", + insn_opcode, (void *)insn); + goto done; + } + + dest_relative = (long)(dest) - (long)(insn + CALL_INSN_SIZE); + + opcodes[0] = insn_opcode; + memcpy(&opcodes[1], &dest_relative, CALL_INSN_SIZE - 1); + + /* Set up the variable for the breakpoint handler: */ + bp_handler_dest = dest; + + /* Patch the call site: */ + text_poke_bp((void *)insn, opcodes, CALL_INSN_SIZE, + static_call_bp_handler); + +done: + mutex_unlock(&text_mutex); +} +EXPORT_SYMBOL_GPL(arch_static_call_transform); -- 2.17.2