--- arch/x86/include/asm/kvm_host.h | 18 ++++++++++++ arch/x86/include/asm/kvm_vcpu_regs.h | 16 +++++++++++ arch/x86/kvm/Kconfig | 4 +++ arch/x86/kvm/x86.c | 43 ++++++++++++++++++++++++++++ arch/x86/kvm/x86.h | 28 +++++++++++++++++- 5 files changed, 108 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 0b95126505ac..b246a1a96c4e 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -220,6 +220,24 @@ enum { VCPU_SREG_GS, VCPU_SREG_TR, VCPU_SREG_LDTR, +#ifdef CONFIG_KVM_APX + VCPU_XREG_R16 = __VCPU_XREG_R16, + VCPU_XREG_R17 = __VCPU_XREG_R17, + VCPU_XREG_R18 = __VCPU_XREG_R18, + VCPU_XREG_R19 = __VCPU_XREG_R19, + VCPU_XREG_R20 = __VCPU_XREG_R20, + VCPU_XREG_R21 = __VCPU_XREG_R21, + VCPU_XREG_R22 = __VCPU_XREG_R22, + VCPU_XREG_R23 = __VCPU_XREG_R23, + VCPU_XREG_R24 = __VCPU_XREG_R24, + VCPU_XREG_R25 = __VCPU_XREG_R25, + VCPU_XREG_R26 = __VCPU_XREG_R26, + VCPU_XREG_R27 = __VCPU_XREG_R27, + VCPU_XREG_R28 = __VCPU_XREG_R28, + VCPU_XREG_R29 = __VCPU_XREG_R29, + VCPU_XREG_R30 = __VCPU_XREG_R30, + VCPU_XREG_R31 = __VCPU_XREG_R31, +#endif }; enum exit_fastpath_completion { diff --git a/arch/x86/include/asm/kvm_vcpu_regs.h b/arch/x86/include/asm/kvm_vcpu_regs.h index 1af2cb59233b..dd0cc171f405 100644 --- a/arch/x86/include/asm/kvm_vcpu_regs.h +++ b/arch/x86/include/asm/kvm_vcpu_regs.h @@ -20,6 +20,22 @@ #define __VCPU_REGS_R13 13 #define __VCPU_REGS_R14 14 #define __VCPU_REGS_R15 15 +#define __VCPU_XREG_R16 16 +#define __VCPU_XREG_R17 17 +#define __VCPU_XREG_R18 18 +#define __VCPU_XREG_R19 19 +#define __VCPU_XREG_R20 20 +#define __VCPU_XREG_R21 21 +#define __VCPU_XREG_R22 22 +#define __VCPU_XREG_R23 23 +#define __VCPU_XREG_R24 24 +#define __VCPU_XREG_R25 25 +#define __VCPU_XREG_R26 26 +#define __VCPU_XREG_R27 27 +#define __VCPU_XREG_R28 28 +#define __VCPU_XREG_R29 29 +#define __VCPU_XREG_R30 30 +#define __VCPU_XREG_R31 31 #endif #endif /* _ASM_X86_KVM_VCPU_REGS_H */ diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index 801bf9e520db..f27e3f2937f0 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig @@ -93,10 +93,14 @@ config KVM_SW_PROTECTED_VM If unsure, say "N". +config KVM_APX + bool + config KVM_INTEL tristate "KVM for Intel (and compatible) processors support" depends on KVM && IA32_FEAT_CTL select X86_FRED if X86_64 + select KVM_APX if X86_64 help Provides support for KVM on processors equipped with Intel's VT extensions, a.k.a. Virtual Machine Extensions (VMX). diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index a03530795707..07119b4597dc 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1261,6 +1261,49 @@ static inline u64 kvm_guest_supported_xfd(struct kvm_vcpu *vcpu) } #endif +#ifdef CONFIG_KVM_APX + +static unsigned long kvm_read_egpr(int reg) +{ + return 0; +} + +static void kvm_write_egpr(int reg, unsigned long data) +{ +} + +static unsigned long kvm_register_read_ext(struct kvm_vcpu *vcpu, int reg) +{ + switch (reg) { + case VCPU_REGS_RAX ... VCPU_REGS_R15: + return kvm_register_read_raw(vcpu, reg); + case VCPU_XREG_R16 ... VCPU_XREG_R31: + return kvm_read_egpr(reg); + default: + WARN_ON_ONCE(1); + } + + return 0; +} +EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_register_read_ext); + +static void kvm_register_write_ext(struct kvm_vcpu *vcpu, int reg, unsigned long val) +{ + switch (reg) { + case VCPU_REGS_RAX ... VCPU_REGS_R15: + kvm_register_write_raw(vcpu, reg, val); + break; + case VCPU_XREG_R16 ... VCPU_XREG_R31: + kvm_write_egpr(reg, val); + break; + default: + WARN_ON_ONCE(1); + } +} +EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_register_write_ext); + +#endif /* CONFIG_KVM_APX */ + int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) { u64 xcr0 = xcr; diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 94d4f07aaaa0..3447790849e7 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -411,6 +411,29 @@ static inline bool vcpu_match_mmio_gpa(struct kvm_vcpu *vcpu, gpa_t gpa) return false; } +#ifdef CONFIG_KVM_APX + +unsigned long kvm_register_read_ext(struct kvm_vcpu *vcpu, int reg); +void kvm_register_write_ext(struct kvm_vcpu *vcpu, int reg, unsigned long val); + +static inline unsigned long kvm_register_read(struct kvm_vcpu *vcpu, int reg) +{ + unsigned long val = kvm_register_read_ext(vcpu, reg); + + return is_64_bit_mode(vcpu) ? val : (u32)val; +} + +static inline void kvm_register_write(struct kvm_vcpu *vcpu, + int reg, unsigned long val) +{ + if (!is_64_bit_mode(vcpu)) + val = (u32)val; + + return kvm_register_write_ext(vcpu, reg, val); +} + +#else + static inline unsigned long kvm_register_read(struct kvm_vcpu *vcpu, int reg) { unsigned long val = kvm_register_read_raw(vcpu, reg); @@ -419,13 +442,16 @@ static inline unsigned long kvm_register_read(struct kvm_vcpu *vcpu, int reg) } static inline void kvm_register_write(struct kvm_vcpu *vcpu, - int reg, unsigned long val) + int reg, unsigned long val) { if (!is_64_bit_mode(vcpu)) val = (u32)val; + return kvm_register_write_raw(vcpu, reg, val); } +#endif + static inline bool kvm_check_has_quirk(struct kvm *kvm, u64 quirk) { return !(kvm->arch.disabled_quirks & quirk); -- 2.51.0