Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

KVM: arm64: Eagerly save VMCR on exit

We currently save/restore the VMCR register in a pretty lazy way
(on load/put, consistently with what we do with the APRs).

However, we are going to need the group-enable bits that are backed
by VMCR on each entry (so that we can avoid injecting interrupts for
disabled groups).

Move the synchronisation from put to sync, which results in some minor
churn in the nVHE hypercalls to simplify things.

Tested-by: Fuad Tabba <tabba@google.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Tested-by: Mark Brown <broonie@kernel.org>
Link: https://msgid.link/20251120172540.2267180-21-maz@kernel.org
Signed-off-by: Oliver Upton <oupton@kernel.org>

authored by

Marc Zyngier and committed by
Oliver Upton
cf72ee63 dd598fc1

+13 -22
+1 -1
arch/arm64/include/asm/kvm_asm.h
··· 79 79 __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid_range, 80 80 __KVM_HOST_SMCCC_FUNC___kvm_flush_cpu_context, 81 81 __KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntvoff, 82 - __KVM_HOST_SMCCC_FUNC___vgic_v3_save_vmcr_aprs, 82 + __KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs, 83 83 __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_vmcr_aprs, 84 84 __KVM_HOST_SMCCC_FUNC___pkvm_reserve_vm, 85 85 __KVM_HOST_SMCCC_FUNC___pkvm_unreserve_vm,
+1 -1
arch/arm64/include/asm/kvm_hyp.h
··· 82 82 void __vgic_v3_restore_state(struct vgic_v3_cpu_if *cpu_if); 83 83 void __vgic_v3_activate_traps(struct vgic_v3_cpu_if *cpu_if); 84 84 void __vgic_v3_deactivate_traps(struct vgic_v3_cpu_if *cpu_if); 85 - void __vgic_v3_save_vmcr_aprs(struct vgic_v3_cpu_if *cpu_if); 85 + void __vgic_v3_save_aprs(struct vgic_v3_cpu_if *cpu_if); 86 86 void __vgic_v3_restore_vmcr_aprs(struct vgic_v3_cpu_if *cpu_if); 87 87 int __vgic_v3_perform_cpuif_access(struct kvm_vcpu *vcpu); 88 88
+1 -2
arch/arm64/kvm/arm.c
··· 659 659 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) 660 660 { 661 661 if (is_protected_kvm_enabled()) { 662 - kvm_call_hyp(__vgic_v3_save_vmcr_aprs, 663 - &vcpu->arch.vgic_cpu.vgic_v3); 662 + kvm_call_hyp(__vgic_v3_save_aprs, &vcpu->arch.vgic_cpu.vgic_v3); 664 663 kvm_call_hyp_nvhe(__pkvm_vcpu_put); 665 664 } 666 665
+4 -3
arch/arm64/kvm/hyp/nvhe/hyp-main.c
··· 157 157 host_vcpu->arch.iflags = hyp_vcpu->vcpu.arch.iflags; 158 158 159 159 host_cpu_if->vgic_hcr = hyp_cpu_if->vgic_hcr; 160 + host_cpu_if->vgic_vmcr = hyp_cpu_if->vgic_vmcr; 160 161 for (i = 0; i < hyp_cpu_if->used_lrs; ++i) 161 162 host_cpu_if->vgic_lr[i] = hyp_cpu_if->vgic_lr[i]; 162 163 } ··· 465 464 __vgic_v3_init_lrs(); 466 465 } 467 466 468 - static void handle___vgic_v3_save_vmcr_aprs(struct kvm_cpu_context *host_ctxt) 467 + static void handle___vgic_v3_save_aprs(struct kvm_cpu_context *host_ctxt) 469 468 { 470 469 DECLARE_REG(struct vgic_v3_cpu_if *, cpu_if, host_ctxt, 1); 471 470 472 - __vgic_v3_save_vmcr_aprs(kern_hyp_va(cpu_if)); 471 + __vgic_v3_save_aprs(kern_hyp_va(cpu_if)); 473 472 } 474 473 475 474 static void handle___vgic_v3_restore_vmcr_aprs(struct kvm_cpu_context *host_ctxt) ··· 617 616 HANDLE_FUNC(__kvm_tlb_flush_vmid_range), 618 617 HANDLE_FUNC(__kvm_flush_cpu_context), 619 618 HANDLE_FUNC(__kvm_timer_set_cntvoff), 620 - HANDLE_FUNC(__vgic_v3_save_vmcr_aprs), 619 + HANDLE_FUNC(__vgic_v3_save_aprs), 621 620 HANDLE_FUNC(__vgic_v3_restore_vmcr_aprs), 622 621 HANDLE_FUNC(__pkvm_reserve_vm), 623 622 HANDLE_FUNC(__pkvm_unreserve_vm),
+3 -12
arch/arm64/kvm/hyp/vgic-v3-sr.c
··· 235 235 } 236 236 } 237 237 238 + cpu_if->vgic_vmcr = read_gicreg(ICH_VMCR_EL2); 239 + 238 240 if (cpu_if->vgic_hcr & ICH_HCR_EL2_LRENPIE) { 239 241 u64 val = read_gicreg(ICH_HCR_EL2); 240 242 cpu_if->vgic_hcr &= ~ICH_HCR_EL2_EOIcount; ··· 334 332 { 335 333 u64 val; 336 334 337 - if (!cpu_if->vgic_sre) { 338 - cpu_if->vgic_vmcr = read_gicreg(ICH_VMCR_EL2); 339 - } 340 - 341 335 /* Only restore SRE if the host implements the GICv2 interface */ 342 336 if (static_branch_unlikely(&vgic_v3_has_v2_compat)) { 343 337 val = read_gicreg(ICC_SRE_EL2); ··· 355 357 write_gicreg(0, ICH_HCR_EL2); 356 358 } 357 359 358 - static void __vgic_v3_save_aprs(struct vgic_v3_cpu_if *cpu_if) 360 + void __vgic_v3_save_aprs(struct vgic_v3_cpu_if *cpu_if) 359 361 { 360 362 u64 val; 361 363 u32 nr_pre_bits; ··· 514 516 static void __vgic_v3_write_vmcr(u32 vmcr) 515 517 { 516 518 write_gicreg(vmcr, ICH_VMCR_EL2); 517 - } 518 - 519 - void __vgic_v3_save_vmcr_aprs(struct vgic_v3_cpu_if *cpu_if) 520 - { 521 - __vgic_v3_save_aprs(cpu_if); 522 - if (cpu_if->vgic_sre) 523 - cpu_if->vgic_vmcr = __vgic_v3_read_vmcr(); 524 519 } 525 520 526 521 void __vgic_v3_restore_vmcr_aprs(struct vgic_v3_cpu_if *cpu_if)
+1 -1
arch/arm64/kvm/vgic/vgic-v2.c
··· 451 451 if (!base) 452 452 return; 453 453 454 + cpu_if->vgic_vmcr = readl_relaxed(kvm_vgic_global_state.vctrl_base + GICH_VMCR); 454 455 455 456 if (used_lrs) 456 457 save_lrs(vcpu, base); ··· 496 495 { 497 496 struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; 498 497 499 - cpu_if->vgic_vmcr = readl_relaxed(kvm_vgic_global_state.vctrl_base + GICH_VMCR); 500 498 cpu_if->vgic_apr = readl_relaxed(kvm_vgic_global_state.vctrl_base + GICH_APR); 501 499 }
+1 -1
arch/arm64/kvm/vgic/vgic-v3-nested.c
··· 340 340 u64 val; 341 341 int i; 342 342 343 - __vgic_v3_save_vmcr_aprs(s_cpu_if); 343 + __vgic_v3_save_aprs(s_cpu_if); 344 344 __vgic_v3_deactivate_traps(s_cpu_if); 345 345 __vgic_v3_save_state(s_cpu_if); 346 346
+1 -1
arch/arm64/kvm/vgic/vgic-v3.c
··· 815 815 } 816 816 817 817 if (likely(!is_protected_kvm_enabled())) 818 - kvm_call_hyp(__vgic_v3_save_vmcr_aprs, cpu_if); 818 + kvm_call_hyp(__vgic_v3_save_aprs, cpu_if); 819 819 WARN_ON(vgic_v4_put(vcpu)); 820 820 821 821 if (has_vhe())