[PATCH v3 1/1] kvm: arm64: Add SVE support for nVHE.
CPUs that support SVE are architecturally required to support the Virtualization Host Extensions (VHE), so far the kernel supported SVE alongside KVM with VHE enabled. In same cases it is desired to run nVHE config even when VHE is available. This patch add support for SVE for nVHE configuration too. Tested on FVP with a Linux guest VM that run with a different VL than the host system. Signed-off-by: Daniel Kiss --- arch/arm64/Kconfig | 7 - arch/arm64/include/asm/el2_setup.h | 2 +- arch/arm64/include/asm/fpsimd.h | 6 arch/arm64/include/asm/fpsimdmacros.h | 24 ++-- arch/arm64/include/asm/kvm_arm.h| 6 arch/arm64/include/asm/kvm_host.h | 17 +++ arch/arm64/kernel/entry-fpsimd.S| 5 arch/arm64/kvm/arm.c| 5 arch/arm64/kvm/fpsimd.c | 38 - arch/arm64/kvm/hyp/fpsimd.S | 15 ++ arch/arm64/kvm/hyp/include/hyp/switch.h | 34 +++--- arch/arm64/kvm/hyp/nvhe/switch.c| 24 arch/arm64/kvm/reset.c | 4 --- 13 files changed, 127 insertions(+), 60 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index f39568b28ec1..049428f1bf27 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1676,7 +1676,6 @@ endmenu config ARM64_SVE bool "ARM Scalable Vector Extension support" default y - depends on !KVM || ARM64_VHE help The Scalable Vector Extension (SVE) is an extension to the AArch64 execution state which complements and extends the SIMD functionality @@ -1705,12 +1704,6 @@ config ARM64_SVE booting the kernel. If unsure and you are not observing these symptoms, you should assume that it is safe to say Y. - CPUs that support SVE are architecturally required to support the - Virtualization Host Extensions (VHE), so the kernel makes no - provision for supporting SVE alongside KVM without VHE enabled. - Thus, you will need to enable CONFIG_ARM64_VHE if you want to support - KVM in the same kernel image. - config ARM64_MODULE_PLTS bool "Use PLTs to allow module memory to spill over into vmalloc area" depends on MODULES diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h index a7f5a1bbc8ac..0207393e67c3 100644 --- a/arch/arm64/include/asm/el2_setup.h +++ b/arch/arm64/include/asm/el2_setup.h @@ -133,7 +133,7 @@ bic x0, x0, #CPTR_EL2_TZ// Also disable SVE traps msr cptr_el2, x0// Disable copro. traps to EL2 isb - mov x1, #ZCR_ELx_LEN_MASK // SVE: Enable full vector + mov x1, #ZCR_EL2_LEN_HOST // SVE: Enable full vector msr_s SYS_ZCR_EL2, x1 // length for EL1. 1: .endm diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h index bec5f14b622a..526d69f3eeb3 100644 --- a/arch/arm64/include/asm/fpsimd.h +++ b/arch/arm64/include/asm/fpsimd.h @@ -69,6 +69,12 @@ static inline void *sve_pffr(struct thread_struct *thread) extern void sve_save_state(void *state, u32 *pfpsr); extern void sve_load_state(void const *state, u32 const *pfpsr, unsigned long vq_minus_1); +/* + * sve_load_state_nvhe function for the hyp code where the SVE registers are + * handled from the EL2, vector length is governed by ZCR_EL2. + */ +extern void sve_load_state_nvhe(void const *state, u32 const *pfpsr, + unsigned long vq_minus_1); extern void sve_flush_live(void); extern void sve_load_from_fpsimd_state(struct user_fpsimd_state const *state, unsigned long vq_minus_1); diff --git a/arch/arm64/include/asm/fpsimdmacros.h b/arch/arm64/include/asm/fpsimdmacros.h index af43367534c7..d309c6071bce 100644 --- a/arch/arm64/include/asm/fpsimdmacros.h +++ b/arch/arm64/include/asm/fpsimdmacros.h @@ -205,6 +205,17 @@ 921: .endm +/* Update ZCR_EL2.LEN with the new VQ */ +.macro sve_load_vq_nvhe xvqminus1, xtmp, xtmp2 + mrs_s \xtmp, SYS_ZCR_EL2 + bic \xtmp2, \xtmp, ZCR_ELx_LEN_MASK + orr \xtmp2, \xtmp2, \xvqminus1 + cmp \xtmp2, \xtmp + b.eq922f + msr_s SYS_ZCR_EL2, \xtmp2 //self-synchronising +922: +.endm + /* Preserve the first 128-bits of Znz and zero the rest. */ .macro _sve_flush_z nz _sve_check_zreg \nz @@ -230,8 +241,7 @@ str w\nxtmp, [\xpfpsr, #4] .endm -.macro sve_load nxbase, xpfpsr, xvqminus1, nxtmp, xtmp2 - sve_load_vq \xvqminus1, x\nxtmp, \xtmp2 +.macro _sve_load nxbase, xpfpsr, nxtmp _for n, 0, 31,_sve_ldr_v \n, \nxbase, \n - 34
[PATCH v3 0/1] kvm: arm64: Add SVE support for nVHE.
Addressing review comments from the previous version[1]. The discussed optimisation will be a sparate patch later. [1] https://www.spinics.net/lists/arm-kernel/msg874768.html Changes from v2: * Comments are addressed. * rebased to v5.11 Changes from v1: * Vector length handling is changed. Daniel Kiss (1): kvm: arm64: Add SVE support for nVHE. arch/arm64/Kconfig | 7 - arch/arm64/include/asm/el2_setup.h | 2 +- arch/arm64/include/asm/fpsimd.h | 6 arch/arm64/include/asm/fpsimdmacros.h | 24 ++-- arch/arm64/include/asm/kvm_arm.h| 6 arch/arm64/include/asm/kvm_host.h | 17 +++ arch/arm64/kernel/entry-fpsimd.S| 5 arch/arm64/kvm/arm.c| 5 arch/arm64/kvm/fpsimd.c | 38 - arch/arm64/kvm/hyp/fpsimd.S | 15 ++ arch/arm64/kvm/hyp/include/hyp/switch.h | 34 +++--- arch/arm64/kvm/hyp/nvhe/switch.c| 24 arch/arm64/kvm/reset.c | 4 --- 13 files changed, 127 insertions(+), 60 deletions(-) -- 2.25.1 ___ kvmarm mailing list kvmarm@lists.cs.columbia.edu https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCHv2] kvm: arm64: Add SVE support for nVHE.
> On 4 Feb 2021, at 18:36, Dave Martin wrote: > > On Tue, Feb 02, 2021 at 07:52:54PM +0100, Daniel Kiss wrote: >> CPUs that support SVE are architecturally required to support the >> Virtualization Host Extensions (VHE), so far the kernel supported >> SVE alongside KVM with VHE enabled. In same cases it is desired to >> run nVHE config even when VHE is available. >> This patch add support for SVE for nVHE configuration too. >> >> Tested on FVP with a Linux guest VM that run with a different VL than >> the host system. >> >> Signed-off-by: Daniel Kiss >> --- >> arch/arm64/Kconfig | 7 - >> arch/arm64/include/asm/fpsimd.h | 6 >> arch/arm64/include/asm/fpsimdmacros.h | 24 +-- >> arch/arm64/include/asm/kvm_host.h | 17 +++ >> arch/arm64/kernel/entry-fpsimd.S| 5 >> arch/arm64/kvm/arm.c| 5 >> arch/arm64/kvm/fpsimd.c | 39 - >> arch/arm64/kvm/hyp/fpsimd.S | 15 ++ >> arch/arm64/kvm/hyp/include/hyp/switch.h | 34 +++-- >> arch/arm64/kvm/hyp/nvhe/switch.c| 29 +- >> arch/arm64/kvm/reset.c | 6 +--- >> 11 files changed, 126 insertions(+), 61 deletions(-) >> >> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig >> index f39568b28ec1..049428f1bf27 100644 >> --- a/arch/arm64/Kconfig >> +++ b/arch/arm64/Kconfig >> @@ -1676,7 +1676,6 @@ endmenu >> config ARM64_SVE >> bool "ARM Scalable Vector Extension support" >> default y >> -depends on !KVM || ARM64_VHE >> help >>The Scalable Vector Extension (SVE) is an extension to the AArch64 >>execution state which complements and extends the SIMD functionality >> @@ -1705,12 +1704,6 @@ config ARM64_SVE >>booting the kernel. If unsure and you are not observing these >>symptoms, you should assume that it is safe to say Y. >> >> - CPUs that support SVE are architecturally required to support the >> - Virtualization Host Extensions (VHE), so the kernel makes no >> - provision for supporting SVE alongside KVM without VHE enabled. >> - Thus, you will need to enable CONFIG_ARM64_VHE if you want to support >> - KVM in the same kernel image. >> - >> config ARM64_MODULE_PLTS >> bool "Use PLTs to allow module memory to spill over into vmalloc area" >> depends on MODULES >> diff --git a/arch/arm64/include/asm/fpsimd.h >> b/arch/arm64/include/asm/fpsimd.h >> index bec5f14b622a..526d69f3eeb3 100644 >> --- a/arch/arm64/include/asm/fpsimd.h >> +++ b/arch/arm64/include/asm/fpsimd.h >> @@ -69,6 +69,12 @@ static inline void *sve_pffr(struct thread_struct *thread) >> extern void sve_save_state(void *state, u32 *pfpsr); >> extern void sve_load_state(void const *state, u32 const *pfpsr, >> unsigned long vq_minus_1); >> +/* >> + * sve_load_state_nvhe function for the hyp code where the SVE registers are >> + * handled from the EL2, vector length is governed by ZCR_EL2. >> + */ >> +extern void sve_load_state_nvhe(void const *state, u32 const *pfpsr, >> + unsigned long vq_minus_1); >> extern void sve_flush_live(void); >> extern void sve_load_from_fpsimd_state(struct user_fpsimd_state const *state, >> unsigned long vq_minus_1); >> diff --git a/arch/arm64/include/asm/fpsimdmacros.h >> b/arch/arm64/include/asm/fpsimdmacros.h >> index af43367534c7..d309c6071bce 100644 >> --- a/arch/arm64/include/asm/fpsimdmacros.h >> +++ b/arch/arm64/include/asm/fpsimdmacros.h >> @@ -205,6 +205,17 @@ >> 921: >> .endm >> >> +/* Update ZCR_EL2.LEN with the new VQ */ >> +.macro sve_load_vq_nvhe xvqminus1, xtmp, xtmp2 >> +mrs_s \xtmp, SYS_ZCR_EL2 >> +bic \xtmp2, \xtmp, ZCR_ELx_LEN_MASK >> +orr \xtmp2, \xtmp2, \xvqminus1 >> +cmp \xtmp2, \xtmp >> +b.eq922f >> +msr_s SYS_ZCR_EL2, \xtmp2 //self-synchronising >> +922: >> +.endm >> + > > This looks a little better, but can we just give sve_load_vq an extra > argument, say > > .macro sve_load_vq ... , el=EL1 Sounds good, will do. > > [...] > >> +.macro sve_load_nvhe nxbase, xpfpsr, xvqminus1, nxtmp, xtmp2 >> +sve_load_vq_nvhe\xvqminu
Re: [PATCH] kvm: arm64: Add SVE support for nVHE.
Thanks for the comments, I’m going to send v2 soon. Thanks Daniel > On 26 Jan 2021, at 16:49, Dave Martin wrote: > > On Fri, Jan 22, 2021 at 06:21:21PM +, Marc Zyngier wrote: >> Daniel, >> >> Please consider cc'ing the maintainer (me) as well as the KVM/arm64 >> reviewers (Julien, James, Suzuki) and the kvmarm list (all now Cc'd). >> >> On 2021-01-22 01:07, Daniel Kiss wrote: >>> CPUs that support SVE are architecturally required to support the >>> Virtualization Host Extensions (VHE), so far the kernel supported >>> SVE alongside KVM with VHE enabled. In same cases it is desired to >>> run nVHE config even when VHE is available. >>> This patch add support for SVE for nVHE configuration too. >>> >>> In case of nVHE the system registers behave a bit differently. >>> ZCR_EL2 defines the maximum vector length that could be set in ZCR_EL1 >>> effectively. To limit the vector length for the guest the ZCR_EL2 need >>> to be set accordingly therefore it become part of the context. >> >> Not really. It's just part of the *hypervisor* state for this guest, >> and not part of the guest state. Not different from HCR_EL2, for example. > > Also, ZCR_EL2 doesn't affect what can be written in ZCR_EL1, so this > might be reworded to say that it just limits the effective vector length > available to the guest. Okay, found a way to switch the ZCR_EL2 without adding to the context. >>> The sve_state will be loaded in EL2 so it need to be mapped and during >>> the load ZCR_EL2 will control the vector length. >>> Trap control is similar to the VHE case except the bit values are the >>> opposite. ZCR_EL1 access trapping with VHE is ZEN value 0 but in case of >>> nVHE the TZ need to be set 1 to trigger the exception. Trap control need >>> to be respected during the context switch even in EL2. >> >> Isn't that exactly the same as FPSIMD accesses? > > (Yes, this isn't really new. It might be best to let the code speak for > itself on that point, rather than trying to explain it in the commit > message.) > >> >>> >>> Tested on FVP with a Linux guest VM that run with a different VL than >>> the host system. >>> >>> This patch requires sve_set_vq from >>> - arm64/sve: Rework SVE trap access to minimise memory access >> >> Care to add a pointer to this patch? This also shouldn't be part >> of the commit message. When you repost it, please include the >> other patch as a series unless it has already been merged by then. Thanks, I will do like this next time. By the new changes seems it is not even needed. >>> >>> Signed-off-by: Daniel Kiss >>> --- >>> arch/arm64/Kconfig | 7 >>> arch/arm64/include/asm/fpsimd.h| 4 ++ >>> arch/arm64/include/asm/fpsimdmacros.h | 38 + >>> arch/arm64/include/asm/kvm_host.h | 19 +++-- >>> arch/arm64/kernel/fpsimd.c | 11 + >>> arch/arm64/kvm/arm.c | 5 --- >>> arch/arm64/kvm/fpsimd.c| 22 +++--- >>> arch/arm64/kvm/hyp/fpsimd.S| 15 +++ >>> arch/arm64/kvm/hyp/include/hyp/switch.h| 48 -- >>> arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 26 >>> arch/arm64/kvm/hyp/nvhe/switch.c | 6 ++- >>> arch/arm64/kvm/reset.c | 8 ++-- >>> 12 files changed, 153 insertions(+), 56 deletions(-) >>> >>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig >>> index a6b5b7ef40ae..f17ab095e99f 100644 >>> --- a/arch/arm64/Kconfig >>> +++ b/arch/arm64/Kconfig >>> @@ -1692,7 +1692,6 @@ endmenu >>> config ARM64_SVE >>> bool "ARM Scalable Vector Extension support" >>> default y >>> - depends on !KVM || ARM64_VHE >>> help >>> The Scalable Vector Extension (SVE) is an extension to the AArch64 >>> execution state which complements and extends the SIMD functionality >>> @@ -1721,12 +1720,6 @@ config ARM64_SVE >>> booting the kernel. If unsure and you are not observing these >>> symptoms, you should assume that it is safe to say Y. >>> >>> - CPUs that support SVE are architecturally required to support the >>> - Virtualization Host Extensions (VHE), so the kernel makes no >>> - provision for supporting SVE alongside KVM without VHE enabled. >>> - Th
[PATCHv2] kvm: arm64: Add SVE support for nVHE.
CPUs that support SVE are architecturally required to support the Virtualization Host Extensions (VHE), so far the kernel supported SVE alongside KVM with VHE enabled. In same cases it is desired to run nVHE config even when VHE is available. This patch add support for SVE for nVHE configuration too. Tested on FVP with a Linux guest VM that run with a different VL than the host system. Signed-off-by: Daniel Kiss --- arch/arm64/Kconfig | 7 - arch/arm64/include/asm/fpsimd.h | 6 arch/arm64/include/asm/fpsimdmacros.h | 24 +-- arch/arm64/include/asm/kvm_host.h | 17 +++ arch/arm64/kernel/entry-fpsimd.S| 5 arch/arm64/kvm/arm.c| 5 arch/arm64/kvm/fpsimd.c | 39 - arch/arm64/kvm/hyp/fpsimd.S | 15 ++ arch/arm64/kvm/hyp/include/hyp/switch.h | 34 +++-- arch/arm64/kvm/hyp/nvhe/switch.c| 29 +- arch/arm64/kvm/reset.c | 6 +--- 11 files changed, 126 insertions(+), 61 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index f39568b28ec1..049428f1bf27 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1676,7 +1676,6 @@ endmenu config ARM64_SVE bool "ARM Scalable Vector Extension support" default y - depends on !KVM || ARM64_VHE help The Scalable Vector Extension (SVE) is an extension to the AArch64 execution state which complements and extends the SIMD functionality @@ -1705,12 +1704,6 @@ config ARM64_SVE booting the kernel. If unsure and you are not observing these symptoms, you should assume that it is safe to say Y. - CPUs that support SVE are architecturally required to support the - Virtualization Host Extensions (VHE), so the kernel makes no - provision for supporting SVE alongside KVM without VHE enabled. - Thus, you will need to enable CONFIG_ARM64_VHE if you want to support - KVM in the same kernel image. - config ARM64_MODULE_PLTS bool "Use PLTs to allow module memory to spill over into vmalloc area" depends on MODULES diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h index bec5f14b622a..526d69f3eeb3 100644 --- a/arch/arm64/include/asm/fpsimd.h +++ b/arch/arm64/include/asm/fpsimd.h @@ -69,6 +69,12 @@ static inline void *sve_pffr(struct thread_struct *thread) extern void sve_save_state(void *state, u32 *pfpsr); extern void sve_load_state(void const *state, u32 const *pfpsr, unsigned long vq_minus_1); +/* + * sve_load_state_nvhe function for the hyp code where the SVE registers are + * handled from the EL2, vector length is governed by ZCR_EL2. + */ +extern void sve_load_state_nvhe(void const *state, u32 const *pfpsr, + unsigned long vq_minus_1); extern void sve_flush_live(void); extern void sve_load_from_fpsimd_state(struct user_fpsimd_state const *state, unsigned long vq_minus_1); diff --git a/arch/arm64/include/asm/fpsimdmacros.h b/arch/arm64/include/asm/fpsimdmacros.h index af43367534c7..d309c6071bce 100644 --- a/arch/arm64/include/asm/fpsimdmacros.h +++ b/arch/arm64/include/asm/fpsimdmacros.h @@ -205,6 +205,17 @@ 921: .endm +/* Update ZCR_EL2.LEN with the new VQ */ +.macro sve_load_vq_nvhe xvqminus1, xtmp, xtmp2 + mrs_s \xtmp, SYS_ZCR_EL2 + bic \xtmp2, \xtmp, ZCR_ELx_LEN_MASK + orr \xtmp2, \xtmp2, \xvqminus1 + cmp \xtmp2, \xtmp + b.eq922f + msr_s SYS_ZCR_EL2, \xtmp2 //self-synchronising +922: +.endm + /* Preserve the first 128-bits of Znz and zero the rest. */ .macro _sve_flush_z nz _sve_check_zreg \nz @@ -230,8 +241,7 @@ str w\nxtmp, [\xpfpsr, #4] .endm -.macro sve_load nxbase, xpfpsr, xvqminus1, nxtmp, xtmp2 - sve_load_vq \xvqminus1, x\nxtmp, \xtmp2 +.macro _sve_load nxbase, xpfpsr, nxtmp _for n, 0, 31,_sve_ldr_v \n, \nxbase, \n - 34 _sve_ldr_p 0, \nxbase _sve_wrffr 0 @@ -242,3 +252,13 @@ ldr w\nxtmp, [\xpfpsr, #4] msr fpcr, x\nxtmp .endm + +.macro sve_load nxbase, xpfpsr, xvqminus1, nxtmp, xtmp2 + sve_load_vq \xvqminus1, x\nxtmp, \xtmp2 + _sve_load \nxbase, \xpfpsr, \nxtmp +.endm + +.macro sve_load_nvhe nxbase, xpfpsr, xvqminus1, nxtmp, xtmp2 + sve_load_vq_nvhe\xvqminus1, x\nxtmp, \xtmp2 + _sve_load\nxbase, \xpfpsr, \nxtmp +.endm diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 8fcfab0c2567..11a058c81c1d 100644 --- a/arch/arm64/in