Re: [PATCH] OF: DT-Overlay configfs interface (v3)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




Hi Geert,

> On May 13, 2015, at 18:31 , Geert Uytterhoeven <geert@xxxxxxxxxxxxxx> wrote:
> 
> Hi Pantelis,
> 
> On Wed, Dec 3, 2014 at 12:23 PM, Pantelis Antoniou
> <pantelis.antoniou@xxxxxxxxxxxx> wrote:
>> Add a runtime interface to using configfs for generic device tree overlay
>> usage. With it its possible to use device tree overlays without having
>> to use a per-platform overlay manager.
> 
> When loading more than one overlay, I got strange behavior:
> 
>    __allocate_fw_buf: fw-r8a7791-koelsch-exio-a-scifb0.dtbo buf=ee27b140
>    (NULL device *): firmware: direct-loading firmware
> r8a7791-koelsch-exio-a-scifb0.dtbo
>    fw_set_page_data: fw-r8a7791-koelsch-exio-a-scifb0.dtbo
> buf=ee27b140 data=f0bee000 size=820
> 
>    [ loaded overlay is activated!! ]
> 
>    __fw_free_buf: fw-r8a7791-koelsch-exio-a-scifb0.dtbo buf=ee27b140
> data=f0bee000 size=820
>    __allocate_fw_buf: fw-8a7791-koelsch-exio-a-scifb0.dtbo buf=ee3d96c0
>    (NULL device *): Direct firmware load for
> 8a7791-koelsch-exio-a-scifb0.dtbo failed with error -2
>    __fw_free_buf: fw-8a7791-koelsch-exio-a-scifb0.dtbo buf=ee3d96c0
> data=  (null) size=0
> 
> After that:
>  - The overlay itself works fine,
>  - The "status" file in configfs says "applied".
>  - The "path" file in configfs is empty?
> 
> Note that an "r" was dropped from the filename in front of the "8a7791".
> Hence I suspected some obscure memory corruption bug....
> 
> 
>> --- /dev/null
>> +++ b/drivers/of/configfs.c
>> @@ -0,0 +1,332 @@
> 
>> +static int create_overlay(struct cfs_overlay_item *overlay, void *blob)
>> +{
>> +       int err;
>> +
>> +       /* unflatten the tree */
>> +       of_fdt_unflatten_tree(blob, &overlay->overlay);
>> +       if (overlay->overlay == NULL) {
>> +               pr_err("%s: failed to unflatten tree\n", __func__);
>> +               err = -EINVAL;
>> +               goto out_err;
>> +       }
>> +       pr_debug("%s: unflattened OK\n", __func__);
>> +
>> +       /* mark it as detached */
>> +       of_node_set_flag(overlay->overlay, OF_DETACHED);
>> +
>> +       /* perform resolution */
>> +       err = of_resolve_phandles(overlay->overlay);
>> +       if (err != 0) {
>> +               pr_err("%s: Failed to resolve tree\n", __func__);
>> +               goto out_err;
>> +       }
>> +       pr_debug("%s: resolved OK\n", __func__);
>> +
>> +       err = of_overlay_create(overlay->overlay);
>> +       if (err < 0) {
>> +               pr_err("%s: Failed to create overlay (err=%d)\n",
>> +                               __func__, err);
>> +               goto out_err;
>> +       }
>> +       overlay->ov_id = err;
>> +
>> +out_err:
>> +       return err;
> 
> This returns either a strict negative error code, or a positive overlay ID.
> 
>> +}
> 
>> +static ssize_t cfs_overlay_item_path_store(struct cfs_overlay_item *overlay,
>> +               const char *page, size_t count)
>> +{
>> +       const char *p = page;
>> +       char *s;
>> +       int err;
>> +
>> +       /* if it's set do not allow changes */
>> +       if (overlay->path[0] != '\0' || overlay->dtbo_size > 0)
>> +               return -EPERM;
>> +
>> +       /* copy to path buffer (and make sure it's always zero terminated */
>> +       count = snprintf(overlay->path, sizeof(overlay->path) - 1, "%s", p);
>> +       overlay->path[sizeof(overlay->path) - 1] = '\0';
>> +
>> +       /* strip trailing newlines */
>> +       s = overlay->path + strlen(overlay->path);
>> +       while (s > overlay->path && *--s == '\n')
>> +               *s = '\0';
>> +
>> +       pr_debug("%s: path is '%s'\n", __func__, overlay->path);
>> +
>> +       err = request_firmware(&overlay->fw, overlay->path, NULL);
>> +       if (err != 0)
>> +               goto out_err;
>> +
>> +       err = create_overlay(overlay, (void *)overlay->fw->data);
>> +       if (err != 0)
> 
> Woops, this test should be "if (err < 0)"!
> For the first overlay, err == 0, and everything works fine.
> For subsequent overlays, err > 0, and …
> 
You are absolutely correct! Good catch.


>> +               goto out_err;
>> +
>> +       return count;
>> +
>> +out_err:
>> +
>> +       release_firmware(overlay->fw);
>> +       overlay->fw = NULL;
>> +
>> +       overlay->path[0] = '\0';
> 
> ... the path is cleared...
> 
>> +       return err;
> 
> ...and a positive number is returned, smaller than the passed filename length.
> This makes VFS believe the write was truncated, hence it retries, writing only
> the remaining part of the filename again. That explains the dropped first
> character of the filename, and the firmware load failure.
> 
>> +}
> 
>> +ssize_t cfs_overlay_item_dtbo_write(struct cfs_overlay_item *overlay,
>> +               const void *buf, size_t count)
>> +{
>> +       int err;
>> +
>> +       /* if it's set do not allow changes */
>> +       if (overlay->path[0] != '\0' || overlay->dtbo_size > 0)
>> +               return -EPERM;
>> +
>> +       /* copy the contents */
>> +       overlay->dtbo = kmemdup(buf, count, GFP_KERNEL);
>> +       if (overlay->dtbo == NULL)
>> +               return -ENOMEM;
>> +
>> +       overlay->dtbo_size = count;
>> +
>> +       err = create_overlay(overlay, overlay->dtbo);
>> +       if (err != 0)
> 
> Same here: "if (err < 0)"
> 
>> +               goto out_err;
>> +
>> +       return count;
>> +
>> +out_err:
>> +       kfree(overlay->dtbo);
>> +       overlay->dtbo = NULL;
>> +       overlay->dtbo_size = 0;
>> +
>> +       return err;
>> +}
> 
> Gr{oetje,eeting}s,
> 
>                        Geert
> 

I will apply the fixes you pointed out. Good catch.

> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                -- Linus Torvalds

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]
  Powered by Linux