Skip to content

Commit 1f364c8

Browse files
author
Marc Zyngier
committed
arm64: VHE: Add support for running Linux in EL2 mode
With ARMv8.1 VHE, the architecture is able to (almost) transparently run the kernel at EL2, despite being written for EL1. This patch takes care of the "almost" part, mostly preventing the kernel from dropping from EL2 to EL1, and setting up the HYP configuration. Reviewed-by: Christoffer Dall <[email protected]> Acked-by: Catalin Marinas <[email protected]> Signed-off-by: Marc Zyngier <[email protected]>
1 parent ae7e27f commit 1f364c8

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

arch/arm64/Kconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,19 @@ config ARM64_LSE_ATOMICS
750750
not support these instructions and requires the kernel to be
751751
built with binutils >= 2.25.
752752

753+
config ARM64_VHE
754+
bool "Enable support for Virtualization Host Extensions (VHE)"
755+
default y
756+
help
757+
Virtualization Host Extensions (VHE) allow the kernel to run
758+
directly at EL2 (instead of EL1) on processors that support
759+
it. This leads to better performance for KVM, as they reduce
760+
the cost of the world switch.
761+
762+
Selecting this option allows the VHE feature to be detected
763+
at runtime, and does not affect processors that do not
764+
implement this feature.
765+
753766
endmenu
754767

755768
endmenu

arch/arm64/kernel/head.S

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <asm/cache.h>
3131
#include <asm/cputype.h>
3232
#include <asm/kernel-pgtable.h>
33+
#include <asm/kvm_arm.h>
3334
#include <asm/memory.h>
3435
#include <asm/pgtable-hwdef.h>
3536
#include <asm/pgtable.h>
@@ -464,9 +465,27 @@ CPU_LE( bic x0, x0, #(3 << 24) ) // Clear the EE and E0E bits for EL1
464465
isb
465466
ret
466467

468+
2:
469+
#ifdef CONFIG_ARM64_VHE
470+
/*
471+
* Check for VHE being present. For the rest of the EL2 setup,
472+
* x2 being non-zero indicates that we do have VHE, and that the
473+
* kernel is intended to run at EL2.
474+
*/
475+
mrs x2, id_aa64mmfr1_el1
476+
ubfx x2, x2, #8, #4
477+
#else
478+
mov x2, xzr
479+
#endif
480+
467481
/* Hyp configuration. */
468-
2: mov x0, #(1 << 31) // 64-bit EL1
482+
mov x0, #HCR_RW // 64-bit EL1
483+
cbz x2, set_hcr
484+
orr x0, x0, #HCR_TGE // Enable Host Extensions
485+
orr x0, x0, #HCR_E2H
486+
set_hcr:
469487
msr hcr_el2, x0
488+
isb
470489

471490
/* Generic timers. */
472491
mrs x0, cnthctl_el2
@@ -526,6 +545,13 @@ CPU_LE( movk x0, #0x30d0, lsl #16 ) // Clear EE and E0E on LE systems
526545
/* Stage-2 translation */
527546
msr vttbr_el2, xzr
528547

548+
cbz x2, install_el2_stub
549+
550+
mov w20, #BOOT_CPU_MODE_EL2 // This CPU booted in EL2
551+
isb
552+
ret
553+
554+
install_el2_stub:
529555
/* Hypervisor stub */
530556
adrp x0, __hyp_stub_vectors
531557
add x0, x0, #:lo12:__hyp_stub_vectors

0 commit comments

Comments
 (0)