aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-11-26 14:42:25 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-26 14:42:25 -0500
commit4fe5e199ebcd82a05c7446e7e6b85027358dc274 (patch)
tree9a98fc2a40abd0fcdfe18108625f298f09253ef7
parent02a5fec18297bb6991f5bc5ebc7e73fa6810809d (diff)
parent8620015499101090ae275bf11e9bc2f9febfdf08 (diff)
Merge tag 'for-linus-4.4-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen bug fixes from David Vrabel: - Fix gntdev and numa balancing. - Fix x86 boot crash due to unallocated legacy irq descs. - Fix overflow in evtchn device when > 1024 event channels. * tag 'for-linus-4.4-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen/evtchn: dynamically grow pending event channel ring xen/events: Always allocate legacy interrupts on PV guests xen/gntdev: Grant maps should not be subject to NUMA balancing
-rw-r--r--arch/arm/include/asm/irq.h5
-rw-r--r--arch/arm64/include/asm/irq.h5
-rw-r--r--drivers/xen/events/events_base.c5
-rw-r--r--drivers/xen/evtchn.c123
-rw-r--r--drivers/xen/gntdev.c2
5 files changed, 121 insertions, 19 deletions
diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h
index be1d07d59ee9..1bd9510de1b9 100644
--- a/arch/arm/include/asm/irq.h
+++ b/arch/arm/include/asm/irq.h
@@ -40,6 +40,11 @@ extern void arch_trigger_all_cpu_backtrace(bool);
40#define arch_trigger_all_cpu_backtrace(x) arch_trigger_all_cpu_backtrace(x) 40#define arch_trigger_all_cpu_backtrace(x) arch_trigger_all_cpu_backtrace(x)
41#endif 41#endif
42 42
43static inline int nr_legacy_irqs(void)
44{
45 return NR_IRQS_LEGACY;
46}
47
43#endif 48#endif
44 49
45#endif 50#endif
diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h
index 23eb450b820b..8e8d30684392 100644
--- a/arch/arm64/include/asm/irq.h
+++ b/arch/arm64/include/asm/irq.h
@@ -7,4 +7,9 @@ struct pt_regs;
7 7
8extern void set_handle_irq(void (*handle_irq)(struct pt_regs *)); 8extern void set_handle_irq(void (*handle_irq)(struct pt_regs *));
9 9
10static inline int nr_legacy_irqs(void)
11{
12 return 0;
13}
14
10#endif 15#endif
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 849500e4e14d..524c22146429 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -39,6 +39,7 @@
39#include <asm/irq.h> 39#include <asm/irq.h>
40#include <asm/idle.h> 40#include <asm/idle.h>
41#include <asm/io_apic.h> 41#include <asm/io_apic.h>
42#include <asm/i8259.h>
42#include <asm/xen/pci.h> 43#include <asm/xen/pci.h>
43#endif 44#endif
44#include <asm/sync_bitops.h> 45#include <asm/sync_bitops.h>
@@ -420,7 +421,7 @@ static int __must_check xen_allocate_irq_gsi(unsigned gsi)
420 return xen_allocate_irq_dynamic(); 421 return xen_allocate_irq_dynamic();
421 422
422 /* Legacy IRQ descriptors are already allocated by the arch. */ 423 /* Legacy IRQ descriptors are already allocated by the arch. */
423 if (gsi < NR_IRQS_LEGACY) 424 if (gsi < nr_legacy_irqs())
424 irq = gsi; 425 irq = gsi;
425 else 426 else
426 irq = irq_alloc_desc_at(gsi, -1); 427 irq = irq_alloc_desc_at(gsi, -1);
@@ -446,7 +447,7 @@ static void xen_free_irq(unsigned irq)
446 kfree(info); 447 kfree(info);
447 448
448 /* Legacy IRQ descriptors are managed by the arch. */ 449 /* Legacy IRQ descriptors are managed by the arch. */
449 if (irq < NR_IRQS_LEGACY) 450 if (irq < nr_legacy_irqs())
450 return; 451 return;
451 452
452 irq_free_desc(irq); 453 irq_free_desc(irq);
diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c
index 00f40f051d95..38272ad24551 100644
--- a/drivers/xen/evtchn.c
+++ b/drivers/xen/evtchn.c
@@ -49,6 +49,8 @@
49#include <linux/init.h> 49#include <linux/init.h>
50#include <linux/mutex.h> 50#include <linux/mutex.h>
51#include <linux/cpu.h> 51#include <linux/cpu.h>
52#include <linux/mm.h>
53#include <linux/vmalloc.h>
52 54
53#include <xen/xen.h> 55#include <xen/xen.h>
54#include <xen/events.h> 56#include <xen/events.h>
@@ -58,10 +60,10 @@
58struct per_user_data { 60struct per_user_data {
59 struct mutex bind_mutex; /* serialize bind/unbind operations */ 61 struct mutex bind_mutex; /* serialize bind/unbind operations */
60 struct rb_root evtchns; 62 struct rb_root evtchns;
63 unsigned int nr_evtchns;
61 64
62 /* Notification ring, accessed via /dev/xen/evtchn. */ 65 /* Notification ring, accessed via /dev/xen/evtchn. */
63#define EVTCHN_RING_SIZE (PAGE_SIZE / sizeof(evtchn_port_t)) 66 unsigned int ring_size;
64#define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1))
65 evtchn_port_t *ring; 67 evtchn_port_t *ring;
66 unsigned int ring_cons, ring_prod, ring_overflow; 68 unsigned int ring_cons, ring_prod, ring_overflow;
67 struct mutex ring_cons_mutex; /* protect against concurrent readers */ 69 struct mutex ring_cons_mutex; /* protect against concurrent readers */
@@ -80,10 +82,41 @@ struct user_evtchn {
80 bool enabled; 82 bool enabled;
81}; 83};
82 84
85static evtchn_port_t *evtchn_alloc_ring(unsigned int size)
86{
87 evtchn_port_t *ring;
88 size_t s = size * sizeof(*ring);
89
90 ring = kmalloc(s, GFP_KERNEL);
91 if (!ring)
92 ring = vmalloc(s);
93
94 return ring;
95}
96
97static void evtchn_free_ring(evtchn_port_t *ring)
98{
99 kvfree(ring);
100}
101
102static unsigned int evtchn_ring_offset(struct per_user_data *u,
103 unsigned int idx)
104{
105 return idx & (u->ring_size - 1);
106}
107
108static evtchn_port_t *evtchn_ring_entry(struct per_user_data *u,
109 unsigned int idx)
110{
111 return u->ring + evtchn_ring_offset(u, idx);
112}
113
83static int add_evtchn(struct per_user_data *u, struct user_evtchn *evtchn) 114static int add_evtchn(struct per_user_data *u, struct user_evtchn *evtchn)
84{ 115{
85 struct rb_node **new = &(u->evtchns.rb_node), *parent = NULL; 116 struct rb_node **new = &(u->evtchns.rb_node), *parent = NULL;
86 117
118 u->nr_evtchns++;
119
87 while (*new) { 120 while (*new) {
88 struct user_evtchn *this; 121 struct user_evtchn *this;
89 122
@@ -107,6 +140,7 @@ static int add_evtchn(struct per_user_data *u, struct user_evtchn *evtchn)
107 140
108static void del_evtchn(struct per_user_data *u, struct user_evtchn *evtchn) 141static void del_evtchn(struct per_user_data *u, struct user_evtchn *evtchn)
109{ 142{
143 u->nr_evtchns--;
110 rb_erase(&evtchn->node, &u->evtchns); 144 rb_erase(&evtchn->node, &u->evtchns);
111 kfree(evtchn); 145 kfree(evtchn);
112} 146}
@@ -144,8 +178,8 @@ static irqreturn_t evtchn_interrupt(int irq, void *data)
144 178
145 spin_lock(&u->ring_prod_lock); 179 spin_lock(&u->ring_prod_lock);
146 180
147 if ((u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE) { 181 if ((u->ring_prod - u->ring_cons) < u->ring_size) {
148 u->ring[EVTCHN_RING_MASK(u->ring_prod)] = evtchn->port; 182 *evtchn_ring_entry(u, u->ring_prod) = evtchn->port;
149 wmb(); /* Ensure ring contents visible */ 183 wmb(); /* Ensure ring contents visible */
150 if (u->ring_cons == u->ring_prod++) { 184 if (u->ring_cons == u->ring_prod++) {
151 wake_up_interruptible(&u->evtchn_wait); 185 wake_up_interruptible(&u->evtchn_wait);
@@ -200,10 +234,10 @@ static ssize_t evtchn_read(struct file *file, char __user *buf,
200 } 234 }
201 235
202 /* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */ 236 /* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */
203 if (((c ^ p) & EVTCHN_RING_SIZE) != 0) { 237 if (((c ^ p) & u->ring_size) != 0) {
204 bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) * 238 bytes1 = (u->ring_size - evtchn_ring_offset(u, c)) *
205 sizeof(evtchn_port_t); 239 sizeof(evtchn_port_t);
206 bytes2 = EVTCHN_RING_MASK(p) * sizeof(evtchn_port_t); 240 bytes2 = evtchn_ring_offset(u, p) * sizeof(evtchn_port_t);
207 } else { 241 } else {
208 bytes1 = (p - c) * sizeof(evtchn_port_t); 242 bytes1 = (p - c) * sizeof(evtchn_port_t);
209 bytes2 = 0; 243 bytes2 = 0;
@@ -219,7 +253,7 @@ static ssize_t evtchn_read(struct file *file, char __user *buf,
219 253
220 rc = -EFAULT; 254 rc = -EFAULT;
221 rmb(); /* Ensure that we see the port before we copy it. */ 255 rmb(); /* Ensure that we see the port before we copy it. */
222 if (copy_to_user(buf, &u->ring[EVTCHN_RING_MASK(c)], bytes1) || 256 if (copy_to_user(buf, evtchn_ring_entry(u, c), bytes1) ||
223 ((bytes2 != 0) && 257 ((bytes2 != 0) &&
224 copy_to_user(&buf[bytes1], &u->ring[0], bytes2))) 258 copy_to_user(&buf[bytes1], &u->ring[0], bytes2)))
225 goto unlock_out; 259 goto unlock_out;
@@ -278,6 +312,66 @@ static ssize_t evtchn_write(struct file *file, const char __user *buf,
278 return rc; 312 return rc;
279} 313}
280 314
315static int evtchn_resize_ring(struct per_user_data *u)
316{
317 unsigned int new_size;
318 evtchn_port_t *new_ring, *old_ring;
319 unsigned int p, c;
320
321 /*
322 * Ensure the ring is large enough to capture all possible
323 * events. i.e., one free slot for each bound event.
324 */
325 if (u->nr_evtchns <= u->ring_size)
326 return 0;
327
328 if (u->ring_size == 0)
329 new_size = 64;
330 else
331 new_size = 2 * u->ring_size;
332
333 new_ring = evtchn_alloc_ring(new_size);
334 if (!new_ring)
335 return -ENOMEM;
336
337 old_ring = u->ring;
338
339 /*
340 * Access to the ring contents is serialized by either the
341 * prod /or/ cons lock so take both when resizing.
342 */
343 mutex_lock(&u->ring_cons_mutex);
344 spin_lock_irq(&u->ring_prod_lock);
345
346 /*
347 * Copy the old ring contents to the new ring.
348 *
349 * If the ring contents crosses the end of the current ring,
350 * it needs to be copied in two chunks.
351 *
352 * +---------+ +------------------+
353 * |34567 12| -> | 1234567 |
354 * +-----p-c-+ +------------------+
355 */
356 p = evtchn_ring_offset(u, u->ring_prod);
357 c = evtchn_ring_offset(u, u->ring_cons);
358 if (p < c) {
359 memcpy(new_ring + c, u->ring + c, (u->ring_size - c) * sizeof(*u->ring));
360 memcpy(new_ring + u->ring_size, u->ring, p * sizeof(*u->ring));
361 } else
362 memcpy(new_ring + c, u->ring + c, (p - c) * sizeof(*u->ring));
363
364 u->ring = new_ring;
365 u->ring_size = new_size;
366
367 spin_unlock_irq(&u->ring_prod_lock);
368 mutex_unlock(&u->ring_cons_mutex);
369
370 evtchn_free_ring(old_ring);
371
372 return 0;
373}
374
281static int evtchn_bind_to_user(struct per_user_data *u, int port) 375static int evtchn_bind_to_user(struct per_user_data *u, int port)
282{ 376{
283 struct user_evtchn *evtchn; 377 struct user_evtchn *evtchn;
@@ -305,6 +399,10 @@ static int evtchn_bind_to_user(struct per_user_data *u, int port)
305 if (rc < 0) 399 if (rc < 0)
306 goto err; 400 goto err;
307 401
402 rc = evtchn_resize_ring(u);
403 if (rc < 0)
404 goto err;
405
308 rc = bind_evtchn_to_irqhandler(port, evtchn_interrupt, 0, 406 rc = bind_evtchn_to_irqhandler(port, evtchn_interrupt, 0,
309 u->name, evtchn); 407 u->name, evtchn);
310 if (rc < 0) 408 if (rc < 0)
@@ -503,13 +601,6 @@ static int evtchn_open(struct inode *inode, struct file *filp)
503 601
504 init_waitqueue_head(&u->evtchn_wait); 602 init_waitqueue_head(&u->evtchn_wait);
505 603
506 u->ring = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
507 if (u->ring == NULL) {
508 kfree(u->name);
509 kfree(u);
510 return -ENOMEM;
511 }
512
513 mutex_init(&u->bind_mutex); 604 mutex_init(&u->bind_mutex);
514 mutex_init(&u->ring_cons_mutex); 605 mutex_init(&u->ring_cons_mutex);
515 spin_lock_init(&u->ring_prod_lock); 606 spin_lock_init(&u->ring_prod_lock);
@@ -532,7 +623,7 @@ static int evtchn_release(struct inode *inode, struct file *filp)
532 evtchn_unbind_from_user(u, evtchn); 623 evtchn_unbind_from_user(u, evtchn);
533 } 624 }
534 625
535 free_page((unsigned long)u->ring); 626 evtchn_free_ring(u->ring);
536 kfree(u->name); 627 kfree(u->name);
537 kfree(u); 628 kfree(u);
538 629
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index 2ea0b3b2a91d..1be5dd048622 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -804,7 +804,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
804 804
805 vma->vm_ops = &gntdev_vmops; 805 vma->vm_ops = &gntdev_vmops;
806 806
807 vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; 807 vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_IO;
808 808
809 if (use_ptemod) 809 if (use_ptemod)
810 vma->vm_flags |= VM_DONTCOPY; 810 vma->vm_flags |= VM_DONTCOPY;