From owner-svn-src-all@freebsd.org Sat Aug 4 21:41:12 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 17BEA1053B3E; Sat, 4 Aug 2018 21:41:12 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id E42BD897B7; Sat, 4 Aug 2018 21:41:11 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id C59EC150F8; Sat, 4 Aug 2018 21:41:11 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w74LfB1J044398; Sat, 4 Aug 2018 21:41:11 GMT (envelope-from kevans@FreeBSD.org) Received: (from kevans@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w74LfAb1044394; Sat, 4 Aug 2018 21:41:10 GMT (envelope-from kevans@FreeBSD.org) Message-Id: <201808042141.w74LfAb1044394@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kevans set sender to kevans@FreeBSD.org using -f From: Kyle Evans Date: Sat, 4 Aug 2018 21:41:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r337331 - in head/sys: amd64/amd64 arm64/arm64 dev/efidev sys X-SVN-Group: head X-SVN-Commit-Author: kevans X-SVN-Commit-Paths: in head/sys: amd64/amd64 arm64/arm64 dev/efidev sys X-SVN-Commit-Revision: 337331 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 04 Aug 2018 21:41:12 -0000 Author: kevans Date: Sat Aug 4 21:41:10 2018 New Revision: 337331 URL: https://svnweb.freebsd.org/changeset/base/337331 Log: efirt: Don't enter EFI context early, convert addrs to KVA instead efi_enter here was needed because efi_runtime dereference causes a fault outside of EFI context, due to runtime table living in runtime service space. This may cause problems early in boot, though, so instead access it by converting paddr to KVA for access. While here, remove the other direct PHYS_TO_DMAP calls and the explicit DMAP requirement from efidev. Reviewed by: kib MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D16591 Modified: head/sys/amd64/amd64/efirt_machdep.c head/sys/arm64/arm64/efirt_machdep.c head/sys/dev/efidev/efirt.c head/sys/sys/efi.h Modified: head/sys/amd64/amd64/efirt_machdep.c ============================================================================== --- head/sys/amd64/amd64/efirt_machdep.c Sat Aug 4 20:45:43 2018 (r337330) +++ head/sys/amd64/amd64/efirt_machdep.c Sat Aug 4 21:41:10 2018 (r337331) @@ -84,6 +84,19 @@ efi_destroy_1t1_map(void) efi_pml4_page = NULL; } +/* + * Map a physical address from EFI runtime space into KVA space. Returns 0 to + * indicate a failed mapping so that the caller may handle error. + */ +vm_offset_t +efi_phys_to_kva(vm_paddr_t paddr) +{ + + if (paddr >= dmaplimit) + return (0); + return (PHYS_TO_DMAP(paddr)); +} + static vm_page_t efi_1t1_page(void) { Modified: head/sys/arm64/arm64/efirt_machdep.c ============================================================================== --- head/sys/arm64/arm64/efirt_machdep.c Sat Aug 4 20:45:43 2018 (r337330) +++ head/sys/arm64/arm64/efirt_machdep.c Sat Aug 4 21:41:10 2018 (r337331) @@ -143,6 +143,19 @@ efi_1t1_l3(vm_offset_t va) } /* + * Map a physical address from EFI runtime space into KVA space. Returns 0 to + * indicate a failed mapping so that the caller may handle error. + */ +vm_offset_t +efi_phys_to_kva(vm_paddr_t paddr) +{ + + if (!PHYS_IN_DMAP(paddr)) + return (0); + return (PHYS_TO_DMAP(paddr)); +} + +/* * Create the 1:1 virtual to physical map for EFI */ bool Modified: head/sys/dev/efidev/efirt.c ============================================================================== --- head/sys/dev/efidev/efirt.c Sat Aug 4 20:45:43 2018 (r337330) +++ head/sys/dev/efidev/efirt.c Sat Aug 4 21:41:10 2018 (r337331) @@ -131,9 +131,10 @@ efi_init(void) { struct efi_map_header *efihdr; struct efi_md *map; + struct efi_rt *rtdm; caddr_t kmdp; size_t efisz; - int rt_disabled; + int ndesc, rt_disabled; rt_disabled = 0; TUNABLE_INT_FETCH("efi.rt.disabled", &rt_disabled); @@ -146,13 +147,9 @@ efi_init(void) printf("EFI systbl not available\n"); return (0); } - if (!PMAP_HAS_DMAP) { - if (bootverbose) - printf("EFI systbl requires direct map\n"); - return (0); - } - efi_systbl = (struct efi_systbl *)PHYS_TO_DMAP(efi_systbl_phys); - if (efi_systbl->st_hdr.th_sig != EFI_SYSTBL_SIG) { + + efi_systbl = (struct efi_systbl *)efi_phys_to_kva(efi_systbl_phys); + if (efi_systbl == NULL || efi_systbl->st_hdr.th_sig != EFI_SYSTBL_SIG) { efi_systbl = NULL; if (bootverbose) printf("EFI systbl signature invalid\n"); @@ -180,8 +177,8 @@ efi_init(void) if (efihdr->descriptor_size == 0) return (ENOMEM); - if (!efi_create_1t1_map(map, efihdr->memory_size / - efihdr->descriptor_size, efihdr->descriptor_size)) { + ndesc = efihdr->memory_size / efihdr->descriptor_size; + if (!efi_create_1t1_map(map, ndesc, efihdr->descriptor_size)) { if (bootverbose) printf("EFI cannot create runtime map\n"); return (ENOMEM); @@ -196,6 +193,7 @@ efi_init(void) return (ENXIO); } +#if defined(__aarch64__) || defined(__amd64__) /* * Some UEFI implementations have multiple implementations of the * RS->GetTime function. They switch from one we can only use early @@ -203,14 +201,10 @@ efi_init(void) * call RS->SetVirtualAddressMap. As this is not always the case, e.g. * with an old loader.efi, check if the RS->GetTime function is within * the EFI map, and fail to attach if not. - * - * We need to enter into the EFI environment as efi_runtime may point - * to an EFI address. */ - efi_enter(); - if (!efi_is_in_map(map, efihdr->memory_size / efihdr->descriptor_size, - efihdr->descriptor_size, (vm_offset_t)efi_runtime->rt_gettime)) { - efi_leave(); + rtdm = (struct efi_rt *)efi_phys_to_kva((uintptr_t)efi_runtime); + if (rtdm == NULL || !efi_is_in_map(map, ndesc, efihdr->descriptor_size, + (vm_offset_t)rtdm->rt_gettime)) { if (bootverbose) printf( "EFI runtime services table has an invalid pointer\n"); @@ -218,7 +212,7 @@ efi_init(void) efi_destroy_1t1_map(); return (ENXIO); } - efi_leave(); +#endif return (0); } @@ -291,7 +285,7 @@ efi_get_table(struct uuid *uuid, void **ptr) ct = efi_cfgtbl; while (count--) { if (!bcmp(&ct->ct_uuid, uuid, sizeof(*uuid))) { - *ptr = (void *)PHYS_TO_DMAP(ct->ct_data); + *ptr = (void *)efi_phys_to_kva(ct->ct_data); return (0); } ct++; Modified: head/sys/sys/efi.h ============================================================================== --- head/sys/sys/efi.h Sat Aug 4 20:45:43 2018 (r337330) +++ head/sys/sys/efi.h Sat Aug 4 21:41:10 2018 (r337331) @@ -172,6 +172,7 @@ extern vm_paddr_t efi_systbl_phys; /* Internal MD EFI functions */ int efi_arch_enter(void); void efi_arch_leave(void); +vm_offset_t efi_phys_to_kva(vm_paddr_t); bool efi_create_1t1_map(struct efi_md *, int, int); void efi_destroy_1t1_map(void);