From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753538AbcFOTEX (ORCPT ); Wed, 15 Jun 2016 15:04:23 -0400 Received: from relay2.sgi.com ([192.48.180.65]:45562 "EHLO relay.sgi.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753160AbcFOTET (ORCPT ); Wed, 15 Jun 2016 15:04:19 -0400 From: Alex Thorlton To: linux-kernel@vger.kernel.org Cc: Alex Thorlton , Matt Fleming , Russ Anderson , Dimitri Sivanich , Russell King , Catalin Marinas , Will Deacon , Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , Ard Biesheuvel , Mark Rutland , Roy Franz , linux-arm-kernel@lists.infradead.org, linux-efi@vger.kernel.org, x86@kernel.org Subject: [PATCH 2/3] Update uv_bios_call to use efi_call_virt_pointer Date: Wed, 15 Jun 2016 14:04:14 -0500 Message-Id: <1466017455-236934-3-git-send-email-athorlton@sgi.com> X-Mailer: git-send-email 1.8.5.6 In-Reply-To: <1466017455-236934-1-git-send-email-athorlton@sgi.com> References: <1466017455-236934-1-git-send-email-athorlton@sgi.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Now that the efi_call_virt macro has been generalized to be able to use EFI system tables besides efi.systab, we are able to convert our uv_bios_call wrapper to use this standard EFI callback mechanism. This simple change is part of a much larger effort to recover from some issues with the way we were mapping in some of our MMRs, and the way that we were doing our BIOS callbacks, which were uncovered by commit 67a9108ed431 ("x86/efi: Build our own page table structures"). The first issue that this uncovered was that we were relying on the EFI memory mapping mechanism to map in our MMR space for us, which, while reliable, was technically a bug, as it relied on "undefined" behavior in the mapping code. The reason we were able to piggyback on the EFI memory mapping code to map in our MMRs was because, previously, EFI code used the trampoline_pgd, which shares a few entries with the main kernel pgd. It just so happened, that the memory range containing our MMRs was inside one of those shared regions, which kept our code working without issue for quite a while. Anyways, once we discovered this problem, we brought back our original code to map in the MMRs with commit 08914f436bdd ("x86/platform/UV: Bring back the call to map_low_mmrs in uv_system_init"). This got our systems a little further along, but we were still running into trouble with our EFI callbacks, which prevented us from booting all the way up. Our first step towards fixing the BIOS callbacks was to get our uv_bios_call wrapper updated to use efi_call_virt instead of the plain efi_call. The previous patch took care of the effort needed to make that possible. Along the way, we hit a major issue with some confusion about how to properly pull arguments higher than number 6 off the stack in the efi_call code, which resulted in Linus's commit 683ad8092cd2 ("x86/efi: Fix 7-parameter efi_call()s"). Now that all of those issues are out of the way, we're able to make this simple change to use the new efi_call_virt_pointer in uv_bios_call which gets our machines booting, running properly, and able to execute our callbacks with 6+ arguments. Note that, since we are now using the EFI page table when we make our function call, we are no longer able to make the call using the __va() of our function pointer, since the memory range containing that address isn't mapped into the EFI page table. For now, we will use the physical address of the function directly, since that is mapped into the EFI page table. In the near future, we're going to get some code added in to properly update our function pointer to its virtual address during SetVirtualAddressMap. Signed-off-by: Alex Thorlton Cc: Matt Fleming Cc: Russ Anderson Cc: Dimitri Sivanich Cc: Russell King Cc: Catalin Marinas Cc: Will Deacon Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: Ard Biesheuvel Cc: Mark Rutland Cc: Roy Franz Cc: linux-arm-kernel@lists.infradead.org Cc: linux-efi@vger.kernel.org Cc: x86@kernel.org --- arch/x86/platform/uv/bios_uv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86/platform/uv/bios_uv.c b/arch/x86/platform/uv/bios_uv.c index 815fec6..66b2166 100644 --- a/arch/x86/platform/uv/bios_uv.c +++ b/arch/x86/platform/uv/bios_uv.c @@ -40,8 +40,7 @@ s64 uv_bios_call(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5) */ return BIOS_STATUS_UNIMPLEMENTED; - ret = efi_call((void *)__va(tab->function), (u64)which, - a1, a2, a3, a4, a5); + ret = efi_call_virt_pointer(tab, function, (u64)which, a1, a2, a3, a4, a5); return ret; } EXPORT_SYMBOL_GPL(uv_bios_call); -- 1.8.5.6 From mboxrd@z Thu Jan 1 00:00:00 1970 From: athorlton@sgi.com (Alex Thorlton) Date: Wed, 15 Jun 2016 14:04:14 -0500 Subject: [PATCH 2/3] Update uv_bios_call to use efi_call_virt_pointer In-Reply-To: <1466017455-236934-1-git-send-email-athorlton@sgi.com> References: <1466017455-236934-1-git-send-email-athorlton@sgi.com> Message-ID: <1466017455-236934-3-git-send-email-athorlton@sgi.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Now that the efi_call_virt macro has been generalized to be able to use EFI system tables besides efi.systab, we are able to convert our uv_bios_call wrapper to use this standard EFI callback mechanism. This simple change is part of a much larger effort to recover from some issues with the way we were mapping in some of our MMRs, and the way that we were doing our BIOS callbacks, which were uncovered by commit 67a9108ed431 ("x86/efi: Build our own page table structures"). The first issue that this uncovered was that we were relying on the EFI memory mapping mechanism to map in our MMR space for us, which, while reliable, was technically a bug, as it relied on "undefined" behavior in the mapping code. The reason we were able to piggyback on the EFI memory mapping code to map in our MMRs was because, previously, EFI code used the trampoline_pgd, which shares a few entries with the main kernel pgd. It just so happened, that the memory range containing our MMRs was inside one of those shared regions, which kept our code working without issue for quite a while. Anyways, once we discovered this problem, we brought back our original code to map in the MMRs with commit 08914f436bdd ("x86/platform/UV: Bring back the call to map_low_mmrs in uv_system_init"). This got our systems a little further along, but we were still running into trouble with our EFI callbacks, which prevented us from booting all the way up. Our first step towards fixing the BIOS callbacks was to get our uv_bios_call wrapper updated to use efi_call_virt instead of the plain efi_call. The previous patch took care of the effort needed to make that possible. Along the way, we hit a major issue with some confusion about how to properly pull arguments higher than number 6 off the stack in the efi_call code, which resulted in Linus's commit 683ad8092cd2 ("x86/efi: Fix 7-parameter efi_call()s"). Now that all of those issues are out of the way, we're able to make this simple change to use the new efi_call_virt_pointer in uv_bios_call which gets our machines booting, running properly, and able to execute our callbacks with 6+ arguments. Note that, since we are now using the EFI page table when we make our function call, we are no longer able to make the call using the __va() of our function pointer, since the memory range containing that address isn't mapped into the EFI page table. For now, we will use the physical address of the function directly, since that is mapped into the EFI page table. In the near future, we're going to get some code added in to properly update our function pointer to its virtual address during SetVirtualAddressMap. Signed-off-by: Alex Thorlton Cc: Matt Fleming Cc: Russ Anderson Cc: Dimitri Sivanich Cc: Russell King Cc: Catalin Marinas Cc: Will Deacon Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: Ard Biesheuvel Cc: Mark Rutland Cc: Roy Franz Cc: linux-arm-kernel at lists.infradead.org Cc: linux-efi at vger.kernel.org Cc: x86 at kernel.org --- arch/x86/platform/uv/bios_uv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86/platform/uv/bios_uv.c b/arch/x86/platform/uv/bios_uv.c index 815fec6..66b2166 100644 --- a/arch/x86/platform/uv/bios_uv.c +++ b/arch/x86/platform/uv/bios_uv.c @@ -40,8 +40,7 @@ s64 uv_bios_call(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5) */ return BIOS_STATUS_UNIMPLEMENTED; - ret = efi_call((void *)__va(tab->function), (u64)which, - a1, a2, a3, a4, a5); + ret = efi_call_virt_pointer(tab, function, (u64)which, a1, a2, a3, a4, a5); return ret; } EXPORT_SYMBOL_GPL(uv_bios_call); -- 1.8.5.6