Loading Documentation/admin-guide/kernel-parameters.txt +1 −2 Original line number Diff line number Diff line Loading @@ -2279,8 +2279,7 @@ state is kept private from the host. Not valid if the kernel is running in EL2. Defaults to VHE/nVHE based on hardware support and the value of CONFIG_ARM64_VHE. Defaults to VHE/nVHE based on hardware support. kvm-arm.vgic_v3_group0_trap= [KVM,ARM] Trap guest accesses to GICv3 group-0 Loading arch/arm64/Kconfig +0 −13 Original line number Diff line number Diff line Loading @@ -1416,19 +1416,6 @@ config ARM64_USE_LSE_ATOMICS built with binutils >= 2.25 in order for the new instructions to be used. config ARM64_VHE bool "Enable support for Virtualization Host Extensions (VHE)" default y help Virtualization Host Extensions (VHE) allow the kernel to run directly at EL2 (instead of EL1) on processors that support it. This leads to better performance for KVM, as they reduce the cost of the world switch. Selecting this option allows the VHE feature to be detected at runtime, and does not affect processors that do not implement this feature. endmenu menu "ARMv8.2 architectural features" Loading arch/arm64/include/asm/cpufeature.h +17 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,23 @@ struct arm64_ftr_bits { s64 safe_val; /* safe value for FTR_EXACT features */ }; /* * Describe the early feature override to the core override code: * * @val Values that are to be merged into the final * sanitised value of the register. Only the bitfields * set to 1 in @mask are valid * @mask Mask of the features that are overridden by @val * * A @mask field set to full-1 indicates that the corresponding field * in @val is a valid override. * * A @mask field set to full-0 with the corresponding @val field set * to full-0 denotes that this field has no override * * A @mask field set to full-0 with the corresponding @val field set * to full-1 denotes thath this field has an invalid override. */ struct arm64_ftr_override { u64 val; u64 mask; Loading arch/arm64/kernel/cpufeature.c +6 −4 Original line number Diff line number Diff line Loading @@ -808,6 +808,12 @@ static void __init init_cpu_ftr_reg(u32 sys_reg, u64 new) reg->name, ftrp->shift + ftrp->width - 1, ftrp->shift, str, tmp); } else if ((ftr_mask & reg->override->val) == ftr_mask) { reg->override->val &= ~ftr_mask; pr_warn("%s[%d:%d]: impossible override, ignored\n", reg->name, ftrp->shift + ftrp->width - 1, ftrp->shift); } val = arm64_ftr_set_value(ftrp, val, ftr_new); Loading Loading @@ -1616,7 +1622,6 @@ int get_cpu_with_amu_feat(void) } #endif #ifdef CONFIG_ARM64_VHE static bool runs_at_el2(const struct arm64_cpu_capabilities *entry, int __unused) { return is_kernel_in_hyp_mode(); Loading @@ -1635,7 +1640,6 @@ static void cpu_copy_el2regs(const struct arm64_cpu_capabilities *__unused) if (!alternative_is_applied(ARM64_HAS_VIRT_HOST_EXTN)) write_sysreg(read_sysreg(tpidr_el1), tpidr_el2); } #endif static void cpu_has_fwb(const struct arm64_cpu_capabilities *__unused) { Loading Loading @@ -1838,7 +1842,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE, .matches = has_no_hw_prefetch, }, #ifdef CONFIG_ARM64_VHE { .desc = "Virtualization Host Extensions", .capability = ARM64_HAS_VIRT_HOST_EXTN, Loading @@ -1846,7 +1849,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .matches = runs_at_el2, .cpu_enable = cpu_copy_el2regs, }, #endif /* CONFIG_ARM64_VHE */ { .desc = "32-bit EL0 Support", .capability = ARM64_HAS_32BIT_EL0, Loading arch/arm64/kernel/head.S +36 −3 Original line number Diff line number Diff line Loading @@ -477,14 +477,13 @@ EXPORT_SYMBOL(kimage_vaddr) * booted in EL1 or EL2 respectively. */ SYM_FUNC_START(init_kernel_el) mov_q x0, INIT_SCTLR_EL1_MMU_OFF msr sctlr_el1, x0 mrs x0, CurrentEL cmp x0, #CurrentEL_EL2 b.eq init_el2 SYM_INNER_LABEL(init_el1, SYM_L_LOCAL) mov_q x0, INIT_SCTLR_EL1_MMU_OFF msr sctlr_el1, x0 isb mov_q x0, INIT_PSTATE_EL1 msr spsr_el1, x0 Loading @@ -504,9 +503,43 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL) msr vbar_el2, x0 isb /* * Fruity CPUs seem to have HCR_EL2.E2H set to RES1, * making it impossible to start in nVHE mode. Is that * compliant with the architecture? Absolutely not! */ mrs x0, hcr_el2 and x0, x0, #HCR_E2H cbz x0, 1f /* Switching to VHE requires a sane SCTLR_EL1 as a start */ mov_q x0, INIT_SCTLR_EL1_MMU_OFF msr_s SYS_SCTLR_EL12, x0 /* * Force an eret into a helper "function", and let it return * to our original caller... This makes sure that we have * initialised the basic PSTATE state. */ mov x0, #INIT_PSTATE_EL2 msr spsr_el1, x0 adr x0, __cpu_stick_to_vhe msr elr_el1, x0 eret 1: mov_q x0, INIT_SCTLR_EL1_MMU_OFF msr sctlr_el1, x0 msr elr_el2, lr mov w0, #BOOT_CPU_MODE_EL2 eret __cpu_stick_to_vhe: mov x0, #HVC_VHE_RESTART hvc #0 mov x0, #BOOT_CPU_MODE_EL2 ret SYM_FUNC_END(init_kernel_el) /* Loading Loading
Documentation/admin-guide/kernel-parameters.txt +1 −2 Original line number Diff line number Diff line Loading @@ -2279,8 +2279,7 @@ state is kept private from the host. Not valid if the kernel is running in EL2. Defaults to VHE/nVHE based on hardware support and the value of CONFIG_ARM64_VHE. Defaults to VHE/nVHE based on hardware support. kvm-arm.vgic_v3_group0_trap= [KVM,ARM] Trap guest accesses to GICv3 group-0 Loading
arch/arm64/Kconfig +0 −13 Original line number Diff line number Diff line Loading @@ -1416,19 +1416,6 @@ config ARM64_USE_LSE_ATOMICS built with binutils >= 2.25 in order for the new instructions to be used. config ARM64_VHE bool "Enable support for Virtualization Host Extensions (VHE)" default y help Virtualization Host Extensions (VHE) allow the kernel to run directly at EL2 (instead of EL1) on processors that support it. This leads to better performance for KVM, as they reduce the cost of the world switch. Selecting this option allows the VHE feature to be detected at runtime, and does not affect processors that do not implement this feature. endmenu menu "ARMv8.2 architectural features" Loading
arch/arm64/include/asm/cpufeature.h +17 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,23 @@ struct arm64_ftr_bits { s64 safe_val; /* safe value for FTR_EXACT features */ }; /* * Describe the early feature override to the core override code: * * @val Values that are to be merged into the final * sanitised value of the register. Only the bitfields * set to 1 in @mask are valid * @mask Mask of the features that are overridden by @val * * A @mask field set to full-1 indicates that the corresponding field * in @val is a valid override. * * A @mask field set to full-0 with the corresponding @val field set * to full-0 denotes that this field has no override * * A @mask field set to full-0 with the corresponding @val field set * to full-1 denotes thath this field has an invalid override. */ struct arm64_ftr_override { u64 val; u64 mask; Loading
arch/arm64/kernel/cpufeature.c +6 −4 Original line number Diff line number Diff line Loading @@ -808,6 +808,12 @@ static void __init init_cpu_ftr_reg(u32 sys_reg, u64 new) reg->name, ftrp->shift + ftrp->width - 1, ftrp->shift, str, tmp); } else if ((ftr_mask & reg->override->val) == ftr_mask) { reg->override->val &= ~ftr_mask; pr_warn("%s[%d:%d]: impossible override, ignored\n", reg->name, ftrp->shift + ftrp->width - 1, ftrp->shift); } val = arm64_ftr_set_value(ftrp, val, ftr_new); Loading Loading @@ -1616,7 +1622,6 @@ int get_cpu_with_amu_feat(void) } #endif #ifdef CONFIG_ARM64_VHE static bool runs_at_el2(const struct arm64_cpu_capabilities *entry, int __unused) { return is_kernel_in_hyp_mode(); Loading @@ -1635,7 +1640,6 @@ static void cpu_copy_el2regs(const struct arm64_cpu_capabilities *__unused) if (!alternative_is_applied(ARM64_HAS_VIRT_HOST_EXTN)) write_sysreg(read_sysreg(tpidr_el1), tpidr_el2); } #endif static void cpu_has_fwb(const struct arm64_cpu_capabilities *__unused) { Loading Loading @@ -1838,7 +1842,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE, .matches = has_no_hw_prefetch, }, #ifdef CONFIG_ARM64_VHE { .desc = "Virtualization Host Extensions", .capability = ARM64_HAS_VIRT_HOST_EXTN, Loading @@ -1846,7 +1849,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .matches = runs_at_el2, .cpu_enable = cpu_copy_el2regs, }, #endif /* CONFIG_ARM64_VHE */ { .desc = "32-bit EL0 Support", .capability = ARM64_HAS_32BIT_EL0, Loading
arch/arm64/kernel/head.S +36 −3 Original line number Diff line number Diff line Loading @@ -477,14 +477,13 @@ EXPORT_SYMBOL(kimage_vaddr) * booted in EL1 or EL2 respectively. */ SYM_FUNC_START(init_kernel_el) mov_q x0, INIT_SCTLR_EL1_MMU_OFF msr sctlr_el1, x0 mrs x0, CurrentEL cmp x0, #CurrentEL_EL2 b.eq init_el2 SYM_INNER_LABEL(init_el1, SYM_L_LOCAL) mov_q x0, INIT_SCTLR_EL1_MMU_OFF msr sctlr_el1, x0 isb mov_q x0, INIT_PSTATE_EL1 msr spsr_el1, x0 Loading @@ -504,9 +503,43 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL) msr vbar_el2, x0 isb /* * Fruity CPUs seem to have HCR_EL2.E2H set to RES1, * making it impossible to start in nVHE mode. Is that * compliant with the architecture? Absolutely not! */ mrs x0, hcr_el2 and x0, x0, #HCR_E2H cbz x0, 1f /* Switching to VHE requires a sane SCTLR_EL1 as a start */ mov_q x0, INIT_SCTLR_EL1_MMU_OFF msr_s SYS_SCTLR_EL12, x0 /* * Force an eret into a helper "function", and let it return * to our original caller... This makes sure that we have * initialised the basic PSTATE state. */ mov x0, #INIT_PSTATE_EL2 msr spsr_el1, x0 adr x0, __cpu_stick_to_vhe msr elr_el1, x0 eret 1: mov_q x0, INIT_SCTLR_EL1_MMU_OFF msr sctlr_el1, x0 msr elr_el2, lr mov w0, #BOOT_CPU_MODE_EL2 eret __cpu_stick_to_vhe: mov x0, #HVC_VHE_RESTART hvc #0 mov x0, #BOOT_CPU_MODE_EL2 ret SYM_FUNC_END(init_kernel_el) /* Loading