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

kvm/ppc: Hold srcu lock when calling kvm_io_bus_read/write

These functions do an srcu_dereference without acquiring the srcu lock
themselves.

Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Alexander Graf <agraf@suse.de>

authored by

Scott Wood and committed by
Alexander Graf
ed840ee9 1d6f6b73

+19 -4
+19 -4
arch/powerpc/kvm/powerpc.c
··· 622 622 int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, 623 623 unsigned int rt, unsigned int bytes, int is_bigendian) 624 624 { 625 + int idx, ret; 626 + 625 627 if (bytes > sizeof(run->mmio.data)) { 626 628 printk(KERN_ERR "%s: bad MMIO length: %d\n", __func__, 627 629 run->mmio.len); ··· 639 637 vcpu->mmio_is_write = 0; 640 638 vcpu->arch.mmio_sign_extend = 0; 641 639 642 - if (!kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, run->mmio.phys_addr, 643 - bytes, &run->mmio.data)) { 640 + idx = srcu_read_lock(&vcpu->kvm->srcu); 641 + 642 + ret = kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, run->mmio.phys_addr, 643 + bytes, &run->mmio.data); 644 + 645 + srcu_read_unlock(&vcpu->kvm->srcu, idx); 646 + 647 + if (!ret) { 644 648 kvmppc_complete_mmio_load(vcpu, run); 645 649 vcpu->mmio_needed = 0; 646 650 return EMULATE_DONE; ··· 671 663 u64 val, unsigned int bytes, int is_bigendian) 672 664 { 673 665 void *data = run->mmio.data; 666 + int idx, ret; 674 667 675 668 if (bytes > sizeof(run->mmio.data)) { 676 669 printk(KERN_ERR "%s: bad MMIO length: %d\n", __func__, ··· 701 692 } 702 693 } 703 694 704 - if (!kvm_io_bus_write(vcpu->kvm, KVM_MMIO_BUS, run->mmio.phys_addr, 705 - bytes, &run->mmio.data)) { 695 + idx = srcu_read_lock(&vcpu->kvm->srcu); 696 + 697 + ret = kvm_io_bus_write(vcpu->kvm, KVM_MMIO_BUS, run->mmio.phys_addr, 698 + bytes, &run->mmio.data); 699 + 700 + srcu_read_unlock(&vcpu->kvm->srcu, idx); 701 + 702 + if (!ret) { 706 703 vcpu->mmio_needed = 0; 707 704 return EMULATE_DONE; 708 705 }