diff options
author | Peter Zijlstra <peterz@infradead.org> | 2021-12-13 13:07:40 +0300 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2022-01-07 18:44:46 +0300 |
commit | 907d139318b5109e5b676b32b0f4a2c666a8d9ac (patch) | |
tree | 7a10101dbaaeab54b3bef7528d78911caee3d31b /arch | |
parent | 55749769fe608fa3f4a075e42e89d237c8e37637 (diff) | |
download | linux-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')
-rw-r--r-- | arch/x86/kvm/vmx/vmx_ops.h | 27 |
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) |