diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-12-20 07:42:21 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-12-20 07:42:21 -0800 |
commit | 59b3f9448833a447085a22cf573f7c48db93c44d (patch) | |
tree | 0ad0ca297d485a90c2f1c035a5a9ab5bf2147c52 /drivers/tty | |
parent | a7904a538933c525096ca2ccde1e60d0ee62c08e (diff) | |
parent | be81992f9086b230623ae3ebbc85ecee4d00a3d3 (diff) |
Merge branch 'xsa' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Merge xen fixes from Juergen Gross:
"Fixes for two issues related to Xen and malicious guests:
- Guest can force the netback driver to hog large amounts of memory
- Denial of Service in other guests due to event storms"
* 'xsa' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
xen/netback: don't queue unlimited number of packages
xen/netback: fix rx queue stall detection
xen/console: harden hvc_xen against event channel storms
xen/netfront: harden netfront against event channel storms
xen/blkfront: harden blkfront against event channel storms
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/hvc/hvc_xen.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index 71e0dd2c0ce5..ebaf7500f48f 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c @@ -37,6 +37,8 @@ struct xencons_info { struct xenbus_device *xbdev; struct xencons_interface *intf; unsigned int evtchn; + XENCONS_RING_IDX out_cons; + unsigned int out_cons_same; struct hvc_struct *hvc; int irq; int vtermno; @@ -138,6 +140,8 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len) XENCONS_RING_IDX cons, prod; int recv = 0; struct xencons_info *xencons = vtermno_to_xencons(vtermno); + unsigned int eoiflag = 0; + if (xencons == NULL) return -EINVAL; intf = xencons->intf; @@ -157,7 +161,27 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len) mb(); /* read ring before consuming */ intf->in_cons = cons; - notify_daemon(xencons); + /* + * When to mark interrupt having been spurious: + * - there was no new data to be read, and + * - the backend did not consume some output bytes, and + * - the previous round with no read data didn't see consumed bytes + * (we might have a race with an interrupt being in flight while + * updating xencons->out_cons, so account for that by allowing one + * round without any visible reason) + */ + if (intf->out_cons != xencons->out_cons) { + xencons->out_cons = intf->out_cons; + xencons->out_cons_same = 0; + } + if (recv) { + notify_daemon(xencons); + } else if (xencons->out_cons_same++ > 1) { + eoiflag = XEN_EOI_FLAG_SPURIOUS; + } + + xen_irq_lateeoi(xencons->irq, eoiflag); + return recv; } @@ -386,7 +410,7 @@ static int xencons_connect_backend(struct xenbus_device *dev, if (ret) return ret; info->evtchn = evtchn; - irq = bind_evtchn_to_irq(evtchn); + irq = bind_interdomain_evtchn_to_irq_lateeoi(dev, evtchn); if (irq < 0) return irq; info->irq = irq; @@ -551,7 +575,7 @@ static int __init xen_hvc_init(void) return r; info = vtermno_to_xencons(HVC_COOKIE); - info->irq = bind_evtchn_to_irq(info->evtchn); + info->irq = bind_evtchn_to_irq_lateeoi(info->evtchn); } if (info->irq < 0) info->irq = 0; /* NO_IRQ */ |