|
@@ -100,6 +100,25 @@ static unsigned evtchn_fifo_nr_channels(void)
|
|
return event_array_pages * EVENT_WORDS_PER_PAGE;
|
|
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)
|
|
static void free_unused_array_pages(void)
|
|
{
|
|
{
|
|
unsigned i;
|
|
unsigned i;
|
|
@@ -324,7 +343,6 @@ static void evtchn_fifo_resume(void)
|
|
|
|
|
|
for_each_possible_cpu(cpu) {
|
|
for_each_possible_cpu(cpu) {
|
|
void *control_block = per_cpu(cpu_control_block, cpu);
|
|
void *control_block = per_cpu(cpu_control_block, cpu);
|
|
- struct evtchn_init_control init_control;
|
|
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
if (!control_block)
|
|
if (!control_block)
|
|
@@ -341,12 +359,7 @@ static void evtchn_fifo_resume(void)
|
|
continue;
|
|
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)
|
|
if (ret < 0)
|
|
BUG();
|
|
BUG();
|
|
}
|
|
}
|
|
@@ -374,30 +387,25 @@ static const struct evtchn_ops evtchn_ops_fifo = {
|
|
.resume = evtchn_fifo_resume,
|
|
.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;
|
|
int ret = -ENOMEM;
|
|
|
|
|
|
- control_block = alloc_page(GFP_KERNEL|__GFP_ZERO);
|
|
|
|
|
|
+ control_block = (void *)__get_free_page(GFP_KERNEL);
|
|
if (control_block == NULL)
|
|
if (control_block == NULL)
|
|
goto error;
|
|
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)
|
|
if (ret < 0)
|
|
goto error;
|
|
goto error;
|
|
|
|
|
|
- per_cpu(cpu_control_block, cpu) = page_address(control_block);
|
|
|
|
|
|
+ per_cpu(cpu_control_block, cpu) = control_block;
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
error:
|
|
error:
|
|
- __free_page(control_block);
|
|
|
|
|
|
+ free_page((unsigned long)control_block);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -411,7 +419,7 @@ static int evtchn_fifo_cpu_notification(struct notifier_block *self,
|
|
switch (action) {
|
|
switch (action) {
|
|
case CPU_UP_PREPARE:
|
|
case CPU_UP_PREPARE:
|
|
if (!per_cpu(cpu_control_block, cpu))
|
|
if (!per_cpu(cpu_control_block, cpu))
|
|
- ret = evtchn_fifo_init_control_block(cpu);
|
|
|
|
|
|
+ ret = evtchn_fifo_alloc_control_block(cpu);
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
break;
|
|
break;
|
|
@@ -428,7 +436,7 @@ int __init xen_evtchn_fifo_init(void)
|
|
int cpu = get_cpu();
|
|
int cpu = get_cpu();
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
- ret = evtchn_fifo_init_control_block(cpu);
|
|
|
|
|
|
+ ret = evtchn_fifo_alloc_control_block(cpu);
|
|
if (ret < 0)
|
|
if (ret < 0)
|
|
goto out;
|
|
goto out;
|
|
|
|
|