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

netfilter: nft_set_pipapo_avx2: disable softinterrupts

We need to disable softinterrupts, else we get following problem:

1. pipapo_avx2 called from process context; fpu usable
2. preempt_disable() called, pcpu scratchmap in use
3. softirq handles rx or tx, we re-enter pipapo_avx2
4. fpu busy, fallback to generic non-avx version
5. fallback reuses scratch map and index, which are in use
by the preempted process

Handle this same way as generic version by first disabling
softinterrupts while the scratchmap is in use.

Fixes: f0b3d338064e ("netfilter: nft_set_pipapo_avx2: Add irq_fpu_usable() check, fallback to non-AVX2 version")
Cc: Stefano Brivio <sbrivio@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Florian Westphal and committed by
Pablo Neira Ayuso
a16909ae 3ba359c0

+10 -2
+10 -2
net/netfilter/nft_set_pipapo_avx2.c
··· 1139 1139 bool map_index; 1140 1140 int i, ret = 0; 1141 1141 1142 - if (unlikely(!irq_fpu_usable())) 1143 - return nft_pipapo_lookup(net, set, key, ext); 1142 + local_bh_disable(); 1143 + 1144 + if (unlikely(!irq_fpu_usable())) { 1145 + bool fallback_res = nft_pipapo_lookup(net, set, key, ext); 1146 + 1147 + local_bh_enable(); 1148 + return fallback_res; 1149 + } 1144 1150 1145 1151 m = rcu_dereference(priv->match); 1146 1152 ··· 1161 1155 scratch = *raw_cpu_ptr(m->scratch); 1162 1156 if (unlikely(!scratch)) { 1163 1157 kernel_fpu_end(); 1158 + local_bh_enable(); 1164 1159 return false; 1165 1160 } 1166 1161 ··· 1242 1235 if (i % 2) 1243 1236 scratch->map_index = !map_index; 1244 1237 kernel_fpu_end(); 1238 + local_bh_enable(); 1245 1239 1246 1240 return ret >= 0; 1247 1241 }