From owner-svn-src-all@freebsd.org Mon Feb 12 05:55:45 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 E6478F1B833; Mon, 12 Feb 2018 05:55:44 +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 8D8D181043; Mon, 12 Feb 2018 05:55:44 +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 885095F23; Mon, 12 Feb 2018 05:55:44 +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 w1C5tiWm017011; Mon, 12 Feb 2018 05:55:44 GMT (envelope-from kevans@FreeBSD.org) Received: (from kevans@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w1C5tiZ1017010; Mon, 12 Feb 2018 05:55:44 GMT (envelope-from kevans@FreeBSD.org) Message-Id: <201802120555.w1C5tiZ1017010@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kevans set sender to kevans@FreeBSD.org using -f From: Kyle Evans Date: Mon, 12 Feb 2018 05:55:44 +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: r329152 - stable/11/stand/fdt X-SVN-Group: stable-11 X-SVN-Commit-Author: kevans X-SVN-Commit-Paths: stable/11/stand/fdt X-SVN-Commit-Revision: 329152 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.25 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: Mon, 12 Feb 2018 05:55:45 -0000 Author: kevans Date: Mon Feb 12 05:55:44 2018 New Revision: 329152 URL: https://svnweb.freebsd.org/changeset/base/329152 Log: MFC r328505,r328659: stand/fdt improvements r328505: stand/fdt: Check /compatible property on overlay if it exists r328659: stand/fdt: Rip out FDT VA tracking Modified: stable/11/stand/fdt/fdt_loader_cmd.c Directory Properties: stable/11/ (props changed) Modified: stable/11/stand/fdt/fdt_loader_cmd.c ============================================================================== --- stable/11/stand/fdt/fdt_loader_cmd.c Mon Feb 12 05:28:52 2018 (r329151) +++ stable/11/stand/fdt/fdt_loader_cmd.c Mon Feb 12 05:55:44 2018 (r329152) @@ -67,13 +67,10 @@ static struct fdt_header *fdt_to_load = NULL; static struct fdt_header *fdtp = NULL; /* Size of FDT blob */ static size_t fdtp_size = 0; -/* Location of FDT in kernel or module. */ -/* This won't be set if FDT is loaded from disk or memory. */ -/* If it is set, we'll update it when fdt_copy() gets called. */ -static vm_offset_t fdtp_va = 0; static int fdt_load_dtb(vm_offset_t va); static void fdt_print_overlay_load_error(int err, const char *filename); +static int fdt_check_overlay_compatible(void *base_fdt, void *overlay_fdt); static int fdt_cmd_nyi(int argc, char *argv[]); static int fdt_load_dtb_overlays_string(const char * filenames); @@ -220,7 +217,6 @@ fdt_load_dtb(vm_offset_t va) return (1); } - fdtp_va = va; COPYOUT(va, fdtp, fdtp_size); debugf("DTB blob found at 0x%jx, size: 0x%jx\n", (uintmax_t)va, (uintmax_t)fdtp_size); @@ -247,7 +243,6 @@ fdt_load_dtb_addr(struct fdt_header *header) return (1); } - fdtp_va = 0; // Don't write this back into module or kernel. bcopy(header, fdtp, fdtp_size); return (0); } @@ -374,6 +369,62 @@ fdt_load_dtb_overlays_string(const char * filenames) return (0); } +/* + * fdt_check_overlay_compatible - check that the overlay_fdt is compatible with + * base_fdt before we attempt to apply it. It will need to re-calculate offsets + * in the base every time, rather than trying to cache them earlier in the + * process, because the overlay application process can/will invalidate a lot of + * offsets. + */ +static int +fdt_check_overlay_compatible(void *base_fdt, void *overlay_fdt) +{ + const char *compat; + int compat_len, ocompat_len; + int oroot_offset, root_offset; + int slidx, sllen; + + oroot_offset = fdt_path_offset(overlay_fdt, "/"); + if (oroot_offset < 0) + return (oroot_offset); + /* + * If /compatible in the overlay does not exist or if it is empty, then + * we're automatically compatible. We do this for the sake of rapid + * overlay development for overlays that aren't intended to be deployed. + * The user assumes the risk of using an overlay without /compatible. + */ + if (fdt_get_property(overlay_fdt, oroot_offset, "compatible", + &ocompat_len) == NULL || ocompat_len == 0) + return (0); + root_offset = fdt_path_offset(base_fdt, "/"); + if (root_offset < 0) + return (root_offset); + /* + * However, an empty or missing /compatible on the base is an error, + * because allowing this offers no advantages. + */ + if (fdt_get_property(base_fdt, root_offset, "compatible", + &compat_len) == NULL) + return (compat_len); + else if(compat_len == 0) + return (1); + + slidx = 0; + compat = fdt_stringlist_get(overlay_fdt, oroot_offset, "compatible", + slidx, &sllen); + while (compat != NULL) { + if (fdt_stringlist_search(base_fdt, root_offset, "compatible", + compat) >= 0) + return (0); + ++slidx; + compat = fdt_stringlist_get(overlay_fdt, oroot_offset, + "compatible", slidx, &sllen); + }; + + /* We've exhausted the overlay's /compatible property... no match */ + return (1); +} + void fdt_apply_overlays() { @@ -406,6 +457,13 @@ fdt_apply_overlays() current_fdtp = fdtp; current_fdtp_size = fdtp_size; for (fp = file_findfile(NULL, "dtbo"); fp != NULL; fp = fp->f_next) { + COPYOUT(fp->f_addr, overlay, fp->f_size); + /* Check compatible first to avoid unnecessary allocation */ + rv = fdt_check_overlay_compatible(current_fdtp, overlay); + if (rv != 0) { + printf("DTB overlay '%s' not compatible\n", fp->f_name); + continue; + } printf("applying DTB overlay '%s'\n", fp->f_name); next_fdtp_size = current_fdtp_size + fp->f_size; next_fdtp = malloc(next_fdtp_size); @@ -423,7 +481,6 @@ fdt_apply_overlays() printf("failed to open base dtb into overlay base\n"); continue; } - COPYOUT(fp->f_addr, overlay, fp->f_size); /* Both overlay and next_fdtp may be modified in place */ rv = fdt_overlay_apply(next_fdtp, overlay); if (rv == 0) { @@ -899,11 +956,6 @@ fdt_copy(vm_offset_t va) if (fdt_fixup() == 0) return (0); - if (fdtp_va != 0) { - /* Overwrite the FDT with the fixed version. */ - /* XXX Is this really appropriate? */ - COPYIN(fdtp, fdtp_va, fdtp_size); - } COPYIN(fdtp, va, fdtp_size); return (fdtp_size); }