X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-kernel.git;a=blobdiff_plain;f=drivers%2Fhv%2Fhv.c;h=f5cccd0edf5671faf6104a23c7c9091589425494;hp=0fb100ed91a36a79910b0d7fec72c51ca1aa4264;hb=3397f7383687aaefb18f6d13e3cc7ca863d1570e;hpb=c125d5e846894043361c0c89c1140be8fd6600b7 diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index 0fb100ed91a3..f5cccd0edf56 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -158,6 +158,8 @@ int hv_init(void) memset(hv_context.synic_event_page, 0, sizeof(void *) * MAX_NUM_CPUS); memset(hv_context.synic_message_page, 0, sizeof(void *) * MAX_NUM_CPUS); + memset(hv_context.post_msg_page, 0, + sizeof(void *) * MAX_NUM_CPUS); if (!query_hypervisor_presence()) goto cleanup; @@ -176,7 +178,7 @@ int hv_init(void) /* See if the hypercall page is already set */ rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); - virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_EXEC); + virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_RX); if (!virtaddr) goto cleanup; @@ -258,26 +260,18 @@ u16 hv_post_message(union hv_connection_id connection_id, enum hv_message_type message_type, void *payload, size_t payload_size) { - struct aligned_input { - u64 alignment8; - struct hv_input_post_message msg; - }; struct hv_input_post_message *aligned_msg; u16 status; - unsigned long addr; if (payload_size > HV_MESSAGE_PAYLOAD_BYTE_COUNT) return -EMSGSIZE; - addr = (unsigned long)kmalloc(sizeof(struct aligned_input), GFP_ATOMIC); - if (!addr) - return -ENOMEM; - aligned_msg = (struct hv_input_post_message *) - (ALIGN(addr, HV_HYPERCALL_PARAM_ALIGN)); + hv_context.post_msg_page[get_cpu()]; aligned_msg->connectionid = connection_id; + aligned_msg->reserved = 0; aligned_msg->message_type = message_type; aligned_msg->payload_size = payload_size; memcpy((void *)aligned_msg->payload, payload, payload_size); @@ -285,8 +279,7 @@ u16 hv_post_message(union hv_connection_id connection_id, status = do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL) & 0xFFFF; - kfree((void *)addr); - + put_cpu(); return status; } @@ -347,6 +340,14 @@ void hv_synic_init(void *irqarg) goto cleanup; } + hv_context.post_msg_page[cpu] = + (void *)get_zeroed_page(GFP_ATOMIC); + + if (hv_context.post_msg_page[cpu] == NULL) { + pr_err("Unable to allocate post msg page\n"); + goto cleanup; + } + /* Setup the Synic's message page */ rdmsrl(HV_X64_MSR_SIMP, simp.as_uint64); simp.simp_enabled = 1; @@ -388,6 +389,8 @@ cleanup: if (hv_context.synic_message_page[cpu]) free_page((unsigned long)hv_context.synic_message_page[cpu]); + if (hv_context.post_msg_page[cpu]) + free_page((unsigned long)hv_context.post_msg_page[cpu]); return; } @@ -426,4 +429,5 @@ void hv_synic_cleanup(void *arg) free_page((unsigned long)hv_context.synic_message_page[cpu]); free_page((unsigned long)hv_context.synic_event_page[cpu]); + free_page((unsigned long)hv_context.post_msg_page[cpu]); }