All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Maydell <peter.maydell@linaro.org>
To: Eric Auger <eric.auger@linaro.org>
Cc: "Baptiste Reynal" <b.reynal@virtualopensystems.com>,
	"Thomas Huth" <thuth@redhat.com>,
	eric.auger@st.com, "Patch Tracking" <patches@linaro.org>,
	"Peter Crosthwaite" <crosthwaitepeter@gmail.com>,
	"QEMU Developers" <qemu-devel@nongnu.org>,
	"Alex Williamson" <alex.williamson@redhat.com>,
	"Suravee Suthikulpanit" <suravee.suthikulpanit@amd.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	thomas.lendacky@amd.com, "Alex Bennée" <alex.bennee@linaro.org>,
	"Christoffer Dall" <christoffer.dall@linaro.org>,
	"David Gibson" <david@gibson.dropbear.id.au>
Subject: Re: [Qemu-devel] [PATCH 2/6] device_tree: introduce load_device_tree_from_sysfs
Date: Fri, 18 Dec 2015 14:10:57 +0000	[thread overview]
Message-ID: <CAFEAcA-r3XCgHP5GHztJAx1D=sVZW=aFCuATEAnc_WBMPn9EnA@mail.gmail.com> (raw)
In-Reply-To: <1450355367-14818-3-git-send-email-eric.auger@linaro.org>

On 17 December 2015 at 12:29, Eric Auger <eric.auger@linaro.org> wrote:
> This function returns the host device tree blob from sysfs
> (/sys/firmware/devicetree/base). It uses a recursive function
> inspired from dtc read_fstree.
>
> Signed-off-by: Eric Auger <eric.auger@linaro.org>
>
> ---
>
> RFC -> v1:
> - remove runtime dependency on dtc binary and introduce read_fstree
> ---
>  device_tree.c                | 102 +++++++++++++++++++++++++++++++++++++++++++
>  include/sysemu/device_tree.h |   1 +
>  2 files changed, 103 insertions(+)
>
> diff --git a/device_tree.c b/device_tree.c
> index a9f5f8e..e556a99 100644
> --- a/device_tree.c
> +++ b/device_tree.c
> @@ -17,6 +17,7 @@
>  #include <fcntl.h>
>  #include <unistd.h>
>  #include <stdlib.h>
> +#include <dirent.h>

Does this code compile on non-Linux hosts? (You've put it in a file
which is built everywhere, but it's definitely semantically Linux
specific.)

>  #include "qemu-common.h"
>  #include "qemu/error-report.h"
> @@ -117,6 +118,107 @@ fail:
>      return NULL;
>  }
>
> +/**
> + * read_fstree: this function is inspired from dtc read_fstree
> + * @fdt: preallocated fdt blob buffer, to be populated
> + * @dirname: directory to scan under /sys/firmware/devicetree/base
> + * the search is recursive and the tree is search down to the
> + * leafs (property files).
> + *
> + * the function self-asserts in case of error
> + */
> +static void read_fstree(void *fdt, const char *dirname)
> +{
> +        DIR *d;
> +        struct dirent *de;

Indent here doesn't match QEMU coding style, which is four-space.

> +        struct stat st;
> +        const char *root_dir = "/sys/firmware/devicetree/base";

You use this string twice and its length once so it would be nice
to have it in a #define.

> +        char *parent_node;
> +
> +        if (strstr(dirname, root_dir) != dirname) {
> +            error_report("%s: %s must be searched within %s",
> +                         __func__, dirname, root_dir);
> +            exit(1);
> +        }
> +        parent_node = (char *)&dirname[29];

I think 29 here should be strlen(SYSFS_DT_BASEDIR) or whatever
you want to call it.

> +
> +        d = opendir(dirname);
> +        if (!d) {
> +                error_report("%s cannot open %s", __func__, dirname);
> +                exit(1);
> +        }
> +
> +        while ((de = readdir(d)) != NULL) {
> +                char *tmpnam;
> +
> +                if (!g_strcmp0(de->d_name, ".")
> +                    || !g_strcmp0(de->d_name, "..")) {
> +                        continue;
> +                }

If you used glib g_dir_open/g_dir_read_name/g_dir_close it would
automatically skip '.' and '..' for you, but I'm not sure the
benefit is enough to bother redoing this code now.

> +
> +                tmpnam = g_strjoin("/", dirname, de->d_name, NULL);
> +
> +                if (lstat(tmpnam, &st) < 0) {
> +                        error_report("%s cannot lstat %s", __func__, tmpnam);
> +                        exit(1);
> +                }
> +
> +                if (S_ISREG(st.st_mode)) {
> +                    int ret, size = st.st_size;
> +                    void *val = g_malloc0(size);
> +                    FILE *pfile;
> +
> +                    pfile = fopen(tmpnam, "r");
> +                    if (!pfile) {
> +                        error_report("%s cannot open %s", __func__, tmpnam);
> +                        exit(1);
> +                    }
> +                    ret = fread(val, 1, size, pfile);
> +                    if (ferror(pfile) || ret < size) {
> +                        error_report("%s fail reading %s", __func__, tmpnam);
> +                        exit(1);
> +                    }
> +                    fclose(pfile);

This looks like it's reimplementing g_file_get_contents().

> +
> +                    if (strlen(parent_node) > 0) {
> +                        qemu_fdt_setprop(fdt, parent_node,
> +                                         de->d_name, val, size);
> +                    } else {
> +                        qemu_fdt_setprop(fdt, "/", de->d_name, val, size);
> +                    }
> +                    g_free(val);
> +                } else if (S_ISDIR(st.st_mode)) {
> +                        char *node_name;
> +
> +                        node_name = g_strdup_printf("%s/%s",
> +                                                    parent_node, de->d_name);
> +                        qemu_fdt_add_subnode(fdt, node_name);
> +                        g_free(node_name);
> +                        read_fstree(fdt, tmpnam);
> +                }
> +
> +                g_free(tmpnam);
> +        }
> +
> +        closedir(d);
> +}
> +
> +/* load_device_tree_from_sysfs: extract the dt blob from host sysfs */
> +void *load_device_tree_from_sysfs(void)
> +{
> +    void *host_fdt;
> +    int host_fdt_size;
> +
> +    host_fdt = create_device_tree(&host_fdt_size);
> +    read_fstree(host_fdt, "/sys/firmware/devicetree/base");
> +    if (fdt_check_header(host_fdt)) {
> +        error_report("%s host device tree extracted into memory is invalid",
> +                     __func__);
> +        g_free(host_fdt);

Why do we exit-on-error for the errors inside read_fstree() but
plough on (returning a pointer to freed memory!) in this case?

> +    }
> +    return host_fdt;
> +}
> +
>  static int findnode_nofail(void *fdt, const char *node_path)
>  {
>      int offset;
> diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h
> index 359e143..307e53d 100644
> --- a/include/sysemu/device_tree.h
> +++ b/include/sysemu/device_tree.h
> @@ -16,6 +16,7 @@
>
>  void *create_device_tree(int *sizep);
>  void *load_device_tree(const char *filename_path, int *sizep);
> +void *load_device_tree_from_sysfs(void);
>
>  int qemu_fdt_setprop(void *fdt, const char *node_path,
>                       const char *property, const void *val, int size);
> --
> 1.9.1

thanks
-- PMM

  reply	other threads:[~2015-12-18 14:11 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-17 12:29 [Qemu-devel] [PATCH 0/6] AMD XGBE KVM platform passthrough Eric Auger
2015-12-17 12:29 ` [Qemu-devel] [PATCH 1/6] hw/vfio/platform: amd-xgbe device Eric Auger
2015-12-18 13:53   ` Peter Maydell
2015-12-17 12:29 ` [Qemu-devel] [PATCH 2/6] device_tree: introduce load_device_tree_from_sysfs Eric Auger
2015-12-18 14:10   ` Peter Maydell [this message]
2016-01-04 17:37     ` Eric Auger
2016-01-04 21:33       ` Peter Maydell
2015-12-17 12:29 ` [Qemu-devel] [PATCH 3/6] device_tree: introduce qemu_fdt_node_path Eric Auger
2015-12-18 14:23   ` Peter Maydell
2016-01-05 16:20     ` Eric Auger
2016-01-05 17:55       ` Peter Maydell
2016-01-06  8:43         ` Eric Auger
2015-12-17 12:29 ` [Qemu-devel] [PATCH 4/6] device_tree: qemu_fdt_getprop converted to use the error API Eric Auger
2015-12-18 14:36   ` Peter Maydell
2016-01-05 16:20     ` Eric Auger
2016-01-05 17:54       ` Peter Maydell
2015-12-17 12:29 ` [Qemu-devel] [PATCH 5/6] hw/arm/sysbus-fdt: helpers for clock node generation Eric Auger
2015-12-18 14:54   ` Peter Maydell
2016-01-05 17:04     ` Eric Auger
2015-12-17 12:29 ` [Qemu-devel] [PATCH 6/6] hw/arm/sysbus-fdt: enable amd-xgbe dynamic instantiation Eric Auger
2015-12-18 15:05   ` Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAFEAcA-r3XCgHP5GHztJAx1D=sVZW=aFCuATEAnc_WBMPn9EnA@mail.gmail.com' \
    --to=peter.maydell@linaro.org \
    --cc=alex.bennee@linaro.org \
    --cc=alex.williamson@redhat.com \
    --cc=b.reynal@virtualopensystems.com \
    --cc=christoffer.dall@linaro.org \
    --cc=crosthwaitepeter@gmail.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=eric.auger@linaro.org \
    --cc=eric.auger@st.com \
    --cc=patches@linaro.org \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=suravee.suthikulpanit@amd.com \
    --cc=thomas.lendacky@amd.com \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.