KVM: VMX: Provide vmread version using asm-goto-with-outputs
authorPeter Zijlstra <peterz@infradead.org>
Mon, 13 Dec 2021 10:07:40 +0000 (11:07 +0100)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 7 Jan 2022 15:44:46 +0000 (10:44 -0500)
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>
arch/x86/kvm/vmx/vmx_ops.h

index 9e9ef47e988c12f66ec3240de8994b1f15c67251..67f745250e50ae329b5cfe6d27504b6cff4ce856 100644 (file)
@@ -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)