int hv_synic_alloc()

in hv.c [118:180]


int hv_synic_alloc(void)
{
	int cpu;
	struct hv_per_cpu_context *hv_cpu;

	/*
	 * First, zero all per-cpu memory areas so hv_synic_free() can
	 * detect what memory has been allocated and cleanup properly
	 * after any failures.
	 */
	for_each_present_cpu(cpu) {
		hv_cpu = per_cpu_ptr(hv_context.cpu_context, cpu);
		memset(hv_cpu, 0, sizeof(*hv_cpu));
	}

	hv_context.hv_numa_map = kcalloc(nr_node_ids, sizeof(struct cpumask),
					 GFP_KERNEL);
	if (hv_context.hv_numa_map == NULL) {
		pr_err("Unable to allocate NUMA map\n");
		goto err;
	}

	for_each_present_cpu(cpu) {
		hv_cpu = per_cpu_ptr(hv_context.cpu_context, cpu);

		tasklet_init(&hv_cpu->msg_dpc,
			     vmbus_on_msg_dpc, (unsigned long) hv_cpu);

		/*
		 * Synic message and event pages are allocated by paravisor.
		 * Skip these pages allocation here.
		 */
		if (!hv_isolation_type_snp()) {
			hv_cpu->synic_message_page =
				(void *)get_zeroed_page(GFP_ATOMIC);
			if (hv_cpu->synic_message_page == NULL) {
				pr_err("Unable to allocate SYNIC message page\n");
				goto err;
			}

			hv_cpu->synic_event_page =
				(void *)get_zeroed_page(GFP_ATOMIC);
			if (hv_cpu->synic_event_page == NULL) {
				pr_err("Unable to allocate SYNIC event page\n");
				goto err;
			}
		}

		hv_cpu->post_msg_page = (void *)get_zeroed_page(GFP_ATOMIC);
		if (hv_cpu->post_msg_page == NULL) {
			pr_err("Unable to allocate post msg page\n");
			goto err;
		}
	}

	return 0;
err:
	/*
	 * Any memory allocations that succeeded will be freed when
	 * the caller cleans up by calling hv_synic_free()
	 */
	return -ENOMEM;
}