summaryrefslogtreecommitdiff
path: root/arch/x86/kvm/vmx/vmx_ops.h
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2021-12-13 13:07:40 +0300
committerPaolo Bonzini <pbonzini@redhat.com>2022-01-07 18:44:46 +0300
commit907d139318b5109e5b676b32b0f4a2c666a8d9ac (patch)
tree7a10101dbaaeab54b3bef7528d78911caee3d31b /arch/x86/kvm/vmx/vmx_ops.h
parent55749769fe608fa3f4a075e42e89d237c8e37637 (diff)
downloadlinux-907d139318b5109e5b676b32b0f4a2c666a8d9ac.tar.xz
KVM: VMX: Provide vmread version using asm-goto-with-outputs
Use asm-goto-output for smaller fast path code. Message-Id: <YbcbbGW2GcMx6KpD@hirez.programming.kicks-ass.net> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm/vmx/vmx_ops.h')
-rw-r--r--arch/x86/kvm/vmx/vmx_ops.h27
1 files changed, 27 insertions, 0 deletions
diff --git a/arch/x86/kvm/vmx/vmx_ops.h b/arch/x86/kvm/vmx/vmx_ops.h
index 9e9ef47e988c..67f745250e50 100644
--- a/arch/x86/kvm/vmx/vmx_ops.h
+++ b/arch/x86/kvm/vmx/vmx_ops.h
@@ -71,6 +71,31 @@ static __always_inline unsigned long __vmcs_readl(unsigned long field)
{
unsigned long value;
+#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
+
+ asm_volatile_goto("1: vmread %[field], %[output]\n\t"
+ "jna %l[do_fail]\n\t"
+
+ _ASM_EXTABLE(1b, %l[do_exception])
+
+ : [output] "=r" (value)
+ : [field] "r" (field)
+ : "cc"
+ : do_fail, do_exception);
+
+ return value;
+
+do_fail:
+ WARN_ONCE(1, "kvm: vmread failed: field=%lx\n", field);
+ pr_warn_ratelimited("kvm: vmread failed: field=%lx\n", field);
+ return 0;
+
+do_exception:
+ kvm_spurious_fault();
+ return 0;
+
+#else /* !CONFIG_CC_HAS_ASM_GOTO_OUTPUT */
+
asm volatile("1: vmread %2, %1\n\t"
".byte 0x3e\n\t" /* branch taken hint */
"ja 3f\n\t"
@@ -101,6 +126,8 @@ static __always_inline unsigned long __vmcs_readl(unsigned long field)
_ASM_EXTABLE(1b, 4b)
: ASM_CALL_CONSTRAINT, "=r"(value) : "r"(field) : "cc");
return value;
+
+#endif /* CONFIG_CC_HAS_ASM_GOTO_OUTPUT */
}
static __always_inline u16 vmcs_read16(unsigned long field)