17854f1c81
25833-32on64-bogus-pt_base-adjust.patch 25835-adjust-rcu-lock-domain.patch 25836-VT-d-S3-MSI-resume.patch 25850-tmem-xsa-15-1.patch 25851-tmem-xsa-15-2.patch 25852-tmem-xsa-15-3.patch 25853-tmem-xsa-15-4.patch 25854-tmem-xsa-15-5.patch 25855-tmem-xsa-15-6.patch 25856-tmem-xsa-15-7.patch 25857-tmem-xsa-15-8.patch 25858-tmem-xsa-15-9.patch 25859-tmem-missing-break.patch 25860-tmem-cleanup.patch 25861-x86-early-fixmap.patch 25862-sercon-non-com.patch 25863-sercon-ehci-dbgp.patch 25864-sercon-unused.patch 25866-sercon-ns16550-pci-irq.patch 25867-sercon-ns16550-parse.patch 25874-x86-EFI-chain-cfg.patch 25909-xenpm-consistent.patch OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=201
275 lines
7.5 KiB
Diff
275 lines
7.5 KiB
Diff
# HG changeset patch
|
|
# User Jan Beulich <jbeulich@suse.com>
|
|
# Date 1347033492 -7200
|
|
# Node ID c70d70d85306b3e4a0538353be131100c5ee38d5
|
|
# Parent 0376c85caaf34fe3cc8c3327f7a1d9ecd6f070b4
|
|
adjust a few RCU domain locking calls
|
|
|
|
x86's do_physdev_op() had a case where the locking was entirely
|
|
superfluous. Its physdev_map_pirq() further had a case where the lock
|
|
was being obtained too early, needlessly complicating early exit paths.
|
|
|
|
Grant table code had two open coded instances of
|
|
rcu_lock_target_domain_by_id(), and a third code section could be
|
|
consolidated by using the newly introduced helper function.
|
|
|
|
The memory hypercall code had two more instances of open coding
|
|
rcu_lock_target_domain_by_id(), but note that here this is not just
|
|
cleanup, but also fixes an error return path in memory_exchange() to
|
|
actually return an error.
|
|
|
|
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
|
Acked-by: Keir Fraser <keir@xen.org>
|
|
|
|
--- a/xen/arch/x86/physdev.c
|
|
+++ b/xen/arch/x86/physdev.c
|
|
@@ -90,14 +90,10 @@ static int physdev_hvm_map_pirq(
|
|
int physdev_map_pirq(domid_t domid, int type, int *index, int *pirq_p,
|
|
struct msi_info *msi)
|
|
{
|
|
- struct domain *d;
|
|
+ struct domain *d = current->domain;
|
|
int pirq, irq, ret = 0;
|
|
void *map_data = NULL;
|
|
|
|
- ret = rcu_lock_target_domain_by_id(domid, &d);
|
|
- if ( ret )
|
|
- return ret;
|
|
-
|
|
if ( domid == DOMID_SELF && is_hvm_domain(d) )
|
|
{
|
|
/*
|
|
@@ -105,14 +101,15 @@ int physdev_map_pirq(domid_t domid, int
|
|
* calls back into itself and deadlocks on hvm_domain.irq_lock.
|
|
*/
|
|
if ( !is_hvm_pv_evtchn_domain(d) )
|
|
- {
|
|
- ret = -EINVAL;
|
|
- goto free_domain;
|
|
- }
|
|
- ret = physdev_hvm_map_pirq(d, type, index, pirq_p);
|
|
- goto free_domain;
|
|
+ return -EINVAL;
|
|
+
|
|
+ return physdev_hvm_map_pirq(d, type, index, pirq_p);
|
|
}
|
|
|
|
+ ret = rcu_lock_target_domain_by_id(domid, &d);
|
|
+ if ( ret )
|
|
+ return ret;
|
|
+
|
|
if ( !IS_PRIV_FOR(current->domain, d) )
|
|
{
|
|
ret = -EPERM;
|
|
@@ -696,13 +693,12 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
|
|
}
|
|
case PHYSDEVOP_get_free_pirq: {
|
|
struct physdev_get_free_pirq out;
|
|
- struct domain *d;
|
|
+ struct domain *d = v->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);
|
|
@@ -717,7 +713,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
|
|
}
|
|
|
|
spin_unlock(&d->event_lock);
|
|
- rcu_unlock_domain(d);
|
|
|
|
if ( ret >= 0 )
|
|
{
|
|
--- a/xen/common/grant_table.c
|
|
+++ b/xen/common/grant_table.c
|
|
@@ -24,7 +24,7 @@
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
-#include <xen/config.h>
|
|
+#include <xen/err.h>
|
|
#include <xen/iocap.h>
|
|
#include <xen/lib.h>
|
|
#include <xen/sched.h>
|
|
@@ -195,6 +195,30 @@ double_gt_unlock(struct grant_table *lgt
|
|
spin_unlock(&rgt->lock);
|
|
}
|
|
|
|
+static struct domain *gt_lock_target_domain_by_id(domid_t dom)
|
|
+{
|
|
+ struct domain *d;
|
|
+ int rc = GNTST_general_error;
|
|
+
|
|
+ switch ( rcu_lock_target_domain_by_id(dom, &d) )
|
|
+ {
|
|
+ case 0:
|
|
+ return d;
|
|
+
|
|
+ case -ESRCH:
|
|
+ gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
|
|
+ rc = GNTST_bad_domain;
|
|
+ break;
|
|
+
|
|
+ case -EPERM:
|
|
+ rc = GNTST_permission_denied;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ ASSERT(rc < 0 && -rc <= MAX_ERRNO);
|
|
+ return ERR_PTR(rc);
|
|
+}
|
|
+
|
|
static inline int
|
|
__get_maptrack_handle(
|
|
struct grant_table *t)
|
|
@@ -1261,7 +1285,6 @@ gnttab_setup_table(
|
|
struct grant_table *gt;
|
|
int i;
|
|
unsigned long gmfn;
|
|
- domid_t dom;
|
|
|
|
if ( count != 1 )
|
|
return -EINVAL;
|
|
@@ -1281,25 +1304,11 @@ gnttab_setup_table(
|
|
goto out1;
|
|
}
|
|
|
|
- dom = op.dom;
|
|
- if ( dom == DOMID_SELF )
|
|
+ d = gt_lock_target_domain_by_id(op.dom);
|
|
+ if ( IS_ERR(d) )
|
|
{
|
|
- d = rcu_lock_current_domain();
|
|
- }
|
|
- else
|
|
- {
|
|
- if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
|
|
- {
|
|
- gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
|
|
- op.status = GNTST_bad_domain;
|
|
- goto out1;
|
|
- }
|
|
-
|
|
- if ( unlikely(!IS_PRIV_FOR(current->domain, d)) )
|
|
- {
|
|
- op.status = GNTST_permission_denied;
|
|
- goto out2;
|
|
- }
|
|
+ op.status = PTR_ERR(d);
|
|
+ goto out1;
|
|
}
|
|
|
|
if ( xsm_grant_setup(current->domain, d) )
|
|
@@ -1352,7 +1361,6 @@ gnttab_query_size(
|
|
{
|
|
struct gnttab_query_size op;
|
|
struct domain *d;
|
|
- domid_t dom;
|
|
int rc;
|
|
|
|
if ( count != 1 )
|
|
@@ -1364,25 +1372,11 @@ gnttab_query_size(
|
|
return -EFAULT;
|
|
}
|
|
|
|
- dom = op.dom;
|
|
- if ( dom == DOMID_SELF )
|
|
- {
|
|
- d = rcu_lock_current_domain();
|
|
- }
|
|
- else
|
|
+ d = gt_lock_target_domain_by_id(op.dom);
|
|
+ if ( IS_ERR(d) )
|
|
{
|
|
- if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
|
|
- {
|
|
- gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
|
|
- op.status = GNTST_bad_domain;
|
|
- goto query_out;
|
|
- }
|
|
-
|
|
- if ( unlikely(!IS_PRIV_FOR(current->domain, d)) )
|
|
- {
|
|
- op.status = GNTST_permission_denied;
|
|
- goto query_out_unlock;
|
|
- }
|
|
+ op.status = PTR_ERR(d);
|
|
+ goto query_out;
|
|
}
|
|
|
|
rc = xsm_grant_query_size(current->domain, d);
|
|
@@ -2251,15 +2245,10 @@ gnttab_get_status_frames(XEN_GUEST_HANDL
|
|
return -EFAULT;
|
|
}
|
|
|
|
- rc = rcu_lock_target_domain_by_id(op.dom, &d);
|
|
- if ( rc < 0 )
|
|
+ d = gt_lock_target_domain_by_id(op.dom);
|
|
+ if ( IS_ERR(d) )
|
|
{
|
|
- if ( rc == -ESRCH )
|
|
- op.status = GNTST_bad_domain;
|
|
- else if ( rc == -EPERM )
|
|
- op.status = GNTST_permission_denied;
|
|
- else
|
|
- op.status = GNTST_general_error;
|
|
+ op.status = PTR_ERR(d);
|
|
goto out1;
|
|
}
|
|
rc = xsm_grant_setup(current->domain, d);
|
|
--- a/xen/common/memory.c
|
|
+++ b/xen/common/memory.c
|
|
@@ -329,22 +329,9 @@ static long memory_exchange(XEN_GUEST_HA
|
|
out_chunk_order = exch.in.extent_order - exch.out.extent_order;
|
|
}
|
|
|
|
- if ( likely(exch.in.domid == DOMID_SELF) )
|
|
- {
|
|
- d = rcu_lock_current_domain();
|
|
- }
|
|
- else
|
|
- {
|
|
- if ( (d = rcu_lock_domain_by_id(exch.in.domid)) == NULL )
|
|
- goto fail_early;
|
|
-
|
|
- if ( !IS_PRIV_FOR(current->domain, d) )
|
|
- {
|
|
- rcu_unlock_domain(d);
|
|
- rc = -EPERM;
|
|
- goto fail_early;
|
|
- }
|
|
- }
|
|
+ rc = rcu_lock_target_domain_by_id(exch.in.domid, &d);
|
|
+ if ( rc )
|
|
+ goto fail_early;
|
|
|
|
memflags |= MEMF_bits(domain_clamp_alloc_bitsize(
|
|
d,
|
|
@@ -583,20 +570,8 @@ long do_memory_op(unsigned long cmd, XEN
|
|
&& (reservation.mem_flags & XENMEMF_populate_on_demand) )
|
|
args.memflags |= MEMF_populate_on_demand;
|
|
|
|
- if ( likely(reservation.domid == DOMID_SELF) )
|
|
- {
|
|
- d = rcu_lock_current_domain();
|
|
- }
|
|
- else
|
|
- {
|
|
- if ( (d = rcu_lock_domain_by_id(reservation.domid)) == NULL )
|
|
- return start_extent;
|
|
- if ( !IS_PRIV_FOR(current->domain, d) )
|
|
- {
|
|
- rcu_unlock_domain(d);
|
|
- return start_extent;
|
|
- }
|
|
- }
|
|
+ if ( unlikely(rcu_lock_target_domain_by_id(reservation.domid, &d)) )
|
|
+ return start_extent;
|
|
args.domain = d;
|
|
|
|
rc = xsm_memory_adjust_reservation(current->domain, d);
|