Skip to content

Commit 58f6259

Browse files
rahul-sinjgross1
authored andcommitted
xen/evtchn: Introduce new IOCTL to bind static evtchn
Xen 4.17 supports the creation of static evtchns. To allow user space application to bind static evtchns introduce new ioctl "IOCTL_EVTCHN_BIND_STATIC". Existing IOCTL doing more than binding that’s why we need to introduce the new IOCTL to only bind the static event channels. Static evtchns to be available for use during the lifetime of the guest. When the application exits, __unbind_from_irq() ends up being called from release() file operations because of that static evtchns are getting closed. To avoid closing the static event channel, add the new bool variable "is_static" in "struct irq_info" to mark the event channel static when creating the event channel to avoid closing the static evtchn. Also, take this opportunity to remove the open-coded version of the evtchn close in drivers/xen/evtchn.c file and use xen_evtchn_close(). Signed-off-by: Rahul Singh <rahul.singh@arm.com> Reviewed-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com> Acked-by: Stefano Stabellini <sstabellini@kernel.org> Link: https://lore.kernel.org/r/ae7329bf1713f83e4aad4f3fa0f316258c40a3e9.1689677042.git.rahul.singh@arm.com Signed-off-by: Juergen Gross <jgross@suse.com>
1 parent 0d8f7cc commit 58f6259

File tree

4 files changed

+50
-21
lines changed

4 files changed

+50
-21
lines changed

drivers/xen/events/events_base.c

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ struct irq_info {
112112
unsigned int irq_epoch; /* If eoi_cpu valid: irq_epoch of event */
113113
u64 eoi_time; /* Time in jiffies when to EOI. */
114114
raw_spinlock_t lock;
115+
bool is_static; /* Is event channel static */
115116

116117
union {
117118
unsigned short virq;
@@ -815,15 +816,6 @@ static void xen_free_irq(unsigned irq)
815816
irq_free_desc(irq);
816817
}
817818

818-
static void xen_evtchn_close(evtchn_port_t port)
819-
{
820-
struct evtchn_close close;
821-
822-
close.port = port;
823-
if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
824-
BUG();
825-
}
826-
827819
/* Not called for lateeoi events. */
828820
static void event_handler_exit(struct irq_info *info)
829821
{
@@ -982,7 +974,8 @@ static void __unbind_from_irq(unsigned int irq)
982974
unsigned int cpu = cpu_from_irq(irq);
983975
struct xenbus_device *dev;
984976

985-
xen_evtchn_close(evtchn);
977+
if (!info->is_static)
978+
xen_evtchn_close(evtchn);
986979

987980
switch (type_from_irq(irq)) {
988981
case IRQT_VIRQ:
@@ -1574,7 +1567,7 @@ int xen_set_irq_priority(unsigned irq, unsigned priority)
15741567
}
15751568
EXPORT_SYMBOL_GPL(xen_set_irq_priority);
15761569

1577-
int evtchn_make_refcounted(evtchn_port_t evtchn)
1570+
int evtchn_make_refcounted(evtchn_port_t evtchn, bool is_static)
15781571
{
15791572
int irq = get_evtchn_to_irq(evtchn);
15801573
struct irq_info *info;
@@ -1590,6 +1583,7 @@ int evtchn_make_refcounted(evtchn_port_t evtchn)
15901583
WARN_ON(info->refcnt != -1);
15911584

15921585
info->refcnt = 1;
1586+
info->is_static = is_static;
15931587

15941588
return 0;
15951589
}

drivers/xen/evtchn.c

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -366,10 +366,10 @@ static int evtchn_resize_ring(struct per_user_data *u)
366366
return 0;
367367
}
368368

369-
static int evtchn_bind_to_user(struct per_user_data *u, evtchn_port_t port)
369+
static int evtchn_bind_to_user(struct per_user_data *u, evtchn_port_t port,
370+
bool is_static)
370371
{
371372
struct user_evtchn *evtchn;
372-
struct evtchn_close close;
373373
int rc = 0;
374374

375375
/*
@@ -402,14 +402,14 @@ static int evtchn_bind_to_user(struct per_user_data *u, evtchn_port_t port)
402402
if (rc < 0)
403403
goto err;
404404

405-
rc = evtchn_make_refcounted(port);
405+
rc = evtchn_make_refcounted(port, is_static);
406406
return rc;
407407

408408
err:
409409
/* bind failed, should close the port now */
410-
close.port = port;
411-
if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
412-
BUG();
410+
if (!is_static)
411+
xen_evtchn_close(port);
412+
413413
del_evtchn(u, evtchn);
414414
return rc;
415415
}
@@ -456,7 +456,7 @@ static long evtchn_ioctl(struct file *file,
456456
if (rc != 0)
457457
break;
458458

459-
rc = evtchn_bind_to_user(u, bind_virq.port);
459+
rc = evtchn_bind_to_user(u, bind_virq.port, false);
460460
if (rc == 0)
461461
rc = bind_virq.port;
462462
break;
@@ -482,7 +482,7 @@ static long evtchn_ioctl(struct file *file,
482482
if (rc != 0)
483483
break;
484484

485-
rc = evtchn_bind_to_user(u, bind_interdomain.local_port);
485+
rc = evtchn_bind_to_user(u, bind_interdomain.local_port, false);
486486
if (rc == 0)
487487
rc = bind_interdomain.local_port;
488488
break;
@@ -507,7 +507,7 @@ static long evtchn_ioctl(struct file *file,
507507
if (rc != 0)
508508
break;
509509

510-
rc = evtchn_bind_to_user(u, alloc_unbound.port);
510+
rc = evtchn_bind_to_user(u, alloc_unbound.port, false);
511511
if (rc == 0)
512512
rc = alloc_unbound.port;
513513
break;
@@ -536,6 +536,23 @@ static long evtchn_ioctl(struct file *file,
536536
break;
537537
}
538538

539+
case IOCTL_EVTCHN_BIND_STATIC: {
540+
struct ioctl_evtchn_bind bind;
541+
struct user_evtchn *evtchn;
542+
543+
rc = -EFAULT;
544+
if (copy_from_user(&bind, uarg, sizeof(bind)))
545+
break;
546+
547+
rc = -EISCONN;
548+
evtchn = find_evtchn(u, bind.port);
549+
if (evtchn)
550+
break;
551+
552+
rc = evtchn_bind_to_user(u, bind.port, true);
553+
break;
554+
}
555+
539556
case IOCTL_EVTCHN_NOTIFY: {
540557
struct ioctl_evtchn_notify notify;
541558
struct user_evtchn *evtchn;

include/uapi/xen/evtchn.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,13 @@ struct ioctl_evtchn_restrict_domid {
101101
domid_t domid;
102102
};
103103

104+
/*
105+
* Bind statically allocated @port.
106+
*/
107+
#define IOCTL_EVTCHN_BIND_STATIC \
108+
_IOC(_IOC_NONE, 'E', 7, sizeof(struct ioctl_evtchn_bind))
109+
struct ioctl_evtchn_bind {
110+
unsigned int port;
111+
};
112+
104113
#endif /* __LINUX_PUBLIC_EVTCHN_H__ */

include/xen/events.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ int xen_set_irq_priority(unsigned irq, unsigned priority);
6969
/*
7070
* Allow extra references to event channels exposed to userspace by evtchn
7171
*/
72-
int evtchn_make_refcounted(evtchn_port_t evtchn);
72+
int evtchn_make_refcounted(evtchn_port_t evtchn, bool is_static);
7373
int evtchn_get(evtchn_port_t evtchn);
7474
void evtchn_put(evtchn_port_t evtchn);
7575

@@ -141,4 +141,13 @@ void xen_init_IRQ(void);
141141

142142
irqreturn_t xen_debug_interrupt(int irq, void *dev_id);
143143

144+
static inline void xen_evtchn_close(evtchn_port_t port)
145+
{
146+
struct evtchn_close close;
147+
148+
close.port = port;
149+
if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
150+
BUG();
151+
}
152+
144153
#endif /* _XEN_EVENTS_H */

0 commit comments

Comments
 (0)