aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-08-13 16:36:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-08-13 16:36:22 -0400
commit6b476e114061599a6ab8d5464a5e16989cb98653 (patch)
tree09cfafc404949980bde3b646624ece82d8e08a47 /drivers/xen
parented596cde9425509ec6ce88e19f03e9b13b6f518b (diff)
parentc22fe519e7e2b94ad173e0ea3b89c1a7d8be8d00 (diff)
Merge tag 'for-linus-4.2-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen bug fixes from David Vrabel: - revert a fix from 4.2-rc5 that was causing lots of WARNING spam. - fix a memory leak affecting backends in HVM guests. - fix PV domU hang with certain configurations. * tag 'for-linus-4.2-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen/xenbus: Don't leak memory when unmapping the ring on HVM backend Revert "xen/events/fifo: Handle linked events when closing a port" x86/xen: build "Xen PV" APIC driver for domU as well
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/events/events_base.c10
-rw-r--r--drivers/xen/events/events_fifo.c45
-rw-r--r--drivers/xen/events/events_internal.h7
-rw-r--r--drivers/xen/xenbus/xenbus_client.c4
4 files changed, 12 insertions, 54 deletions
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 1495eccb1617..96093ae369a5 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -452,12 +452,10 @@ static void xen_free_irq(unsigned irq)
452 irq_free_desc(irq); 452 irq_free_desc(irq);
453} 453}
454 454
455static void xen_evtchn_close(unsigned int port, unsigned int cpu) 455static void xen_evtchn_close(unsigned int port)
456{ 456{
457 struct evtchn_close close; 457 struct evtchn_close close;
458 458
459 xen_evtchn_op_close(port, cpu);
460
461 close.port = port; 459 close.port = port;
462 if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0) 460 if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
463 BUG(); 461 BUG();
@@ -546,7 +544,7 @@ out:
546 544
547err: 545err:
548 pr_err("irq%d: Failed to set port to irq mapping (%d)\n", irq, rc); 546 pr_err("irq%d: Failed to set port to irq mapping (%d)\n", irq, rc);
549 xen_evtchn_close(evtchn, NR_CPUS); 547 xen_evtchn_close(evtchn);
550 return 0; 548 return 0;
551} 549}
552 550
@@ -567,7 +565,7 @@ static void shutdown_pirq(struct irq_data *data)
567 return; 565 return;
568 566
569 mask_evtchn(evtchn); 567 mask_evtchn(evtchn);
570 xen_evtchn_close(evtchn, cpu_from_evtchn(evtchn)); 568 xen_evtchn_close(evtchn);
571 xen_irq_info_cleanup(info); 569 xen_irq_info_cleanup(info);
572} 570}
573 571
@@ -611,7 +609,7 @@ static void __unbind_from_irq(unsigned int irq)
611 if (VALID_EVTCHN(evtchn)) { 609 if (VALID_EVTCHN(evtchn)) {
612 unsigned int cpu = cpu_from_irq(irq); 610 unsigned int cpu = cpu_from_irq(irq);
613 611
614 xen_evtchn_close(evtchn, cpu); 612 xen_evtchn_close(evtchn);
615 613
616 switch (type_from_irq(irq)) { 614 switch (type_from_irq(irq)) {
617 case IRQT_VIRQ: 615 case IRQT_VIRQ:
diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c
index 6df8aac966b9..ed673e1acd61 100644
--- a/drivers/xen/events/events_fifo.c
+++ b/drivers/xen/events/events_fifo.c
@@ -255,12 +255,6 @@ static void evtchn_fifo_unmask(unsigned port)
255 } 255 }
256} 256}
257 257
258static bool evtchn_fifo_is_linked(unsigned port)
259{
260 event_word_t *word = event_word_from_port(port);
261 return sync_test_bit(EVTCHN_FIFO_BIT(LINKED, word), BM(word));
262}
263
264static uint32_t clear_linked(volatile event_word_t *word) 258static uint32_t clear_linked(volatile event_word_t *word)
265{ 259{
266 event_word_t new, old, w; 260 event_word_t new, old, w;
@@ -287,8 +281,7 @@ static void handle_irq_for_port(unsigned port)
287 281
288static void consume_one_event(unsigned cpu, 282static void consume_one_event(unsigned cpu,
289 struct evtchn_fifo_control_block *control_block, 283 struct evtchn_fifo_control_block *control_block,
290 unsigned priority, unsigned long *ready, 284 unsigned priority, unsigned long *ready)
291 bool drop)
292{ 285{
293 struct evtchn_fifo_queue *q = &per_cpu(cpu_queue, cpu); 286 struct evtchn_fifo_queue *q = &per_cpu(cpu_queue, cpu);
294 uint32_t head; 287 uint32_t head;
@@ -320,15 +313,13 @@ static void consume_one_event(unsigned cpu,
320 if (head == 0) 313 if (head == 0)
321 clear_bit(priority, ready); 314 clear_bit(priority, ready);
322 315
323 if (evtchn_fifo_is_pending(port) && !evtchn_fifo_is_masked(port)) { 316 if (evtchn_fifo_is_pending(port) && !evtchn_fifo_is_masked(port))
324 if (likely(!drop)) 317 handle_irq_for_port(port);
325 handle_irq_for_port(port);
326 }
327 318
328 q->head[priority] = head; 319 q->head[priority] = head;
329} 320}
330 321
331static void __evtchn_fifo_handle_events(unsigned cpu, bool drop) 322static void evtchn_fifo_handle_events(unsigned cpu)
332{ 323{
333 struct evtchn_fifo_control_block *control_block; 324 struct evtchn_fifo_control_block *control_block;
334 unsigned long ready; 325 unsigned long ready;
@@ -340,16 +331,11 @@ static void __evtchn_fifo_handle_events(unsigned cpu, bool drop)
340 331
341 while (ready) { 332 while (ready) {
342 q = find_first_bit(&ready, EVTCHN_FIFO_MAX_QUEUES); 333 q = find_first_bit(&ready, EVTCHN_FIFO_MAX_QUEUES);
343 consume_one_event(cpu, control_block, q, &ready, drop); 334 consume_one_event(cpu, control_block, q, &ready);
344 ready |= xchg(&control_block->ready, 0); 335 ready |= xchg(&control_block->ready, 0);
345 } 336 }
346} 337}
347 338
348static void evtchn_fifo_handle_events(unsigned cpu)
349{
350 __evtchn_fifo_handle_events(cpu, false);
351}
352
353static void evtchn_fifo_resume(void) 339static void evtchn_fifo_resume(void)
354{ 340{
355 unsigned cpu; 341 unsigned cpu;
@@ -385,26 +371,6 @@ static void evtchn_fifo_resume(void)
385 event_array_pages = 0; 371 event_array_pages = 0;
386} 372}
387 373
388static void evtchn_fifo_close(unsigned port, unsigned int cpu)
389{
390 if (cpu == NR_CPUS)
391 return;
392
393 get_online_cpus();
394 if (cpu_online(cpu)) {
395 if (WARN_ON(irqs_disabled()))
396 goto out;
397
398 while (evtchn_fifo_is_linked(port))
399 cpu_relax();
400 } else {
401 __evtchn_fifo_handle_events(cpu, true);
402 }
403
404out:
405 put_online_cpus();
406}
407
408static const struct evtchn_ops evtchn_ops_fifo = { 374static const struct evtchn_ops evtchn_ops_fifo = {
409 .max_channels = evtchn_fifo_max_channels, 375 .max_channels = evtchn_fifo_max_channels,
410 .nr_channels = evtchn_fifo_nr_channels, 376 .nr_channels = evtchn_fifo_nr_channels,
@@ -418,7 +384,6 @@ static const struct evtchn_ops evtchn_ops_fifo = {
418 .unmask = evtchn_fifo_unmask, 384 .unmask = evtchn_fifo_unmask,
419 .handle_events = evtchn_fifo_handle_events, 385 .handle_events = evtchn_fifo_handle_events,
420 .resume = evtchn_fifo_resume, 386 .resume = evtchn_fifo_resume,
421 .close = evtchn_fifo_close,
422}; 387};
423 388
424static int evtchn_fifo_alloc_control_block(unsigned cpu) 389static int evtchn_fifo_alloc_control_block(unsigned cpu)
diff --git a/drivers/xen/events/events_internal.h b/drivers/xen/events/events_internal.h
index d18e12315ec0..50c2050a1e32 100644
--- a/drivers/xen/events/events_internal.h
+++ b/drivers/xen/events/events_internal.h
@@ -68,7 +68,6 @@ struct evtchn_ops {
68 bool (*test_and_set_mask)(unsigned port); 68 bool (*test_and_set_mask)(unsigned port);
69 void (*mask)(unsigned port); 69 void (*mask)(unsigned port);
70 void (*unmask)(unsigned port); 70 void (*unmask)(unsigned port);
71 void (*close)(unsigned port, unsigned cpu);
72 71
73 void (*handle_events)(unsigned cpu); 72 void (*handle_events)(unsigned cpu);
74 void (*resume)(void); 73 void (*resume)(void);
@@ -146,12 +145,6 @@ static inline void xen_evtchn_resume(void)
146 evtchn_ops->resume(); 145 evtchn_ops->resume();
147} 146}
148 147
149static inline void xen_evtchn_op_close(unsigned port, unsigned cpu)
150{
151 if (evtchn_ops->close)
152 return evtchn_ops->close(port, cpu);
153}
154
155void xen_evtchn_2l_init(void); 148void xen_evtchn_2l_init(void);
156int xen_evtchn_fifo_init(void); 149int xen_evtchn_fifo_init(void);
157 150
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index 9ad327238ba9..e30353575d5d 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -814,8 +814,10 @@ static int xenbus_unmap_ring_vfree_hvm(struct xenbus_device *dev, void *vaddr)
814 814
815 rv = xenbus_unmap_ring(dev, node->handles, node->nr_handles, 815 rv = xenbus_unmap_ring(dev, node->handles, node->nr_handles,
816 addrs); 816 addrs);
817 if (!rv) 817 if (!rv) {
818 vunmap(vaddr); 818 vunmap(vaddr);
819 free_xenballooned_pages(node->nr_handles, node->hvm.pages);
820 }
819 else 821 else
820 WARN(1, "Leaking %p, size %u page(s)\n", vaddr, 822 WARN(1, "Leaking %p, size %u page(s)\n", vaddr,
821 node->nr_handles); 823 node->nr_handles);