diff options
author | Scott Wood <scottwood@freescale.com> | 2013-04-26 14:53:39 +0000 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2013-05-02 15:28:35 +0200 |
commit | ed840ee9c8f15a726a1e7b98c9f5cfc49c2a0ff2 (patch) | |
tree | cbd985731084194cc944b3cb61647e6f60010d40 | |
parent | 1d6f6b73396859fb13c1222c19d0ec1421777847 (diff) | |
download | lwn-ed840ee9c8f15a726a1e7b98c9f5cfc49c2a0ff2.tar.gz lwn-ed840ee9c8f15a726a1e7b98c9f5cfc49c2a0ff2.zip |
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>
-rw-r--r-- | arch/powerpc/kvm/powerpc.c | 23 |
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, int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, unsigned int rt, unsigned int bytes, int is_bigendian) { + int idx, ret; + if (bytes > sizeof(run->mmio.data)) { printk(KERN_ERR "%s: bad MMIO length: %d\n", __func__, run->mmio.len); @@ -637,8 +639,14 @@ int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, vcpu->mmio_is_write = 0; vcpu->arch.mmio_sign_extend = 0; - if (!kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, run->mmio.phys_addr, - bytes, &run->mmio.data)) { + idx = srcu_read_lock(&vcpu->kvm->srcu); + + ret = kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, run->mmio.phys_addr, + bytes, &run->mmio.data); + + srcu_read_unlock(&vcpu->kvm->srcu, idx); + + if (!ret) { kvmppc_complete_mmio_load(vcpu, run); vcpu->mmio_needed = 0; return EMULATE_DONE; @@ -663,6 +671,7 @@ int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, u64 val, unsigned int bytes, int is_bigendian) { void *data = run->mmio.data; + int idx, ret; if (bytes > sizeof(run->mmio.data)) { 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, } } - if (!kvm_io_bus_write(vcpu->kvm, KVM_MMIO_BUS, run->mmio.phys_addr, - bytes, &run->mmio.data)) { + idx = srcu_read_lock(&vcpu->kvm->srcu); + + ret = kvm_io_bus_write(vcpu->kvm, KVM_MMIO_BUS, run->mmio.phys_addr, + bytes, &run->mmio.data); + + srcu_read_unlock(&vcpu->kvm->srcu, idx); + + if (!ret) { vcpu->mmio_needed = 0; return EMULATE_DONE; } |