aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2015-10-28 08:45:37 +0000
committerAmit Pundir <amit.pundir@linaro.org>2017-06-06 00:09:25 +0530
commitf5aae56ec8209bcd4b9efb5312582ee59c7112a1 (patch)
treeb392dd56a50eebfd7ec23c8a9306dca5c90df62a
parentd3faba18b1b370bb0bc3938317b7d5b04ef8dc79 (diff)
downloadlinaro-android-f5aae56ec8209bcd4b9efb5312582ee59c7112a1.tar.gz
UPSTREAM: arm64: KVM: Add patchable function selector
KVM so far relies on code patching, and is likely to use it more in the future. The main issue is that our alternative system works at the instruction level, while we'd like to have alternatives at the function level. In order to cope with this, add the "hyp_alternate_select" macro that outputs a brief sequence of code that in turn can be patched, allowing an alternative function to be selected. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> (cherry picked from commit c1bf6e18e97e7ead77371d4251f8ef1567455584) Signed-off-by: Alex Shi <alex.shi@linaro.org> Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
-rw-r--r--arch/arm64/kvm/hyp/hyp.h24
1 files changed, 24 insertions, 0 deletions
diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h
index 080965348def..73419a769112 100644
--- a/arch/arm64/kvm/hyp/hyp.h
+++ b/arch/arm64/kvm/hyp/hyp.h
@@ -29,6 +29,30 @@
#define hyp_kern_va(v) (typeof(v))((unsigned long)(v) - HYP_PAGE_OFFSET \
+ PAGE_OFFSET)
+/**
+ * hyp_alternate_select - Generates patchable code sequences that are
+ * used to switch between two implementations of a function, depending
+ * on the availability of a feature.
+ *
+ * @fname: a symbol name that will be defined as a function returning a
+ * function pointer whose type will match @orig and @alt
+ * @orig: A pointer to the default function, as returned by @fname when
+ * @cond doesn't hold
+ * @alt: A pointer to the alternate function, as returned by @fname
+ * when @cond holds
+ * @cond: a CPU feature (as described in asm/cpufeature.h)
+ */
+#define hyp_alternate_select(fname, orig, alt, cond) \
+typeof(orig) * __hyp_text fname(void) \
+{ \
+ typeof(alt) *val = orig; \
+ asm volatile(ALTERNATIVE("nop \n", \
+ "mov %0, %1 \n", \
+ cond) \
+ : "+r" (val) : "r" (alt)); \
+ return val; \
+}
+
void __vgic_v2_save_state(struct kvm_vcpu *vcpu);
void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);