From 236b5a27d564a86ccd4a9858050f3e9abe0ce8fd Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 2 Jul 2024 12:41:17 +0200 Subject: [PATCH] 5.10-stable patches added patches: kvm-arm64-vgic-v4-make-the-doorbell-request-robust-w.r.t-preemption.patch --- ...bell-request-robust-w.r.t-preemption.patch | 140 ++++++++++++++++++ queue-5.10/series | 1 + 2 files changed, 141 insertions(+) create mode 100644 queue-5.10/kvm-arm64-vgic-v4-make-the-doorbell-request-robust-w.r.t-preemption.patch diff --git a/queue-5.10/kvm-arm64-vgic-v4-make-the-doorbell-request-robust-w.r.t-preemption.patch b/queue-5.10/kvm-arm64-vgic-v4-make-the-doorbell-request-robust-w.r.t-preemption.patch new file mode 100644 index 00000000000..86f267a8fcd --- /dev/null +++ b/queue-5.10/kvm-arm64-vgic-v4-make-the-doorbell-request-robust-w.r.t-preemption.patch @@ -0,0 +1,140 @@ +From b321c31c9b7b309dcde5e8854b741c8e6a9a05f0 Mon Sep 17 00:00:00 2001 +From: Marc Zyngier +Date: Thu, 13 Jul 2023 08:06:57 +0100 +Subject: KVM: arm64: vgic-v4: Make the doorbell request robust w.r.t preemption + +From: Marc Zyngier + +commit b321c31c9b7b309dcde5e8854b741c8e6a9a05f0 upstream. + +Xiang reports that VMs occasionally fail to boot on GICv4.1 systems when +running a preemptible kernel, as it is possible that a vCPU is blocked +without requesting a doorbell interrupt. + +The issue is that any preemption that occurs between vgic_v4_put() and +schedule() on the block path will mark the vPE as nonresident and *not* +request a doorbell irq. This occurs because when the vcpu thread is +resumed on its way to block, vcpu_load() will make the vPE resident +again. Once the vcpu actually blocks, we don't request a doorbell +anymore, and the vcpu won't be woken up on interrupt delivery. + +Fix it by tracking that we're entering WFI, and key the doorbell +request on that flag. This allows us not to make the vPE resident +when going through a preempt/schedule cycle, meaning we don't lose +any state. + +Cc: stable@vger.kernel.org +Fixes: 8e01d9a396e6 ("KVM: arm64: vgic-v4: Move the GICv4 residency flow to be driven by vcpu_load/put") +Reported-by: Xiang Chen +Suggested-by: Zenghui Yu +Tested-by: Xiang Chen +Co-developed-by: Oliver Upton +Signed-off-by: Marc Zyngier +Acked-by: Zenghui Yu +Link: https://lore.kernel.org/r/20230713070657.3873244-1-maz@kernel.org +Signed-off-by: Oliver Upton +[ modified to wrangle the vCPU flags directly instead of going through + the flag helper macros as they have not yet been introduced. Also doing + the flag wranging in the kvm_arch_vcpu_{un}blocking() hooks as the + introduction of kvm_vcpu_wfi has not yet happened. See: + 6109c5a6ab7f ("KVM: arm64: Move vGIC v4 handling for WFI out arch callback hook") ] +Signed-off-by: James Gowans +Acked-by: Marc Zyngier +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/include/asm/kvm_host.h | 1 + + arch/arm64/kvm/arm.c | 6 ++++-- + arch/arm64/kvm/vgic/vgic-v3.c | 2 +- + arch/arm64/kvm/vgic/vgic-v4.c | 8 ++++++-- + include/kvm/arm_vgic.h | 2 +- + 5 files changed, 13 insertions(+), 6 deletions(-) + +--- a/arch/arm64/include/asm/kvm_host.h ++++ b/arch/arm64/include/asm/kvm_host.h +@@ -410,6 +410,7 @@ struct kvm_vcpu_arch { + #define KVM_ARM64_GUEST_HAS_SVE (1 << 5) /* SVE exposed to guest */ + #define KVM_ARM64_VCPU_SVE_FINALIZED (1 << 6) /* SVE config completed */ + #define KVM_ARM64_GUEST_HAS_PTRAUTH (1 << 7) /* PTRAUTH exposed to guest */ ++#define KVM_ARM64_VCPU_IN_WFI (1 << 8) /* WFI instruction trapped */ + + #define vcpu_has_sve(vcpu) (system_supports_sve() && \ + ((vcpu)->arch.flags & KVM_ARM64_GUEST_HAS_SVE)) +--- a/arch/arm64/kvm/arm.c ++++ b/arch/arm64/kvm/arm.c +@@ -332,13 +332,15 @@ void kvm_arch_vcpu_blocking(struct kvm_v + */ + preempt_disable(); + kvm_vgic_vmcr_sync(vcpu); +- vgic_v4_put(vcpu, true); ++ vcpu->arch.flags |= KVM_ARM64_VCPU_IN_WFI; ++ vgic_v4_put(vcpu); + preempt_enable(); + } + + void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) + { + preempt_disable(); ++ vcpu->arch.flags &= ~KVM_ARM64_VCPU_IN_WFI; + vgic_v4_load(vcpu); + preempt_enable(); + } +@@ -649,7 +651,7 @@ static void check_vcpu_requests(struct k + if (kvm_check_request(KVM_REQ_RELOAD_GICv4, vcpu)) { + /* The distributor enable bits were changed */ + preempt_disable(); +- vgic_v4_put(vcpu, false); ++ vgic_v4_put(vcpu); + vgic_v4_load(vcpu); + preempt_enable(); + } +--- a/arch/arm64/kvm/vgic/vgic-v3.c ++++ b/arch/arm64/kvm/vgic/vgic-v3.c +@@ -682,7 +682,7 @@ void vgic_v3_put(struct kvm_vcpu *vcpu) + { + struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3; + +- WARN_ON(vgic_v4_put(vcpu, false)); ++ WARN_ON(vgic_v4_put(vcpu)); + + vgic_v3_vmcr_sync(vcpu); + +--- a/arch/arm64/kvm/vgic/vgic-v4.c ++++ b/arch/arm64/kvm/vgic/vgic-v4.c +@@ -310,14 +310,15 @@ void vgic_v4_teardown(struct kvm *kvm) + its_vm->vpes = NULL; + } + +-int vgic_v4_put(struct kvm_vcpu *vcpu, bool need_db) ++int vgic_v4_put(struct kvm_vcpu *vcpu) + { + struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe; + + if (!vgic_supports_direct_msis(vcpu->kvm) || !vpe->resident) + return 0; + +- return its_make_vpe_non_resident(vpe, need_db); ++ return its_make_vpe_non_resident(vpe, ++ vcpu->arch.flags & KVM_ARM64_VCPU_IN_WFI); + } + + int vgic_v4_load(struct kvm_vcpu *vcpu) +@@ -328,6 +329,9 @@ int vgic_v4_load(struct kvm_vcpu *vcpu) + if (!vgic_supports_direct_msis(vcpu->kvm) || vpe->resident) + return 0; + ++ if (vcpu->arch.flags & KVM_ARM64_VCPU_IN_WFI) ++ return 0; ++ + /* + * Before making the VPE resident, make sure the redistributor + * corresponding to our current CPU expects us here. See the +--- a/include/kvm/arm_vgic.h ++++ b/include/kvm/arm_vgic.h +@@ -402,6 +402,6 @@ int kvm_vgic_v4_unset_forwarding(struct + struct kvm_kernel_irq_routing_entry *irq_entry); + + int vgic_v4_load(struct kvm_vcpu *vcpu); +-int vgic_v4_put(struct kvm_vcpu *vcpu, bool need_db); ++int vgic_v4_put(struct kvm_vcpu *vcpu); + + #endif /* __KVM_ARM_VGIC_H */ diff --git a/queue-5.10/series b/queue-5.10/series index 7de7a808206..96717730e6e 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -337,3 +337,4 @@ efi-correct-comment-on-efi_memmap_alloc.patch efi-memmap-move-manipulation-routines-into-x86-arch-tree.patch efi-xen-set-efi_paravirt-for-xen-dom0-boot-on-all-architectures.patch efi-x86-free-efi-memory-map-only-when-installing-a-new-one.patch +kvm-arm64-vgic-v4-make-the-doorbell-request-robust-w.r.t-preemption.patch -- 2.47.3