[PATCH v3 1/1] kvm: arm64: Add SVE support for nVHE.

2021-03-02 Thread Daniel Kiss
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.

2021-03-02 Thread Daniel Kiss
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.

2021-02-05 Thread Daniel Kiss


> 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.

2021-02-02 Thread Daniel Kiss
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.

2021-02-02 Thread Daniel Kiss
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