From: Jan Beulich <jbeulich@suse.com>
To: "xen-devel@lists.xenproject.org" <xen-devel@lists.xenproject.org>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>,
George Dunlap <George.Dunlap@eu.citrix.com>,
Ian Jackson <iwj@xenproject.org>, Julien Grall <julien@xen.org>,
Wei Liu <wl@xen.org>, Stefano Stabellini <sstabellini@kernel.org>
Subject: [PATCH v5 4/6] evtchn: add helper for port_is_valid() + evtchn_from_port()
Date: Wed, 27 Jan 2021 09:16:59 +0100 [thread overview]
Message-ID: <cf871b03-35e5-a81e-feca-a0c6d71b1c30@suse.com> (raw)
In-Reply-To: <306e62e8-9070-2db9-c959-858465c50c1d@suse.com>
The combination is pretty common, so adding a simple local helper seems
worthwhile. Make it const- and type-correct, in turn requiring the
two called function to also be const-correct (and at this occasion also
make them type-correct).
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Julien Grall <jgrall@amazon.com>
---
v4: New.
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -147,6 +147,11 @@ static bool virq_is_global(unsigned int
return true;
}
+static struct evtchn *_evtchn_from_port(const struct domain *d,
+ evtchn_port_t port)
+{
+ return port_is_valid(d, port) ? evtchn_from_port(d, port) : NULL;
+}
static struct evtchn *alloc_evtchn_bucket(struct domain *d, unsigned int port)
{
@@ -369,9 +374,9 @@ static long evtchn_bind_interdomain(evtc
ERROR_EXIT(lport);
lchn = evtchn_from_port(ld, lport);
- if ( !port_is_valid(rd, rport) )
+ rchn = _evtchn_from_port(rd, rport);
+ if ( !rchn )
ERROR_EXIT_DOM(-EINVAL, rd);
- rchn = evtchn_from_port(rd, rport);
if ( (rchn->state != ECS_UNBOUND) ||
(rchn->u.unbound.remote_domid != ld->domain_id) )
ERROR_EXIT_DOM(-EINVAL, rd);
@@ -606,15 +611,12 @@ static long evtchn_bind_pirq(evtchn_bind
int evtchn_close(struct domain *d1, int port1, bool guest)
{
struct domain *d2 = NULL;
- struct evtchn *chn1, *chn2;
- int port2;
+ struct evtchn *chn1 = _evtchn_from_port(d1, port1), *chn2;
long rc = 0;
- if ( !port_is_valid(d1, port1) )
+ if ( !chn1 )
return -EINVAL;
- chn1 = evtchn_from_port(d1, port1);
-
again:
write_lock(&d1->event_lock);
@@ -700,10 +702,8 @@ int evtchn_close(struct domain *d1, int
goto out;
}
- port2 = chn1->u.interdomain.remote_port;
- BUG_ON(!port_is_valid(d2, port2));
-
- chn2 = evtchn_from_port(d2, port2);
+ chn2 = _evtchn_from_port(d2, chn1->u.interdomain.remote_port);
+ BUG_ON(!chn2);
BUG_ON(chn2->state != ECS_INTERDOMAIN);
BUG_ON(chn2->u.interdomain.remote_dom != d1);
@@ -741,15 +741,13 @@ int evtchn_close(struct domain *d1, int
int evtchn_send(struct domain *ld, unsigned int lport)
{
- struct evtchn *lchn, *rchn;
+ struct evtchn *lchn = _evtchn_from_port(ld, lport), *rchn;
struct domain *rd;
int rport, ret = 0;
- if ( !port_is_valid(ld, lport) )
+ if ( !lchn )
return -EINVAL;
- lchn = evtchn_from_port(ld, lport);
-
evtchn_read_lock(lchn);
/* Guest cannot send via a Xen-attached event channel. */
@@ -961,7 +959,6 @@ int evtchn_status(evtchn_status_t *statu
{
struct domain *d;
domid_t dom = status->dom;
- int port = status->port;
struct evtchn *chn;
long rc = 0;
@@ -969,14 +966,13 @@ int evtchn_status(evtchn_status_t *statu
if ( d == NULL )
return -ESRCH;
- if ( !port_is_valid(d, port) )
+ chn = _evtchn_from_port(d, status->port);
+ if ( !chn )
{
rcu_unlock_domain(d);
return -EINVAL;
}
- chn = evtchn_from_port(d, port);
-
evtchn_read_lock(chn);
if ( consumer_is_xen(chn) )
@@ -1041,11 +1037,10 @@ long evtchn_bind_vcpu(unsigned int port,
if ( (v = domain_vcpu(d, vcpu_id)) == NULL )
return -ENOENT;
- if ( !port_is_valid(d, port) )
+ chn = _evtchn_from_port(d, port);
+ if ( !chn )
return -EINVAL;
- chn = evtchn_from_port(d, port);
-
write_lock(&d->event_lock);
/* Guest cannot re-bind a Xen-attached event channel. */
@@ -1091,13 +1086,11 @@ long evtchn_bind_vcpu(unsigned int port,
int evtchn_unmask(unsigned int port)
{
struct domain *d = current->domain;
- struct evtchn *evtchn;
+ struct evtchn *evtchn = _evtchn_from_port(d, port);
- if ( unlikely(!port_is_valid(d, port)) )
+ if ( unlikely(!evtchn) )
return -EINVAL;
- evtchn = evtchn_from_port(d, port);
-
evtchn_read_lock(evtchn);
evtchn_port_unmask(d, evtchn);
@@ -1180,14 +1173,12 @@ static long evtchn_set_priority(const st
{
struct domain *d = current->domain;
unsigned int port = set_priority->port;
- struct evtchn *chn;
+ struct evtchn *chn = _evtchn_from_port(d, port);
long ret;
- if ( !port_is_valid(d, port) )
+ if ( !chn )
return -EINVAL;
- chn = evtchn_from_port(d, port);
-
evtchn_read_lock(chn);
ret = evtchn_port_set_priority(d, chn, set_priority->priority);
@@ -1413,10 +1404,10 @@ void free_xen_event_channel(struct domai
void notify_via_xen_event_channel(struct domain *ld, int lport)
{
- struct evtchn *lchn, *rchn;
+ struct evtchn *lchn = _evtchn_from_port(ld, lport), *rchn;
struct domain *rd;
- if ( !port_is_valid(ld, lport) )
+ if ( !lchn )
{
/*
* Make sure ->is_dying is read /after/ ->valid_evtchns, pairing
@@ -1427,8 +1418,6 @@ void notify_via_xen_event_channel(struct
return;
}
- lchn = evtchn_from_port(ld, lport);
-
if ( !evtchn_read_trylock(lchn) )
return;
@@ -1582,16 +1571,17 @@ static void domain_dump_evtchn_info(stru
"Polling vCPUs: {%*pbl}\n"
" port [p/m/s]\n", d->domain_id, d->max_vcpus, d->poll_mask);
- for ( port = 1; port_is_valid(d, port); ++port )
+ for ( port = 1; ; ++port )
{
- struct evtchn *chn;
+ struct evtchn *chn = _evtchn_from_port(d, port);
char *ssid;
+ if ( !chn )
+ break;
+
if ( !(port & 0x3f) )
process_pending_softirqs();
- chn = evtchn_from_port(d, port);
-
if ( !evtchn_read_trylock(chn) )
{
printk(" %4u in flux\n", port);
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -120,7 +120,7 @@ static inline void evtchn_read_unlock(st
read_unlock(&evtchn->lock);
}
-static inline bool_t port_is_valid(struct domain *d, unsigned int p)
+static inline bool port_is_valid(const struct domain *d, evtchn_port_t p)
{
if ( p >= read_atomic(&d->valid_evtchns) )
return false;
@@ -135,7 +135,8 @@ static inline bool_t port_is_valid(struc
return true;
}
-static inline struct evtchn *evtchn_from_port(struct domain *d, unsigned int p)
+static inline struct evtchn *evtchn_from_port(const struct domain *d,
+ evtchn_port_t p)
{
if ( p < EVTCHNS_PER_BUCKET )
return &d->evtchn[array_index_nospec(p, EVTCHNS_PER_BUCKET)];
next prev parent reply other threads:[~2021-01-27 8:17 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-27 8:13 [PATCH v5 0/6] evtchn: (not so) recent XSAs follow-on Jan Beulich
2021-01-27 8:15 ` [PATCH v5 1/6] evtchn: use per-channel lock where possible Jan Beulich
2021-01-27 8:16 ` [PATCH v5 2/6] evtchn: convert domain event lock to an r/w one Jan Beulich
2021-05-27 11:01 ` Roger Pau Monné
2021-05-27 11:16 ` Jan Beulich
2022-07-07 18:00 ` Julien Grall
2021-01-27 8:16 ` [PATCH v5 3/6] evtchn: slightly defer lock acquire where possible Jan Beulich
2021-01-27 8:16 ` Jan Beulich [this message]
2021-01-27 8:17 ` [PATCH v5 5/6] evtchn: type adjustments Jan Beulich
2021-01-27 8:17 ` [PATCH v5 6/6] evtchn: drop acquiring of per-channel lock from send_guest_{global,vcpu}_virq() Jan Beulich
2021-04-21 15:23 ` Ping: [PATCH v5 0/6] evtchn: (not so) recent XSAs follow-on Jan Beulich
2021-04-21 15:56 ` Julien Grall
2021-04-22 8:53 ` Jan Beulich
2021-05-14 15:29 ` Roger Pau Monné
2021-05-17 7:15 ` Jan Beulich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cf871b03-35e5-a81e-feca-a0c6d71b1c30@suse.com \
--to=jbeulich@suse.com \
--cc=George.Dunlap@eu.citrix.com \
--cc=andrew.cooper3@citrix.com \
--cc=iwj@xenproject.org \
--cc=julien@xen.org \
--cc=sstabellini@kernel.org \
--cc=wl@xen.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.