From patchwork Fri Sep 10 02:12:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Daniel P. Smith" X-Patchwork-Id: 12484043 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00, DATE_IN_FUTURE_03_06,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3D48DC433F5 for ; Thu, 9 Sep 2021 22:12:57 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CA845611BD for ; Thu, 9 Sep 2021 22:12:56 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org CA845611BD Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=apertussolutions.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=lists.xenproject.org Received: from list by lists.xenproject.org with outflank-mailman.183572.331844 (Exim 4.92) (envelope-from ) id 1mOSHf-0003tT-97; Thu, 09 Sep 2021 22:12:39 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 183572.331844; Thu, 09 Sep 2021 22:12:39 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1mOSHf-0003tM-5G; Thu, 09 Sep 2021 22:12:39 +0000 Received: by outflank-mailman (input) for mailman id 183572; Thu, 09 Sep 2021 22:12:38 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1mOSHe-0003t6-QS for xen-devel@lists.xenproject.org; Thu, 09 Sep 2021 22:12:38 +0000 Received: from sender4-of-o51.zoho.com (unknown [136.143.188.51]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 27bdd14b-110b-436e-a028-df8262e444b9; Thu, 09 Sep 2021 22:12:37 +0000 (UTC) Received: from sisyou.hme. (static-72-81-132-2.bltmmd.fios.verizon.net [72.81.132.2]) by mx.zohomail.com with SMTPS id 163122554711490.57395943312747; Thu, 9 Sep 2021 15:12:27 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 27bdd14b-110b-436e-a028-df8262e444b9 ARC-Seal: i=1; a=rsa-sha256; t=1631225552; cv=none; d=zohomail.com; s=zohoarc; b=JftKRVijsDv7+cQVOBsiTPJIEgxiWP2ToMQVQaWt9NvZo5x7jzbG6RIF/TNi8pY4qXvEffOVAucOLkGxmlfLOnfv7ulbetcnWVbQDieYSuqEQD7f3QaoodhvEgOBhY1yQVdrdDsBJSWuXEKuSLWgIQOwoqf0KAqdl7MOzw7Ft7c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1631225552; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:To; bh=XBdaaKkwEvH0I0vbH2y5Ky8zmphGkZHpWf/ybI9eSE4=; b=Oggn84Lu5ldQYhM2v5ielJ1IHq/Ib5a+AWFXm9bhEOgssLlHSK/zw6XocxbuMdcQlnoc9uG93j4kQXSllxeZNnD6HcqW78ZGmxDfLV4PebHVLQ+pMq9nPw0/Gfb8koYd9OOuXCh0AcT0/kfqcbKyVKPA8zqNr7Rws6Vr0Y8F9p0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=apertussolutions.com; spf=pass smtp.mailfrom=dpsmith@apertussolutions.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1631225552; s=zoho; d=apertussolutions.com; i=dpsmith@apertussolutions.com; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Content-Type:Content-Transfer-Encoding; bh=XBdaaKkwEvH0I0vbH2y5Ky8zmphGkZHpWf/ybI9eSE4=; b=RIjmXCTMIcrujVH5Gaudc6m++A+q0PN/Eeq1hvJcVC+mQSVlzz0MLT3US5IgZs08 nrtd+49t7f7eDn0wn6pvrOMstTFFqI1Rd1JEkTDyNJ8n9fXv9p26amt5nsjCLxRcStG JW5uCPFqehQakVvK6AlmD+/ZnaEwyB0kK6I0zcwo= From: "Daniel P. Smith" To: Wei Liu , xen-devel@lists.xenproject.org Cc: Andrew Cooper , "Daniel P . Smith" , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= , Stefano Stabellini , Julien Grall , Volodymyr Babchuk , Bob Eshleman , Alistair Francis , Connor Davis , Jan Beulich , George Dunlap , Ian Jackson Subject: [PATCH v5 01/10] xen: Implement xen/alternative-call.h for use in common code Date: Thu, 9 Sep 2021 22:12:26 -0400 Message-Id: <20210910021236.15082-2-dpsmith@apertussolutions.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210910021236.15082-1-dpsmith@apertussolutions.com> References: <20210910021236.15082-1-dpsmith@apertussolutions.com> MIME-Version: 1.0 X-ZohoMailClient: External From: Andrew Cooper The alternative call infrastructure is x86-only for now, but the common iommu code has a variant and more common code wants to use the infrastructure. Introduce CONFIG_ALTERNATIVE_CALL and a conditional implemetnation so common code can use the optimisation when available, without requiring all architectures to implement no-op stubs. Write some documentation, which was thus far entirely absent, covering the requirements for an architecture to implement this optimsiation, and how to use the infrastructure in general code. Signed-off-by: Andrew Cooper Signed-off-by: Daniel P. Smith --- CC: Jan Beulich CC: Roger Pau Monné CC: Wei Liu CC: Stefano Stabellini CC: Julien Grall CC: Volodymyr Babchuk CC: Bob Eshleman CC: Alistair Francis CC: Connor Davis CC: Daniel P. Smith v3: * Drop __alt_call_maybe_initconst This is a pre-requisite to "xsm: refactor xsm_ops handling" to avoid breaking the ARM build. Build test for the XSM code: diff --git a/xen/xsm/xsm_core.c b/xen/xsm/xsm_core.c index 5eab21e1b168..592074e8f41c 100644 --- a/xen/xsm/xsm_core.c +++ b/xen/xsm/xsm_core.c @@ -195,6 +195,16 @@ bool __init has_xsm_magic(paddr_t start) } #endif +#include +struct foo { + int (*bar)(void *); +} foo __alt_call_maybe_initdata; + +int test_alternative_call(void) +{ + return alternative_call(foo.bar, NULL); +} + int __init register_xsm(struct xsm_operations *ops) { if ( verify(ops) ) --- xen/arch/x86/Kconfig | 1 + xen/common/Kconfig | 3 ++ xen/include/xen/alternative-call.h | 63 ++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 xen/include/xen/alternative-call.h diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig index 9b164db641..1f83518ee0 100644 --- a/xen/arch/x86/Kconfig +++ b/xen/arch/x86/Kconfig @@ -6,6 +6,7 @@ config X86 def_bool y select ACPI select ACPI_LEGACY_TABLES_LOOKUP + select ALTERNATIVE_CALL select ARCH_SUPPORTS_INT128 select CORE_PARKING select HAS_ALTERNATIVE diff --git a/xen/common/Kconfig b/xen/common/Kconfig index 0ddd18e11a..ac5491b1cc 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -22,6 +22,9 @@ config GRANT_TABLE If unsure, say Y. +config ALTERNATIVE_CALL + bool + config HAS_ALTERNATIVE bool diff --git a/xen/include/xen/alternative-call.h b/xen/include/xen/alternative-call.h new file mode 100644 index 0000000000..d10af90b1b --- /dev/null +++ b/xen/include/xen/alternative-call.h @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef XEN_ALTERNATIVE_CALL +#define XEN_ALTERNATIVE_CALL + +/* + * Some subsystems in Xen may have multiple implementions, which can be + * resolved to a single implementation at boot time. By default, this will + * result in the use of function pointers. + * + * Some architectures may have mechanisms for dynamically modifying .text. + * Using this mechnaism, function pointers can be converted to direct calls + * which are typically more efficient at runtime. + * + * For architectures to support: + * + * - Implement alternative_{,v}call() in asm/alternative.h. Code generation + * requirements are to emit a function pointer call at build time, and stash + * enough metadata to simplify the call at boot once the implementation has + * been resolved. + * - Select ALTERNATIVE_CALL in Kconfig. + * + * To use: + * + * Consider the following simplified example. + * + * 1) struct foo_ops __alt_call_maybe_initdata ops; + * + * 2) const struct foo_ops __initconst foo_a_ops = { ... }; + * const struct foo_ops __initconst foo_b_ops = { ... }; + * + * void foo_init(void) + * { + * ... + * if ( use_impl_a ) + * ops = *foo_a_ops; + * else if ( use_impl_b ) + * ops = *foo_b_ops; + * ... + * } + * + * 3) alternative_call(ops.bar, ...); + * + * There needs to a single ops object (1) which will eventually contain the + * function pointers. This should be populated in foo's init() function (2) + * by one of the available implementations. To call functions, use + * alternative_{,v}call() referencing the main ops object (3). + */ + +#ifdef CONFIG_ALTERNATIVE_CALL + +#include + +#define __alt_call_maybe_initdata __initdata + +#else + +#define alternative_call(func, args...) (func)(args) +#define alternative_vcall(func, args...) (func)(args) + +#define __alt_call_maybe_initdata __read_mostly + +#endif /* !CONFIG_ALTERNATIVE_CALL */ +#endif /* XEN_ALTERNATIVE_CALL */