linux/arch/powerpc/kvm
Gautam Menghani a373830f96 KVM: PPC: Book3S HV: Mask off LPCR_MER for a vCPU before running it to avoid spurious interrupts
Running a L2 vCPU (see [1] for terminology) with LPCR_MER bit set and no
pending interrupts results in that L2 vCPU getting an infinite flood of
spurious interrupts. The 'if check' in kvmhv_run_single_vcpu() sets the
LPCR_MER bit if there are pending interrupts.

The spurious flood problem can be observed in 2 cases:
1. Crashing the guest while interrupt heavy workload is running
  a. Start a L2 guest and run an interrupt heavy workload (eg: ipistorm)
  b. While the workload is running, crash the guest (make sure kdump
     is configured)
  c. Any one of the vCPUs of the guest will start getting an infinite
     flood of spurious interrupts.

2. Running LTP stress tests in multiple guests at the same time
   a. Start 4 L2 guests.
   b. Start running LTP stress tests on all 4 guests at same time.
   c. In some time, any one/more of the vCPUs of any of the guests will
      start getting an infinite flood of spurious interrupts.

The root cause of both the above issues is the same:
1. A NMI is sent to a running vCPU that has LPCR_MER bit set.
2. In the NMI path, all registers are refreshed, i.e, H_GUEST_GET_STATE
   is called for all the registers.
3. When H_GUEST_GET_STATE is called for LPCR, the vcpu->arch.vcore->lpcr
   of that vCPU at L1 level gets updated with LPCR_MER set to 1, and this
   new value is always used whenever that vCPU runs, regardless of whether
   there was a pending interrupt.
4. Since LPCR_MER is set, the vCPU in L2 always jumps to the external
   interrupt handler, and this cycle never ends.

Fix the spurious flood by masking off the LPCR_MER bit before running a
L2 vCPU to ensure that it is not set if there are no pending interrupts.

[1] Terminology:
1. L0 : PAPR hypervisor running in HV mode
2. L1 : Linux guest (logical partition) running on top of L0
3. L2 : KVM guest running on top of L1

Fixes: ec0f6639fa ("KVM: PPC: Book3S HV nestedv2: Ensure LPCR_MER bit is passed to the L0")
Cc: stable@vger.kernel.org # v6.8+
Signed-off-by: Gautam Menghani <gautam@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
2024-11-06 11:36:09 +05:30
..
book3s_32_mmu_host.c powerpc/32s: move CTX_TO_VSID() into mmu-hash.h 2021-06-17 00:09:08 +10:00
book3s_32_mmu.c KVM: Use 'unsigned long' as kvm_for_each_vcpu()'s index 2021-12-08 04:24:15 -05:00
book3s_32_sr.S KVM: PPC: Book3S PR: Enable MSR_DR for switch_mmu_context() 2022-05-11 23:03:16 +10:00
book3s_64_entry.S docs: move powerpc under arch 2023-10-10 13:35:55 -06:00
book3s_64_mmu_host.c KVM: Rename mmu_notifier_* to mmu_invalidate_* 2022-08-19 04:05:41 -04:00
book3s_64_mmu_hv.c KVM: delete .change_pte MMU notifier callback 2024-04-11 13:18:27 -04:00
book3s_64_mmu_radix.c mm/powerpc: replace pXd_is_leaf() with pXd_leaf() 2024-03-06 13:04:19 -08:00
book3s_64_mmu.c KVM: Use 'unsigned long' as kvm_for_each_vcpu()'s index 2021-12-08 04:24:15 -05:00
book3s_64_slb.S
book3s_64_vio.c introduce fd_file(), convert all accessors to it. 2024-08-12 22:00:43 -04:00
book3s_emulate.c powerpc: rename SPRN_HID2 define to SPRN_HID2_750FX 2024-05-08 00:25:00 +10:00
book3s_exports.c
book3s_hv_builtin.c KVM: PPC: Book3S HV: Introduce low level MSR accessor 2023-09-14 22:04:24 +10:00
book3s_hv_hmi.c KVM: PPC: Book3S HV P9: Remove subcore HMI handling 2021-11-24 21:09:03 +11:00
book3s_hv_interrupts.S powerpc: Fix objtool unannotated intra-function call warnings 2022-11-15 20:11:47 +11:00
book3s_hv_nested.c treewide: update LLVM Bugzilla links 2024-02-22 15:38:51 -08:00
book3s_hv_nestedv2.c KVM: PPC: Book3S HV nestedv2: Keep nested guest HASHPKEYR in sync 2024-06-06 22:39:04 +10:00
book3s_hv_p9_entry.c KVM: PPC: Use accessors for VCPU registers 2023-09-14 22:04:24 +10:00
book3s_hv_p9_perf.c powerpc/kvm: Remove comment related to moving PMU code to perf subsystem 2022-07-20 22:28:31 +10:00
book3s_hv_ras.c KVM: PPC: Use accessors for VCORE registers 2023-09-14 22:04:24 +10:00
book3s_hv_rm_mmu.c KVM: PPC: Always use the GPR accessors 2023-09-14 22:04:23 +10:00
book3s_hv_rm_xics.c genirq: Convert kstat_irqs to a struct 2024-04-12 17:08:05 +02:00
book3s_hv_rmhandlers.S powerpc: replace #include <asm/export.h> with #include <linux/export.h> 2023-08-16 23:54:48 +10:00
book3s_hv_tm_builtin.c
book3s_hv_tm.c KVM: PPC: Book3S HV Nested: Fix TM softpatch HFAC interrupt emulation 2021-08-25 16:37:17 +10:00
book3s_hv_uvmem.c KVM: PPC: Book3s HV: Hold LPIDs in an unsigned long 2023-09-14 22:04:24 +10:00
book3s_hv.c KVM: PPC: Book3S HV: Mask off LPCR_MER for a vCPU before running it to avoid spurious interrupts 2024-11-06 11:36:09 +05:30
book3s_hv.h KVM: PPC: Book3S HV: Add one-reg interface for HASHPKEYR register 2024-06-06 22:39:04 +10:00
book3s_interrupts.S powerpc: Replace PPC64_ELF_ABI_v{1/2} by CONFIG_PPC64_ELF_ABI_V{1/2} 2022-05-19 23:11:29 +10:00
book3s_mmu_hpte.c
book3s_paired_singles.c KVM: PPC: Make kvmppc_get_last_inst() produce a ppc_inst_t 2023-04-03 15:45:41 +10:00
book3s_pr_papr.c KVM: remove KVM_REQ_UNHALT 2022-09-26 12:37:21 -04:00
book3s_pr.c KVM: PPC: add missing MODULE_DESCRIPTION() macros 2024-07-04 22:20:47 +10:00
book3s_rmhandlers.S KVM: PPC: Enable prefixed instructions for HV KVM and disable for PR KVM 2023-04-03 15:45:59 +10:00
book3s_rtas.c KVM: Add helpers to wrap vcpu->srcu_idx and yell if it's abused 2022-04-21 13:16:11 -04:00
book3s_segment.S KVM: PPC: Book3S 64: move bad_host_intr check to HV handler 2021-06-10 22:12:12 +10:00
book3s_xics.c powerpc: fix typos in comments 2022-05-05 22:12:44 +10:00
book3s_xics.h KVM: PPC: Book3s: Fix warning about xics_rm_h_xirr_x 2022-06-24 12:58:33 +10:00
book3s_xive_native.c powerpc: Use NULL instead of 0 for null pointers 2023-10-19 17:12:47 +11:00
book3s_xive.c powerpc: Fix typos 2024-05-08 00:21:30 +10:00
book3s_xive.h powerpc/xive: remove unused parameter 2022-11-24 23:12:18 +11:00
book3s.c powerpc updates for 6.10 2024-05-17 09:05:46 -07:00
book3s.h KVM: delete .change_pte MMU notifier callback 2024-04-11 13:18:27 -04:00
booke_emulate.c
booke_interrupts.S powerpc: Remove CONFIG_FSL_BOOKE 2022-09-26 22:47:37 +10:00
booke.c KVM: PPC: Fetch prefixed instructions from the guest 2023-04-03 15:45:50 +10:00
booke.h KVM: PPC: BookE: Fix W=1 warnings 2023-04-03 14:54:20 +10:00
bookehv_interrupts.S KVM: PPC: Fetch prefixed instructions from the guest 2023-04-03 15:45:50 +10:00
e500_emulate.c KVM: Use 'unsigned long' as kvm_for_each_vcpu()'s index 2021-12-08 04:24:15 -05:00
e500_mmu_host.c KVM: delete .change_pte MMU notifier callback 2024-04-11 13:18:27 -04:00
e500_mmu_host.h
e500_mmu.c
e500.c KVM: Drop kvm_arch_check_processor_compat() hook 2022-12-29 15:41:28 -05:00
e500.h powerpc: Remove CONFIG_PPC_BOOK3E_MMU 2022-09-26 23:00:14 +10:00
e500mc.c powerpc/inst: add PPC_TLBILX_LPID 2023-08-16 23:54:48 +10:00
emulate_loadstore.c KVM: PPC: Reduce reliance on analyse_instr() in mmio emulation 2023-12-07 23:33:08 +11:00
emulate.c KVM: PPC: Fetch prefixed instructions from the guest 2023-04-03 15:45:50 +10:00
fpu.S powerpc/32: Fix objtool unannotated intra-function call warnings 2022-11-18 19:00:06 +11:00
guest-state-buffer.c KVM: PPC: Add support for nestedv2 guests 2023-09-14 22:04:24 +10:00
Kconfig kvm: move "select IRQ_BYPASS_MANAGER" to common code 2024-02-08 08:45:34 -05:00
Makefile KVM: PPC: Add support for nestedv2 guests 2023-09-14 22:04:24 +10:00
mpic.c
powerpc.c introduce fd_file(), convert all accessors to it. 2024-08-12 22:00:43 -04:00
test-guest-state-buffer.c KVM: PPC: add missing MODULE_DESCRIPTION() macros 2024-07-04 22:20:47 +10:00
timing.c KVM: PPC: Merge powerpc's debugfs entry content into generic entry 2022-02-02 20:30:26 +11:00
timing.h KVM: PPC: Merge powerpc's debugfs entry content into generic entry 2022-02-02 20:30:26 +11:00
tm.S powerpc: replace #include <asm/export.h> with #include <linux/export.h> 2023-08-16 23:54:48 +10:00
trace_book3s.h
trace_booke.h KVM: Move arm64's MMU notifier trace events to generic code 2021-04-17 08:30:56 -04:00
trace_hv.h KVM: PPC: Book3S HV nestedv2: Add support for reading VPA counters for pseries guests 2024-06-03 22:06:28 +10:00
trace_pr.h
trace.h