aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/xen/events/events_fifo.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c
index 84b4bfb84344..c7ff2035b98e 100644
--- a/drivers/xen/events/events_fifo.c
+++ b/drivers/xen/events/events_fifo.c
@@ -100,6 +100,25 @@ static unsigned evtchn_fifo_nr_channels(void)
100 return event_array_pages * EVENT_WORDS_PER_PAGE; 100 return event_array_pages * EVENT_WORDS_PER_PAGE;
101} 101}
102 102
103static int init_control_block(int cpu,
104 struct evtchn_fifo_control_block *control_block)
105{
106 struct evtchn_fifo_queue *q = &per_cpu(cpu_queue, cpu);
107 struct evtchn_init_control init_control;
108 unsigned int i;
109
110 /* Reset the control block and the local HEADs. */
111 clear_page(control_block);
112 for (i = 0; i < EVTCHN_FIFO_MAX_QUEUES; i++)
113 q->head[i] = 0;
114
115 init_control.control_gfn = virt_to_mfn(control_block);
116 init_control.offset = 0;
117 init_control.vcpu = cpu;
118
119 return HYPERVISOR_event_channel_op(EVTCHNOP_init_control, &init_control);
120}
121
103static void free_unused_array_pages(void) 122static void free_unused_array_pages(void)
104{ 123{
105 unsigned i; 124 unsigned i;
@@ -324,7 +343,6 @@ static void evtchn_fifo_resume(void)
324 343
325 for_each_possible_cpu(cpu) { 344 for_each_possible_cpu(cpu) {
326 void *control_block = per_cpu(cpu_control_block, cpu); 345 void *control_block = per_cpu(cpu_control_block, cpu);
327 struct evtchn_init_control init_control;
328 int ret; 346 int ret;
329 347
330 if (!control_block) 348 if (!control_block)
@@ -341,12 +359,7 @@ static void evtchn_fifo_resume(void)
341 continue; 359 continue;
342 } 360 }
343 361
344 init_control.control_gfn = virt_to_mfn(control_block); 362 ret = init_control_block(cpu, control_block);
345 init_control.offset = 0;
346 init_control.vcpu = cpu;
347
348 ret = HYPERVISOR_event_channel_op(EVTCHNOP_init_control,
349 &init_control);
350 if (ret < 0) 363 if (ret < 0)
351 BUG(); 364 BUG();
352 } 365 }
@@ -374,30 +387,25 @@ static const struct evtchn_ops evtchn_ops_fifo = {
374 .resume = evtchn_fifo_resume, 387 .resume = evtchn_fifo_resume,
375}; 388};
376 389
377static int evtchn_fifo_init_control_block(unsigned cpu) 390static int evtchn_fifo_alloc_control_block(unsigned cpu)
378{ 391{
379 struct page *control_block = NULL; 392 void *control_block = NULL;
380 struct evtchn_init_control init_control;
381 int ret = -ENOMEM; 393 int ret = -ENOMEM;
382 394
383 control_block = alloc_page(GFP_KERNEL|__GFP_ZERO); 395 control_block = (void *)__get_free_page(GFP_KERNEL);
384 if (control_block == NULL) 396 if (control_block == NULL)
385 goto error; 397 goto error;
386 398
387 init_control.control_gfn = virt_to_mfn(page_address(control_block)); 399 ret = init_control_block(cpu, control_block);
388 init_control.offset = 0;
389 init_control.vcpu = cpu;
390
391 ret = HYPERVISOR_event_channel_op(EVTCHNOP_init_control, &init_control);
392 if (ret < 0) 400 if (ret < 0)
393 goto error; 401 goto error;
394 402
395 per_cpu(cpu_control_block, cpu) = page_address(control_block); 403 per_cpu(cpu_control_block, cpu) = control_block;
396 404
397 return 0; 405 return 0;
398 406
399 error: 407 error:
400 __free_page(control_block); 408 free_page((unsigned long)control_block);
401 return ret; 409 return ret;
402} 410}
403 411
@@ -411,7 +419,7 @@ static int evtchn_fifo_cpu_notification(struct notifier_block *self,
411 switch (action) { 419 switch (action) {
412 case CPU_UP_PREPARE: 420 case CPU_UP_PREPARE:
413 if (!per_cpu(cpu_control_block, cpu)) 421 if (!per_cpu(cpu_control_block, cpu))
414 ret = evtchn_fifo_init_control_block(cpu); 422 ret = evtchn_fifo_alloc_control_block(cpu);
415 break; 423 break;
416 default: 424 default:
417 break; 425 break;
@@ -428,7 +436,7 @@ int __init xen_evtchn_fifo_init(void)
428 int cpu = get_cpu(); 436 int cpu = get_cpu();
429 int ret; 437 int ret;
430 438
431 ret = evtchn_fifo_init_control_block(cpu); 439 ret = evtchn_fifo_alloc_control_block(cpu);
432 if (ret < 0) 440 if (ret < 0)
433 goto out; 441 goto out;
434 442