From owner-svn-src-all@freebsd.org Thu Feb 21 02:37:03 2019 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 2064414EA85D; Thu, 21 Feb 2019 02:37:03 +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.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id B01E485760; Thu, 21 Feb 2019 02:37:02 +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 A25E5F008; Thu, 21 Feb 2019 02:37:02 +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 x1L2b2ii080671; Thu, 21 Feb 2019 02:37:02 GMT (envelope-from kevans@FreeBSD.org) Received: (from kevans@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x1L2b28G080669; Thu, 21 Feb 2019 02:37:02 GMT (envelope-from kevans@FreeBSD.org) Message-Id: <201902210237.x1L2b28G080669@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kevans set sender to kevans@FreeBSD.org using -f From: Kyle Evans Date: Thu, 21 Feb 2019 02:37:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r344406 - in stable/11/stand/efi: include libefi X-SVN-Group: stable-11 X-SVN-Commit-Author: kevans X-SVN-Commit-Paths: in stable/11/stand/efi: include libefi X-SVN-Commit-Revision: 344406 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: B01E485760 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.94 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.999,0]; NEURAL_HAM_SHORT(-0.95)[-0.947,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_HAM_LONG(-1.00)[-0.999,0] X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 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: Thu, 21 Feb 2019 02:37:03 -0000 Author: kevans Date: Thu Feb 21 02:37:01 2019 New Revision: 344406 URL: https://svnweb.freebsd.org/changeset/base/344406 Log: MFC r336651-r336655: stand: libefi: various boot protocol aux impl. r336651: Implement efi_devpath_to_media_path Takes a generic device path as its input. Scans through it to find the first media_path node in it and returns a pointer to it. If none is found, NULL is returned. r336652: Store the number of handles we get back in efipart_nhandles rather than the number of bytes. Don't divide by the element size every time we have to iterate. Eliminate now-unused variables. r336653: Implement efi_devpath_match_node Returns true if the first node pointed to by devpath1 is identical to the first node pointed to by devpath2, with care taken to not read past the end of the valid parts of either devpath1 or devpath2. Otherwise, returns false. r336654: Implement efi_devpath_length Return the total length, in bytes, of the device path (including the terminating node at the end). r336655: Implement efiblk_get_pdinfo_by_device_path Lookup a block device by it's device path. We use a 'loose' lookup whereby we scan forward to the first Media Path portion of the device path, then look at all our handles for one whose first Media Path matches. This will also work if the device path pointed to has a following file path (or paths) as that's ignored. It assumes that there's only one media path node that describes the entire device, which is true as of the latest UEFI spec (2.7 Errata A) as far as I've been able to determine. Modified: stable/11/stand/efi/include/efilib.h stable/11/stand/efi/libefi/devpath.c stable/11/stand/efi/libefi/efipart.c Directory Properties: stable/11/ (props changed) Modified: stable/11/stand/efi/include/efilib.h ============================================================================== --- stable/11/stand/efi/include/efilib.h Thu Feb 21 02:32:30 2019 (r344405) +++ stable/11/stand/efi/include/efilib.h Thu Feb 21 02:37:01 2019 (r344406) @@ -66,6 +66,7 @@ typedef struct pdinfo pdinfo_list_t *efiblk_get_pdinfo_list(struct devsw *dev); pdinfo_t *efiblk_get_pdinfo(struct devdesc *dev); pdinfo_t *efiblk_get_pdinfo_by_handle(EFI_HANDLE h); +pdinfo_t *efiblk_get_pdinfo_by_device_path(EFI_DEVICE_PATH *path); void *efi_get_table(EFI_GUID *tbl); @@ -85,9 +86,12 @@ EFI_HANDLE efi_devpath_handle(EFI_DEVICE_PATH *); EFI_DEVICE_PATH *efi_devpath_last_node(EFI_DEVICE_PATH *); EFI_DEVICE_PATH *efi_devpath_trim(EFI_DEVICE_PATH *); bool efi_devpath_match(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *); +bool efi_devpath_match_node(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *); bool efi_devpath_is_prefix(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *); CHAR16 *efi_devpath_name(EFI_DEVICE_PATH *); void efi_free_devpath_name(CHAR16 *); +EFI_DEVICE_PATH *efi_devpath_to_media_path(EFI_DEVICE_PATH *); +UINTN efi_devpath_length(EFI_DEVICE_PATH *); int efi_status_to_errno(EFI_STATUS); EFI_STATUS errno_to_efi_status(int errno); Modified: stable/11/stand/efi/libefi/devpath.c ============================================================================== --- stable/11/stand/efi/libefi/devpath.c Thu Feb 21 02:32:30 2019 (r344405) +++ stable/11/stand/efi/libefi/devpath.c Thu Feb 21 02:37:01 2019 (r344406) @@ -140,25 +140,33 @@ efi_devpath_handle(EFI_DEVICE_PATH *devpath) } bool -efi_devpath_match(EFI_DEVICE_PATH *devpath1, EFI_DEVICE_PATH *devpath2) +efi_devpath_match_node(EFI_DEVICE_PATH *devpath1, EFI_DEVICE_PATH *devpath2) { size_t len; if (devpath1 == NULL || devpath2 == NULL) return (false); + if (DevicePathType(devpath1) != DevicePathType(devpath2) || + DevicePathSubType(devpath1) != DevicePathSubType(devpath2)) + return (false); + len = DevicePathNodeLength(devpath1); + if (len != DevicePathNodeLength(devpath2)) + return (false); + if (memcmp(devpath1, devpath2, len) != 0) + return (false); + return (true); +} - while (true) { - if (DevicePathType(devpath1) != DevicePathType(devpath2) || - DevicePathSubType(devpath1) != DevicePathSubType(devpath2)) - return (false); +bool +efi_devpath_match(EFI_DEVICE_PATH *devpath1, EFI_DEVICE_PATH *devpath2) +{ - len = DevicePathNodeLength(devpath1); - if (len != DevicePathNodeLength(devpath2)) - return (false); + if (devpath1 == NULL || devpath2 == NULL) + return (false); - if (memcmp(devpath1, devpath2, len) != 0) - return (false); - + while (true) { + if (!efi_devpath_match_node(devpath1, devpath2)) + return false; if (IsDevicePathEnd(devpath1)) break; devpath1 = NextDevicePathNode(devpath1); @@ -194,4 +202,30 @@ efi_devpath_is_prefix(EFI_DEVICE_PATH *prefix, EFI_DEV path = NextDevicePathNode(path); } return (true); +} + +/* + * Skip over the 'prefix' part of path and return the part of the path + * that starts with the first node that's a MEDIA_DEVICE_PATH. + */ +EFI_DEVICE_PATH * +efi_devpath_to_media_path(EFI_DEVICE_PATH *path) +{ + + while (!IsDevicePathEnd(path)) { + if (DevicePathType(path) == MEDIA_DEVICE_PATH) + return (path); + path = NextDevicePathNode(path); + } + return (NULL); +} + +UINTN +efi_devpath_length(EFI_DEVICE_PATH *path) +{ + EFI_DEVICE_PATH *start = path; + + while (!IsDevicePathEnd(path)) + path = NextDevicePathNode(path); + return ((UINTN)path - (UINTN)start) + DevicePathNodeLength(path); } Modified: stable/11/stand/efi/libefi/efipart.c ============================================================================== --- stable/11/stand/efi/libefi/efipart.c Thu Feb 21 02:32:30 2019 (r344405) +++ stable/11/stand/efi/libefi/efipart.c Thu Feb 21 02:37:01 2019 (r344406) @@ -137,6 +137,28 @@ efiblk_get_pdinfo(struct devdesc *dev) return (pd); } +pdinfo_t * +efiblk_get_pdinfo_by_device_path(EFI_DEVICE_PATH *path) +{ + unsigned i; + EFI_DEVICE_PATH *media, *devpath; + EFI_HANDLE h; + + media = efi_devpath_to_media_path(path); + if (media == NULL) + return (NULL); + for (i = 0; i < efipart_nhandles; i++) { + h = efipart_handles[i]; + devpath = efi_lookup_devpath(h); + if (devpath == NULL) + continue; + if (!efi_devpath_match_node(media, efi_devpath_to_media_path(devpath))) + continue; + return (efiblk_get_pdinfo_by_handle(h)); + } + return (NULL); +} + static bool same_handle(pdinfo_t *pd, EFI_HANDLE h) { @@ -210,7 +232,7 @@ efipart_inithandles(void) return (efi_status_to_errno(status)); efipart_handles = hin; - efipart_nhandles = sz; + efipart_nhandles = sz / sizeof(*hin); #ifdef EFIPART_DEBUG printf("%s: Got %d BLOCK IO MEDIA handle(s)\n", __func__, efipart_nhandles); @@ -246,7 +268,7 @@ efipart_floppy(EFI_DEVICE_PATH *node) static bool efipart_hdd(EFI_DEVICE_PATH *dp) { - unsigned i, nin; + unsigned i; EFI_DEVICE_PATH *devpath, *node; EFI_BLOCK_IO *blkio; EFI_STATUS status; @@ -264,8 +286,7 @@ efipart_hdd(EFI_DEVICE_PATH *dp) * Test every EFI BLOCK IO handle to make sure dp is not device path * for CD/DVD. */ - nin = efipart_nhandles / sizeof (*efipart_handles); - for (i = 0; i < nin; i++) { + for (i = 0; i < efipart_nhandles; i++) { devpath = efi_lookup_devpath(efipart_handles[i]); if (devpath == NULL) return (false); @@ -340,10 +361,9 @@ efipart_updatefd(void) { EFI_DEVICE_PATH *devpath, *node; ACPI_HID_DEVICE_PATH *acpi; - int i, nin; + int i; - nin = efipart_nhandles / sizeof (*efipart_handles); - for (i = 0; i < nin; i++) { + for (i = 0; i < efipart_nhandles; i++) { devpath = efi_lookup_devpath(efipart_handles[i]); if (devpath == NULL) continue; @@ -410,14 +430,13 @@ efipart_cdinfo_add(EFI_HANDLE handle, EFI_HANDLE alias static void efipart_updatecd(void) { - int i, nin; + int i; EFI_DEVICE_PATH *devpath, *devpathcpy, *tmpdevpath, *node; EFI_HANDLE handle; EFI_BLOCK_IO *blkio; EFI_STATUS status; - nin = efipart_nhandles / sizeof (*efipart_handles); - for (i = 0; i < nin; i++) { + for (i = 0; i < efipart_nhandles; i++) { devpath = efi_lookup_devpath(efipart_handles[i]); if (devpath == NULL) continue; @@ -666,14 +685,13 @@ efipart_hdinfo_add_filepath(EFI_HANDLE disk_handle) static void efipart_updatehd(void) { - int i, nin; + int i; EFI_DEVICE_PATH *devpath, *devpathcpy, *tmpdevpath, *node; EFI_HANDLE handle; EFI_BLOCK_IO *blkio; EFI_STATUS status; - nin = efipart_nhandles / sizeof (*efipart_handles); - for (i = 0; i < nin; i++) { + for (i = 0; i < efipart_nhandles; i++) { devpath = efi_lookup_devpath(efipart_handles[i]); if (devpath == NULL) continue;