Message ID | 20230609162200.2024064-5-maz@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM: arm64: Allow using VHE in the nVHE hypervisor | expand |
On Fri, Jun 09, 2023 at 05:21:47PM +0100, Marc Zyngier wrote: > Expose a capability keying the hVHE feature as well as a new > predicate testing it. Nothing is so far using it, and nothing > is enabling it yet. > > Signed-off-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Hi Marc, Should we have a document about the hVHE? Because it's a sw feature, there is no spec about it. And later people may need to read the code itself to understand what is hVHE. On 6/10/23 00:21, Marc Zyngier wrote: > Expose a capability keying the hVHE feature as well as a new > predicate testing it. Nothing is so far using it, and nothing > is enabling it yet. > > Signed-off-by: Marc Zyngier <maz@kernel.org> Besides that, the code itself LGTM. Reviewed-by: Shaoqin Huang <shahuang@redhat.com> > --- > arch/arm64/include/asm/cpufeature.h | 1 + > arch/arm64/include/asm/virt.h | 8 ++++++++ > arch/arm64/kernel/cpufeature.c | 19 +++++++++++++++++++ > arch/arm64/tools/cpucaps | 1 + > 4 files changed, 29 insertions(+) > > diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h > index bc1009890180..3d4b547ae312 100644 > --- a/arch/arm64/include/asm/cpufeature.h > +++ b/arch/arm64/include/asm/cpufeature.h > @@ -16,6 +16,7 @@ > #define cpu_feature(x) KERNEL_HWCAP_ ## x > > #define ARM64_SW_FEATURE_OVERRIDE_NOKASLR 0 > +#define ARM64_SW_FEATURE_OVERRIDE_HVHE 4 > > #ifndef __ASSEMBLY__ > > diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h > index 21e94068804d..5227db7640c8 100644 > --- a/arch/arm64/include/asm/virt.h > +++ b/arch/arm64/include/asm/virt.h > @@ -142,6 +142,14 @@ static __always_inline bool is_protected_kvm_enabled(void) > return cpus_have_final_cap(ARM64_KVM_PROTECTED_MODE); > } > > +static __always_inline bool has_hvhe(void) > +{ > + if (is_vhe_hyp_code()) > + return false; > + > + return cpus_have_final_cap(ARM64_KVM_HVHE); > +} > + > static inline bool is_hyp_nvhe(void) > { > return is_hyp_mode_available() && !is_kernel_in_hyp_mode(); > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c > index 2d2b7bb5fa0c..c743b1a5ae31 100644 > --- a/arch/arm64/kernel/cpufeature.c > +++ b/arch/arm64/kernel/cpufeature.c > @@ -1998,6 +1998,19 @@ static bool has_nested_virt_support(const struct arm64_cpu_capabilities *cap, > return true; > } > > +static bool hvhe_possible(const struct arm64_cpu_capabilities *entry, > + int __unused) > +{ > + u64 val; > + > + val = read_sysreg(id_aa64mmfr1_el1); > + if (!cpuid_feature_extract_unsigned_field(val, ID_AA64MMFR1_EL1_VH_SHIFT)) > + return false; > + > + val = arm64_sw_feature_override.val & arm64_sw_feature_override.mask; > + return cpuid_feature_extract_unsigned_field(val, ARM64_SW_FEATURE_OVERRIDE_HVHE); > +} > + > #ifdef CONFIG_ARM64_PAN > static void cpu_enable_pan(const struct arm64_cpu_capabilities *__unused) > { > @@ -2643,6 +2656,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = { > .cpu_enable = cpu_enable_dit, > ARM64_CPUID_FIELDS(ID_AA64PFR0_EL1, DIT, IMP) > }, > + { > + .desc = "VHE for hypervisor only", > + .capability = ARM64_KVM_HVHE, > + .type = ARM64_CPUCAP_SYSTEM_FEATURE, > + .matches = hvhe_possible, > + }, > {}, > }; > > diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps > index 40ba95472594..3c23a55d7c2f 100644 > --- a/arch/arm64/tools/cpucaps > +++ b/arch/arm64/tools/cpucaps > @@ -47,6 +47,7 @@ HAS_TLB_RANGE > HAS_VIRT_HOST_EXTN > HAS_WFXT > HW_DBM > +KVM_HVHE > KVM_PROTECTED_MODE > MISMATCHED_CACHE_TYPE > MTE
On Wed, 14 Jun 2023 08:35:13 +0100, Shaoqin Huang <shahuang@redhat.com> wrote: > > Hi Marc, > > Should we have a document about the hVHE? Because it's a sw feature, > there is no spec about it. And later people may need to read the code > itself to understand what is hVHE. I'm planning to eventually do that once the hVHE code actually does something useful. So far, it doesn't really do much. But what I really want is to *hide* this low level option, and have it driven by something like "kvm-arm.mode=hvhe,protected". It is just that writing a parser is hard at the point where this is evaluated (we don't have much of the kernel running). > > On 6/10/23 00:21, Marc Zyngier wrote: > > Expose a capability keying the hVHE feature as well as a new > > predicate testing it. Nothing is so far using it, and nothing > > is enabling it yet. > > > > Signed-off-by: Marc Zyngier <maz@kernel.org> > Besides that, the code itself LGTM. > > Reviewed-by: Shaoqin Huang <shahuang@redhat.com> Thanks, M.
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index bc1009890180..3d4b547ae312 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -16,6 +16,7 @@ #define cpu_feature(x) KERNEL_HWCAP_ ## x #define ARM64_SW_FEATURE_OVERRIDE_NOKASLR 0 +#define ARM64_SW_FEATURE_OVERRIDE_HVHE 4 #ifndef __ASSEMBLY__ diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h index 21e94068804d..5227db7640c8 100644 --- a/arch/arm64/include/asm/virt.h +++ b/arch/arm64/include/asm/virt.h @@ -142,6 +142,14 @@ static __always_inline bool is_protected_kvm_enabled(void) return cpus_have_final_cap(ARM64_KVM_PROTECTED_MODE); } +static __always_inline bool has_hvhe(void) +{ + if (is_vhe_hyp_code()) + return false; + + return cpus_have_final_cap(ARM64_KVM_HVHE); +} + static inline bool is_hyp_nvhe(void) { return is_hyp_mode_available() && !is_kernel_in_hyp_mode(); diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 2d2b7bb5fa0c..c743b1a5ae31 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1998,6 +1998,19 @@ static bool has_nested_virt_support(const struct arm64_cpu_capabilities *cap, return true; } +static bool hvhe_possible(const struct arm64_cpu_capabilities *entry, + int __unused) +{ + u64 val; + + val = read_sysreg(id_aa64mmfr1_el1); + if (!cpuid_feature_extract_unsigned_field(val, ID_AA64MMFR1_EL1_VH_SHIFT)) + return false; + + val = arm64_sw_feature_override.val & arm64_sw_feature_override.mask; + return cpuid_feature_extract_unsigned_field(val, ARM64_SW_FEATURE_OVERRIDE_HVHE); +} + #ifdef CONFIG_ARM64_PAN static void cpu_enable_pan(const struct arm64_cpu_capabilities *__unused) { @@ -2643,6 +2656,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .cpu_enable = cpu_enable_dit, ARM64_CPUID_FIELDS(ID_AA64PFR0_EL1, DIT, IMP) }, + { + .desc = "VHE for hypervisor only", + .capability = ARM64_KVM_HVHE, + .type = ARM64_CPUCAP_SYSTEM_FEATURE, + .matches = hvhe_possible, + }, {}, }; diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps index 40ba95472594..3c23a55d7c2f 100644 --- a/arch/arm64/tools/cpucaps +++ b/arch/arm64/tools/cpucaps @@ -47,6 +47,7 @@ HAS_TLB_RANGE HAS_VIRT_HOST_EXTN HAS_WFXT HW_DBM +KVM_HVHE KVM_PROTECTED_MODE MISMATCHED_CACHE_TYPE MTE
Expose a capability keying the hVHE feature as well as a new predicate testing it. Nothing is so far using it, and nothing is enabling it yet. Signed-off-by: Marc Zyngier <maz@kernel.org> --- arch/arm64/include/asm/cpufeature.h | 1 + arch/arm64/include/asm/virt.h | 8 ++++++++ arch/arm64/kernel/cpufeature.c | 19 +++++++++++++++++++ arch/arm64/tools/cpucaps | 1 + 4 files changed, 29 insertions(+)