Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+121 -19
+5
arch/arm/include/asm/irq.h
··· 40 40 #define arch_trigger_all_cpu_backtrace(x) arch_trigger_all_cpu_backtrace(x) 41 41 #endif 42 42 43 + static inline int nr_legacy_irqs(void) 44 + { 45 + return NR_IRQS_LEGACY; 46 + } 47 + 43 48 #endif 44 49 45 50 #endif
+5
arch/arm64/include/asm/irq.h
··· 7 7 8 8 extern void set_handle_irq(void (*handle_irq)(struct pt_regs *)); 9 9 10 + static inline int nr_legacy_irqs(void) 11 + { 12 + return 0; 13 + } 14 + 10 15 #endif
+3 -2
drivers/xen/events/events_base.c
··· 39 39 #include <asm/irq.h> 40 40 #include <asm/idle.h> 41 41 #include <asm/io_apic.h> 42 + #include <asm/i8259.h> 42 43 #include <asm/xen/pci.h> 43 44 #endif 44 45 #include <asm/sync_bitops.h> ··· 421 420 return xen_allocate_irq_dynamic(); 422 421 423 422 /* Legacy IRQ descriptors are already allocated by the arch. */ 424 - if (gsi < NR_IRQS_LEGACY) 423 + if (gsi < nr_legacy_irqs()) 425 424 irq = gsi; 426 425 else 427 426 irq = irq_alloc_desc_at(gsi, -1); ··· 447 446 kfree(info); 448 447 449 448 /* Legacy IRQ descriptors are managed by the arch. */ 450 - if (irq < NR_IRQS_LEGACY) 449 + if (irq < nr_legacy_irqs()) 451 450 return; 452 451 453 452 irq_free_desc(irq);
+107 -16
drivers/xen/evtchn.c
··· 49 49 #include <linux/init.h> 50 50 #include <linux/mutex.h> 51 51 #include <linux/cpu.h> 52 + #include <linux/mm.h> 53 + #include <linux/vmalloc.h> 52 54 53 55 #include <xen/xen.h> 54 56 #include <xen/events.h> ··· 60 58 struct per_user_data { 61 59 struct mutex bind_mutex; /* serialize bind/unbind operations */ 62 60 struct rb_root evtchns; 61 + unsigned int nr_evtchns; 63 62 64 63 /* Notification ring, accessed via /dev/xen/evtchn. */ 65 - #define EVTCHN_RING_SIZE (PAGE_SIZE / sizeof(evtchn_port_t)) 66 - #define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1)) 64 + unsigned int ring_size; 67 65 evtchn_port_t *ring; 68 66 unsigned int ring_cons, ring_prod, ring_overflow; 69 67 struct mutex ring_cons_mutex; /* protect against concurrent readers */ ··· 82 80 bool enabled; 83 81 }; 84 82 83 + static evtchn_port_t *evtchn_alloc_ring(unsigned int size) 84 + { 85 + evtchn_port_t *ring; 86 + size_t s = size * sizeof(*ring); 87 + 88 + ring = kmalloc(s, GFP_KERNEL); 89 + if (!ring) 90 + ring = vmalloc(s); 91 + 92 + return ring; 93 + } 94 + 95 + static void evtchn_free_ring(evtchn_port_t *ring) 96 + { 97 + kvfree(ring); 98 + } 99 + 100 + static unsigned int evtchn_ring_offset(struct per_user_data *u, 101 + unsigned int idx) 102 + { 103 + return idx & (u->ring_size - 1); 104 + } 105 + 106 + static evtchn_port_t *evtchn_ring_entry(struct per_user_data *u, 107 + unsigned int idx) 108 + { 109 + return u->ring + evtchn_ring_offset(u, idx); 110 + } 111 + 85 112 static int add_evtchn(struct per_user_data *u, struct user_evtchn *evtchn) 86 113 { 87 114 struct rb_node **new = &(u->evtchns.rb_node), *parent = NULL; 115 + 116 + u->nr_evtchns++; 88 117 89 118 while (*new) { 90 119 struct user_evtchn *this; ··· 140 107 141 108 static void del_evtchn(struct per_user_data *u, struct user_evtchn *evtchn) 142 109 { 110 + u->nr_evtchns--; 143 111 rb_erase(&evtchn->node, &u->evtchns); 144 112 kfree(evtchn); 145 113 } ··· 178 144 179 145 spin_lock(&u->ring_prod_lock); 180 146 181 - if ((u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE) { 182 - u->ring[EVTCHN_RING_MASK(u->ring_prod)] = evtchn->port; 147 + if ((u->ring_prod - u->ring_cons) < u->ring_size) { 148 + *evtchn_ring_entry(u, u->ring_prod) = evtchn->port; 183 149 wmb(); /* Ensure ring contents visible */ 184 150 if (u->ring_cons == u->ring_prod++) { 185 151 wake_up_interruptible(&u->evtchn_wait); ··· 234 200 } 235 201 236 202 /* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */ 237 - if (((c ^ p) & EVTCHN_RING_SIZE) != 0) { 238 - bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) * 203 + if (((c ^ p) & u->ring_size) != 0) { 204 + bytes1 = (u->ring_size - evtchn_ring_offset(u, c)) * 239 205 sizeof(evtchn_port_t); 240 - bytes2 = EVTCHN_RING_MASK(p) * sizeof(evtchn_port_t); 206 + bytes2 = evtchn_ring_offset(u, p) * sizeof(evtchn_port_t); 241 207 } else { 242 208 bytes1 = (p - c) * sizeof(evtchn_port_t); 243 209 bytes2 = 0; ··· 253 219 254 220 rc = -EFAULT; 255 221 rmb(); /* Ensure that we see the port before we copy it. */ 256 - if (copy_to_user(buf, &u->ring[EVTCHN_RING_MASK(c)], bytes1) || 222 + if (copy_to_user(buf, evtchn_ring_entry(u, c), bytes1) || 257 223 ((bytes2 != 0) && 258 224 copy_to_user(&buf[bytes1], &u->ring[0], bytes2))) 259 225 goto unlock_out; ··· 312 278 return rc; 313 279 } 314 280 281 + static int evtchn_resize_ring(struct per_user_data *u) 282 + { 283 + unsigned int new_size; 284 + evtchn_port_t *new_ring, *old_ring; 285 + unsigned int p, c; 286 + 287 + /* 288 + * Ensure the ring is large enough to capture all possible 289 + * events. i.e., one free slot for each bound event. 290 + */ 291 + if (u->nr_evtchns <= u->ring_size) 292 + return 0; 293 + 294 + if (u->ring_size == 0) 295 + new_size = 64; 296 + else 297 + new_size = 2 * u->ring_size; 298 + 299 + new_ring = evtchn_alloc_ring(new_size); 300 + if (!new_ring) 301 + return -ENOMEM; 302 + 303 + old_ring = u->ring; 304 + 305 + /* 306 + * Access to the ring contents is serialized by either the 307 + * prod /or/ cons lock so take both when resizing. 308 + */ 309 + mutex_lock(&u->ring_cons_mutex); 310 + spin_lock_irq(&u->ring_prod_lock); 311 + 312 + /* 313 + * Copy the old ring contents to the new ring. 314 + * 315 + * If the ring contents crosses the end of the current ring, 316 + * it needs to be copied in two chunks. 317 + * 318 + * +---------+ +------------------+ 319 + * |34567 12| -> | 1234567 | 320 + * +-----p-c-+ +------------------+ 321 + */ 322 + p = evtchn_ring_offset(u, u->ring_prod); 323 + c = evtchn_ring_offset(u, u->ring_cons); 324 + if (p < c) { 325 + memcpy(new_ring + c, u->ring + c, (u->ring_size - c) * sizeof(*u->ring)); 326 + memcpy(new_ring + u->ring_size, u->ring, p * sizeof(*u->ring)); 327 + } else 328 + memcpy(new_ring + c, u->ring + c, (p - c) * sizeof(*u->ring)); 329 + 330 + u->ring = new_ring; 331 + u->ring_size = new_size; 332 + 333 + spin_unlock_irq(&u->ring_prod_lock); 334 + mutex_unlock(&u->ring_cons_mutex); 335 + 336 + evtchn_free_ring(old_ring); 337 + 338 + return 0; 339 + } 340 + 315 341 static int evtchn_bind_to_user(struct per_user_data *u, int port) 316 342 { 317 343 struct user_evtchn *evtchn; ··· 396 302 evtchn->enabled = true; /* start enabled */ 397 303 398 304 rc = add_evtchn(u, evtchn); 305 + if (rc < 0) 306 + goto err; 307 + 308 + rc = evtchn_resize_ring(u); 399 309 if (rc < 0) 400 310 goto err; 401 311 ··· 601 503 602 504 init_waitqueue_head(&u->evtchn_wait); 603 505 604 - u->ring = (evtchn_port_t *)__get_free_page(GFP_KERNEL); 605 - if (u->ring == NULL) { 606 - kfree(u->name); 607 - kfree(u); 608 - return -ENOMEM; 609 - } 610 - 611 506 mutex_init(&u->bind_mutex); 612 507 mutex_init(&u->ring_cons_mutex); 613 508 spin_lock_init(&u->ring_prod_lock); ··· 623 532 evtchn_unbind_from_user(u, evtchn); 624 533 } 625 534 626 - free_page((unsigned long)u->ring); 535 + evtchn_free_ring(u->ring); 627 536 kfree(u->name); 628 537 kfree(u); 629 538
+1 -1
drivers/xen/gntdev.c
··· 804 804 805 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 809 if (use_ptemod) 810 810 vma->vm_flags |= VM_DONTCOPY;