2019-06-03 13:44:50 +08:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
2015-10-21 17:09:49 +08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2015 - ARM Ltd
|
|
|
|
* Author: Marc Zyngier <marc.zyngier@arm.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __ARM64_KVM_HYP_H__
|
|
|
|
#define __ARM64_KVM_HYP_H__
|
|
|
|
|
|
|
|
#include <linux/compiler.h>
|
|
|
|
#include <linux/kvm_host.h>
|
2018-12-07 01:31:24 +08:00
|
|
|
#include <asm/alternative.h>
|
2018-12-11 22:26:31 +08:00
|
|
|
#include <asm/kvm_mmu.h>
|
2015-10-21 17:09:49 +08:00
|
|
|
#include <asm/sysreg.h>
|
|
|
|
|
|
|
|
#define __hyp_text __section(.hyp.text) notrace
|
|
|
|
|
2015-10-28 20:00:00 +08:00
|
|
|
#define read_sysreg_elx(r,nvh,vh) \
|
|
|
|
({ \
|
|
|
|
u64 reg; \
|
KVM: arm64: Migrate _elx sysreg accessors to msr_s/mrs_s
Currently, the {read,write}_sysreg_el*() accessors for accessing
particular ELs' sysregs in the presence of VHE rely on some local
hacks and define their system register encodings in a way that is
inconsistent with the core definitions in <asm/sysreg.h>.
As a result, it is necessary to add duplicate definitions for any
system register that already needs a definition in sysreg.h for
other reasons.
This is a bit of a maintenance headache, and the reasons for the
_el*() accessors working the way they do is a bit historical.
This patch gets rid of the shadow sysreg definitions in
<asm/kvm_hyp.h>, converts the _el*() accessors to use the core
__msr_s/__mrs_s interface, and converts all call sites to use the
standard sysreg #define names (i.e., upper case, with SYS_ prefix).
This patch will conflict heavily anyway, so the opportunity
to clean up some bad whitespace in the context of the changes is
taken.
The change exposes a few system registers that have no sysreg.h
definition, due to msr_s/mrs_s being used in place of msr/mrs:
additions are made in order to fill in the gaps.
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Christoffer Dall <christoffer.dall@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Link: https://www.spinics.net/lists/kvm-arm/msg31717.html
[Rebased to v4.21-rc1]
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
[Rebased to v5.2-rc5, changelog updates]
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2019-04-06 18:29:40 +08:00
|
|
|
asm volatile(ALTERNATIVE(__mrs_s("%0", r##nvh), \
|
arm64: sysreg: Make mrs_s and msr_s macros work with Clang and LTO
Clang's integrated assembler does not allow assembly macros defined
in one inline asm block using the .macro directive to be used across
separate asm blocks. LLVM developers consider this a feature and not a
bug, recommending code refactoring:
https://bugs.llvm.org/show_bug.cgi?id=19749
As binutils doesn't allow macros to be redefined, this change uses
UNDEFINE_MRS_S and UNDEFINE_MSR_S to define corresponding macros
in-place and workaround gcc and clang limitations on redefining macros
across different assembler blocks.
Specifically, the current state after preprocessing looks like this:
asm volatile(".macro mXX_s ... .endm");
void f()
{
asm volatile("mXX_s a, b");
}
With GCC, it gives macro redefinition error because sysreg.h is included
in multiple source files, and assembler code for all of them is later
combined for LTO (I've seen an intermediate file with hundreds of
identical definitions).
With clang, it gives macro undefined error because clang doesn't allow
sharing macros between inline asm statements.
I also seem to remember catching another sort of undefined error with
GCC due to reordering of macro definition asm statement and generated
asm code for function that uses the macro.
The solution with defining and undefining for each use, while certainly
not elegant, satisfies both GCC and clang, LTO and non-LTO.
Co-developed-by: Alex Matveev <alxmtvv@gmail.com>
Co-developed-by: Yury Norov <ynorov@caviumnetworks.com>
Co-developed-by: Sami Tolvanen <samitolvanen@google.com>
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
2019-04-25 00:55:37 +08:00
|
|
|
__mrs_s("%0", r##vh), \
|
2015-10-28 20:00:00 +08:00
|
|
|
ARM64_HAS_VIRT_HOST_EXTN) \
|
|
|
|
: "=r" (reg)); \
|
|
|
|
reg; \
|
|
|
|
})
|
|
|
|
|
|
|
|
#define write_sysreg_elx(v,r,nvh,vh) \
|
|
|
|
do { \
|
|
|
|
u64 __val = (u64)(v); \
|
KVM: arm64: Migrate _elx sysreg accessors to msr_s/mrs_s
Currently, the {read,write}_sysreg_el*() accessors for accessing
particular ELs' sysregs in the presence of VHE rely on some local
hacks and define their system register encodings in a way that is
inconsistent with the core definitions in <asm/sysreg.h>.
As a result, it is necessary to add duplicate definitions for any
system register that already needs a definition in sysreg.h for
other reasons.
This is a bit of a maintenance headache, and the reasons for the
_el*() accessors working the way they do is a bit historical.
This patch gets rid of the shadow sysreg definitions in
<asm/kvm_hyp.h>, converts the _el*() accessors to use the core
__msr_s/__mrs_s interface, and converts all call sites to use the
standard sysreg #define names (i.e., upper case, with SYS_ prefix).
This patch will conflict heavily anyway, so the opportunity
to clean up some bad whitespace in the context of the changes is
taken.
The change exposes a few system registers that have no sysreg.h
definition, due to msr_s/mrs_s being used in place of msr/mrs:
additions are made in order to fill in the gaps.
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Christoffer Dall <christoffer.dall@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Link: https://www.spinics.net/lists/kvm-arm/msg31717.html
[Rebased to v4.21-rc1]
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
[Rebased to v5.2-rc5, changelog updates]
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2019-04-06 18:29:40 +08:00
|
|
|
asm volatile(ALTERNATIVE(__msr_s(r##nvh, "%x0"), \
|
arm64: sysreg: Make mrs_s and msr_s macros work with Clang and LTO
Clang's integrated assembler does not allow assembly macros defined
in one inline asm block using the .macro directive to be used across
separate asm blocks. LLVM developers consider this a feature and not a
bug, recommending code refactoring:
https://bugs.llvm.org/show_bug.cgi?id=19749
As binutils doesn't allow macros to be redefined, this change uses
UNDEFINE_MRS_S and UNDEFINE_MSR_S to define corresponding macros
in-place and workaround gcc and clang limitations on redefining macros
across different assembler blocks.
Specifically, the current state after preprocessing looks like this:
asm volatile(".macro mXX_s ... .endm");
void f()
{
asm volatile("mXX_s a, b");
}
With GCC, it gives macro redefinition error because sysreg.h is included
in multiple source files, and assembler code for all of them is later
combined for LTO (I've seen an intermediate file with hundreds of
identical definitions).
With clang, it gives macro undefined error because clang doesn't allow
sharing macros between inline asm statements.
I also seem to remember catching another sort of undefined error with
GCC due to reordering of macro definition asm statement and generated
asm code for function that uses the macro.
The solution with defining and undefining for each use, while certainly
not elegant, satisfies both GCC and clang, LTO and non-LTO.
Co-developed-by: Alex Matveev <alxmtvv@gmail.com>
Co-developed-by: Yury Norov <ynorov@caviumnetworks.com>
Co-developed-by: Sami Tolvanen <samitolvanen@google.com>
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
2019-04-25 00:55:37 +08:00
|
|
|
__msr_s(r##vh, "%x0"), \
|
2015-10-28 20:00:00 +08:00
|
|
|
ARM64_HAS_VIRT_HOST_EXTN) \
|
|
|
|
: : "rZ" (__val)); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Unified accessors for registers that have a different encoding
|
|
|
|
* between VHE and non-VHE. They must be specified without their "ELx"
|
KVM: arm64: Migrate _elx sysreg accessors to msr_s/mrs_s
Currently, the {read,write}_sysreg_el*() accessors for accessing
particular ELs' sysregs in the presence of VHE rely on some local
hacks and define their system register encodings in a way that is
inconsistent with the core definitions in <asm/sysreg.h>.
As a result, it is necessary to add duplicate definitions for any
system register that already needs a definition in sysreg.h for
other reasons.
This is a bit of a maintenance headache, and the reasons for the
_el*() accessors working the way they do is a bit historical.
This patch gets rid of the shadow sysreg definitions in
<asm/kvm_hyp.h>, converts the _el*() accessors to use the core
__msr_s/__mrs_s interface, and converts all call sites to use the
standard sysreg #define names (i.e., upper case, with SYS_ prefix).
This patch will conflict heavily anyway, so the opportunity
to clean up some bad whitespace in the context of the changes is
taken.
The change exposes a few system registers that have no sysreg.h
definition, due to msr_s/mrs_s being used in place of msr/mrs:
additions are made in order to fill in the gaps.
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Christoffer Dall <christoffer.dall@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Link: https://www.spinics.net/lists/kvm-arm/msg31717.html
[Rebased to v4.21-rc1]
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
[Rebased to v5.2-rc5, changelog updates]
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2019-04-06 18:29:40 +08:00
|
|
|
* encoding, but with the SYS_ prefix, as defined in asm/sysreg.h.
|
2015-10-28 20:00:00 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
#define read_sysreg_el0(r) read_sysreg_elx(r, _EL0, _EL02)
|
|
|
|
#define write_sysreg_el0(v,r) write_sysreg_elx(v, r, _EL0, _EL02)
|
|
|
|
#define read_sysreg_el1(r) read_sysreg_elx(r, _EL1, _EL12)
|
|
|
|
#define write_sysreg_el1(v,r) write_sysreg_elx(v, r, _EL1, _EL12)
|
KVM: arm64: Migrate _elx sysreg accessors to msr_s/mrs_s
Currently, the {read,write}_sysreg_el*() accessors for accessing
particular ELs' sysregs in the presence of VHE rely on some local
hacks and define their system register encodings in a way that is
inconsistent with the core definitions in <asm/sysreg.h>.
As a result, it is necessary to add duplicate definitions for any
system register that already needs a definition in sysreg.h for
other reasons.
This is a bit of a maintenance headache, and the reasons for the
_el*() accessors working the way they do is a bit historical.
This patch gets rid of the shadow sysreg definitions in
<asm/kvm_hyp.h>, converts the _el*() accessors to use the core
__msr_s/__mrs_s interface, and converts all call sites to use the
standard sysreg #define names (i.e., upper case, with SYS_ prefix).
This patch will conflict heavily anyway, so the opportunity
to clean up some bad whitespace in the context of the changes is
taken.
The change exposes a few system registers that have no sysreg.h
definition, due to msr_s/mrs_s being used in place of msr/mrs:
additions are made in order to fill in the gaps.
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Christoffer Dall <christoffer.dall@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Link: https://www.spinics.net/lists/kvm-arm/msg31717.html
[Rebased to v4.21-rc1]
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
[Rebased to v5.2-rc5, changelog updates]
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2019-04-06 18:29:40 +08:00
|
|
|
#define read_sysreg_el2(r) read_sysreg_elx(r, _EL2, _EL1)
|
|
|
|
#define write_sysreg_el2(v,r) write_sysreg_elx(v, r, _EL2, _EL1)
|
2015-10-28 20:00:00 +08:00
|
|
|
|
2016-09-06 21:02:17 +08:00
|
|
|
int __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu);
|
2015-10-19 22:50:37 +08:00
|
|
|
|
2015-10-19 22:50:58 +08:00
|
|
|
void __vgic_v3_save_state(struct kvm_vcpu *vcpu);
|
|
|
|
void __vgic_v3_restore_state(struct kvm_vcpu *vcpu);
|
2017-10-05 23:19:19 +08:00
|
|
|
void __vgic_v3_activate_traps(struct kvm_vcpu *vcpu);
|
|
|
|
void __vgic_v3_deactivate_traps(struct kvm_vcpu *vcpu);
|
2017-10-05 06:18:07 +08:00
|
|
|
void __vgic_v3_save_aprs(struct kvm_vcpu *vcpu);
|
|
|
|
void __vgic_v3_restore_aprs(struct kvm_vcpu *vcpu);
|
2017-06-09 19:49:33 +08:00
|
|
|
int __vgic_v3_perform_cpuif_access(struct kvm_vcpu *vcpu);
|
2015-10-19 22:50:58 +08:00
|
|
|
|
2017-01-04 23:10:28 +08:00
|
|
|
void __timer_enable_traps(struct kvm_vcpu *vcpu);
|
|
|
|
void __timer_disable_traps(struct kvm_vcpu *vcpu);
|
2015-10-19 23:32:20 +08:00
|
|
|
|
2017-10-11 04:40:13 +08:00
|
|
|
void __sysreg_save_state_nvhe(struct kvm_cpu_context *ctxt);
|
|
|
|
void __sysreg_restore_state_nvhe(struct kvm_cpu_context *ctxt);
|
2017-10-11 04:19:31 +08:00
|
|
|
void sysreg_save_host_state_vhe(struct kvm_cpu_context *ctxt);
|
|
|
|
void sysreg_restore_host_state_vhe(struct kvm_cpu_context *ctxt);
|
|
|
|
void sysreg_save_guest_state_vhe(struct kvm_cpu_context *ctxt);
|
|
|
|
void sysreg_restore_guest_state_vhe(struct kvm_cpu_context *ctxt);
|
2015-10-20 02:28:29 +08:00
|
|
|
void __sysreg32_save_state(struct kvm_vcpu *vcpu);
|
|
|
|
void __sysreg32_restore_state(struct kvm_vcpu *vcpu);
|
2015-10-20 01:02:48 +08:00
|
|
|
|
2017-10-11 02:10:08 +08:00
|
|
|
void __debug_switch_to_guest(struct kvm_vcpu *vcpu);
|
|
|
|
void __debug_switch_to_host(struct kvm_vcpu *vcpu);
|
2015-10-20 04:02:46 +08:00
|
|
|
|
2015-10-26 16:34:09 +08:00
|
|
|
void __fpsimd_save_state(struct user_fpsimd_state *fp_regs);
|
|
|
|
void __fpsimd_restore_state(struct user_fpsimd_state *fp_regs);
|
|
|
|
|
2017-08-04 19:47:18 +08:00
|
|
|
void activate_traps_vhe_load(struct kvm_vcpu *vcpu);
|
|
|
|
void deactivate_traps_vhe_put(void);
|
|
|
|
|
2015-10-22 15:32:18 +08:00
|
|
|
u64 __guest_enter(struct kvm_vcpu *vcpu, struct kvm_cpu_context *host_ctxt);
|
2015-10-25 23:21:52 +08:00
|
|
|
void __noreturn __hyp_do_panic(unsigned long, ...);
|
2015-10-22 15:32:18 +08:00
|
|
|
|
2018-09-27 00:32:39 +08:00
|
|
|
/*
|
|
|
|
* Must be called from hyp code running at EL2 with an updated VTTBR
|
|
|
|
* and interrupts disabled.
|
|
|
|
*/
|
|
|
|
static __always_inline void __hyp_text __load_guest_stage2(struct kvm *kvm)
|
|
|
|
{
|
2018-09-27 00:32:43 +08:00
|
|
|
write_sysreg(kvm->arch.vtcr, vtcr_el2);
|
2018-12-11 22:26:31 +08:00
|
|
|
write_sysreg(kvm_get_vttbr(kvm), vttbr_el2);
|
2018-12-07 01:31:24 +08:00
|
|
|
|
|
|
|
/*
|
2019-12-16 19:56:31 +08:00
|
|
|
* ARM errata 1165522 and 1530923 require the actual execution of the
|
|
|
|
* above before we can switch to the EL1/EL0 translation regime used by
|
2018-12-07 01:31:24 +08:00
|
|
|
* the guest.
|
|
|
|
*/
|
2019-12-16 19:56:29 +08:00
|
|
|
asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT_VHE));
|
2018-09-27 00:32:39 +08:00
|
|
|
}
|
|
|
|
|
2015-10-21 17:09:49 +08:00
|
|
|
#endif /* __ARM64_KVM_HYP_H__ */
|
|
|
|
|