mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
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:
1 parent
c76cfada1c
commit
f26bb28594
3 files changed
+67
No files matched your search
@@ -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
|
||||
|
||||
@@ -22,6 +22,9 @@ config GRANT_TABLE
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config ALTERNATIVE_CALL
|
||||
bool
|
||||
|
||||
config HAS_ALTERNATIVE
|
||||
bool
|
||||
|
||||
|
||||
@@ -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 */
|
||||