From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964873AbbFCPNn (ORCPT ); Wed, 3 Jun 2015 11:13:43 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53305 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933312AbbFCPNQ (ORCPT ); Wed, 3 Jun 2015 11:13:16 -0400 From: Vitaly Kuznetsov To: devel@linuxdriverproject.org Cc: "K. Y. Srinivasan" , Haiyang Zhang , linux-kernel@vger.kernel.org, Dexuan Cui , Ingo Molnar , "H. Peter Anvin" , Thomas Gleixner , x86@kernel.org Subject: [PATCH v2 3/3] Drivers: hv: don't do hypercalls when hypercall_page is NULL Date: Wed, 3 Jun 2015 17:13:05 +0200 Message-Id: <1433344385-26944-4-git-send-email-vkuznets@redhat.com> In-Reply-To: <1433344385-26944-1-git-send-email-vkuznets@redhat.com> References: <1433344385-26944-1-git-send-email-vkuznets@redhat.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org At the very late stage of kexec a driver (which are not being unloaded) can try to post a message or signal an event. This will crash the kernel as we already did hv_cleanup() and the hypercall page is NULL. Move all common (between 32 and 64 bit code) declarations to the beginning of the do_hypercall() function. Unfortunately we have to write the !hypercall_page check twice to not mix declarations and code. Signed-off-by: Vitaly Kuznetsov --- drivers/hv/hv.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index 5b87042..41d8072 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -93,11 +93,14 @@ static int query_hypervisor_info(void) */ static u64 do_hypercall(u64 control, void *input, void *output) { -#ifdef CONFIG_X86_64 - u64 hv_status = 0; u64 input_address = (input) ? virt_to_phys(input) : 0; u64 output_address = (output) ? virt_to_phys(output) : 0; void *hypercall_page = hv_context.hypercall_page; +#ifdef CONFIG_X86_64 + u64 hv_status = 0; + + if (!hypercall_page) + return (u64)ULLONG_MAX; __asm__ __volatile__("mov %0, %%r8" : : "r" (output_address) : "r8"); __asm__ __volatile__("call *%3" : "=a" (hv_status) : @@ -112,13 +115,13 @@ static u64 do_hypercall(u64 control, void *input, void *output) u32 control_lo = control & 0xFFFFFFFF; u32 hv_status_hi = 1; u32 hv_status_lo = 1; - u64 input_address = (input) ? virt_to_phys(input) : 0; u32 input_address_hi = input_address >> 32; u32 input_address_lo = input_address & 0xFFFFFFFF; - u64 output_address = (output) ? virt_to_phys(output) : 0; u32 output_address_hi = output_address >> 32; u32 output_address_lo = output_address & 0xFFFFFFFF; - void *hypercall_page = hv_context.hypercall_page; + + if (!hypercall_page) + return (u64)ULLONG_MAX; __asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi), "=a"(hv_status_lo) : "d" (control_hi), -- 1.9.3