Re: [PATCH] powerpc/64s: Fix native_hpte_remove() to be irq-safe

2023-07-16 Thread Michael Ellerman
On Wed, 17 May 2023 22:30:33 +1000, Michael Ellerman wrote:
> Lockdep warns that the use of the hpte_lock in native_hpte_remove() is
> not safe against an IRQ coming in:
> 
>   
>   WARNING: inconsistent lock state
>   6.4.0-rc2-g0c54f4d30ecc #1 Not tainted
>   
>   inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage.
>   qemu-system-ppc/93865 [HC0[0]:SC0[0]:HE1:SE1] takes:
>   c21f5180 (hpte_lock){+.?.}-{0:0}, at: native_lock_hpte+0x8/0xd0
>   {IN-SOFTIRQ-W} state was registered at:
> lock_acquire+0x134/0x3f0
> native_lock_hpte+0x44/0xd0
> native_hpte_insert+0xd4/0x2a0
> __hash_page_64K+0x218/0x4f0
> hash_page_mm+0x464/0x840
> do_hash_fault+0x11c/0x260
> data_access_common_virt+0x210/0x220
> __ip_select_ident+0x140/0x150
> ...
> net_rx_action+0x3bc/0x440
> __do_softirq+0x180/0x534
> ...
> sys_sendmmsg+0x34/0x50
> system_call_exception+0x128/0x320
> system_call_common+0x160/0x2e4
>   ...
>Possible unsafe locking scenario:
> 
> [...]

Applied to powerpc/fixes.

[1/1] powerpc/64s: Fix native_hpte_remove() to be irq-safe
  https://git.kernel.org/powerpc/c/8bbe9fee5848371d4af101be445303cac8d880c5

cheers


[PATCH] powerpc/64s: Fix native_hpte_remove() to be irq-safe

2023-05-17 Thread Michael Ellerman
Lockdep warns that the use of the hpte_lock in native_hpte_remove() is
not safe against an IRQ coming in:

  
  WARNING: inconsistent lock state
  6.4.0-rc2-g0c54f4d30ecc #1 Not tainted
  
  inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage.
  qemu-system-ppc/93865 [HC0[0]:SC0[0]:HE1:SE1] takes:
  c21f5180 (hpte_lock){+.?.}-{0:0}, at: native_lock_hpte+0x8/0xd0
  {IN-SOFTIRQ-W} state was registered at:
lock_acquire+0x134/0x3f0
native_lock_hpte+0x44/0xd0
native_hpte_insert+0xd4/0x2a0
__hash_page_64K+0x218/0x4f0
hash_page_mm+0x464/0x840
do_hash_fault+0x11c/0x260
data_access_common_virt+0x210/0x220
__ip_select_ident+0x140/0x150
...
net_rx_action+0x3bc/0x440
__do_softirq+0x180/0x534
...
sys_sendmmsg+0x34/0x50
system_call_exception+0x128/0x320
system_call_common+0x160/0x2e4
  ...
   Possible unsafe locking scenario:

 CPU0
 
lock(hpte_lock);

  lock(hpte_lock);

   *** DEADLOCK ***
  ...
  Call Trace:
dump_stack_lvl+0x98/0xe0 (unreliable)
print_usage_bug.part.0+0x250/0x278
mark_lock+0xc9c/0xd30
__lock_acquire+0x440/0x1ca0
lock_acquire+0x134/0x3f0
native_lock_hpte+0x44/0xd0
native_hpte_remove+0xb0/0x190
kvmppc_mmu_map_page+0x650/0x698 [kvm_pr]
kvmppc_handle_pagefault+0x534/0x6e8 [kvm_pr]
kvmppc_handle_exit_pr+0x6d8/0xe90 [kvm_pr]
after_sprg3_load+0x80/0x90 [kvm_pr]
kvmppc_vcpu_run_pr+0x108/0x270 [kvm_pr]
kvmppc_vcpu_run+0x34/0x48 [kvm]
kvm_arch_vcpu_ioctl_run+0x340/0x470 [kvm]
kvm_vcpu_ioctl+0x338/0x8b8 [kvm]
sys_ioctl+0x7c4/0x13e0
system_call_exception+0x128/0x320
system_call_common+0x160/0x2e4

I suspect kvm_pr is the only caller that doesn't already have IRQs
disabled, which is why this hasn't been reported previously.

Fix it by disabling IRQs in native_hpte_remove().

Fixes: 35159b5717fa ("powerpc/64s: make HPTE lock and native_tlbie_lock 
irq-safe")
Cc: sta...@vger.kernel.org # v6.1+
Signed-off-by: Michael Ellerman 
---
 arch/powerpc/mm/book3s64/hash_native.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/mm/book3s64/hash_native.c 
b/arch/powerpc/mm/book3s64/hash_native.c
index 9342e79870df..430d1d935a7c 100644
--- a/arch/powerpc/mm/book3s64/hash_native.c
+++ b/arch/powerpc/mm/book3s64/hash_native.c
@@ -328,10 +328,12 @@ static long native_hpte_insert(unsigned long hpte_group, 
unsigned long vpn,
 
 static long native_hpte_remove(unsigned long hpte_group)
 {
+   unsigned long hpte_v, flags;
struct hash_pte *hptep;
int i;
int slot_offset;
-   unsigned long hpte_v;
+
+   local_irq_save(flags);
 
DBG_LOW("remove(group=%lx)\n", hpte_group);
 
@@ -356,13 +358,16 @@ static long native_hpte_remove(unsigned long hpte_group)
slot_offset &= 0x7;
}
 
-   if (i == HPTES_PER_GROUP)
-   return -1;
+   if (i == HPTES_PER_GROUP) {
+   i = -1;
+   goto out;
+   }
 
/* Invalidate the hpte. NOTE: this also unlocks it */
release_hpte_lock();
hptep->v = 0;
-
+out:
+   local_irq_restore(flags);
return i;
 }
 
-- 
2.40.1