xen: Implement xen/alternative-call.h for use in common code

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 implementation 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 optimisation, and how to
use the infrastructure in general code.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Andrew Cooper committed 2021-09-10 20:30:26 +01:00
1 parent c76cfada1c
commit f26bb28594
3 files changed
+67

No files matched your search

+1
View File
@@ -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
+3
View File
@@ -22,6 +22,9 @@ config GRANT_TABLE
If unsure, say Y.
config ALTERNATIVE_CALL
bool
config HAS_ALTERNATIVE
bool
+63
View File
@@ -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 implementations, 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 mechanism, 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 __initconstrel foo_a_ops = { ... };
* const struct foo_ops __initconstrel foo_b_ops = { ... };
*
* void __init 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 <asm/alternative.h>
#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 */
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.