Skip to content

Commit e2ee2e9

Browse files
committed
Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull KVM/arm64 updates from Will Deacon: "New features: - Support for non-protected guest in protected mode, achieving near feature parity with the non-protected mode - Support for the EL2 timers as part of the ongoing NV support - Allow control of hardware tracing for nVHE/hVHE Improvements, fixes and cleanups: - Massive cleanup of the debug infrastructure, making it a bit less awkward and definitely easier to maintain. This should pave the way for further optimisations - Complete rewrite of pKVM's fixed-feature infrastructure, aligning it with the rest of KVM and making the code easier to follow - Large simplification of pKVM's memory protection infrastructure - Better handling of RES0/RES1 fields for memory-backed system registers - Add a workaround for Qualcomm's Snapdragon X CPUs, which suffer from a pretty nasty timer bug - Small collection of cleanups and low-impact fixes" * tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (87 commits) arm64/sysreg: Get rid of TRFCR_ELx SysregFields KVM: arm64: nv: Fix doc header layout for timers KVM: arm64: nv: Apply RESx settings to sysreg reset values KVM: arm64: nv: Always evaluate HCR_EL2 using sanitising accessors KVM: arm64: Fix selftests after sysreg field name update coresight: Pass guest TRFCR value to KVM KVM: arm64: Support trace filtering for guests KVM: arm64: coresight: Give TRBE enabled state to KVM coresight: trbe: Remove redundant disable call arm64/sysreg/tools: Move TRFCR definitions to sysreg tools: arm64: Update sysreg.h header files KVM: arm64: Drop pkvm_mem_transition for host/hyp donations KVM: arm64: Drop pkvm_mem_transition for host/hyp sharing KVM: arm64: Drop pkvm_mem_transition for FF-A KVM: arm64: Explicitly handle BRBE traps as UNDEFINED KVM: arm64: vgic: Use str_enabled_disabled() in vgic_v3_probe() arm64: kvm: Introduce nvhe stack size constants KVM: arm64: Fix nVHE stacktrace VA bits mask KVM: arm64: Fix FEAT_MTE in pKVM Documentation: Update the behaviour of "kvm-arm.mode" ...
2 parents 9ff28f2 + 01009b0 commit e2ee2e9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+3112
-2218
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2824,17 +2824,21 @@
28242824
nvhe: Standard nVHE-based mode, without support for
28252825
protected guests.
28262826

2827-
protected: nVHE-based mode with support for guests whose
2828-
state is kept private from the host.
2827+
protected: Mode with support for guests whose state is
2828+
kept private from the host, using VHE or
2829+
nVHE depending on HW support.
28292830

28302831
nested: VHE-based mode with support for nested
2831-
virtualization. Requires at least ARMv8.3
2832-
hardware.
2832+
virtualization. Requires at least ARMv8.4
2833+
hardware (with FEAT_NV2).
28332834

28342835
Defaults to VHE/nVHE based on hardware support. Setting
28352836
mode to "protected" will disable kexec and hibernation
2836-
for the host. "nested" is experimental and should be
2837-
used with extreme caution.
2837+
for the host. To force nVHE on VHE hardware, add
2838+
"arm64_sw.hvhe=0 id_aa64mmfr1.vh=0" to the
2839+
command-line.
2840+
"nested" is experimental and should be used with
2841+
extreme caution.
28382842

28392843
kvm-arm.vgic_v3_group0_trap=
28402844
[KVM,ARM,EARLY] Trap guest accesses to GICv3 group-0

Documentation/virt/kvm/devices/vcpu.rst

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ the cpu field to the processor id.
142142

143143
:Architectures: ARM64
144144

145-
2.1. ATTRIBUTES: KVM_ARM_VCPU_TIMER_IRQ_VTIMER, KVM_ARM_VCPU_TIMER_IRQ_PTIMER
146-
-----------------------------------------------------------------------------
145+
2.1. ATTRIBUTES: KVM_ARM_VCPU_TIMER_IRQ_{VTIMER,PTIMER,HVTIMER,HPTIMER}
146+
-----------------------------------------------------------------------
147147

148148
:Parameters: in kvm_device_attr.addr the address for the timer interrupt is a
149149
pointer to an int
@@ -159,10 +159,12 @@ A value describing the architected timer interrupt number when connected to an
159159
in-kernel virtual GIC. These must be a PPI (16 <= intid < 32). Setting the
160160
attribute overrides the default values (see below).
161161

162-
============================= ==========================================
163-
KVM_ARM_VCPU_TIMER_IRQ_VTIMER The EL1 virtual timer intid (default: 27)
164-
KVM_ARM_VCPU_TIMER_IRQ_PTIMER The EL1 physical timer intid (default: 30)
165-
============================= ==========================================
162+
============================== ==========================================
163+
KVM_ARM_VCPU_TIMER_IRQ_VTIMER The EL1 virtual timer intid (default: 27)
164+
KVM_ARM_VCPU_TIMER_IRQ_PTIMER The EL1 physical timer intid (default: 30)
165+
KVM_ARM_VCPU_TIMER_IRQ_HVTIMER The EL2 virtual timer intid (default: 28)
166+
KVM_ARM_VCPU_TIMER_IRQ_HPTIMER The EL2 physical timer intid (default: 26)
167+
============================== ==========================================
166168

167169
Setting the same PPI for different timers will prevent the VCPUs from running.
168170
Setting the interrupt number on a VCPU configures all VCPUs created at that

arch/arm64/include/asm/cputype.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@
122122
#define QCOM_CPU_PART_KRYO_3XX_SILVER 0x803
123123
#define QCOM_CPU_PART_KRYO_4XX_GOLD 0x804
124124
#define QCOM_CPU_PART_KRYO_4XX_SILVER 0x805
125+
#define QCOM_CPU_PART_ORYON_X1 0x001
125126

126127
#define NVIDIA_CPU_PART_DENVER 0x003
127128
#define NVIDIA_CPU_PART_CARMEL 0x004
@@ -198,6 +199,7 @@
198199
#define MIDR_QCOM_KRYO_3XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_3XX_SILVER)
199200
#define MIDR_QCOM_KRYO_4XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_GOLD)
200201
#define MIDR_QCOM_KRYO_4XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_SILVER)
202+
#define MIDR_QCOM_ORYON_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_ORYON_X1)
201203
#define MIDR_NVIDIA_DENVER MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_DENVER)
202204
#define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL)
203205
#define MIDR_FUJITSU_A64FX MIDR_CPU_MODEL(ARM_CPU_IMP_FUJITSU, FUJITSU_CPU_PART_A64FX)

arch/arm64/include/asm/kvm_arm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@
300300
#define CPTR_EL2_TSM (1 << 12)
301301
#define CPTR_EL2_TFP (1 << CPTR_EL2_TFP_SHIFT)
302302
#define CPTR_EL2_TZ (1 << 8)
303-
#define CPTR_NVHE_EL2_RES1 0x000032ff /* known RES1 bits in CPTR_EL2 (nVHE) */
303+
#define CPTR_NVHE_EL2_RES1 (BIT(13) | BIT(9) | GENMASK(7, 0))
304304
#define CPTR_NVHE_EL2_RES0 (GENMASK(63, 32) | \
305305
GENMASK(29, 21) | \
306306
GENMASK(19, 14) | \

arch/arm64/include/asm/kvm_asm.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@
5353
enum __kvm_host_smccc_func {
5454
/* Hypercalls available only prior to pKVM finalisation */
5555
/* __KVM_HOST_SMCCC_FUNC___kvm_hyp_init */
56-
__KVM_HOST_SMCCC_FUNC___kvm_get_mdcr_el2 = __KVM_HOST_SMCCC_FUNC___kvm_hyp_init + 1,
57-
__KVM_HOST_SMCCC_FUNC___pkvm_init,
56+
__KVM_HOST_SMCCC_FUNC___pkvm_init = __KVM_HOST_SMCCC_FUNC___kvm_hyp_init + 1,
5857
__KVM_HOST_SMCCC_FUNC___pkvm_create_private_mapping,
5958
__KVM_HOST_SMCCC_FUNC___pkvm_cpu_set_vector,
6059
__KVM_HOST_SMCCC_FUNC___kvm_enable_ssbs,
@@ -65,6 +64,12 @@ enum __kvm_host_smccc_func {
6564
/* Hypercalls available after pKVM finalisation */
6665
__KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
6766
__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
67+
__KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
68+
__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
69+
__KVM_HOST_SMCCC_FUNC___pkvm_host_relax_perms_guest,
70+
__KVM_HOST_SMCCC_FUNC___pkvm_host_wrprotect_guest,
71+
__KVM_HOST_SMCCC_FUNC___pkvm_host_test_clear_young_guest,
72+
__KVM_HOST_SMCCC_FUNC___pkvm_host_mkyoung_guest,
6873
__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
6974
__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
7075
__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
@@ -79,6 +84,9 @@ enum __kvm_host_smccc_func {
7984
__KVM_HOST_SMCCC_FUNC___pkvm_init_vm,
8085
__KVM_HOST_SMCCC_FUNC___pkvm_init_vcpu,
8186
__KVM_HOST_SMCCC_FUNC___pkvm_teardown_vm,
87+
__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load,
88+
__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put,
89+
__KVM_HOST_SMCCC_FUNC___pkvm_tlb_flush_vmid,
8290
};
8391

8492
#define DECLARE_KVM_VHE_SYM(sym) extern char sym[]
@@ -247,8 +255,6 @@ extern void __kvm_adjust_pc(struct kvm_vcpu *vcpu);
247255
extern u64 __vgic_v3_get_gic_config(void);
248256
extern void __vgic_v3_init_lrs(void);
249257

250-
extern u64 __kvm_get_mdcr_el2(void);
251-
252258
#define __KVM_EXTABLE(from, to) \
253259
" .pushsection __kvm_ex_table, \"a\"\n" \
254260
" .align 3\n" \

arch/arm64/include/asm/kvm_emulate.h

Lines changed: 27 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -184,29 +184,30 @@ static inline bool vcpu_is_el2(const struct kvm_vcpu *vcpu)
184184
return vcpu_is_el2_ctxt(&vcpu->arch.ctxt);
185185
}
186186

187-
static inline bool __vcpu_el2_e2h_is_set(const struct kvm_cpu_context *ctxt)
187+
static inline bool vcpu_el2_e2h_is_set(const struct kvm_vcpu *vcpu)
188188
{
189189
return (!cpus_have_final_cap(ARM64_HAS_HCR_NV1) ||
190-
(ctxt_sys_reg(ctxt, HCR_EL2) & HCR_E2H));
190+
(__vcpu_sys_reg(vcpu, HCR_EL2) & HCR_E2H));
191191
}
192192

193-
static inline bool vcpu_el2_e2h_is_set(const struct kvm_vcpu *vcpu)
193+
static inline bool vcpu_el2_tge_is_set(const struct kvm_vcpu *vcpu)
194194
{
195-
return __vcpu_el2_e2h_is_set(&vcpu->arch.ctxt);
195+
return ctxt_sys_reg(&vcpu->arch.ctxt, HCR_EL2) & HCR_TGE;
196196
}
197197

198-
static inline bool __vcpu_el2_tge_is_set(const struct kvm_cpu_context *ctxt)
198+
static inline bool is_hyp_ctxt(const struct kvm_vcpu *vcpu)
199199
{
200-
return ctxt_sys_reg(ctxt, HCR_EL2) & HCR_TGE;
201-
}
200+
bool e2h, tge;
201+
u64 hcr;
202202

203-
static inline bool vcpu_el2_tge_is_set(const struct kvm_vcpu *vcpu)
204-
{
205-
return __vcpu_el2_tge_is_set(&vcpu->arch.ctxt);
206-
}
203+
if (!vcpu_has_nv(vcpu))
204+
return false;
205+
206+
hcr = __vcpu_sys_reg(vcpu, HCR_EL2);
207+
208+
e2h = (hcr & HCR_E2H);
209+
tge = (hcr & HCR_TGE);
207210

208-
static inline bool __is_hyp_ctxt(const struct kvm_cpu_context *ctxt)
209-
{
210211
/*
211212
* We are in a hypervisor context if the vcpu mode is EL2 or
212213
* E2H and TGE bits are set. The latter means we are in the user space
@@ -215,14 +216,7 @@ static inline bool __is_hyp_ctxt(const struct kvm_cpu_context *ctxt)
215216
* Note that the HCR_EL2.{E2H,TGE}={0,1} isn't really handled in the
216217
* rest of the KVM code, and will result in a misbehaving guest.
217218
*/
218-
return vcpu_is_el2_ctxt(ctxt) ||
219-
(__vcpu_el2_e2h_is_set(ctxt) && __vcpu_el2_tge_is_set(ctxt)) ||
220-
__vcpu_el2_tge_is_set(ctxt);
221-
}
222-
223-
static inline bool is_hyp_ctxt(const struct kvm_vcpu *vcpu)
224-
{
225-
return vcpu_has_nv(vcpu) && __is_hyp_ctxt(&vcpu->arch.ctxt);
219+
return vcpu_is_el2(vcpu) || (e2h && tge) || tge;
226220
}
227221

228222
static inline bool vcpu_is_host_el0(const struct kvm_vcpu *vcpu)
@@ -619,7 +613,8 @@ static __always_inline void kvm_write_cptr_el2(u64 val)
619613
write_sysreg(val, cptr_el2);
620614
}
621615

622-
static __always_inline u64 kvm_get_reset_cptr_el2(struct kvm_vcpu *vcpu)
616+
/* Resets the value of cptr_el2 when returning to the host. */
617+
static __always_inline void __kvm_reset_cptr_el2(struct kvm *kvm)
623618
{
624619
u64 val;
625620

@@ -630,29 +625,28 @@ static __always_inline u64 kvm_get_reset_cptr_el2(struct kvm_vcpu *vcpu)
630625
} else if (has_hvhe()) {
631626
val = CPACR_EL1_FPEN;
632627

633-
if (!vcpu_has_sve(vcpu) || !guest_owns_fp_regs())
628+
if (!kvm_has_sve(kvm) || !guest_owns_fp_regs())
634629
val |= CPACR_EL1_ZEN;
635630
if (cpus_have_final_cap(ARM64_SME))
636631
val |= CPACR_EL1_SMEN;
637632
} else {
638633
val = CPTR_NVHE_EL2_RES1;
639634

640-
if (vcpu_has_sve(vcpu) && guest_owns_fp_regs())
635+
if (kvm_has_sve(kvm) && guest_owns_fp_regs())
641636
val |= CPTR_EL2_TZ;
642-
if (cpus_have_final_cap(ARM64_SME))
643-
val &= ~CPTR_EL2_TSM;
637+
if (!cpus_have_final_cap(ARM64_SME))
638+
val |= CPTR_EL2_TSM;
644639
}
645640

646-
return val;
647-
}
648-
649-
static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
650-
{
651-
u64 val = kvm_get_reset_cptr_el2(vcpu);
652-
653641
kvm_write_cptr_el2(val);
654642
}
655643

644+
#ifdef __KVM_NVHE_HYPERVISOR__
645+
#define kvm_reset_cptr_el2(v) __kvm_reset_cptr_el2(kern_hyp_va((v)->kvm))
646+
#else
647+
#define kvm_reset_cptr_el2(v) __kvm_reset_cptr_el2((v)->kvm)
648+
#endif
649+
656650
/*
657651
* Returns a 'sanitised' view of CPTR_EL2, translating from nVHE to the VHE
658652
* format if E2H isn't set.
@@ -697,9 +691,4 @@ static inline bool guest_hyp_sve_traps_enabled(const struct kvm_vcpu *vcpu)
697691
{
698692
return __guest_hyp_cptr_xen_trap_enabled(vcpu, ZEN);
699693
}
700-
701-
static inline void kvm_vcpu_enable_ptrauth(struct kvm_vcpu *vcpu)
702-
{
703-
vcpu_set_flag(vcpu, GUEST_HAS_PTRAUTH);
704-
}
705694
#endif /* __ARM64_KVM_EMULATE_H__ */

0 commit comments

Comments
 (0)