return event_array_pages * EVENT_WORDS_PER_PAGE;
}
+static int init_control_block(int cpu,
+ struct evtchn_fifo_control_block *control_block)
+{
+ struct evtchn_fifo_queue *q = &per_cpu(cpu_queue, cpu);
+ struct evtchn_init_control init_control;
+ unsigned int i;
+
+ /* Reset the control block and the local HEADs. */
+ clear_page(control_block);
+ for (i = 0; i < EVTCHN_FIFO_MAX_QUEUES; i++)
+ q->head[i] = 0;
+
+ init_control.control_gfn = virt_to_mfn(control_block);
+ init_control.offset = 0;
+ init_control.vcpu = cpu;
+
+ return HYPERVISOR_event_channel_op(EVTCHNOP_init_control, &init_control);
+}
+
static void free_unused_array_pages(void)
{
unsigned i;
for_each_possible_cpu(cpu) {
void *control_block = per_cpu(cpu_control_block, cpu);
- struct evtchn_init_control init_control;
int ret;
if (!control_block)
continue;
}
- init_control.control_gfn = virt_to_mfn(control_block);
- init_control.offset = 0;
- init_control.vcpu = cpu;
-
- ret = HYPERVISOR_event_channel_op(EVTCHNOP_init_control,
- &init_control);
+ ret = init_control_block(cpu, control_block);
if (ret < 0)
BUG();
}
.resume = evtchn_fifo_resume,
};
-static int evtchn_fifo_init_control_block(unsigned cpu)
+static int evtchn_fifo_alloc_control_block(unsigned cpu)
{
- struct page *control_block = NULL;
- struct evtchn_init_control init_control;
+ void *control_block = NULL;
int ret = -ENOMEM;
- control_block = alloc_page(GFP_KERNEL|__GFP_ZERO);
+ control_block = (void *)__get_free_page(GFP_KERNEL);
if (control_block == NULL)
goto error;
- init_control.control_gfn = virt_to_mfn(page_address(control_block));
- init_control.offset = 0;
- init_control.vcpu = cpu;
-
- ret = HYPERVISOR_event_channel_op(EVTCHNOP_init_control, &init_control);
+ ret = init_control_block(cpu, control_block);
if (ret < 0)
goto error;
- per_cpu(cpu_control_block, cpu) = page_address(control_block);
+ per_cpu(cpu_control_block, cpu) = control_block;
return 0;
error:
- __free_page(control_block);
+ free_page((unsigned long)control_block);
return ret;
}
switch (action) {
case CPU_UP_PREPARE:
if (!per_cpu(cpu_control_block, cpu))
- ret = evtchn_fifo_init_control_block(cpu);
+ ret = evtchn_fifo_alloc_control_block(cpu);
break;
default:
break;
int cpu = get_cpu();
int ret;
- ret = evtchn_fifo_init_control_block(cpu);
+ ret = evtchn_fifo_alloc_control_block(cpu);
if (ret < 0)
goto out;