# git rev-parse -q --verify a373830f96db288a3eb43a8692b6bcd0bd88dfe1^{commit} a373830f96db288a3eb43a8692b6bcd0bd88dfe1 already have revision, skipping fetch # git checkout -q -f -B kisskb a373830f96db288a3eb43a8692b6bcd0bd88dfe1 # git clean -qxdf # < git log -1 # commit a373830f96db288a3eb43a8692b6bcd0bd88dfe1 # Author: Gautam Menghani # Date: Mon Oct 28 14:34:09 2024 +0530 # # 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: ec0f6639fa88 ("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 # Signed-off-by: Madhavan Srinivasan # < /opt/cross/kisskb/korg/gcc-5.5.0-nolibc/powerpc64-linux/bin/powerpc64-linux-gcc --version # < /opt/cross/kisskb/korg/gcc-5.5.0-nolibc/powerpc64-linux/bin/powerpc64-linux-ld --version # < git log --format=%s --max-count=1 a373830f96db288a3eb43a8692b6bcd0bd88dfe1 # make -s -j 32 ARCH=powerpc O=/kisskb/build/powerpc-fixes_85xx_ge_imp3a_defconfig_powerpc-gcc5 CROSS_COMPILE=/opt/cross/kisskb/korg/gcc-5.5.0-nolibc/powerpc64-linux/bin/powerpc64-linux- 85xx/ge_imp3a_defconfig # < make -s -j 32 ARCH=powerpc O=/kisskb/build/powerpc-fixes_85xx_ge_imp3a_defconfig_powerpc-gcc5 CROSS_COMPILE=/opt/cross/kisskb/korg/gcc-5.5.0-nolibc/powerpc64-linux/bin/powerpc64-linux- help # make -s -j 32 ARCH=powerpc O=/kisskb/build/powerpc-fixes_85xx_ge_imp3a_defconfig_powerpc-gcc5 CROSS_COMPILE=/opt/cross/kisskb/korg/gcc-5.5.0-nolibc/powerpc64-linux/bin/powerpc64-linux- olddefconfig # make -s -j 32 ARCH=powerpc O=/kisskb/build/powerpc-fixes_85xx_ge_imp3a_defconfig_powerpc-gcc5 CROSS_COMPILE=/opt/cross/kisskb/korg/gcc-5.5.0-nolibc/powerpc64-linux/bin/powerpc64-linux- /kisskb/src/kernel/locking/spinlock.c:68:17: warning: no previous prototype for '__raw_spin_lock' [-Wmissing-prototypes] void __lockfunc __raw_##op##_lock(locktype##_t *lock) \ ^ /kisskb/src/kernel/locking/spinlock.c:126:1: note: in expansion of macro 'BUILD_LOCK_OPS' BUILD_LOCK_OPS(spin, raw_spinlock); ^ /kisskb/src/kernel/locking/spinlock.c:80:26: warning: no previous prototype for '__raw_spin_lock_irqsave' [-Wmissing-prototypes] unsigned long __lockfunc __raw_##op##_lock_irqsave(locktype##_t *lock) \ ^ /kisskb/src/kernel/locking/spinlock.c:126:1: note: in expansion of macro 'BUILD_LOCK_OPS' BUILD_LOCK_OPS(spin, raw_spinlock); ^ /kisskb/src/kernel/locking/spinlock.c:98:17: warning: no previous prototype for '__raw_spin_lock_irq' [-Wmissing-prototypes] void __lockfunc __raw_##op##_lock_irq(locktype##_t *lock) \ ^ /kisskb/src/kernel/locking/spinlock.c:126:1: note: in expansion of macro 'BUILD_LOCK_OPS' BUILD_LOCK_OPS(spin, raw_spinlock); ^ /kisskb/src/kernel/locking/spinlock.c:103:17: warning: no previous prototype for '__raw_spin_lock_bh' [-Wmissing-prototypes] void __lockfunc __raw_##op##_lock_bh(locktype##_t *lock) \ ^ /kisskb/src/kernel/locking/spinlock.c:126:1: note: in expansion of macro 'BUILD_LOCK_OPS' BUILD_LOCK_OPS(spin, raw_spinlock); ^ /kisskb/src/kernel/locking/spinlock.c:68:17: warning: no previous prototype for '__raw_read_lock' [-Wmissing-prototypes] void __lockfunc __raw_##op##_lock(locktype##_t *lock) \ ^ /kisskb/src/kernel/locking/spinlock.c:129:1: note: in expansion of macro 'BUILD_LOCK_OPS' BUILD_LOCK_OPS(read, rwlock); ^ /kisskb/src/kernel/locking/spinlock.c:80:26: warning: no previous prototype for '__raw_read_lock_irqsave' [-Wmissing-prototypes] unsigned long __lockfunc __raw_##op##_lock_irqsave(locktype##_t *lock) \ ^ /kisskb/src/kernel/locking/spinlock.c:129:1: note: in expansion of macro 'BUILD_LOCK_OPS' BUILD_LOCK_OPS(read, rwlock); ^ /kisskb/src/kernel/locking/spinlock.c:98:17: warning: no previous prototype for '__raw_read_lock_irq' [-Wmissing-prototypes] void __lockfunc __raw_##op##_lock_irq(locktype##_t *lock) \ ^ /kisskb/src/kernel/locking/spinlock.c:129:1: note: in expansion of macro 'BUILD_LOCK_OPS' BUILD_LOCK_OPS(read, rwlock); ^ /kisskb/src/kernel/locking/spinlock.c:103:17: warning: no previous prototype for '__raw_read_lock_bh' [-Wmissing-prototypes] void __lockfunc __raw_##op##_lock_bh(locktype##_t *lock) \ ^ /kisskb/src/kernel/locking/spinlock.c:129:1: note: in expansion of macro 'BUILD_LOCK_OPS' BUILD_LOCK_OPS(read, rwlock); ^ /kisskb/src/kernel/locking/spinlock.c:68:17: warning: no previous prototype for '__raw_write_lock' [-Wmissing-prototypes] void __lockfunc __raw_##op##_lock(locktype##_t *lock) \ ^ /kisskb/src/kernel/locking/spinlock.c:130:1: note: in expansion of macro 'BUILD_LOCK_OPS' BUILD_LOCK_OPS(write, rwlock); ^ /kisskb/src/kernel/locking/spinlock.c:80:26: warning: no previous prototype for '__raw_write_lock_irqsave' [-Wmissing-prototypes] unsigned long __lockfunc __raw_##op##_lock_irqsave(locktype##_t *lock) \ ^ /kisskb/src/kernel/locking/spinlock.c:130:1: note: in expansion of macro 'BUILD_LOCK_OPS' BUILD_LOCK_OPS(write, rwlock); ^ /kisskb/src/kernel/locking/spinlock.c:98:17: warning: no previous prototype for '__raw_write_lock_irq' [-Wmissing-prototypes] void __lockfunc __raw_##op##_lock_irq(locktype##_t *lock) \ ^ /kisskb/src/kernel/locking/spinlock.c:130:1: note: in expansion of macro 'BUILD_LOCK_OPS' BUILD_LOCK_OPS(write, rwlock); ^ /kisskb/src/kernel/locking/spinlock.c:103:17: warning: no previous prototype for '__raw_write_lock_bh' [-Wmissing-prototypes] void __lockfunc __raw_##op##_lock_bh(locktype##_t *lock) \ ^ /kisskb/src/kernel/locking/spinlock.c:130:1: note: in expansion of macro 'BUILD_LOCK_OPS' BUILD_LOCK_OPS(write, rwlock); ^ cc1: warning: unrecognized command line option '-Wno-shift-negative-value' cc1: warning: unrecognized command line option '-Wno-stringop-overflow' Completed OK # rm -rf /kisskb/build/powerpc-fixes_85xx_ge_imp3a_defconfig_powerpc-gcc5 # Build took: 0:01:02.749975