.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * kvm eventfd support - use eventfd objects to signal various KVM events |
---|
3 | 4 | * |
---|
.. | .. |
---|
6 | 7 | * |
---|
7 | 8 | * Author: |
---|
8 | 9 | * Gregory Haskins <ghaskins@novell.com> |
---|
9 | | - * |
---|
10 | | - * This file is free software; you can redistribute it and/or modify |
---|
11 | | - * it under the terms of version 2 of the GNU General Public License |
---|
12 | | - * as published by the Free Software Foundation. |
---|
13 | | - * |
---|
14 | | - * This program is distributed in the hope that it will be useful, |
---|
15 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
16 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
17 | | - * GNU General Public License for more details. |
---|
18 | | - * |
---|
19 | | - * You should have received a copy of the GNU General Public License |
---|
20 | | - * along with this program; if not, write to the Free Software Foundation, |
---|
21 | | - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. |
---|
22 | 10 | */ |
---|
23 | 11 | |
---|
24 | 12 | #include <linux/kvm_host.h> |
---|
.. | .. |
---|
128 | 116 | struct kvm *kvm = irqfd->kvm; |
---|
129 | 117 | u64 cnt; |
---|
130 | 118 | |
---|
131 | | - /* Make sure irqfd has been initalized in assign path. */ |
---|
| 119 | + /* Make sure irqfd has been initialized in assign path. */ |
---|
132 | 120 | synchronize_srcu(&kvm->irq_srcu); |
---|
133 | 121 | |
---|
134 | 122 | /* |
---|
.. | .. |
---|
220 | 208 | |
---|
221 | 209 | if (flags & EPOLLHUP) { |
---|
222 | 210 | /* The eventfd is closing, detach from KVM */ |
---|
223 | | - unsigned long flags; |
---|
| 211 | + unsigned long iflags; |
---|
224 | 212 | |
---|
225 | | - spin_lock_irqsave(&kvm->irqfds.lock, flags); |
---|
| 213 | + spin_lock_irqsave(&kvm->irqfds.lock, iflags); |
---|
226 | 214 | |
---|
227 | 215 | /* |
---|
228 | 216 | * We must check if someone deactivated the irqfd before |
---|
.. | .. |
---|
236 | 224 | if (irqfd_is_active(irqfd)) |
---|
237 | 225 | irqfd_deactivate(irqfd); |
---|
238 | 226 | |
---|
239 | | - spin_unlock_irqrestore(&kvm->irqfds.lock, flags); |
---|
| 227 | + spin_unlock_irqrestore(&kvm->irqfds.lock, iflags); |
---|
240 | 228 | } |
---|
241 | 229 | |
---|
242 | 230 | return 0; |
---|
.. | .. |
---|
306 | 294 | if (!kvm_arch_irqfd_allowed(kvm, args)) |
---|
307 | 295 | return -EINVAL; |
---|
308 | 296 | |
---|
309 | | - irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL); |
---|
| 297 | + irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL_ACCOUNT); |
---|
310 | 298 | if (!irqfd) |
---|
311 | 299 | return -ENOMEM; |
---|
312 | 300 | |
---|
.. | .. |
---|
315 | 303 | INIT_LIST_HEAD(&irqfd->list); |
---|
316 | 304 | INIT_WORK(&irqfd->inject, irqfd_inject); |
---|
317 | 305 | INIT_WORK(&irqfd->shutdown, irqfd_shutdown); |
---|
318 | | - seqcount_init(&irqfd->irq_entry_sc); |
---|
| 306 | + seqcount_spinlock_init(&irqfd->irq_entry_sc, &kvm->irqfds.lock); |
---|
319 | 307 | |
---|
320 | 308 | f = fdget(args->fd); |
---|
321 | 309 | if (!f.file) { |
---|
.. | .. |
---|
354 | 342 | } |
---|
355 | 343 | |
---|
356 | 344 | if (!irqfd->resampler) { |
---|
357 | | - resampler = kzalloc(sizeof(*resampler), GFP_KERNEL); |
---|
| 345 | + resampler = kzalloc(sizeof(*resampler), |
---|
| 346 | + GFP_KERNEL_ACCOUNT); |
---|
358 | 347 | if (!resampler) { |
---|
359 | 348 | ret = -ENOMEM; |
---|
360 | 349 | mutex_unlock(&kvm->irqfds.resampler_lock); |
---|
.. | .. |
---|
462 | 451 | idx = srcu_read_lock(&kvm->irq_srcu); |
---|
463 | 452 | gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin); |
---|
464 | 453 | if (gsi != -1) |
---|
465 | | - hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list, |
---|
466 | | - link) |
---|
| 454 | + hlist_for_each_entry_srcu(kian, &kvm->irq_ack_notifier_list, |
---|
| 455 | + link, srcu_read_lock_held(&kvm->irq_srcu)) |
---|
467 | 456 | if (kian->gsi == gsi) { |
---|
468 | 457 | srcu_read_unlock(&kvm->irq_srcu, idx); |
---|
469 | 458 | return true; |
---|
.. | .. |
---|
479 | 468 | { |
---|
480 | 469 | struct kvm_irq_ack_notifier *kian; |
---|
481 | 470 | |
---|
482 | | - hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list, |
---|
483 | | - link) |
---|
| 471 | + hlist_for_each_entry_srcu(kian, &kvm->irq_ack_notifier_list, |
---|
| 472 | + link, srcu_read_lock_held(&kvm->irq_srcu)) |
---|
484 | 473 | if (kian->gsi == gsi) |
---|
485 | 474 | kian->irq_acked(kian); |
---|
486 | 475 | } |
---|
.. | .. |
---|
732 | 721 | return false; |
---|
733 | 722 | } |
---|
734 | 723 | |
---|
735 | | - return _val == p->datamatch ? true : false; |
---|
| 724 | + return _val == p->datamatch; |
---|
736 | 725 | } |
---|
737 | 726 | |
---|
738 | 727 | /* MMIO/PIO writes trigger an event if the addr/val match */ |
---|
.. | .. |
---|
806 | 795 | if (IS_ERR(eventfd)) |
---|
807 | 796 | return PTR_ERR(eventfd); |
---|
808 | 797 | |
---|
809 | | - p = kzalloc(sizeof(*p), GFP_KERNEL); |
---|
| 798 | + p = kzalloc(sizeof(*p), GFP_KERNEL_ACCOUNT); |
---|
810 | 799 | if (!p) { |
---|
811 | 800 | ret = -ENOMEM; |
---|
812 | 801 | goto fail; |
---|
.. | .. |
---|
864 | 853 | struct eventfd_ctx *eventfd; |
---|
865 | 854 | struct kvm_io_bus *bus; |
---|
866 | 855 | int ret = -ENOENT; |
---|
| 856 | + bool wildcard; |
---|
867 | 857 | |
---|
868 | 858 | eventfd = eventfd_ctx_fdget(args->fd); |
---|
869 | 859 | if (IS_ERR(eventfd)) |
---|
870 | 860 | return PTR_ERR(eventfd); |
---|
871 | 861 | |
---|
| 862 | + wildcard = !(args->flags & KVM_IOEVENTFD_FLAG_DATAMATCH); |
---|
| 863 | + |
---|
872 | 864 | mutex_lock(&kvm->slots_lock); |
---|
873 | 865 | |
---|
874 | 866 | list_for_each_entry_safe(p, tmp, &kvm->ioeventfds, list) { |
---|
875 | | - bool wildcard = !(args->flags & KVM_IOEVENTFD_FLAG_DATAMATCH); |
---|
876 | 867 | |
---|
877 | 868 | if (p->bus_idx != bus_idx || |
---|
878 | 869 | p->eventfd != eventfd || |
---|