Skip to content

Commit 0d3b2b4

Browse files
committed
Merge branch kvm-arm64/nv-prefix into kvmarm/next
* kvm-arm64/nv-prefix: : Preamble to NV support, courtesy of Marc Zyngier. : : This brings in a set of prerequisite patches for supporting nested : virtualization in KVM/arm64. Of course, there is a long way to go until : NV is actually enabled in KVM. : : - Introduce cpucap / vCPU feature flag to pivot the NV code on : : - Add support for EL2 vCPU register state : : - Basic nested exception handling : : - Hide unsupported features from the ID registers for NV-capable VMs KVM: arm64: nv: Use reg_to_encoding() to get sysreg ID KVM: arm64: nv: Only toggle cache for virtual EL2 when SCTLR_EL2 changes KVM: arm64: nv: Filter out unsupported features from ID regs KVM: arm64: nv: Emulate EL12 register accesses from the virtual EL2 KVM: arm64: nv: Allow a sysreg to be hidden from userspace only KVM: arm64: nv: Emulate PSTATE.M for a guest hypervisor KVM: arm64: nv: Add accessors for SPSR_EL1, ELR_EL1 and VBAR_EL1 from virtual EL2 KVM: arm64: nv: Handle SMCs taken from virtual EL2 KVM: arm64: nv: Handle trapped ERET from virtual EL2 KVM: arm64: nv: Inject HVC exceptions to the virtual EL2 KVM: arm64: nv: Support virtual EL2 exceptions KVM: arm64: nv: Handle HCR_EL2.NV system register traps KVM: arm64: nv: Add nested virt VCPU primitives for vEL2 VCPU state KVM: arm64: nv: Add EL2 system registers to vcpu context KVM: arm64: nv: Allow userspace to set PSR_MODE_EL2x KVM: arm64: nv: Reset VCPU to EL2 registers if VCPU nested virt is set KVM: arm64: nv: Introduce nested virtualization VCPU feature KVM: arm64: Use the S2 MMU context to iterate over S2 table arm64: Add ARM64_HAS_NESTED_VIRT cpufeature Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
2 parents 022d3f0 + 3fb901c commit 0d3b2b4

26 files changed

Lines changed: 1042 additions & 47 deletions

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2553,9 +2553,14 @@
25532553
protected: nVHE-based mode with support for guests whose
25542554
state is kept private from the host.
25552555

2556+
nested: VHE-based mode with support for nested
2557+
virtualization. Requires at least ARMv8.3
2558+
hardware.
2559+
25562560
Defaults to VHE/nVHE based on hardware support. Setting
25572561
mode to "protected" will disable kexec and hibernation
2558-
for the host.
2562+
for the host. "nested" is experimental and should be
2563+
used with extreme caution.
25592564

25602565
kvm-arm.vgic_v3_group0_trap=
25612566
[KVM,ARM] Trap guest accesses to GICv3 group-0

arch/arm64/include/asm/esr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,10 @@
272272
(((e) & ESR_ELx_SYS64_ISS_OP2_MASK) >> \
273273
ESR_ELx_SYS64_ISS_OP2_SHIFT))
274274

275+
/* ISS field definitions for ERET/ERETAA/ERETAB trapping */
276+
#define ESR_ELx_ERET_ISS_ERET 0x2
277+
#define ESR_ELx_ERET_ISS_ERETA 0x1
278+
275279
/*
276280
* ISS field definitions for floating-point exception traps
277281
* (FP_EXC_32/FP_EXC_64).

arch/arm64/include/asm/kvm_arm.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,9 +345,26 @@
345345
ECN(SP_ALIGN), ECN(FP_EXC32), ECN(FP_EXC64), ECN(SERROR), \
346346
ECN(BREAKPT_LOW), ECN(BREAKPT_CUR), ECN(SOFTSTP_LOW), \
347347
ECN(SOFTSTP_CUR), ECN(WATCHPT_LOW), ECN(WATCHPT_CUR), \
348-
ECN(BKPT32), ECN(VECTOR32), ECN(BRK64)
348+
ECN(BKPT32), ECN(VECTOR32), ECN(BRK64), ECN(ERET)
349349

350350
#define CPACR_EL1_DEFAULT (CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN |\
351351
CPACR_EL1_ZEN_EL1EN)
352352

353+
#define kvm_mode_names \
354+
{ PSR_MODE_EL0t, "EL0t" }, \
355+
{ PSR_MODE_EL1t, "EL1t" }, \
356+
{ PSR_MODE_EL1h, "EL1h" }, \
357+
{ PSR_MODE_EL2t, "EL2t" }, \
358+
{ PSR_MODE_EL2h, "EL2h" }, \
359+
{ PSR_MODE_EL3t, "EL3t" }, \
360+
{ PSR_MODE_EL3h, "EL3h" }, \
361+
{ PSR_AA32_MODE_USR, "32-bit USR" }, \
362+
{ PSR_AA32_MODE_FIQ, "32-bit FIQ" }, \
363+
{ PSR_AA32_MODE_IRQ, "32-bit IRQ" }, \
364+
{ PSR_AA32_MODE_SVC, "32-bit SVC" }, \
365+
{ PSR_AA32_MODE_ABT, "32-bit ABT" }, \
366+
{ PSR_AA32_MODE_HYP, "32-bit HYP" }, \
367+
{ PSR_AA32_MODE_UND, "32-bit UND" }, \
368+
{ PSR_AA32_MODE_SYS, "32-bit SYS" }
369+
353370
#endif /* __ARM64_KVM_ARM_H__ */

arch/arm64/include/asm/kvm_emulate.h

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ enum exception_type {
3333
except_type_serror = 0x180,
3434
};
3535

36+
#define kvm_exception_type_names \
37+
{ except_type_sync, "SYNC" }, \
38+
{ except_type_irq, "IRQ" }, \
39+
{ except_type_fiq, "FIQ" }, \
40+
{ except_type_serror, "SERROR" }
41+
3642
bool kvm_condition_valid32(const struct kvm_vcpu *vcpu);
3743
void kvm_skip_instr32(struct kvm_vcpu *vcpu);
3844

@@ -44,6 +50,10 @@ void kvm_inject_size_fault(struct kvm_vcpu *vcpu);
4450

4551
void kvm_vcpu_wfi(struct kvm_vcpu *vcpu);
4652

53+
void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu);
54+
int kvm_inject_nested_sync(struct kvm_vcpu *vcpu, u64 esr_el2);
55+
int kvm_inject_nested_irq(struct kvm_vcpu *vcpu);
56+
4757
#if defined(__KVM_VHE_HYPERVISOR__) || defined(__KVM_NVHE_HYPERVISOR__)
4858
static __always_inline bool vcpu_el1_is_32bit(struct kvm_vcpu *vcpu)
4959
{
@@ -179,6 +189,62 @@ static __always_inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num,
179189
vcpu_gp_regs(vcpu)->regs[reg_num] = val;
180190
}
181191

192+
static inline bool vcpu_is_el2_ctxt(const struct kvm_cpu_context *ctxt)
193+
{
194+
switch (ctxt->regs.pstate & (PSR_MODE32_BIT | PSR_MODE_MASK)) {
195+
case PSR_MODE_EL2h:
196+
case PSR_MODE_EL2t:
197+
return true;
198+
default:
199+
return false;
200+
}
201+
}
202+
203+
static inline bool vcpu_is_el2(const struct kvm_vcpu *vcpu)
204+
{
205+
return vcpu_is_el2_ctxt(&vcpu->arch.ctxt);
206+
}
207+
208+
static inline bool __vcpu_el2_e2h_is_set(const struct kvm_cpu_context *ctxt)
209+
{
210+
return ctxt_sys_reg(ctxt, HCR_EL2) & HCR_E2H;
211+
}
212+
213+
static inline bool vcpu_el2_e2h_is_set(const struct kvm_vcpu *vcpu)
214+
{
215+
return __vcpu_el2_e2h_is_set(&vcpu->arch.ctxt);
216+
}
217+
218+
static inline bool __vcpu_el2_tge_is_set(const struct kvm_cpu_context *ctxt)
219+
{
220+
return ctxt_sys_reg(ctxt, HCR_EL2) & HCR_TGE;
221+
}
222+
223+
static inline bool vcpu_el2_tge_is_set(const struct kvm_vcpu *vcpu)
224+
{
225+
return __vcpu_el2_tge_is_set(&vcpu->arch.ctxt);
226+
}
227+
228+
static inline bool __is_hyp_ctxt(const struct kvm_cpu_context *ctxt)
229+
{
230+
/*
231+
* We are in a hypervisor context if the vcpu mode is EL2 or
232+
* E2H and TGE bits are set. The latter means we are in the user space
233+
* of the VHE kernel. ARMv8.1 ARM describes this as 'InHost'
234+
*
235+
* Note that the HCR_EL2.{E2H,TGE}={0,1} isn't really handled in the
236+
* rest of the KVM code, and will result in a misbehaving guest.
237+
*/
238+
return vcpu_is_el2_ctxt(ctxt) ||
239+
(__vcpu_el2_e2h_is_set(ctxt) && __vcpu_el2_tge_is_set(ctxt)) ||
240+
__vcpu_el2_tge_is_set(ctxt);
241+
}
242+
243+
static inline bool is_hyp_ctxt(const struct kvm_vcpu *vcpu)
244+
{
245+
return __is_hyp_ctxt(&vcpu->arch.ctxt);
246+
}
247+
182248
/*
183249
* The layout of SPSR for an AArch32 state is different when observed from an
184250
* AArch64 SPSR_ELx or an AArch32 SPSR_*. This function generates the AArch32

arch/arm64/include/asm/kvm_host.h

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,14 @@
6060
enum kvm_mode {
6161
KVM_MODE_DEFAULT,
6262
KVM_MODE_PROTECTED,
63+
KVM_MODE_NV,
6364
KVM_MODE_NONE,
6465
};
66+
#ifdef CONFIG_KVM
6567
enum kvm_mode kvm_get_mode(void);
68+
#else
69+
static inline enum kvm_mode kvm_get_mode(void) { return KVM_MODE_NONE; };
70+
#endif
6671

6772
DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
6873

@@ -321,12 +326,43 @@ enum vcpu_sysreg {
321326
TFSR_EL1, /* Tag Fault Status Register (EL1) */
322327
TFSRE0_EL1, /* Tag Fault Status Register (EL0) */
323328

324-
/* 32bit specific registers. Keep them at the end of the range */
329+
/* 32bit specific registers. */
325330
DACR32_EL2, /* Domain Access Control Register */
326331
IFSR32_EL2, /* Instruction Fault Status Register */
327332
FPEXC32_EL2, /* Floating-Point Exception Control Register */
328333
DBGVCR32_EL2, /* Debug Vector Catch Register */
329334

335+
/* EL2 registers */
336+
VPIDR_EL2, /* Virtualization Processor ID Register */
337+
VMPIDR_EL2, /* Virtualization Multiprocessor ID Register */
338+
SCTLR_EL2, /* System Control Register (EL2) */
339+
ACTLR_EL2, /* Auxiliary Control Register (EL2) */
340+
HCR_EL2, /* Hypervisor Configuration Register */
341+
MDCR_EL2, /* Monitor Debug Configuration Register (EL2) */
342+
CPTR_EL2, /* Architectural Feature Trap Register (EL2) */
343+
HSTR_EL2, /* Hypervisor System Trap Register */
344+
HACR_EL2, /* Hypervisor Auxiliary Control Register */
345+
TTBR0_EL2, /* Translation Table Base Register 0 (EL2) */
346+
TTBR1_EL2, /* Translation Table Base Register 1 (EL2) */
347+
TCR_EL2, /* Translation Control Register (EL2) */
348+
VTTBR_EL2, /* Virtualization Translation Table Base Register */
349+
VTCR_EL2, /* Virtualization Translation Control Register */
350+
SPSR_EL2, /* EL2 saved program status register */
351+
ELR_EL2, /* EL2 exception link register */
352+
AFSR0_EL2, /* Auxiliary Fault Status Register 0 (EL2) */
353+
AFSR1_EL2, /* Auxiliary Fault Status Register 1 (EL2) */
354+
ESR_EL2, /* Exception Syndrome Register (EL2) */
355+
FAR_EL2, /* Fault Address Register (EL2) */
356+
HPFAR_EL2, /* Hypervisor IPA Fault Address Register */
357+
MAIR_EL2, /* Memory Attribute Indirection Register (EL2) */
358+
AMAIR_EL2, /* Auxiliary Memory Attribute Indirection Register (EL2) */
359+
VBAR_EL2, /* Vector Base Address Register (EL2) */
360+
RVBAR_EL2, /* Reset Vector Base Address Register */
361+
CONTEXTIDR_EL2, /* Context ID Register (EL2) */
362+
TPIDR_EL2, /* EL2 Software Thread ID Register */
363+
CNTHCTL_EL2, /* Counter-timer Hypervisor Control register */
364+
SP_EL2, /* EL2 Stack Pointer */
365+
330366
NR_SYS_REGS /* Nothing after this line! */
331367
};
332368

@@ -602,7 +638,7 @@ struct kvm_vcpu_arch {
602638
#define EXCEPT_AA64_EL1_IRQ __vcpu_except_flags(1)
603639
#define EXCEPT_AA64_EL1_FIQ __vcpu_except_flags(2)
604640
#define EXCEPT_AA64_EL1_SERR __vcpu_except_flags(3)
605-
/* For AArch64 with NV (one day): */
641+
/* For AArch64 with NV: */
606642
#define EXCEPT_AA64_EL2_SYNC __vcpu_except_flags(4)
607643
#define EXCEPT_AA64_EL2_IRQ __vcpu_except_flags(5)
608644
#define EXCEPT_AA64_EL2_FIQ __vcpu_except_flags(6)
@@ -613,6 +649,8 @@ struct kvm_vcpu_arch {
613649
#define DEBUG_STATE_SAVE_SPE __vcpu_single_flag(iflags, BIT(5))
614650
/* Save TRBE context if active */
615651
#define DEBUG_STATE_SAVE_TRBE __vcpu_single_flag(iflags, BIT(6))
652+
/* vcpu running in HYP context */
653+
#define VCPU_HYP_CONTEXT __vcpu_single_flag(iflags, BIT(7))
616654

617655
/* SVE enabled for host EL0 */
618656
#define HOST_SVE_ENABLED __vcpu_single_flag(sflags, BIT(0))

arch/arm64/include/asm/kvm_mmu.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ alternative_cb_end
115115
#include <asm/cache.h>
116116
#include <asm/cacheflush.h>
117117
#include <asm/mmu_context.h>
118+
#include <asm/kvm_emulate.h>
118119
#include <asm/kvm_host.h>
119120

120121
void kvm_update_va_mask(struct alt_instr *alt,
@@ -192,7 +193,15 @@ struct kvm;
192193

193194
static inline bool vcpu_has_cache_enabled(struct kvm_vcpu *vcpu)
194195
{
195-
return (vcpu_read_sys_reg(vcpu, SCTLR_EL1) & 0b101) == 0b101;
196+
u64 cache_bits = SCTLR_ELx_M | SCTLR_ELx_C;
197+
int reg;
198+
199+
if (vcpu_is_el2(vcpu))
200+
reg = SCTLR_EL2;
201+
else
202+
reg = SCTLR_EL1;
203+
204+
return (vcpu_read_sys_reg(vcpu, reg) & cache_bits) == cache_bits;
196205
}
197206

198207
static inline void __clean_dcache_guest_page(void *va, size_t size)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef __ARM64_KVM_NESTED_H
3+
#define __ARM64_KVM_NESTED_H
4+
5+
#include <linux/kvm_host.h>
6+
7+
static inline bool vcpu_has_nv(const struct kvm_vcpu *vcpu)
8+
{
9+
return (!__is_defined(__KVM_NVHE_HYPERVISOR__) &&
10+
cpus_have_final_cap(ARM64_HAS_NESTED_VIRT) &&
11+
test_bit(KVM_ARM_VCPU_HAS_EL2, vcpu->arch.features));
12+
}
13+
14+
struct sys_reg_params;
15+
struct sys_reg_desc;
16+
17+
void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p,
18+
const struct sys_reg_desc *r);
19+
20+
#endif /* __ARM64_KVM_NESTED_H */

arch/arm64/include/asm/sysreg.h

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,23 +489,51 @@
489489

490490
#define SYS_PMCCFILTR_EL0 sys_reg(3, 3, 14, 15, 7)
491491

492+
#define SYS_VPIDR_EL2 sys_reg(3, 4, 0, 0, 0)
493+
#define SYS_VMPIDR_EL2 sys_reg(3, 4, 0, 0, 5)
494+
492495
#define SYS_SCTLR_EL2 sys_reg(3, 4, 1, 0, 0)
496+
#define SYS_ACTLR_EL2 sys_reg(3, 4, 1, 0, 1)
497+
#define SYS_HCR_EL2 sys_reg(3, 4, 1, 1, 0)
498+
#define SYS_MDCR_EL2 sys_reg(3, 4, 1, 1, 1)
499+
#define SYS_CPTR_EL2 sys_reg(3, 4, 1, 1, 2)
500+
#define SYS_HSTR_EL2 sys_reg(3, 4, 1, 1, 3)
493501
#define SYS_HFGRTR_EL2 sys_reg(3, 4, 1, 1, 4)
494502
#define SYS_HFGWTR_EL2 sys_reg(3, 4, 1, 1, 5)
495503
#define SYS_HFGITR_EL2 sys_reg(3, 4, 1, 1, 6)
504+
#define SYS_HACR_EL2 sys_reg(3, 4, 1, 1, 7)
505+
506+
#define SYS_TTBR0_EL2 sys_reg(3, 4, 2, 0, 0)
507+
#define SYS_TTBR1_EL2 sys_reg(3, 4, 2, 0, 1)
508+
#define SYS_TCR_EL2 sys_reg(3, 4, 2, 0, 2)
509+
#define SYS_VTTBR_EL2 sys_reg(3, 4, 2, 1, 0)
510+
#define SYS_VTCR_EL2 sys_reg(3, 4, 2, 1, 2)
511+
496512
#define SYS_TRFCR_EL2 sys_reg(3, 4, 1, 2, 1)
497513
#define SYS_HDFGRTR_EL2 sys_reg(3, 4, 3, 1, 4)
498514
#define SYS_HDFGWTR_EL2 sys_reg(3, 4, 3, 1, 5)
499515
#define SYS_HAFGRTR_EL2 sys_reg(3, 4, 3, 1, 6)
500516
#define SYS_SPSR_EL2 sys_reg(3, 4, 4, 0, 0)
501517
#define SYS_ELR_EL2 sys_reg(3, 4, 4, 0, 1)
518+
#define SYS_SP_EL1 sys_reg(3, 4, 4, 1, 0)
502519
#define SYS_IFSR32_EL2 sys_reg(3, 4, 5, 0, 1)
520+
#define SYS_AFSR0_EL2 sys_reg(3, 4, 5, 1, 0)
521+
#define SYS_AFSR1_EL2 sys_reg(3, 4, 5, 1, 1)
503522
#define SYS_ESR_EL2 sys_reg(3, 4, 5, 2, 0)
504523
#define SYS_VSESR_EL2 sys_reg(3, 4, 5, 2, 3)
505524
#define SYS_FPEXC32_EL2 sys_reg(3, 4, 5, 3, 0)
506525
#define SYS_TFSR_EL2 sys_reg(3, 4, 5, 6, 0)
507526

508-
#define SYS_VDISR_EL2 sys_reg(3, 4, 12, 1, 1)
527+
#define SYS_FAR_EL2 sys_reg(3, 4, 6, 0, 0)
528+
#define SYS_HPFAR_EL2 sys_reg(3, 4, 6, 0, 4)
529+
530+
#define SYS_MAIR_EL2 sys_reg(3, 4, 10, 2, 0)
531+
#define SYS_AMAIR_EL2 sys_reg(3, 4, 10, 3, 0)
532+
533+
#define SYS_VBAR_EL2 sys_reg(3, 4, 12, 0, 0)
534+
#define SYS_RVBAR_EL2 sys_reg(3, 4, 12, 0, 1)
535+
#define SYS_RMR_EL2 sys_reg(3, 4, 12, 0, 2)
536+
#define SYS_VDISR_EL2 sys_reg(3, 4, 12, 1, 1)
509537
#define __SYS__AP0Rx_EL2(x) sys_reg(3, 4, 12, 8, x)
510538
#define SYS_ICH_AP0R0_EL2 __SYS__AP0Rx_EL2(0)
511539
#define SYS_ICH_AP0R1_EL2 __SYS__AP0Rx_EL2(1)
@@ -547,6 +575,12 @@
547575
#define SYS_ICH_LR14_EL2 __SYS__LR8_EL2(6)
548576
#define SYS_ICH_LR15_EL2 __SYS__LR8_EL2(7)
549577

578+
#define SYS_CONTEXTIDR_EL2 sys_reg(3, 4, 13, 0, 1)
579+
#define SYS_TPIDR_EL2 sys_reg(3, 4, 13, 0, 2)
580+
581+
#define SYS_CNTVOFF_EL2 sys_reg(3, 4, 14, 0, 3)
582+
#define SYS_CNTHCTL_EL2 sys_reg(3, 4, 14, 1, 0)
583+
550584
/* VHE encodings for architectural EL0/1 system registers */
551585
#define SYS_SCTLR_EL12 sys_reg(3, 5, 1, 0, 0)
552586
#define SYS_TTBR0_EL12 sys_reg(3, 5, 2, 0, 0)
@@ -569,6 +603,8 @@
569603
#define SYS_CNTV_CTL_EL02 sys_reg(3, 5, 14, 3, 1)
570604
#define SYS_CNTV_CVAL_EL02 sys_reg(3, 5, 14, 3, 2)
571605

606+
#define SYS_SP_EL2 sys_reg(3, 6, 4, 1, 0)
607+
572608
/* Common SCTLR_ELx flags. */
573609
#define SCTLR_ELx_ENTP2 (BIT(60))
574610
#define SCTLR_ELx_DSSBS (BIT(44))

arch/arm64/include/uapi/asm/kvm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ struct kvm_regs {
109109
#define KVM_ARM_VCPU_SVE 4 /* enable SVE for this CPU */
110110
#define KVM_ARM_VCPU_PTRAUTH_ADDRESS 5 /* VCPU uses address authentication */
111111
#define KVM_ARM_VCPU_PTRAUTH_GENERIC 6 /* VCPU uses generic authentication */
112+
#define KVM_ARM_VCPU_HAS_EL2 7 /* Support nested virtualization */
112113

113114
struct kvm_vcpu_init {
114115
__u32 target;

arch/arm64/kernel/cpufeature.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1966,6 +1966,20 @@ static void cpu_copy_el2regs(const struct arm64_cpu_capabilities *__unused)
19661966
write_sysreg(read_sysreg(tpidr_el1), tpidr_el2);
19671967
}
19681968

1969+
static bool has_nested_virt_support(const struct arm64_cpu_capabilities *cap,
1970+
int scope)
1971+
{
1972+
if (kvm_get_mode() != KVM_MODE_NV)
1973+
return false;
1974+
1975+
if (!has_cpuid_feature(cap, scope)) {
1976+
pr_warn("unavailable: %s\n", cap->desc);
1977+
return false;
1978+
}
1979+
1980+
return true;
1981+
}
1982+
19691983
#ifdef CONFIG_ARM64_PAN
19701984
static void cpu_enable_pan(const struct arm64_cpu_capabilities *__unused)
19711985
{
@@ -2225,6 +2239,17 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
22252239
.matches = runs_at_el2,
22262240
.cpu_enable = cpu_copy_el2regs,
22272241
},
2242+
{
2243+
.desc = "Nested Virtualization Support",
2244+
.capability = ARM64_HAS_NESTED_VIRT,
2245+
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
2246+
.matches = has_nested_virt_support,
2247+
.sys_reg = SYS_ID_AA64MMFR2_EL1,
2248+
.sign = FTR_UNSIGNED,
2249+
.field_pos = ID_AA64MMFR2_EL1_NV_SHIFT,
2250+
.field_width = 4,
2251+
.min_field_value = ID_AA64MMFR2_EL1_NV_IMP,
2252+
},
22282253
{
22292254
.capability = ARM64_HAS_32BIT_EL0_DO_NOT_USE,
22302255
.type = ARM64_CPUCAP_SYSTEM_FEATURE,

0 commit comments

Comments
 (0)