diff options
author | Jan Beulich <jbeulich@suse.com> | 2012-09-05 15:09:48 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2012-09-05 15:09:48 +0200 |
commit | e3375c7ffb90a8f72c219109840b8b6e51a10a12 (patch) | |
tree | df96645cdbf8d2aeffaf5809dba588a76de46969 | |
parent | 4f8b1ea9753add5fced5024c6bded2eb30c69916 (diff) | |
download | xen-e3375c7ffb90a8f72c219109840b8b6e51a10a12.tar.gz xen-e3375c7ffb90a8f72c219109840b8b6e51a10a12.tar.bz2 xen-e3375c7ffb90a8f72c219109840b8b6e51a10a12.zip |
x86: fix RCU locking in PHYSDEVOP_get_free_pirq
Apart from properly pairing locks with unlocks, also reduce the lock
scope - no need to do the copy_{from,to}_guest()-s inside the protected
region.
I actually wonder whether the RCU locks are needed here at all.
Reported-by: Tim Deegan <tim@xen.org>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
-rw-r--r-- | xen/arch/x86/physdev.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c index a39d6ac6b4..8e7bc24b62 100644 --- a/xen/arch/x86/physdev.c +++ b/xen/arch/x86/physdev.c @@ -698,13 +698,13 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg) struct physdev_get_free_pirq out; struct domain *d; - d = rcu_lock_current_domain(); - ret = -EFAULT; if ( copy_from_guest(&out, arg, 1) != 0 ) break; + d = rcu_lock_current_domain(); spin_lock(&d->event_lock); + ret = get_free_pirq(d, out.type); if ( ret >= 0 ) { @@ -715,7 +715,9 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg) else ret = -ENOMEM; } + spin_unlock(&d->event_lock); + rcu_unlock_domain(d); if ( ret >= 0 ) { @@ -723,7 +725,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg) ret = copy_to_guest(arg, &out, 1) ? -EFAULT : 0; } - rcu_unlock_domain(d); break; } default: |