aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/powerpc.c
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2013-04-26 10:53:39 -0400
committerAlexander Graf <agraf@suse.de>2013-05-02 09:28:35 -0400
commited840ee9c8f15a726a1e7b98c9f5cfc49c2a0ff2 (patch)
treecbd985731084194cc944b3cb61647e6f60010d40 /arch/powerpc/kvm/powerpc.c
parent1d6f6b73396859fb13c1222c19d0ec1421777847 (diff)
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>
Diffstat (limited to 'arch/powerpc/kvm/powerpc.c')
-rw-r--r--arch/powerpc/kvm/powerpc.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 31084c6335c9..270773f0d955 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -622,6 +622,8 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu,
622int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, 622int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
623 unsigned int rt, unsigned int bytes, int is_bigendian) 623 unsigned int rt, unsigned int bytes, int is_bigendian)
624{ 624{
625 int idx, ret;
626
625 if (bytes > sizeof(run->mmio.data)) { 627 if (bytes > sizeof(run->mmio.data)) {
626 printk(KERN_ERR "%s: bad MMIO length: %d\n", __func__, 628 printk(KERN_ERR "%s: bad MMIO length: %d\n", __func__,
627 run->mmio.len); 629 run->mmio.len);
@@ -637,8 +639,14 @@ int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
637 vcpu->mmio_is_write = 0; 639 vcpu->mmio_is_write = 0;
638 vcpu->arch.mmio_sign_extend = 0; 640 vcpu->arch.mmio_sign_extend = 0;
639 641
640 if (!kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, run->mmio.phys_addr, 642 idx = srcu_read_lock(&vcpu->kvm->srcu);
641 bytes, &run->mmio.data)) { 643
644 ret = kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, run->mmio.phys_addr,
645 bytes, &run->mmio.data);
646
647 srcu_read_unlock(&vcpu->kvm->srcu, idx);
648
649 if (!ret) {
642 kvmppc_complete_mmio_load(vcpu, run); 650 kvmppc_complete_mmio_load(vcpu, run);
643 vcpu->mmio_needed = 0; 651 vcpu->mmio_needed = 0;
644 return EMULATE_DONE; 652 return EMULATE_DONE;
@@ -663,6 +671,7 @@ int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
663 u64 val, unsigned int bytes, int is_bigendian) 671 u64 val, unsigned int bytes, int is_bigendian)
664{ 672{
665 void *data = run->mmio.data; 673 void *data = run->mmio.data;
674 int idx, ret;
666 675
667 if (bytes > sizeof(run->mmio.data)) { 676 if (bytes > sizeof(run->mmio.data)) {
668 printk(KERN_ERR "%s: bad MMIO length: %d\n", __func__, 677 printk(KERN_ERR "%s: bad MMIO length: %d\n", __func__,
@@ -692,8 +701,14 @@ int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
692 } 701 }
693 } 702 }
694 703
695 if (!kvm_io_bus_write(vcpu->kvm, KVM_MMIO_BUS, run->mmio.phys_addr, 704 idx = srcu_read_lock(&vcpu->kvm->srcu);
696 bytes, &run->mmio.data)) { 705
706 ret = kvm_io_bus_write(vcpu->kvm, KVM_MMIO_BUS, run->mmio.phys_addr,
707 bytes, &run->mmio.data);
708
709 srcu_read_unlock(&vcpu->kvm->srcu, idx);
710
711 if (!ret) {
697 vcpu->mmio_needed = 0; 712 vcpu->mmio_needed = 0;
698 return EMULATE_DONE; 713 return EMULATE_DONE;
699 } 714 }